Skip to content

Commit

Permalink
removed multi readmes to master
Browse files Browse the repository at this point in the history
  • Loading branch information
mburridge96 committed Sep 13, 2024
1 parent 43acc8e commit 873e582
Show file tree
Hide file tree
Showing 4 changed files with 224 additions and 222 deletions.
226 changes: 223 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,231 @@ full python implementation.

# Libraries

1. [ro-crate-rs core](src/README.md)
2. [rocraters python bindings](python/README.md)
3. [cli tool](cli/README.md)
1. [ro-crate-rs core]
2. [rocraters python bindings]
3. [cli tool]

# Compatability

RO-Crate v1.1 only

# Rust Overview

ro-crate-rs is a rust library that aims to provide a robust, portable
and scalable solution to dealing [RO-Crates](https://www.researchobject.org/ro-crate/1.1/)
within the varying software environments that are present across a
Synthetic Biology Laboratory stack (it's current focus).
This implementation was specifically created to address the challenges of data
handling on automated robotic systems within an automated synthetic biology lab,
however it's noted that this could have more general applicability to other environments.
It enforces minimal
RO-Crate structure adherence through it's defined data types, but equally allows
the crate to be as expansive as needed.

# Basic structure

RO-Crates are based upon the JSON-LD (Javascript Object Notation for Linked Data Model),
using keys that have been defined in schema.org vocabularies, or other custom ontologies. In this library,
RO-Crates are deserialised directly into a `RoCrate` structure using `serde`.
The base Ro-Crate is formed out of a `struct RoCrate` containg a `@context` and a `@graph`.

The `@context` object contains a value refering to either a:
- Reference Context
- Embedded Context
- Extended Context

The `@graph` object is a `vector` containing other RO-Crate entity structures that are one of the following:
- Metadata Descriptor
- Root Data Entity
- Data Entity
- Contextual Entity

Within the `@graph`, there can only be one Metadata Descriptor and Root Data Entity, whilst
there can be zero to many Data Entities or Contextual Entities

Each entity structure consists of an `@id` (or `id` for struct field) and a `@type`
(or `type_` for struct field). For Metadata Descriptor and Root Data Entity, they
consist of other fields that have been determined to be a requirement by the
RO-Crate specification. Fields that have been determined as MUST by the RO-Crate
specification are required in their relevant data structure, whilst fields determined
as SHOULD are Options. Any field that is not described as MUST or SHOULD within
the specification can be added as a `dynamic_entity`.

Each entity structure also has a field called `dynamic_entity`, which allows the
population of any form of JSON-LD compatible value within the statically typed
requirements of rust. These, by default, are instantiated as `None`.

Fig 1 is an example of a base RO-Crate:
![](docs/ro-crate-structure.png "Basic RO-Crate structure")

Fig 2 is a diagram describing how each file relates to one another with a brief
intro to the main structures involved.
![](docs/ro-crate-schema.svg "Brief overview of ro-crate-rs core")

# Usage

To use, you will need to install rust. It's strongly recommended to use the `rustup` tool.
Follow the installation found on the [rust website](https://www.rust-lang.org/tools/install). Once
this is installed, you can then use cargo.

To compile for testing, use `cargo build` or `cargo build --release` is performance is a concern.

# Docs

To compile docs, run `cargo doc --open` and the documentation will open in your
default browser.





# Python Overview

rocraters is a python library that is built upon a rust backend for interfacing with [RO-Crates](https://www.researchobject.org/ro-crate/1.1/).
This implementation was specifically created to address the challenges of data
handling on automated robotic systems within an automated synthetic biology lab,
however it's noted that this could have more general applicability to other environments.

It's aim is to provide a robust, portable and scalable solution to dealing with
RO-Crates within the varying software environments of a synthetic biology lab stack.
It's designed to be maximally flexible with minimal onboarding, allowing you to
incorprate it into scrpits/ data pipelines as easily as possible.
This also relies on you to have an understanding of the structure of an RO-Crate, but focuses more on the fact that some metadata is better than no metadata.


*This is not the go-to python libary for RO-Crate interfacing,
please see [ro-crate-py](https://github.com/ResearchObject/ro-crate-py) for a
full python implementation.*

# Build

Built using PyO3 and maturin. Recommended to setup python venv, then install maturin (and remember maturin[patchelf])

# Installation

```bash
pip install -i https://test.pypi.org/simple/ rocraters
```

# Basic usage

The RO-Crate specification defines an RO-Crate as a JSON-LD file, consisting of a context and a graph. As such, in python it is a dictionary containing a "context" key, with some form of vocab context (default is the RO-Crate context) and a "graph" key, which contains a list of json objects (dictionaries).

To create an empty RO-Crate, you need to do the following:
```python
from rocraters import PyRoCrateContext, PyRoCrate

# Define context
context = PyRoCrateContext.from_string(" https://w3id.org/ro/crate/1.1/context")

# Initialise empty crate
crate = PyRoCrate(context)

# For an easy start, you can make a default crate!
default_crate = PyRoCrate.new_default()
```

Now, there are 4 primary objects (dictionaries) that can be added to the crate:
1. Metadata descriptor (only 1 per crate)
2. Root data entity (only 1 per crate)
3. Data entity (zero - many)
4. Contextual entity (zero - many)

These are all based upon the specification.

To populate the basic crate, with the essential keys to conform to specification:

```python
# Continuation of the above examples
# Metadata descriptor
descriptor = {
"type": "CreativeWork",
"id": "ro-crate-metadata.json",
"conformsTo": {"id": "https://w3id.org/ro/crate/1.1"},
"about": {"id": "./"}
}
# Root data entity
root = {
"id": "./",
"type": "Dataset",
"datePublished": "2017",
"license": {"id": "https://creativecommons.org/licenses/by-nc-sa/3.0/au/"}
}
# Data entity
data = {
"id": "data_file.txt",
"type": "Dataset"
}
# Contextual entity
contextual = {
"id": "#JohnDoe",
"type": "Person",
}

# Update the RO-Crate object
crate.update_descriptor(descriptor)
crate.update_root(root)
crate.update_data(data)
crate.update_contextual(contextual)
```

To then write the crate to a `ro-crate-metadata.json` file in the current working directory:
```python
# Continuation of the above examples
# Write crate
crate.write()
```

To then read a `ro-crate-metadata.json` file and load it in as a structured object:
```python
# New example
from rocraters import read

# Read RO-Crate at specified path
crate = read("ro-crate-metadata.json", True)
```

To zip the folder and all contained directories within the `ro-crate-metadata.json` directory:
```python
# new example
from rocraters import zip

zip("ro-crate-metadata.json", True)
```

# Modifying a RO-Crate

As per the libraries purpose, modification, ie the deletion, update and addition of entites is intended to be as simple as possible, whilst ensuring minimal conformance:

```python
# Example based upon previously made crate
from rocraters import read

crate = read("ro-crate-metadata.json", True)

# Update the data entity and make modification
data_target = crate.get_entity("data_file.txt")
data_target["description"] = "A text file dataset containing information"

# Update the contextual entity and make modification
contextual_target = crate.get_entity("#JohnDoe")
contextual_target.update({"id" : "#JaneDoe"})
crate.update_contextual(contextual_target)

# To delete a key:value
data_target.pop("description")

# To delete an entity - this immediately updates the crate object
contextual_target.delete_entity("#JaneDoe")

# We then update the crate the same way we make it
# The ID will be used to serach the crate and overwrites the object with an indentical "id" key
crate.update_data(data_target)
crate.write()
```

# Custom compilation

PyO3 is used to handle python bindings. Maturin is used as the build tool.


149 changes: 0 additions & 149 deletions python/README.md

This file was deleted.

1 change: 1 addition & 0 deletions python/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,4 @@ dynamic = ["version"]
[tool.maturin]
features = ["pyo3/extension-module"]


Loading

0 comments on commit 873e582

Please sign in to comment.