Skip to content

Commit

Permalink
improve python bindings
Browse files Browse the repository at this point in the history
  • Loading branch information
vemonet committed Nov 20, 2023
1 parent 8bd0e63 commit 0cadc3a
Show file tree
Hide file tree
Showing 7 changed files with 143 additions and 127 deletions.
61 changes: 29 additions & 32 deletions docs/use_python.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,59 +19,56 @@ pip install nanopub-sign
Create a `sign.py` file with:

```python
from nanopub_sign import Nanopub
from nanopub_sign import Nanopub, NpProfile

rdf_str = """@prefix : <http://purl.org/nanopub/temp/mynanopub#> .
@prefix drugbank: <http://identifiers.org/drugbank/> .
@prefix np: <http://www.nanopub.org/nschema#> .
@prefix pav: <http://purl.org/pav/> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix infores: <https://w3id.org/biolink/infores/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix orcid: <https://orcid.org/> .
@prefix biolink: <https://w3id.org/biolink/vocab/> .
@prefix pmid: <http://www.ncbi.nlm.nih.gov/pubmed/> .
@prefix dc: <http://purl.org/dc/terms/> .
@prefix pav: <http://purl.org/pav/> .
@prefix prov: <http://www.w3.org/ns/prov#> .
@prefix np: <http://www.nanopub.org/nschema#> .
@prefix npx: <http://purl.org/nanopub/x/> .
@prefix ex: <http://example.org/> .
:Head {
: a np:Nanopublication ;
np:hasAssertion :assertion;
np:hasProvenance :provenance;
np:hasPublicationInfo :pubInfo .
: np:hasAssertion :assertion ;
np:hasProvenance :provenance ;
np:hasPublicationInfo :pubinfo ;
a np:Nanopublication .
}
:assertion {
drugbank:DB10771 a biolink:Drug .
<http://purl.obolibrary.org/obo/OMIM_130000> a biolink:Disease .
:association rdf:object <http://purl.obolibrary.org/obo/OMIM_130000>;
rdf:predicate biolink:treats;
rdf:subject drugbank:DB10771;
a biolink:ChemicalToDiseaseOrPhenotypicFeatureAssociation .
ex:mosquito ex:transmits ex:malaria .
}
:provenance {
:assertion dcterms:created "2020-09-21T00:00:00"^^xsd:dateTime .
:assertion prov:hadPrimarySource <http://dx.doi.org/10.3233/ISU-2010-0613> .
}
:pubInfo {
: prov:wasAttributedTo orcid:0000-0000-0000-0000 .
:pubinfo {
: dc:created "2014-07-24T18:05:11+01:00"^^xsd:dateTime ;
pav:createdBy <http://orcid.org/0000-0002-1267-0234> ;
a npx:ExampleNanopub .
}"""

private_key = """MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCjY1gsFxmak6SOCouJPuEzHNForkqFhgfHE3aAIAx+Y5q6UDEDM9Q0EksheNffJB4iPqsAfiFpY0ARQY92K5r8P4+a78eu9reYrb2WxZb1qPJmvR7XZ6sN1oHD7dd/EyQoJmQsmOKdrqaLRbzR7tZrf52yvKkwNWXcIVhW8uxe7iUgxiojZpW9srKoK/qFRpaUZSKn7Z/zgtDH9FJkYbBsGPDMqp78Kzt+sJb+U2W+wCSSy34jIUxx6QRbzvn6uexc/emFw/1DU5y7zBudhgC7mVk8vX1gUNKyjZBzlOmRcretrANgffqs5fx/TMHN1xtkA/H1u1IKBfKoyk/xThMLAgMBAAECggEAECuG0GZA3HF8OaqFgMG+W+agOvH04h4Pqv4cHjYNxnxpFcNV9nEssTKWSOvCwYy7hrwZBGV3PQzbjFmmrxVFs20+8yCD7KbyKKQZPVC0zf84bj6NTNgvr6DpGtDxINxuGaMjCt7enqhoRyRRuZ0fj2gD3Wqae/Ds8cpDCefkyMg0TvauHSUj244vGq5nt93txUv1Sa+/8tWZ77Dm0s5a3wUYB2IeAMl5WrO2GMvgzwH+zT+4kvNWg5S0Ze4KE+dG3lSIYZjo99h14LcQS9eALC/VBcAJ6pRXaCTT/TULtcLNeOpoc9Fu25f0yTsDt6Ga5ApliYkb7rDhV+OFrw1sYQKBgQDCE9so+dPg7qbp0cV+lbb7rrV43m5s9Klq0riS7u8m71oTwhmvm6gSLfjzqb8GLrmflCK4lKPDSTdwyvd+2SSmOXySw94zr1Pvc7sHdmMRyA7mH3m+zSOOgyCTTKyhDRCNcRIkysoL+DecDhNo4Fumf71tsqDYogfxpAQhn0re8wKBgQDXhMmmT2oXiMnYHhi2k7CJe3HUqkZgmW4W44SWqKHp0V6sjcHm0N0RT5Hz1BFFUd5Y0ZB3JLcah19myD1kKYCj7xz6oVLb8O7LeAZNlb0FsrtD7NU+Hciywo8qESiA7UYDkU6+hsmxaI01DsttMIdG4lSBbEjA7t4IQC5lyr7xiQKBgQCN87YGJ40Y5ZXCSgOZDepz9hqX2KGOIfnUv2HvXsIfiUwqTXs6HbD18xg3KL4myIBOvywSM+4ABYp+foY+Cpcq2btLIeZhiWjsKIrw71+Q/vIe0YDb1PGf6DsoYhmWBpdHzR9HN+hGjvwlsYny2L9Qbfhgxxmsuf7zeFLpQLijjwKBgH7TD28k8IOk5VKec2CNjKd600OYaA3UfCpP/OhDl/RmVtYoHWDcrBrRvkvEEd2/DZ8qw165Zl7gJs3vK+FTYvYVcfIzGPWA1KU7nkntwewmf3i7V8lT8ZTwVRsmObWU60ySJ8qKuwoBQodki2VX12NpMN1wgWe3qUUlr6gLJU4xAoGAet6nD3QKwk6TTmcGVfSWOzvpaDEzGkXjCLaxLKh9GreM/OE+h5aN2gUoFeQapG5rUwI/7Qq0xiLbRXw+OmfAoV2XKv7iI8DjdIh0F06mlEAwQ/B0CpbqkuuxphIbchtdcz/5ra233r3BMNIqBl3VDDVoJlgHPg9msOTRy13lFqc="""

np = Nanopub(
rdf=rdf_str,
# Check
np = Nanopub.check(rdf_str)
print(np.get_rdf())

# Publish
profile = NpProfile(
name="",
private_key=private_key,
orcid="https://orcid.org/0000-0000-0000-0000",
server_url='',
publish=False,
orcid_id="https://orcid.org/0000-0000-0000-0000",
introduction_nanopub_uri=""
)
np = Nanopub.publish(
rdf=rdf_str,
profile=profile,
server_url=None,
)

print(np.get_rdf())
```

