fair-workflows / nanopub

Python client for searching, publishing and modifying nanopublications.
https://fair-workflows.github.io/nanopub
Apache License 2.0
22 stars 7 forks source link

`nanopub` package can not load profiles and keys that are somewhere else than in `$HOME/.nanopub` #150

Closed vemonet closed 1 year ago

vemonet commented 2 years ago

Hi @svenvanderburg @raar1 , I am trying to sign and publish nanopubs using the nanopub library with different nanopub profiles that are located in unconventional folders (not in the usual $HOME/.nanopub)

But I could not find any way to do so. It seems like the profile is loaded with a static function always using the home path + .nanopub which does not seems configurable: https://github.com/fair-workflows/nanopub/blob/main/nanopub/profile.py#L70 And the static path to $HOME/.nanopub is hard coded here: https://github.com/fair-workflows/nanopub/blob/main/nanopub/definitions.py#L7

For the use we want to do of nanopub we need to be able to load profiles and key pairs from any folder we ask. We cannot restrict ourselves to only one specific harcoded folder in the whole machine ($HOME/.nanopub). And in general it is not developer friendly to force the use of a hardcoded path on a machine, it is much more recommended to make this path configurable by the developers.

So I have started bringing changes to fix this issue by taking the following approach:

The profile is loaded in the np_client at __init__(), and put in a self.profile attribute. It defaults to home/.nanopub when nothing is provided. Then we only use the Profile that have been set in the np_client (no more static calls)

np_client = NanopubClient(profile_path='/somewhere/.nanopub/profile.yml')

# We use the nanopub client like a factory to create the publication
# The np client will pass the loaded Profile to the publication object
# Which might be required to generate some prov and pubinfo attributes
publication = np_client.create_publication(
    assertion_rdf=assertion,
    pubinfo_rdf=pubinfo,
    provenance_rdf=prov
)

np_client.publish(publication)

I already implemented most of it in this branch: https://github.com/vemonet/nanopub/tree/dev-vemonet

I made sure to keep backward compatibility at the moment, and all existing tests pass. But we would need additional improvements to make it really reliable (especially adding test cases)., and we might need to break backward compatibility at some point if we want to really make a clean implementation (otherwise we will still need to rely on some shady static hardcoded paths)

Additionally I also added a np_client.sign(publication) function, so that we can test to sign a publication before publishing them (before all we could do was nothing or publishing, but we could not try to just sign)

So my question is: would you be interested in integrating those changes to the nanopub package? (I prefer asking before going too far, as they are quite consequent)

Let me know if yes, then I will cleanup the code, improve testing and documentation, and send some pull requests

If no, we will directly use our fork in our projects, because not being able to load a nanopub profile from arbitrary folder paths is a major limitation

vemonet commented 2 years ago

Note that one of the advantages with using the NanopubClient to store profile info and create nanopubs is that you can define the different variables when instantiating the np_client, and they will be used by default when creating a Publication with np_client.create_publication(). Which make it really convenient to share the same nanopub configuration accross an application

For example:

np_client = NanopubClient(
    add_prov_generated_time=True,
    add_pubinfo_generated_time=True,
    attribute_assertion_to_profile=True,
    attribute_publication_to_profile=True,
)

publication = np_client.create_publication(
    assertion_rdf=assertion,
    pubinfo_rdf=pubinfo,
    provenance_rdf=prov
)
published_info = np_client.publish(publication)
raar1 commented 2 years ago

Wow, thanks for this! Yes, we would absolutely be interested in these changes. It was something we were always intending to do eventually, but never got around to it, so not an explicit design decision to keep this limitiation. Your changes are a huge improvement in the usability of the library, so please do consider raising a PR here :)

raar1 commented 1 year ago

This update has now been merged and released as part of v2.0.0