Skip to content

Commit 4d38712

Browse files
authored
Merge pull request #103 from apdavison/inherit-ompy
Rewrite of fairgraph on top of openMINDS-Python
2 parents 0b88948 + 39f9fcd commit 4d38712

File tree

311 files changed

+9964
-22404
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

311 files changed

+9964
-22404
lines changed

.github/workflows/tests.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ jobs:
88
runs-on: ubuntu-latest
99
strategy:
1010
matrix:
11-
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
11+
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
1212

1313
steps:
14-
- uses: actions/checkout@v4
14+
- uses: actions/checkout@v5
1515
- name: Set up Python ${{ matrix.python-version }}
16-
uses: actions/setup-python@v5
16+
uses: actions/setup-python@v6
1717
with:
1818
python-version: ${{ matrix.python-version }}
1919
- name: Install dependencies

builder/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
To update the `fairgraph.openminds` module, run:
44

55
```
6-
python update_openminds.py /path/to/openMINDS
6+
python update_openminds.py /path/to/openMINDS/schemas/latest
77
```
88

9-
Where the various submodules have already been cloned and the desired version branches checked out.
9+
Where /path/to/openMINDS is a clone of the main branch of https://github.com/openMetadataInitiative/openMINDS.git
1010

1111
Before committing the resulting generated files, check that any changed introduced seem correct.
1212
Currently a few changes are applied by hand on top of the generated files, be sure not to overwrite these.

builder/fairgraph_module_template.py.txt

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,28 +4,22 @@
44

55
# this file was auto-generated
66

7-
from fairgraph import {{ base_class }}, IRI
8-
from fairgraph.properties import Property
7+
from openminds.properties import Property
8+
from openminds.{{ openminds_version }}.{{ module_name }} import {{ class_name }} as OM{{ class_name }}
9+
from fairgraph import {{ base_class }}
910

1011
{{preamble}}
1112

1213

13-
class {{ class_name }}({{ base_class }}):
14+
class {{ class_name }}({{base_class}}, OM{{ class_name }}):
1415
"""
1516
{{ docstring }}
1617
"""
18+
type_ = "{{ openminds_type }}"
1719
{%- if default_space %}
1820
default_space = "{{ default_space }}"
1921
{%- endif %}
20-
type_ = "{{ openminds_type }}"
21-
properties = [
22-
{% for prop in properties -%}
23-
Property("{{prop.name}}", {{prop.type_str}}, "{{prop.iri}}",
24-
{%- if prop.allow_multiple %}multiple={{prop.allow_multiple}},{% endif -%}
25-
{%- if prop.required %}required={{prop.required}},{% endif -%}
26-
doc="{{prop.doc}}"),
27-
{% endfor %}
28-
]
22+
# forward properties are defined in the parent class (in openMINDS-Python)
2923
reverse_properties = [
3024
{% for prop in reverse_properties -%}
3125
Property(
@@ -42,7 +36,7 @@ class {{ class_name }}({{ base_class }}):
4236
{% endif -%}
4337
{%- if prop.allow_multiple %}multiple={{prop.allow_multiple}},{% endif -%}
4438
{%- if prop.required %}, required={{prop.required}},{% endif -%}
45-
doc="{{prop.doc}}"),
39+
description="{{prop.doc}}"),
4640
{% endfor %}
4741
]
4842
{%- if aliases %}
@@ -53,5 +47,5 @@ class {{ class_name }}({{ base_class }}):
5347
{%- endif %}
5448

5549
def __init__(self {%- for arg in constructor_arguments -%}, {{arg}}=None{%- endfor -%}, id=None, data=None, space=None, scope=None):
56-
return super().__init__({{ standard_init_properties }}data=data {%- for arg in constructor_arguments -%}, {{arg}}={{arg}}{%- endfor -%})
50+
return {{ base_class }}.__init__(self, {{ standard_init_properties }}data=data {%- for arg in constructor_arguments -%}, {{arg}}={{arg}}{%- endfor -%})
5751
{{ additional_methods }}

builder/update_openminds.py

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
from jinja2 import Environment, select_autoescape, FileSystemLoader
1313

14+
OPENMINDS_VERSION = "latest"
1415

