commit 4bbc5a90d4ace5cab791260e9e5cf140fbd7956d Author: fpotier Date: Mon Mar 9 15:25:20 2026 +0100 simple example diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..93248be --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,22 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/python +{ + "name": "Python 3", + // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile + "image": "mcr.microsoft.com/devcontainers/python:2-3.13-trixie" + + // Features to add to the dev container. More info: https://containers.dev/features. + // "features": {}, + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "forwardPorts": [], + + // Use 'postCreateCommand' to run commands after the container is created. + // "postCreateCommand": "pip3 install --user -r requirements.txt", + + // Configure tool-specific properties. + // "customizations": {}, + + // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. + // "remoteUser": "root" +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..97475bc --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.venv +output_crates diff --git a/main.py b/main.py new file mode 100755 index 0000000..68f4c92 --- /dev/null +++ b/main.py @@ -0,0 +1,95 @@ +#!/usr/bin/env python3 + +from typing import List, Optional, Union + +from pydantic import BaseModel +from lib_ro_crate_schema.crate.decorators import ro_crate_schema, Field +from lib_ro_crate_schema.crate.schema_facade import SchemaFacade +from lib_ro_crate_schema.crate.jsonld_utils import add_schema_to_crate +from rocrate.rocrate import ROCrate +from pathlib import Path + + +@ro_crate_schema(ontology="https://schema.org/PropertyValue") +class PropertyValue(BaseModel): + name: str = Field(json_schema_extra={ + "ontology": "https://schema.org/name"}) + value: Union[str, bool, int, float, 'PropertyValue', List['PropertyValue']] = Field(json_schema_extra={ + "ontology": "https://schema.org/value"}) + unitText: Optional[str] = Field(default=None, json_schema_extra={ + "ontology": "https://schema.org/unitText"}) + + +@ro_crate_schema(ontology="https://schema.org/Person") +class Person(BaseModel): + name: str = Field(json_schema_extra={ + "ontology": "https://schema.org/name"}) + givenName: str = Field(json_schema_extra={ + "ontology": "https://schema.org/givenName"}) + familyName: str = Field(json_schema_extra={ + "ontology": "https://schema.org/familyName"}) + + +@ro_crate_schema(ontology="https://schema.org/Dataset") +class Dataset(BaseModel): + name: str = Field(json_schema_extra={ + "ontology": "https://schema.org/name"}) + description: str = Field(json_schema_extra={ + "ontology": "https://schema.org/description"}) + creator: Union[Person, List[Person]] = Field(json_schema_extra={ + "ontology": "https://schema.org/creator"}) + additionalProperty: Union[PropertyValue, List[PropertyValue]] = Field(json_schema_extra={ + "ontology": "https://schema.org/additionalProperty"}) + + +def main(): + facade = SchemaFacade() + facade.add_all_registered_models() + + creator_1 = Person(givenName="John", familyName="Doe", name="Doe, John") + creator_2 = Person(givenName="Jane", familyName="Doe", name="Doe, Jane") + + metadata = [ + PropertyValue(name="data_collection", value=[ + PropertyValue(name="wavelength", value=3.14, unitText='angstrom'), + PropertyValue(name="energy", value=3, unitText='keV'), + PropertyValue(name="detector", value="Eiger"), + ]) + ] + + dataset = Dataset(name="Aare dataset", description="This dataset comes from a RO-Crate", + creator=[creator_1, creator_2], additionalProperty=metadata) + + facade.add_model_instance(dataset, "_:b0") + + # Create RO-Crate + crate = ROCrate() + crate.name = "Minimal Example" + crate.description = "A minimal RO-Crate with one Person" + + final_crate = add_schema_to_crate(facade, crate) + + # Export + # output_path = Path("output_crates/minimal_example") + # output_path.mkdir(parents=True, exist_ok=True) + # final_crate.write(output_path) + + buffer = b''.join(final_crate.stream_zip()) + import requests + import os + response = requests.post( + "http://pc17166.psi.ch:8080/api/v1/ro-crate/import", + headers={ + "content-type": "application/zip", + "accept": "application/json", + "api-key": os.environ["API_KEY"] + }, data=final_crate.stream_zip()) + response.raise_for_status() + print(response.json()) + + # print(f"✓ RO-Crate exported to: {output_path}") + # print(f"✓ Entities: {len(final_crate.get_entities())}") + + +if __name__ == "__main__": + main() diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..85ce42a --- /dev/null +++ b/requirements.txt @@ -0,0 +1,37 @@ +--index-url https://pypi.psi.ch/simple +--extra-index-url https://gitea.psi.ch/api/packages/potier_f/pypi/simple/ + +annotated-types==0.7.0 +arcp==0.2.1 +cachetools==7.0.4 +certifi==2026.2.25 +charset-normalizer==3.4.5 +click==8.3.1 +frozendict==2.4.7 +gitdb==4.0.12 +GitPython==3.1.41 +html5rdf==1.2.1 +idna==3.11 +Jinja2==3.1.6 +lib-ro-crate-schema==0.2.2 +lxml==6.0.2 +MarkupSafe==3.0.3 +owlrl==7.1.4 +packaging==26.0 +prettytable==3.17.0 +pydantic==2.12.5 +pydantic_core==2.41.5 +PyLD==2.0.4 +pyparsing==3.3.2 +pyshacl==0.31.0 +python-dateutil==2.9.0.post0 +rdflib==7.6.0 +requests==2.32.5 +rocrate==0.14.2 +setuptools==78.1.1 +six==1.17.0 +smmap==5.0.2 +typing-inspection==0.4.2 +typing_extensions==4.15.0 +urllib3==2.6.3 +wcwidth==0.6.0