Skip to content

Commit

Permalink
chore: improve the list of prefixes used when building thenanopub, us…
Browse files Browse the repository at this point in the history
  • Loading branch information
vemonet committed Mar 11, 2024
1 parent 1b25934 commit b534f7f
Show file tree
Hide file tree
Showing 12 changed files with 102 additions and 86 deletions.
4 changes: 4 additions & 0 deletions lib/docs/docs/assets/custom.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/* We use emojis for every bullet lists */
ul li {
list-style-type: none;
}
6 changes: 3 additions & 3 deletions lib/docs/docs/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,21 +70,21 @@ np check signed.nanopub.trig

You can generate and enable completions for your shell:

- ZSH
- 🪐 ZSH

```bash
np completions zsh > ~/.zsh/completion/np
source ~/.zsh/completion/np
```

- Bash
- 🥊 Bash

```bash
np completions bash > ~/.bash_completion.d/np
source ~/.bash_completion.d/np
```

- Fish
- 🐟 Fish

```bash
np completions bash > ~/.config/fish/completions/np
Expand Down
55 changes: 15 additions & 40 deletions lib/docs/docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,48 +10,29 @@ Whether you're a developer looking to integrate nanopub functionalities into you

## 🪄 Nanopub management

<ul>
<li style="list-style-type: '✍️'">
&nbsp;<b>Sign & Publish</b> nanopubs using a RSA private key. Customize your workflow with a <code>profile.yml</code> file.
</li>
<li style="list-style-type: '🔍'">
&nbsp;<b>Verify</b>: ensure the integrity of nanopubs by checking their validity, whether they are signed or unsigned.
</li>
<li style="list-style-type: '📡'">
&nbsp;<b>Fetch</b> nanopubs from the network using their URI.
</li>
</ul>
- ✍️ **Sign & Publish** nanopublications RDF using a RSA private key. Support for user profile defined in a `profile.yml` file.
- 🔍 **Verify**: ensure the integrity of nanopubs by checking their validity, whether they are signed or unsigned.
- 📥 **Fetch** nanopubs from the network using their URI.

## 📦️ Packaged for multiple interfaces

This library is packaged for easy use across various interfaces and languages:

<ul>
<li style="list-style-type: '🦀'">
&nbsp;<a href="rust.md"><b>Rust developers</b></a>: available as a Rust crate <code>nanopub</code>.
</li>
<li style="list-style-type: '🐍'">
&nbsp;<a href="python.md"><b>Python programmers</b></a>: available as a Python pip package <code>nanopub-sign</code>.
</li>
<li style="list-style-type: '🌐'">
&nbsp;<a href="javascript.md"><b>Web developers</b></a>: available as a NPM package <code>@nanopub/sign</code>, compiled to <a href="https://webassembly.org/">WebAssembly</a>, for browser integrations with JavaScript, or NodeJS.
</li>
<li style="list-style-type: '⌨️'">
&nbsp;<a href="cli.md"><b>Terminal enthusiasts</b></a>: binary with a Command Line Interface (CLI) for straightforward terminal operations.
</li>
</ul>
- [🦀 **Rust developers**](rust.md): available as a Rust crate `nanopub`.
- [🐍 **Python programmers**](python.md): available as a Python pip package `nanopub-sign`.
- [🌐 **Web developers**](javascript.md): available as a NPM package `@nanopub/sign`, compiled to [WebAssembly](https://webassembly.org/), for browser integrations with JavaScript, or NodeJS.
- [⌨️ **Terminal enthusiasts**](cli.md): binary with a Command Line Interface (CLI) for straightforward terminal operations.


## ⚔️ Cross-platform support

It runs seamlessly on:

<ul>
<li style="list-style-type: '🦊'">&nbsp;Web browsers
<li style="list-style-type: '🐧'">&nbsp;Linux
<li style="list-style-type: '🍎'">&nbsp;MacOS
<li style="list-style-type: '🪟'">&nbsp;Windows
</ul>

- 🦊 Web browsers
- 🐧 Linux
- 🍎 MacOS
- 🪟 Windows


## 🧩 RDF serialization support
Expand All @@ -60,16 +41,10 @@ The library handles most RDF serializations supporting quads, including TriG, Nq

## 📝 Automated metadata creation

When you sign a nanopub, if it has not already been defined in the pubinfo graph yet:
When you sign a nanopub some metadata is added, if it has not already been defined in the pubinfo graph:

<ul>
<li style="list-style-type: '🕓'">
&nbsp;<b>Automatic timestamp</b>: the <code>dct:created</code> attribute is used to add the date and time of creation.
</li>
<li style="list-style-type: '🪪'">
&nbsp;<b>Creator identification</b>: if an ORCID is provided in the profile, it's added using <code>dct:creator</code>. The library also checks for ORCID set with <code>prov:wasAttributedTo</code> or <code>pav:createdBy</code>.
</li>
</ul>
- 🕓 **Automatic timestamp**: the `dct:created` attribute is used to add the date and time of creation.
- 🪪 **Creator identification**: if an ORCID is provided in the profile, it's added using `dct:creator`. The library also checks for ORCID already set with `prov:wasAttributedTo` or `pav:createdBy`.

## 👆 Interactive playground

Expand Down
8 changes: 4 additions & 4 deletions lib/docs/docs/javascript.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ Signed Nanopubs can be published to a Nanopub server. This makes the Nanopub acc

Use the `publish` function on a Nanopub, the 2 arguments are optional:

- `profile` is required if you want to also sign the nanopub, it is not required if you provide a signed nanopub
- If the `server_url` is null it will be published to the test server
- 🔑 `profile` is required if you want to also sign the nanopub, it is not required if you provide a signed nanopub
- 🧫 If the `server_url` is null it will be published to the test server

```typescript
import { Nanopub, NpProfile } from "@nanopub/sign";
Expand Down Expand Up @@ -133,11 +133,11 @@ import init, { Nanopub, NpProfile, KeyPair } from "@nanopub/sign";
let keypair = new KeyPair();
keypair = keypair.toJs();