1516
name_map = {
1617
"scope": "model_scope", # this is because 'scope' is already a keyword
@@ -275,7 +276,7 @@ def invert_dict(D):
275276

276277

277278
DEFAULT_SPACES = {
278-
"chemicals": {"default": "dataset"},
279+
"chemicals": {"default": "in-depth"},
279280
"core": invert_dict(
280281
{
281282
"common": [
@@ -387,7 +388,6 @@ def invert_dict(D):
387388
),
388389
"publications": {"default": "livepapers"},
389390
"ephys": {"default": "in-depth"},
390-
"chemicals": {"default": "in-depth"},
391391
"specimen_prep": {"default": "in-depth"},
392392
"stimulation": {"default": "in-depth"},
393393
}
@@ -489,7 +489,7 @@ def generate_class_name(iri, module_map=None):
489489
assert isinstance(iri, str)
490490
class_name = iri.split("/")[-1]
491491
module_name = generate_python_name(module_map[iri])
492-
return f"openminds.{module_name}.{class_name}"
492+
return f"openminds.{OPENMINDS_VERSION}.{module_name}.{class_name}"
493493

494494

495495
def get_controlled_terms_table(type_):
@@ -586,17 +586,6 @@ def get_controlled_terms_table(type_):
586586
}
587587

588588

589-
def get_type_from_schema(schema_payload, override=True):
590-
if override: # temporarily use the old namespaces, until the KG is updated
591-
cls_name = schema_payload["_type"].split("/")[-1]
592-
module_name = schema_payload['_module']
593-
if module_name == "SANDS":
594-
module_name = "sands"
595-
return f"https://openminds.ebrains.eu/{module_name}/{cls_name}"
596-
else:
597-
return schema_payload["_type"]
598-
599-
600589
class FairgraphClassBuilder:
601590
"""docstring"""
602591

@@ -631,7 +620,6 @@ def get_type(prop):
631620
"email": "str", # todo: add an Email class for validation?
632621
"ECMA262": "str", # ...
633622
}
634-
#breakpoint()
635623
if "_linkedTypes" in prop:
636624
types = []
637625
for item in prop["_linkedTypes"]:
@@ -697,7 +685,7 @@ def get_type(prop):
697685
{
698686
"name": python_name,
699687
"type_str": get_type(prop), # compress using JSON-LD context
700-
"iri": f"vocab:{prop['name']}",
688+
"iri": f"{prop['name']}",
701689
"allow_multiple": allow_multiple,
702690
"required": iri in self._schema_payload.get("required", []),
703691
"doc": generate_doc(prop, class_name),
@@ -732,7 +720,7 @@ def get_type(prop):
732720
# todo: we should fix this at some point, using just the first forward_link_name causes things to break
733721
# making this a dictionary keyed by class names should work?
734722
_forward_link_name_python = generate_python_name(forward_link_name)
735-
iri = f"^vocab:{forward_iri}"
723+
iri = forward_iri
736724
doc = f"reverse of '{_forward_link_name_python}'"
737725
types_str = sorted(types_str)
738726
if len(types_str) == 1:
@@ -749,7 +737,7 @@ def get_type(prop):
749737
forward_iri = linked_from[reverse_link_name][0]
750738
forward_link_name = linked_from[reverse_link_name][1]
751739
_forward_link_name_python = [generate_python_name(name) for name in forward_link_name]
752-
iri = [f"^vocab:{part}" for part in forward_iri]
740+
iri = [part for part in forward_iri]
753741
doc = "reverse of " + ", ".join(name for name in _forward_link_name_python)
754742
reverse_name_python = generate_python_name(reverse_link_name)
755743
if reverse_name_python in forward_property_names:
@@ -777,12 +765,14 @@ def get_type(prop):
777765
with open(f"additional_methods/{class_name}.py.txt") as fp:
778766
additional_methods = fp.read()
779767
self.context = {
768+
"openminds_version": OPENMINDS_VERSION,
780769
"docstring": self._schema_payload.get("description", "<description not available>"),
781770
"base_class": base_class,
782771
"preamble": preamble.get(class_name, ""), # default value, may be updated below
772+
"module_name": module_name,
783773
"class_name": class_name,
784774
"default_space": default_space,
785-
"openminds_type": get_type_from_schema(self._schema_payload, override=True),
775+
"openminds_type": self._schema_payload["_type"],
786776
"properties": sorted(properties, key=lambda p: p["name"]),
787777
"reverse_properties": sorted(reverse_properties, key=lambda p: p["name"]),
788778
"additional_methods": "",
@@ -799,7 +789,7 @@ def get_type(prop):
799789
"date": "from datetime import date",
800790
"datetime": "from datetime import datetime",
801791
"time": "from datetime import time",
802-
"IRI": "from fairgraph.base import IRI",
792+
"IRI": "from openminds import IRI",
803793
"[datetime, time]": "from datetime import datetime, time",
804794
"Real": "from numbers import Real"
805795
}
@@ -849,7 +839,6 @@ def get_edges(self):
849839
reverse_link_name,
850840
) # linked from (cls, prop name, prop name plural, reverse name)
851841
# if self._schema_payload["_type"].endswith("File"):
852-
# breakpoint()
853842
return embedded, linked
854843

855844
def get_module_map(self):

fairgraph/__init__.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,24 @@
1919
limitations under the License.
2020
"""
2121

22+
from openminds import IRI
2223
from .client import KGClient
2324
from .kgobject import KGObject
2425
from .embedded import EmbeddedMetadata
2526
from .kgproxy import KGProxy
2627
from .kgquery import KGQuery
27-
from .base import IRI
28+
from . import client, errors, openminds, utility
2829

2930
__version__ = "0.12.2"
3031

31-
# from . import (
32-
# base, client, errors, utility, openminds)
32+
utility.initialise_instances([
33+
openminds.sands.BrainAtlas,
34+
openminds.sands.BrainAtlasVersion,
35+
openminds.sands.CommonCoordinateSpace,
36+
openminds.sands.CommonCoordinateSpaceVersion,
37+
openminds.core.ContentType,
38+
openminds.core.License,
39+
openminds.sands.ParcellationEntity,
40+
openminds.sands.ParcellationEntityVersion] +
41+
openminds.controlled_terms.list_kg_classes()
42+
)

0 commit comments

Comments
 (0)