Run it:
Expand Down
2 changes: 2 additions & 0 deletions lib/src/nanopub.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use std::collections::HashSet;
use std::{fmt, str};

/// Infos extracted from a nanopublication: graphs URLs, signature, trusty hash...
#[derive(Clone)]
pub struct NpInfo {
pub uri: Iri<String>,
pub ns: Namespace<String>,
Expand Down Expand Up @@ -50,6 +51,7 @@ impl fmt::Display for NpInfo {
}

/// A nanopublication object
#[derive(Clone)]
pub struct Nanopub {
pub uri: String,
pub ns: String,
Expand Down
2 changes: 1 addition & 1 deletion lib/src/profile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::constants::DEFAULT_NP_PROFILE;
use crate::constants::{BOLD, END};
use crate::error::NpError;

#[derive(Debug, Deserialize, Serialize)]
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct NpProfile {
pub orcid_id: String,
pub name: String,
Expand Down
2 changes: 0 additions & 2 deletions python/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ version = "0.0.0"
classifiers = [
"Development Status :: 3 - Alpha",
"Intended Audience :: Developers",
"License :: OSI Approved :: Apache Software License",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.7",
Expand All @@ -18,7 +17,6 @@ classifiers = [
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Rust",
"Topic :: Database :: Database Engines/Servers",
"Topic :: Software Development :: Libraries :: Python Modules",
]
requires-python = ">=3.7"
Expand Down
11 changes: 6 additions & 5 deletions python/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,13 @@ use pyo3::prelude::*;

/// Nanopub Python bindings
#[pymodule]
fn nanopub_sign(_py: Python<'_>, module: &PyModule) -> PyResult<()> {
module.add("__package__", "nanopub-sign")?;
module.add("__version__", env!("CARGO_PKG_VERSION"))?;
module.add("__author__", env!("CARGO_PKG_AUTHORS").replace(':', "\n"))?;
fn nanopub_sign(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
m.add("__package__", "nanopub-sign")?;
m.add("__version__", env!("CARGO_PKG_VERSION"))?;
m.add("__author__", env!("CARGO_PKG_AUTHORS").replace(':', "\n"))?;

module.add_class::<NanopubPy>()
m.add_class::<NpProfilePy>()?;
m.add_class::<NanopubPy>()

// io::add_to_module(module)
}
130 changes: 76 additions & 54 deletions python/src/nanopub.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,68 +2,67 @@ use nanopub::{Nanopub, NpProfile};
use pyo3::prelude::*;

#[pyclass(name = "Nanopub", module = "nanopub_sign")]
#[pyo3(text_signature = "(rdf, private_key, orcid, server_url=None, publish=False)")]
// #[derive(Clone)]
#[derive(Clone)]
pub struct NanopubPy {
np: Nanopub,
}

#[pymethods]
impl NanopubPy {
#[new]
fn new(
// #[new]
#[staticmethod]
#[pyo3(text_signature = "(rdf)")]
fn check(rdf: &str) -> PyResult<Self> {
let np = Nanopub::check(rdf).unwrap();
Ok(Self { np })
}

#[staticmethod]
#[pyo3(text_signature = "(rdf, private_key, orcid, server_url=None)")]
fn publish(
rdf: &str,
private_key: &str,
orcid: &str,
server_url: &str,
publish: bool,
py: Python<'_>,
profile: &NpProfilePy,
// private_key: &str,
// orcid: &str,
server_url: Option<&str>,
// py: Python<'_>,
) -> PyResult<Self> {
py.allow_threads(|| {
let profile = NpProfile::new(orcid, "", private_key, None).unwrap();
let np = if publish {
Nanopub::publish(
// &rdf.unwrap_or("default in py").to_string(),
rdf,
&profile,
Some(server_url),
)
.unwrap()
} else {
Nanopub::sign(rdf, &profile).unwrap()
};
Ok(Self { np })
// py.allow_threads(|| { // Put code in this block to enable true parallel https://pyo3.rs/v0.20.0/parallelism
// let profile = NpProfile::new(orcid, "", private_key, None).unwrap();

let np = Nanopub::publish(rdf, &profile.profile, server_url).unwrap();
// Nanopub::sign(rdf, &profile).unwrap()
Ok(Self { np })

// Ok( Self {
// rdf: nq_stringifier.serialize_dataset(&mut dataset)?.to_string(),
// dataset: dataset,
// public_key: public_key.to_string(),
// private_key: private_key.to_string(),
// orcid: orcid.to_string(),
// server_url: if let Some(server_url) = server_url {
// server_url.to_string()
// } else{
// TEST_SERVER.to_string()
// },
// publish: if let Some(publish) = publish {
// publish.clone()
// } else {
// false
// }
// })
// Ok( Self {
// rdf: nq_stringifier.serialize_dataset(&mut dataset)?.to_string(),
// dataset: dataset,
// public_key: public_key.to_string(),
// private_key: private_key.to_string(),
// orcid: orcid.to_string(),
// server_url: if let Some(server_url) = server_url {
// server_url.to_string()
// } else{
// TEST_SERVER.to_string()
// },
// publish: if let Some(publish) = publish {
// publish.clone()
// } else {
// false
// }
// })

// Ok(Self {
// np: Nanopub::new(&rdf.unwrap_or("default in py").to_string()),
// })
// Ok(Self {
// np: if let Some(rdf) = rdf {
// Nanopub::new(rdf.unwrap_or("default in py"))
// } else {
// Nanopub::new()
// }
// .map_err(map_storage_error)?,
// })
})
// Ok(Self {
// np: Nanopub::new(&rdf.unwrap_or("default in py").to_string()),
// })
// Ok(Self {
// np: if let Some(rdf) = rdf {
// Nanopub::new(rdf.unwrap_or("default in py"))
// } else {
// Nanopub::new()
// }
// .map_err(map_storage_error)?,
// })
}

// #[new]
Expand All @@ -84,8 +83,9 @@ impl NanopubPy {
// }

#[pyo3(text_signature = "($self)")]
fn get_rdf(&self, py: Python<'_>) -> PyResult<String> {
py.allow_threads(|| Ok(self.np.get_rdf()))
fn get_rdf(&self, _py: Python<'_>) -> PyResult<String> {
// py.allow_threads(|| Ok(self.np.get_rdf()))
Ok(self.np.get_rdf())
}

// /// >>> store.update('DELETE WHERE { <http://example.com> ?p ?o }')
Expand All @@ -100,6 +100,28 @@ impl NanopubPy {
// }
}

#[pyclass(name = "NpProfile", module = "nanopub_sign")]
#[derive(Clone)]
pub struct NpProfilePy {
profile: NpProfile,
}

#[pymethods]
impl NpProfilePy {
#[new]
#[pyo3(text_signature = "(orcid_id, name, private_key, introduction_nanopub_uri)")]
fn new(
orcid_id: &str,
name: &str,
private_key: &str,
introduction_nanopub_uri: Option<&str>,
) -> PyResult<Self> {
let profile =
NpProfile::new(orcid_id, name, private_key, introduction_nanopub_uri).unwrap();
Ok(Self { profile })
}
}

// /// Formats the sum of two numbers as string.
// #[pyfunction]
// fn sum_as_string(a: usize, b: usize) -> PyResult<String> {
Expand Down
62 changes: 29 additions & 33 deletions python/try.py
Original file line number Diff line number Diff line change
@@ -1,54 +1,50 @@
from nanopub_sign import Nanopub
from nanopub_sign import Nanopub, NpProfile

rdf_str = """@prefix : <http://purl.org/nanopub/temp/mynanopub#> .
@prefix drugbank: <http://identifiers.org/drugbank/> .
@prefix np: <http://www.nanopub.org/nschema#> .
@prefix pav: <http://purl.org/pav/> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix infores: <https://w3id.org/biolink/infores/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix orcid: <https://orcid.org/> .
@prefix biolink: <https://w3id.org/biolink/vocab/> .
@prefix pmid: <http://www.ncbi.nlm.nih.gov/pubmed/> .
@prefix dc: <http://purl.org/dc/terms/> .
@prefix pav: <http://purl.org/pav/> .
@prefix prov: <http://www.w3.org/ns/prov#> .
@prefix np: <http://www.nanopub.org/nschema#> .
@prefix npx: <http://purl.org/nanopub/x/> .
@prefix ex: <http://example.org/> .
:Head {
: a np:Nanopublication ;
np:hasAssertion :assertion;
np:hasProvenance :provenance;
np:hasPublicationInfo :pubInfo .
: np:hasAssertion :assertion ;
np:hasProvenance :provenance ;
np:hasPublicationInfo :pubinfo ;
a np:Nanopublication .
}
:assertion {
drugbank:DB10771 a biolink:Drug .
<http://purl.obolibrary.org/obo/OMIM_130000> a biolink:Disease .
:association rdf:object <http://purl.obolibrary.org/obo/OMIM_130000>;
rdf:predicate biolink:treats;
rdf:subject drugbank:DB10771;
a biolink:ChemicalToDiseaseOrPhenotypicFeatureAssociation .
ex:mosquito ex:transmits ex:malaria .
}
:provenance {
:assertion dcterms:created "2020-09-21T00:00:00"^^xsd:dateTime .
:assertion prov:hadPrimarySource <http://dx.doi.org/10.3233/ISU-2010-0613> .
}
:pubInfo {
: prov:wasAttributedTo orcid:0000-0000-0000-0000 .
:pubinfo {
: dc:created "2014-07-24T18:05:11+01:00"^^xsd:dateTime ;
pav:createdBy <http://orcid.org/0000-0002-1267-0234> ;
a npx:ExampleNanopub .
}"""

private_key = """MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCjY1gsFxmak6SOCouJPuEzHNForkqFhgfHE3aAIAx+Y5q6UDEDM9Q0EksheNffJB4iPqsAfiFpY0ARQY92K5r8P4+a78eu9reYrb2WxZb1qPJmvR7XZ6sN1oHD7dd/EyQoJmQsmOKdrqaLRbzR7tZrf52yvKkwNWXcIVhW8uxe7iUgxiojZpW9srKoK/qFRpaUZSKn7Z/zgtDH9FJkYbBsGPDMqp78Kzt+sJb+U2W+wCSSy34jIUxx6QRbzvn6uexc/emFw/1DU5y7zBudhgC7mVk8vX1gUNKyjZBzlOmRcretrANgffqs5fx/TMHN1xtkA/H1u1IKBfKoyk/xThMLAgMBAAECggEAECuG0GZA3HF8OaqFgMG+W+agOvH04h4Pqv4cHjYNxnxpFcNV9nEssTKWSOvCwYy7hrwZBGV3PQzbjFmmrxVFs20+8yCD7KbyKKQZPVC0zf84bj6NTNgvr6DpGtDxINxuGaMjCt7enqhoRyRRuZ0fj2gD3Wqae/Ds8cpDCefkyMg0TvauHSUj244vGq5nt93txUv1Sa+/8tWZ77Dm0s5a3wUYB2IeAMl5WrO2GMvgzwH+zT+4kvNWg5S0Ze4KE+dG3lSIYZjo99h14LcQS9eALC/VBcAJ6pRXaCTT/TULtcLNeOpoc9Fu25f0yTsDt6Ga5ApliYkb7rDhV+OFrw1sYQKBgQDCE9so+dPg7qbp0cV+lbb7rrV43m5s9Klq0riS7u8m71oTwhmvm6gSLfjzqb8GLrmflCK4lKPDSTdwyvd+2SSmOXySw94zr1Pvc7sHdmMRyA7mH3m+zSOOgyCTTKyhDRCNcRIkysoL+DecDhNo4Fumf71tsqDYogfxpAQhn0re8wKBgQDXhMmmT2oXiMnYHhi2k7CJe3HUqkZgmW4W44SWqKHp0V6sjcHm0N0RT5Hz1BFFUd5Y0ZB3JLcah19myD1kKYCj7xz6oVLb8O7LeAZNlb0FsrtD7NU+Hciywo8qESiA7UYDkU6+hsmxaI01DsttMIdG4lSBbEjA7t4IQC5lyr7xiQKBgQCN87YGJ40Y5ZXCSgOZDepz9hqX2KGOIfnUv2HvXsIfiUwqTXs6HbD18xg3KL4myIBOvywSM+4ABYp+foY+Cpcq2btLIeZhiWjsKIrw71+Q/vIe0YDb1PGf6DsoYhmWBpdHzR9HN+hGjvwlsYny2L9Qbfhgxxmsuf7zeFLpQLijjwKBgH7TD28k8IOk5VKec2CNjKd600OYaA3UfCpP/OhDl/RmVtYoHWDcrBrRvkvEEd2/DZ8qw165Zl7gJs3vK+FTYvYVcfIzGPWA1KU7nkntwewmf3i7V8lT8ZTwVRsmObWU60ySJ8qKuwoBQodki2VX12NpMN1wgWe3qUUlr6gLJU4xAoGAet6nD3QKwk6TTmcGVfSWOzvpaDEzGkXjCLaxLKh9GreM/OE+h5aN2gUoFeQapG5rUwI/7Qq0xiLbRXw+OmfAoV2XKv7iI8DjdIh0F06mlEAwQ/B0CpbqkuuxphIbchtdcz/5ra233r3BMNIqBl3VDDVoJlgHPg9msOTRy13lFqc="""

np = Nanopub(
rdf=rdf_str,
# Check
np = Nanopub.check(rdf_str)
print(np.get_rdf())

# Publish
profile = NpProfile(
name="",
private_key=private_key,
orcid="https://orcid.org/0000-0000-0000-0000",
# TODO: Defaults don't work
server_url='',
publish=False,
orcid_id="https://orcid.org/0000-0000-0000-0000",
introduction_nanopub_uri=""
)
np = Nanopub.publish(
rdf=rdf_str,
profile=profile,
server_url=None,
)

print(np.get_rdf())

0 comments on commit 0cadc3a

Please sign in to comment.