// Create profile with new private key
// Create a profile with this new private key
const orcid = "https://orcid.org/0000-0000-0000-0000"
const profile = new NpProfile(keypair.private, orcid, "Your Name", "");

// Publish nanopub introduction for this profile
// Publish a nanopub introduction for this profile
Nanopub.publish_intro(profile, getNpServer(false))
.then(np => {
console.log("Published Introduction Nanopub:", np.info());
Expand Down
8 changes: 4 additions & 4 deletions lib/docs/docs/python.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ Signed Nanopubs can be published to a Nanopub server. This makes the Nanopub acc

Use the `publish` function on a Nanopub, the 2 arguments are optional:

- `profile` is required if you want to also sign the nanopub, it is not required if you provide a signed nanopub
- If the `server_url` is null it will be published to the test server
- 🔑 `profile` is required if you want to also sign the nanopub, it is not required if you provide a signed nanopub
- 🧫 If the `server_url` is null it will be published to the test server

```python
from nanopub_sign import Nanopub, NpProfile, get_np_server
Expand Down Expand Up @@ -146,15 +146,15 @@ from nanopub_sign import Nanopub, NpProfile, KeyPair, get_np_server
# Randomly generate a new private/public key pair
keypair = KeyPair()

# Create profile with new private key
# Create a profile with this new private key
new_profile = NpProfile(
private_key=keypair.private,
orcid_id="https://orcid.org/0000-0000-0000-0000",
name="",
introduction_nanopub_uri=""
)

# Publish nanopub introduction for this profile
# Publish a nanopub introduction for this profile
np = Nanopub.publish_intro(new_profile, get_np_server())
print(np.info())

Expand Down
35 changes: 29 additions & 6 deletions lib/docs/docs/rust.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ let signed_np = Nanopub::new(np_rdf).unwrap().sign(&profile).unwrap();
let checked_np = Nanopub::new(&signed_np.rdf().unwrap()).unwrap().check();

// Publish is async
let rt = runtime::Runtime::new().expect("Failed to create Tokio runtime");
let rt = runtime::Runtime::new().expect("Runtime failed");

let published_np = rt.block_on(async {
Nanopub::new(np_rdf).unwrap().publish(Some(&profile), None).await.unwrap()
Expand All @@ -61,8 +61,8 @@ println!("{}", published_np)

The `publish` function takes 2 optional arguments:

- `profile` is required if you want to also sign the nanopub, it is not required if you provide a signed nanopub
- If the `server_url` is none it will be published to the test server
- 🔑 `profile` is required if you want to also sign the nanopub, it is not required if you provide a signed nanopub
- 🧫 If the `server_url` is none it will be published to the test server

> Provide the nanopub signed or unsigned:
>
Expand Down Expand Up @@ -119,14 +119,37 @@ The `fetch` static function on the `Nanopub` struct allows you to retrieve Nanop
use nanopub::{Nanopub, NpProfile, NpError};
use tokio::runtime;

let url = "https://w3id.org/np/RAltRkGOtHoj5LcBJZ62AMVOAVc0hnxt45LMaCXgxJ4fw";
let rt = runtime::Runtime::new().expect("Failed to create Tokio runtime");
let uri = "https://w3id.org/np/RAltRkGOtHoj5LcBJZ62AMVOAVc0hnxt45LMaCXgxJ4fw";
let rt = runtime::Runtime::new().expect("Runtime failed");

let np = rt.block_on(async {
Nanopub::fetch(&url).await
Nanopub::fetch(&uri).await
}).unwrap();
```


### 🔑 Generate private key and publish introduction

You can generate a new private/public key pair, and publish a nanopub introduction to register this key under your ORCID in the Nanopublications network:

```rust
use nanopub::{profile::gen_keys, Nanopub, NpProfile};
use tokio::runtime;

// Randomly generate a new private/public key pair
let (private_key, _pubkey) = gen_keys().unwrap();

// Create a profile with this new private key
let profile = NpProfile::new(&private_key, "https://orcid.org/0000-0000-0000-0000", "", None).unwrap();

// Publish a nanopub introduction for this profile
let rt = runtime::Runtime::new().expect("Runtime failed");
let np = rt.block_on(async {
Nanopub::new_intro(&profile).unwrap()
.publish(Some(&profile), None).await.unwrap();
});
```

## 📖 API reference

Checkout the **[API documentation](https://docs.rs/nanopub)** for more details on how to use the different components and functions of the rust crate.
1 change: 1 addition & 0 deletions lib/docs/includes/abbreviations.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*[OSI]: Open Source Initiative
*[FSF]: Free Software Foundation
*[CVE]: Common Vulnerabilities and Exposures
*[WSL]: Windows Subsystem Linux
*[LLM]: Large Language Model
*[LLMs]: Large Language Models
*[ML]: Machine Learning
Expand Down
4 changes: 2 additions & 2 deletions lib/docs/mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ theme:
- media: "(prefers-color-scheme: light)"
scheme: default
primary: lime
accent: indigo
accent: deep orange
toggle:
icon: material/weather-night
name: Switch to dark mode
- media: "(prefers-color-scheme: dark)"
scheme: slate
primary: lime
accent: indigo
accent: deep orange
toggle:
icon: material/weather-sunny
name: Switch to light mode
Expand Down
2 changes: 1 addition & 1 deletion lib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ pub use error::NpError;
///
/// let signed_np = Nanopub::new(&np_rdf).unwrap().sign(&profile).unwrap();
/// let checked_np = Nanopub::new(&signed_np.rdf().unwrap()).unwrap().check();
/// let rt = runtime::Runtime::new().expect("Failed to create Tokio runtime");
/// let rt = runtime::Runtime::new().expect("Runtime failed");
/// let published_np = rt.block_on(async {
/// Nanopub::new(&np_rdf).unwrap().publish(Some(&profile), None).await.unwrap()
/// });
Expand Down
6 changes: 3 additions & 3 deletions lib/src/nanopub.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ impl Nanopub {
/// use nanopub::Nanopub;
/// use tokio::runtime;
/// let url = "https://w3id.org/np/RAltRkGOtHoj5LcBJZ62AMVOAVc0hnxt45LMaCXgxJ4fw";
/// let rt = runtime::Runtime::new().expect("Failed to create Tokio runtime");
/// let rt = runtime::Runtime::new().expect("Runtime failed");
///
/// let np = rt.block_on(async {
/// Nanopub::fetch(&url).await
Expand Down Expand Up @@ -353,7 +353,7 @@ impl Nanopub {
/// let np_rdf = fs::read_to_string("./tests/resources/simple1-rsa.trig").unwrap();
/// let orcid = "https://orcid.org/0000-0000-0000-0000";
/// let profile = NpProfile::new(&private_key, orcid, "", None).unwrap();
/// let rt = runtime::Runtime::new().expect("Failed to create Tokio runtime");
/// let rt = runtime::Runtime::new().expect("Runtime failed");
///
/// let np = rt.block_on(async {
/// Nanopub::new(&np_rdf).unwrap().publish(Some(&profile), None).await
Expand Down Expand Up @@ -472,7 +472,7 @@ impl Nanopub {
/// let 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=";
/// let orcid = "https://orcid.org/0000-0000-0000-0000";
/// let profile = NpProfile::new(&private_key, orcid, "User Name", None).unwrap();
/// let rt = runtime::Runtime::new().expect("Failed to create Tokio runtime");
/// let rt = runtime::Runtime::new().expect("Runtime failed");
///
/// let np = rt.block_on(async {
/// Nanopub::new_intro(&profile).unwrap().publish(Some(&profile), None).await.unwrap()
Expand Down
44 changes: 30 additions & 14 deletions lib/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use crate::error::NpError;
/// Parse RDF from various format to a `LightDataset` (trig, nquads, JSON-LD)
pub fn parse_rdf(rdf: &str) -> Result<LightDataset, NpError> {
let rdf = rdf.to_string();
// NOTE: an efficient way to differentiate between JSON-LD and TriG is to check if the string starts with '{' or '['
let dataset = if rdf.trim().starts_with('{') || rdf.trim().starts_with('[') {
parse_jsonld(&rdf)?
} else {
Expand Down Expand Up @@ -87,7 +88,7 @@ pub fn ns(ns: &str) -> Namespace<String> {

// TODO: improve to extract prefixes from the input RDF
/// Get the prefixes of a Nanopub
pub fn get_prefixes(np_uri: &str, np_ns: &str) -> [(Prefix<String>, Iri<String>); 14] {
pub fn get_prefixes(np_uri: &str, np_ns: &str) -> [(Prefix<String>, Iri<String>); 18] {
[
(
Prefix::new_unchecked("this".to_string()),
Expand All @@ -109,23 +110,30 @@ pub fn get_prefixes(np_uri: &str, np_ns: &str) -> [(Prefix<String>, Iri<String>)
Prefix::new_unchecked("xsd".to_string()),
Iri::new_unchecked("http://www.w3.org/2001/XMLSchema#".to_string()),
),
// TODO: use https:// by default?
(
Prefix::new_unchecked("schema".to_string()),
Iri::new_unchecked("http://schema.org/".to_string()),
),
(
Prefix::new_unchecked("foaf".to_string()),
Iri::new_unchecked("http://xmlns.com/foaf/0.1/".to_string()),
Prefix::new_unchecked("owl".to_string()),
Iri::new_unchecked("http://www.w3.org/2002/07/owl#".to_string()),
),
(
Prefix::new_unchecked("biolink".to_string()),
Iri::new_unchecked("https://w3id.org/biolink/vocab/".to_string()),
Prefix::new_unchecked("skos".to_string()),
Iri::new_unchecked("http://www.w3.org/2004/02/skos/core#".to_string()),
),
(
Prefix::new_unchecked("np".to_string()),
Iri::new_unchecked(ns("np").to_string()),
),
(
Prefix::new_unchecked("npx".to_string()),
Iri::new_unchecked(ns("npx").to_string()),
),
(
Prefix::new_unchecked("dc".to_string()),
Iri::new_unchecked("http://purl.org/dc/elements/1.1/".to_string()),
),
(
Prefix::new_unchecked("dcterms".to_string()),
Iri::new_unchecked("http://purl.org/dc/terms/".to_string()),
),
(
Prefix::new_unchecked("prov".to_string()),
Iri::new_unchecked("http://www.w3.org/ns/prov#".to_string()),
Expand All @@ -135,16 +143,24 @@ pub fn get_prefixes(np_uri: &str, np_ns: &str) -> [(Prefix<String>, Iri<String>)
Iri::new_unchecked("http://purl.org/pav/".to_string()),
),
(
Prefix::new_unchecked("dcterms".to_string()),
Iri::new_unchecked("http://purl.org/dc/terms/".to_string()),
Prefix::new_unchecked("schema".to_string()),
Iri::new_unchecked("https://schema.org/".to_string()),
),
(
Prefix::new_unchecked("foaf".to_string()),
Iri::new_unchecked("http://xmlns.com/foaf/0.1/".to_string()),
),
(
Prefix::new_unchecked("orcid".to_string()),
Iri::new_unchecked("https://orcid.org/".to_string()),
),
(
Prefix::new_unchecked("npx".to_string()),
Iri::new_unchecked(ns("npx").to_string()),
Prefix::new_unchecked("biolink".to_string()),
Iri::new_unchecked("https://w3id.org/biolink/vocab/".to_string()),
),
(
Prefix::new_unchecked("infores".to_string()),
Iri::new_unchecked("https://w3id.org/biolink/infores/".to_string()),
),
]
}
Loading

0 comments on commit b534f7f

Please sign in to comment.