entitysdk 0.1.0__tar.gz → 0.1.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. {entitysdk-0.1.0/src/entitysdk.egg-info → entitysdk-0.1.2}/PKG-INFO +1 -1
  2. {entitysdk-0.1.0 → entitysdk-0.1.2}/examples/morphology.ipynb +1 -1
  3. {entitysdk-0.1.0 → entitysdk-0.1.2}/examples/searching.ipynb +2 -1
  4. {entitysdk-0.1.0 → entitysdk-0.1.2}/src/entitysdk/models/agent.py +3 -0
  5. {entitysdk-0.1.0 → entitysdk-0.1.2}/src/entitysdk/models/contribution.py +2 -3
  6. {entitysdk-0.1.0 → entitysdk-0.1.2}/src/entitysdk/models/entity.py +3 -3
  7. {entitysdk-0.1.0 → entitysdk-0.1.2}/src/entitysdk/models/morphology.py +1 -0
  8. {entitysdk-0.1.0 → entitysdk-0.1.2}/src/entitysdk/util.py +1 -1
  9. {entitysdk-0.1.0 → entitysdk-0.1.2/src/entitysdk.egg-info}/PKG-INFO +1 -1
  10. {entitysdk-0.1.0 → entitysdk-0.1.2}/src/entitysdk.egg-info/SOURCES.txt +3 -2
  11. {entitysdk-0.1.0 → entitysdk-0.1.2}/tests/unit/conftest.py +3 -2
  12. entitysdk-0.1.2/tests/unit/models/data/reconstruction_morphology.json +175 -0
  13. entitysdk-0.1.2/tests/unit/models/test_agent.py +66 -0
  14. {entitysdk-0.1.0 → entitysdk-0.1.2}/tests/unit/models/test_contribution.py +18 -0
  15. entitysdk-0.1.2/tests/unit/models/test_morphology.py +62 -0
  16. entitysdk-0.1.2/tests/unit/util.py +5 -0
  17. entitysdk-0.1.0/tests/unit/models/test_agent.py +0 -25
  18. entitysdk-0.1.0/tests/unit/models/test_morphology.py +0 -138
  19. entitysdk-0.1.0/tests/unit/util.py +0 -3
  20. {entitysdk-0.1.0 → entitysdk-0.1.2}/.github/workflows/sdist.yml +0 -0
  21. {entitysdk-0.1.0 → entitysdk-0.1.2}/.github/workflows/tox.yml +0 -0
  22. {entitysdk-0.1.0 → entitysdk-0.1.2}/.gitignore +0 -0
  23. {entitysdk-0.1.0 → entitysdk-0.1.2}/CHANGELOG.rst +0 -0
  24. {entitysdk-0.1.0 → entitysdk-0.1.2}/CONTRIBUTING.md +0 -0
  25. {entitysdk-0.1.0 → entitysdk-0.1.2}/LICENSE.txt +0 -0
  26. {entitysdk-0.1.0 → entitysdk-0.1.2}/README.md +0 -0
  27. {entitysdk-0.1.0 → entitysdk-0.1.2}/examples/contribution.ipynb +0 -0
  28. {entitysdk-0.1.0 → entitysdk-0.1.2}/pyproject.toml +0 -0
  29. {entitysdk-0.1.0 → entitysdk-0.1.2}/setup.cfg +0 -0
  30. {entitysdk-0.1.0 → entitysdk-0.1.2}/src/entitysdk/__init__.py +0 -0
  31. {entitysdk-0.1.0 → entitysdk-0.1.2}/src/entitysdk/client.py +0 -0
  32. {entitysdk-0.1.0 → entitysdk-0.1.2}/src/entitysdk/common.py +0 -0
  33. {entitysdk-0.1.0 → entitysdk-0.1.2}/src/entitysdk/config.py +0 -0
  34. {entitysdk-0.1.0 → entitysdk-0.1.2}/src/entitysdk/core.py +0 -0
  35. {entitysdk-0.1.0 → entitysdk-0.1.2}/src/entitysdk/exception.py +0 -0
  36. {entitysdk-0.1.0 → entitysdk-0.1.2}/src/entitysdk/mixin.py +0 -0
  37. {entitysdk-0.1.0 → entitysdk-0.1.2}/src/entitysdk/models/__init__.py +0 -0
  38. {entitysdk-0.1.0 → entitysdk-0.1.2}/src/entitysdk/models/asset.py +0 -0
  39. {entitysdk-0.1.0 → entitysdk-0.1.2}/src/entitysdk/models/base.py +0 -0
  40. {entitysdk-0.1.0 → entitysdk-0.1.2}/src/entitysdk/models/core.py +0 -0
  41. {entitysdk-0.1.0 → entitysdk-0.1.2}/src/entitysdk/models/mtype.py +0 -0
  42. {entitysdk-0.1.0 → entitysdk-0.1.2}/src/entitysdk/models/response.py +0 -0
  43. {entitysdk-0.1.0 → entitysdk-0.1.2}/src/entitysdk/result.py +0 -0
  44. {entitysdk-0.1.0 → entitysdk-0.1.2}/src/entitysdk/route.py +0 -0
  45. {entitysdk-0.1.0 → entitysdk-0.1.2}/src/entitysdk/serdes.py +0 -0
  46. {entitysdk-0.1.0 → entitysdk-0.1.2}/src/entitysdk/token_manager.py +0 -0
  47. {entitysdk-0.1.0 → entitysdk-0.1.2}/src/entitysdk/typedef.py +0 -0
  48. {entitysdk-0.1.0 → entitysdk-0.1.2}/src/entitysdk.egg-info/dependency_links.txt +0 -0
  49. {entitysdk-0.1.0 → entitysdk-0.1.2}/src/entitysdk.egg-info/requires.txt +0 -0
  50. {entitysdk-0.1.0 → entitysdk-0.1.2}/src/entitysdk.egg-info/top_level.txt +0 -0
  51. {entitysdk-0.1.0 → entitysdk-0.1.2}/tests/__init__.py +0 -0
  52. {entitysdk-0.1.0 → entitysdk-0.1.2}/tests/integration/__init__.py +0 -0
  53. {entitysdk-0.1.0 → entitysdk-0.1.2}/tests/integration/conftest.py +0 -0
  54. {entitysdk-0.1.0 → entitysdk-0.1.2}/tests/integration/test_searching.py +0 -0
  55. {entitysdk-0.1.0 → entitysdk-0.1.2}/tests/unit/__init__.py +0 -0
  56. {entitysdk-0.1.0 → entitysdk-0.1.2}/tests/unit/models/__init__.py +0 -0
  57. {entitysdk-0.1.0/tests/unit → entitysdk-0.1.2/tests/unit/models}/data/.gitignore +0 -0
  58. {entitysdk-0.1.0 → entitysdk-0.1.2}/tests/unit/models/test_asset.py +0 -0
  59. {entitysdk-0.1.0 → entitysdk-0.1.2}/tests/unit/test_base.py +0 -0
  60. {entitysdk-0.1.0 → entitysdk-0.1.2}/tests/unit/test_client.py +0 -0
  61. {entitysdk-0.1.0 → entitysdk-0.1.2}/tests/unit/test_config.py +0 -0
  62. {entitysdk-0.1.0 → entitysdk-0.1.2}/tests/unit/test_result.py +0 -0
  63. {entitysdk-0.1.0 → entitysdk-0.1.2}/tests/unit/test_route.py +0 -0
  64. {entitysdk-0.1.0 → entitysdk-0.1.2}/tests/unit/test_serdes.py +0 -0
  65. {entitysdk-0.1.0 → entitysdk-0.1.2}/tests/unit/test_token_manager.py +0 -0
  66. {entitysdk-0.1.0 → entitysdk-0.1.2}/tests/unit/test_util.py +0 -0
  67. {entitysdk-0.1.0 → entitysdk-0.1.2}/tox.ini +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: entitysdk
3
- Version: 0.1.0
3
+ Version: 0.1.2
4
4
  Summary: Python library for interacting with the entitycore service
5
5
  Author-email: Open Brain Institute <info@openbraininstitute.org>
6
6
  Maintainer-email: Open Brain Institute <info@openbraininstitute.org>
@@ -134,7 +134,7 @@
134
134
  " strain=strain,\n",
135
135
  " brain_region=brain_region,\n",
136
136
  " location=brain_location,\n",
137
- " legacy_id=\"temp\",\n",
137
+ " legacy_id=None,\n",
138
138
  ")"
139
139
  ]
140
140
  },
@@ -13,7 +13,8 @@
13
13
  "\n",
14
14
  "from entitysdk.client import Client\n",
15
15
  "from entitysdk.common import ProjectContext\n",
16
- "from entitysdk.models.contribution import Organization, Person, Role\n",
16
+ "from entitysdk.models.agent import Organization, Person\n",
17
+ "from entitysdk.models.contribution import Role\n",
17
18
  "from entitysdk.models.morphology import (\n",
18
19
  " ReconstructionMorphology,\n",
19
20
  " Species,\n",
@@ -66,3 +66,6 @@ class Organization(Agent):
66
66
  description="The alternative name of the organization.",
67
67
  ),
68
68
  ] = None
69
+
70
+
71
+ AgentUnion = Annotated[Person | Organization, Field(discriminator="type")]
@@ -4,7 +4,7 @@ from typing import Annotated
4
4
 
5
5
  from pydantic import Field
6
6
 
7
- from entitysdk.models.agent import Organization, Person
7
+ from entitysdk.models.agent import AgentUnion
8
8
  from entitysdk.models.core import Identifiable
9
9
  from entitysdk.models.entity import Entity
10
10
 
@@ -30,9 +30,8 @@ class Contribution(Identifiable):
30
30
  """Contribution model."""
31
31
 
32
32
  agent: Annotated[
33
- Person | Organization,
33
+ AgentUnion,
34
34
  Field(
35
- discriminator="type",
36
35
  description="The agent of the contribution.",
37
36
  ),
38
37
  ]
@@ -5,7 +5,7 @@ from uuid import UUID
5
5
 
6
6
  from pydantic import Field
7
7
 
8
- from entitysdk.models.agent import Agent
8
+ from entitysdk.models.agent import AgentUnion
9
9
  from entitysdk.models.core import Identifiable
10
10
 
11
11
 
@@ -13,11 +13,11 @@ class Entity(Identifiable):
13
13
  """Entity is a model with id and authorization."""
14
14
 
15
15
  createdBy: Annotated[
16
- Agent | None,
16
+ AgentUnion | None,
17
17
  Field(description="The agent that created this entity."),
18
18
  ] = None
19
19
  updatedBy: Annotated[
20
- Agent | None,
20
+ AgentUnion | None,
21
21
  Field(
22
22
  description="The agent that updated this entity.",
23
23
  ),
@@ -227,3 +227,4 @@ class ReconstructionMorphology(HasAssets, Entity):
227
227
  description="The mtype classes of the morphology.",
228
228
  ),
229
229
  ] = None
230
+ legacy_id: list[str] | None = None
@@ -31,7 +31,7 @@ def make_db_api_request(
31
31
 
32
32
  if project_context:
33
33
  headers["project-id"] = str(project_context.project_id)
34
- headers["virtual-lab-id"] = str(project_context.project_id)
34
+ headers["virtual-lab-id"] = str(project_context.virtual_lab_id)
35
35
 
36
36
  try:
37
37
  response = http_client.request(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: entitysdk
3
- Version: 0.1.0
3
+ Version: 0.1.2
4
4
  Summary: Python library for interacting with the entitycore service
5
5
  Author-email: Open Brain Institute <info@openbraininstitute.org>
6
6
  Maintainer-email: Open Brain Institute <info@openbraininstitute.org>
@@ -53,9 +53,10 @@ tests/unit/test_serdes.py
53
53
  tests/unit/test_token_manager.py
54
54
  tests/unit/test_util.py
55
55
  tests/unit/util.py
56
- tests/unit/data/.gitignore
57
56
  tests/unit/models/__init__.py
58
57
  tests/unit/models/test_agent.py
59
58
  tests/unit/models/test_asset.py
60
59
  tests/unit/models/test_contribution.py
61
- tests/unit/models/test_morphology.py
60
+ tests/unit/models/test_morphology.py
61
+ tests/unit/models/data/.gitignore
62
+ tests/unit/models/data/reconstruction_morphology.json
@@ -4,6 +4,7 @@ import pytest
4
4
 
5
5
  from entitysdk.client import Client
6
6
  from entitysdk.common import ProjectContext
7
+ from tests.unit.util import PROJECT_ID, VIRTUAL_LAB_ID
7
8
 
8
9
 
9
10
  @pytest.fixture(scope="session")
@@ -14,8 +15,8 @@ def api_url():
14
15
  @pytest.fixture(scope="session")
15
16
  def project_context():
16
17
  return ProjectContext(
17
- project_id=uuid.UUID("103d7868-147e-4f07-af0d-71d8568f575c"),
18
- virtual_lab_id=uuid.UUID("103d7868-147e-4f07-af0d-71d8568f575c"),
18
+ project_id=PROJECT_ID,
19
+ virtual_lab_id=VIRTUAL_LAB_ID,
19
20
  )
20
21
 
21
22
 
@@ -0,0 +1,175 @@
1
+ {
2
+ "id": "9720aa4a-0cd1-4f10-b6ad-04deb8f997b6",
3
+ "update_date": "2024-10-29T13:36:30.827776Z",
4
+ "creation_date": "2024-09-10T14:25:03.707956Z",
5
+ "createdBy": null,
6
+ "updatedBy": null,
7
+ "authorized_public": true,
8
+ "authorized_project_id": "0dbced5f-cc3d-488a-8c7f-cfb8ea039dc6",
9
+ "assets": [
10
+ {
11
+ "id": "a90bab5c-8529-4829-99fc-e90a270e8b30",
12
+ "update_date": null,
13
+ "creation_date": null,
14
+ "path": "mpg150211_A_idA.swc",
15
+ "full_path": "public/a98b7abc-fc46-4700-9e3d-37137812c730/0dbced5f-cc3d-488a-8c7f-cfb8ea039dc6/assets/reconstruction_morphology/9720aa4a-0cd1-4f10-b6ad-04deb8f997b6/mpg150211_A_idA.swc",
16
+ "bucket_name": "entitycore-data-dev",
17
+ "is_directory": false,
18
+ "content_type": "application/swc",
19
+ "size": 561221,
20
+ "sha256_digest": "8b850eface3e7b881db62c361dc5da62be008ca81501c406a59646bf7075c95b",
21
+ "status": "created",
22
+ "meta": {
23
+ "legacy": {
24
+ "@id": "https://bbp.epfl.ch/data/public/morphologies/42315b31-081f-4d40-8b94-b72dbd16c99e",
25
+ "name": "mpg150211_A_idA.swc",
26
+ "@type": "DataDownload",
27
+ "digest": {
28
+ "value": "8b850eface3e7b881db62c361dc5da62be008ca81501c406a59646bf7075c95b",
29
+ "algorithm": "SHA-256"
30
+ },
31
+ "atLocation": {
32
+ "@type": "Location",
33
+ "store": {
34
+ "@id": "nxv:diskStorageDefault",
35
+ "_rev": 1,
36
+ "@type": "DiskStorage"
37
+ }
38
+ },
39
+ "contentUrl": "https://bbp.epfl.ch/nexus/v1/files/public/morphologies/https:%2F%2Fbbp.epfl.ch%2Fdata%2Fpublic%2Fmorphologies%2F42315b31-081f-4d40-8b94-b72dbd16c99e",
40
+ "contentSize": {
41
+ "value": 561221,
42
+ "unitCode": "bytes"
43
+ },
44
+ "encodingFormat": "application/swc"
45
+ }
46
+ }
47
+ },
48
+ {
49
+ "id": "56394210-d2fb-4755-990c-8083a97a46fd",
50
+ "update_date": null,
51
+ "creation_date": null,
52
+ "path": "mpg150211_A_idA.ASC",
53
+ "full_path": "public/a98b7abc-fc46-4700-9e3d-37137812c730/0dbced5f-cc3d-488a-8c7f-cfb8ea039dc6/assets/reconstruction_morphology/9720aa4a-0cd1-4f10-b6ad-04deb8f997b6/mpg150211_A_idA.ASC",
54
+ "bucket_name": "entitycore-data-dev",
55
+ "is_directory": false,
56
+ "content_type": "application/asc",
57
+ "size": 525332,
58
+ "sha256_digest": "bf00878444539ead825f2d451cdf6f87072526f9a82c87de35fca5563ae5596b",
59
+ "status": "created",
60
+ "meta": {
61
+ "legacy": {
62
+ "@id": "https://bbp.epfl.ch/data/public/morphologies/7f422a37-48f0-4ea4-8760-f1481403d51f",
63
+ "name": "mpg150211_A_idA.ASC",
64
+ "@type": "DataDownload",
65
+ "digest": {
66
+ "value": "bf00878444539ead825f2d451cdf6f87072526f9a82c87de35fca5563ae5596b",
67
+ "algorithm": "SHA-256"
68
+ },
69
+ "atLocation": {
70
+ "@type": "Location",
71
+ "store": {
72
+ "@id": "nxv:diskStorageDefault",
73
+ "_rev": 1,
74
+ "@type": "DiskStorage"
75
+ }
76
+ },
77
+ "contentUrl": "https://bbp.epfl.ch/nexus/v1/files/public/morphologies/https:%2F%2Fbbp.epfl.ch%2Fdata%2Fpublic%2Fmorphologies%2F7f422a37-48f0-4ea4-8760-f1481403d51f",
78
+ "contentSize": {
79
+ "value": 525332,
80
+ "unitCode": "bytes"
81
+ },
82
+ "encodingFormat": "application/asc"
83
+ }
84
+ }
85
+ }
86
+ ],
87
+ "name": "mpg150211_A_idA",
88
+ "location": null,
89
+ "brain_region": {
90
+ "id": 407,
91
+ "update_date": "2025-03-29T16:48:20.636283Z",
92
+ "creation_date": "2025-03-29T16:48:20.636283Z",
93
+ "createdBy": null,
94
+ "updatedBy": null,
95
+ "authorized_public": null,
96
+ "authorized_project_id": null,
97
+ "name": "Field CA1, pyramidal layer",
98
+ "acronym": "CA1sp",
99
+ "children": []
100
+ },
101
+ "description": "Neuronal morphology of excitatory neuron cell 'mpg150211_A_idA' in Field CA1, pyramidal layer of cell type SR_PC. A neuron that releases excitatory neurotransmitters. This neuron doesn't have axon, has a basal dendrite and apical dendrite.",
102
+ "pref_label": null,
103
+ "species": {
104
+ "id": "0895fa61-fa6d-4674-9014-7300f9edf8da",
105
+ "update_date": "2025-03-29T16:48:36.175090Z",
106
+ "creation_date": "2025-03-29T16:48:36.175090Z",
107
+ "createdBy": null,
108
+ "updatedBy": null,
109
+ "authorized_public": null,
110
+ "authorized_project_id": null,
111
+ "name": "Mus musculus",
112
+ "taxonomy_id": "NCBITaxon:10090"
113
+ },
114
+ "strain": null,
115
+ "license": null,
116
+ "contributions": [
117
+ {
118
+ "id": "79987156-9f97-4095-b69e-6b4e5ca213bb",
119
+ "update_date": "2025-03-29T16:49:12.446844Z",
120
+ "creation_date": "2025-03-29T16:49:12.446844Z",
121
+ "agent": {
122
+ "id": "eda92bb4-560b-4ad2-9c4b-4649bb254e83",
123
+ "update_date": "2024-04-22T14:40:13.122739Z",
124
+ "creation_date": "2021-03-17T16:59:51.555000Z",
125
+ "type": "person",
126
+ "pref_label": "Maurizio Pezzoli Gonzalez",
127
+ "givenName": "Maurizio",
128
+ "familyName": "Pezzoli Gonzalez"
129
+ },
130
+ "role": {
131
+ "id": "8b06e557-277b-4b0c-a439-bfb02d41927c",
132
+ "update_date": "2025-03-29T16:48:36.192831Z",
133
+ "creation_date": "2025-03-29T16:48:36.192831Z",
134
+ "name": "unspecified",
135
+ "role_id": "unspecified"
136
+ },
137
+ "entity": null
138
+ },
139
+ {
140
+ "id": "7f43ce20-e63d-48c1-bc73-dabb38ee181b",
141
+ "update_date": "2025-03-29T16:49:12.449364Z",
142
+ "creation_date": "2025-03-29T16:49:12.449364Z",
143
+ "agent": {
144
+ "id": "f27cfa11-d1bc-4a14-b651-174bb53674ff",
145
+ "update_date": "2021-04-14T09:51:14.062000Z",
146
+ "creation_date": "2021-04-14T09:51:14.062000Z",
147
+ "type": "organization",
148
+ "pref_label": "École Polytechnique Fédérale de Lausanne",
149
+ "alternative_name": ""
150
+ },
151
+ "role": {
152
+ "id": "8b06e557-277b-4b0c-a439-bfb02d41927c",
153
+ "update_date": "2025-03-29T16:48:36.192831Z",
154
+ "creation_date": "2025-03-29T16:48:36.192831Z",
155
+ "name": "unspecified",
156
+ "role_id": "unspecified"
157
+ },
158
+ "entity": null
159
+ }
160
+ ],
161
+ "mtypes": [
162
+ {
163
+ "id": "b2221a58-008a-45a6-8464-7159c324c985",
164
+ "update_date": "2021-09-06T15:47:05.039000Z",
165
+ "creation_date": "2021-09-06T15:47:04.890000Z",
166
+ "createdBy": null,
167
+ "updatedBy": null,
168
+ "authorized_public": null,
169
+ "authorized_project_id": null,
170
+ "pref_label": "SR_PC",
171
+ "definition": "",
172
+ "alt_label": ""
173
+ }
174
+ ]
175
+ }
@@ -0,0 +1,66 @@
1
+ from entitysdk.models import agent as test_module
2
+ from entitysdk.models.core import Identifiable
3
+
4
+ from ..util import MOCK_UUID
5
+
6
+
7
+ def test_person_entity():
8
+ agent = test_module.Person(
9
+ givenName="foo",
10
+ familyName="bar",
11
+ pref_label="test",
12
+ type="person",
13
+ )
14
+ assert agent.givenName == "foo"
15
+ assert agent.familyName == "bar"
16
+ assert agent.pref_label == "test"
17
+ assert agent.type == "person"
18
+
19
+
20
+ def test_organization_entity():
21
+ organization = test_module.Organization(
22
+ pref_label="foo",
23
+ alternative_name="bar",
24
+ type="organization",
25
+ )
26
+ assert organization.pref_label == "foo"
27
+ assert organization.alternative_name == "bar"
28
+ assert organization.type == "organization"
29
+
30
+
31
+ def test_agent_discriminated_union():
32
+ class A(Identifiable):
33
+ agent: test_module.AgentUnion | None = None
34
+
35
+ res = A.model_validate(
36
+ {
37
+ "id": MOCK_UUID,
38
+ }
39
+ )
40
+ assert res.id == MOCK_UUID
41
+
42
+ res = A.model_validate(
43
+ {
44
+ "id": MOCK_UUID,
45
+ "agent": {
46
+ "type": "organization",
47
+ "pref_label": "foo",
48
+ },
49
+ }
50
+ )
51
+ assert res.id == MOCK_UUID
52
+ assert isinstance(res.agent, test_module.Organization)
53
+
54
+ res = A.model_validate(
55
+ {
56
+ "id": MOCK_UUID,
57
+ "agent": {
58
+ "type": "person",
59
+ "pref_label": "foo",
60
+ "givenName": "John",
61
+ "familyName": "Smith",
62
+ },
63
+ }
64
+ )
65
+ assert res.id == MOCK_UUID
66
+ assert isinstance(res.agent, test_module.Person)
@@ -36,3 +36,21 @@ def test_contribution(role):
36
36
 
37
37
  assert res.agent == organization
38
38
  assert res.role == role
39
+
40
+ res = test_module.Contribution.model_validate(
41
+ {
42
+ "agent": person.model_dump(mode="json"),
43
+ "role": role.model_dump(mode="json"),
44
+ }
45
+ )
46
+ assert res.agent == person
47
+ assert res.role == role
48
+
49
+ res = test_module.Contribution.model_validate(
50
+ {
51
+ "agent": organization.model_dump(mode="json"),
52
+ "role": role.model_dump(mode="json"),
53
+ }
54
+ )
55
+ assert res.agent == organization
56
+ assert res.role == role
@@ -0,0 +1,62 @@
1
+ import json
2
+ from pathlib import Path
3
+
4
+ import pytest
5
+
6
+ from entitysdk.models.morphology import (
7
+ ReconstructionMorphology,
8
+ )
9
+
10
+ from ..util import MOCK_UUID
11
+
12
+ DATA_DIR = Path(__file__).parent / "data"
13
+
14
+
15
+ @pytest.fixture
16
+ def json_morphology_expanded():
17
+ return json.loads(Path(DATA_DIR / "reconstruction_morphology.json").read_bytes())
18
+
19
+
20
+ @pytest.fixture
21
+ def morphology(json_morphology_expanded):
22
+ return ReconstructionMorphology.model_validate(json_morphology_expanded)
23
+
24
+
25
+ def test_read_reconstruction_morphology(client, httpx_mock, auth_token, json_morphology_expanded):
26
+ httpx_mock.add_response(method="GET", json=json_morphology_expanded)
27
+ entity = client.get_entity(
28
+ entity_id=MOCK_UUID,
29
+ entity_type=ReconstructionMorphology,
30
+ token=auth_token,
31
+ with_assets=False,
32
+ )
33
+ assert entity.model_dump(mode="json") == json_morphology_expanded | {"legacy_id": None}
34
+
35
+
36
+ def test_register_reconstruction_morphology(
37
+ client, httpx_mock, auth_token, morphology, json_morphology_expanded
38
+ ):
39
+ httpx_mock.add_response(
40
+ method="POST", json=morphology.model_dump(mode="json") | {"id": str(MOCK_UUID)}
41
+ )
42
+ registered = client.register_entity(entity=morphology, token=auth_token)
43
+ expected_json = json_morphology_expanded.copy() | {"id": str(MOCK_UUID)}
44
+ assert registered.model_dump(mode="json") == expected_json | {"legacy_id": None}
45
+
46
+
47
+ def test_update_reconstruction_morphology(
48
+ client, httpx_mock, auth_token, morphology, json_morphology_expanded
49
+ ):
50
+ httpx_mock.add_response(
51
+ method="PATCH",
52
+ json=morphology.model_dump(mode="json") | {"name": "foo"},
53
+ )
54
+ updated = client.update_entity(
55
+ entity_id=morphology.id,
56
+ entity_type=ReconstructionMorphology,
57
+ attrs_or_entity={"name": "foo"},
58
+ token=auth_token,
59
+ )
60
+
61
+ expected_json = json_morphology_expanded.copy() | {"name": "foo"}
62
+ assert updated.model_dump(mode="json") == expected_json | {"legacy_id": None}
@@ -0,0 +1,5 @@
1
+ import uuid
2
+
3
+ MOCK_UUID = uuid.UUID("12341234-1234-1234-1234-123412341234")
4
+ VIRTUAL_LAB_ID = uuid.UUID("ac9b42ed-22b9-4c9d-9dcb-cdd604c6ebf0")
5
+ PROJECT_ID = uuid.UUID("bf0c75df-7dea-43b2-9a11-fcf994f87ccd")
@@ -1,25 +0,0 @@
1
- from entitysdk.models import agent as test_module
2
-
3
-
4
- def test_person_entity():
5
- agent = test_module.Person(
6
- givenName="foo",
7
- familyName="bar",
8
- pref_label="test",
9
- type="person",
10
- )
11
- assert agent.givenName == "foo"
12
- assert agent.familyName == "bar"
13
- assert agent.pref_label == "test"
14
- assert agent.type == "person"
15
-
16
-
17
- def test_organization_entity():
18
- organization = test_module.Organization(
19
- pref_label="foo",
20
- alternative_name="bar",
21
- type="organization",
22
- )
23
- assert organization.pref_label == "foo"
24
- assert organization.alternative_name == "bar"
25
- assert organization.type == "organization"
@@ -1,138 +0,0 @@
1
- import pytest
2
-
3
- from entitysdk.models.morphology import (
4
- BrainLocation,
5
- BrainRegion,
6
- ReconstructionMorphology,
7
- Species,
8
- Strain,
9
- )
10
-
11
- from ..util import MOCK_UUID
12
-
13
-
14
- @pytest.fixture
15
- def species(random_uuid):
16
- return Species(id=random_uuid, name="Mus musculus", taxonomy_id="NCBITaxon:10090")
17
-
18
-
19
- @pytest.fixture
20
- def strain(species, random_uuid):
21
- return Strain(
22
- name="Cux2-CreERT2",
23
- taxonomy_id="http://bbp.epfl.ch/neurosciencegraph/ontologies/speciestaxonomy/RBS4I6tyfUBSDt1i0jXLpgN",
24
- species_id=random_uuid,
25
- )
26
-
27
-
28
- @pytest.fixture
29
- def brain_location(random_uuid):
30
- return BrainLocation(
31
- id=random_uuid,
32
- x=4101.52490234375,
33
- y=1173.8499755859375,
34
- z=4744.60009765625,
35
- )
36
-
37
-
38
- @pytest.fixture
39
- def brain_region():
40
- return BrainRegion(
41
- id=68,
42
- name="Frontal pole, layer 1",
43
- acronym="FRP1",
44
- children=[],
45
- )
46
-
47
-
48
- @pytest.fixture
49
- def morphology(species, strain, brain_region):
50
- return ReconstructionMorphology(
51
- name="my-morph",
52
- description="my-description",
53
- species=species,
54
- strain=strain,
55
- brain_region=brain_region,
56
- )
57
-
58
-
59
- @pytest.fixture
60
- def json_morphology_expanded():
61
- return {
62
- "authorized_project_id": "103d7868-147e-4f07-af0d-71d8568f575c",
63
- "authorized_public": False,
64
- "license": {
65
- "id": str(MOCK_UUID),
66
- "creation_date": "2025-02-20T13:42:46.532333Z",
67
- "update_date": "2025-02-20T13:42:46.532333Z",
68
- "name": "https://creativecommons.org/licenses/by-nc-sa/4.0/",
69
- "description": "Foo",
70
- "label": "CC BY-NC-SA 4.0 Deed",
71
- },
72
- "id": str(MOCK_UUID),
73
- "creation_date": "2025-02-20T13:44:50.111791Z",
74
- "update_date": "2025-02-20T13:44:50.111791Z",
75
- "name": "04446-04462-X10187-Y13578_final",
76
- "description": "Bar",
77
- "location": None,
78
- "species": {
79
- "id": str(MOCK_UUID),
80
- "creation_date": "2025-02-20T13:42:56.228818Z",
81
- "update_date": "2025-02-20T13:42:56.228818Z",
82
- "name": "Mus musculus",
83
- "taxonomy_id": "NCBITaxon:10090",
84
- },
85
- "strain": None,
86
- "brain_region": {
87
- "id": 1,
88
- "creation_date": "2025-02-20T13:36:51.010167Z",
89
- "update_date": "2025-02-20T13:36:51.010167Z",
90
- "name": "Reticular nucleus of the thalamus",
91
- "acronym": "RT",
92
- "children": [],
93
- },
94
- }
95
-
96
-
97
- def test_read_reconstruction_morphology(client, httpx_mock, auth_token, json_morphology_expanded):
98
- httpx_mock.add_response(method="GET", json=json_morphology_expanded)
99
-
100
- entity = client.get_entity(
101
- entity_id=MOCK_UUID,
102
- entity_type=ReconstructionMorphology,
103
- token=auth_token,
104
- with_assets=False,
105
- )
106
-
107
- assert entity.id == MOCK_UUID
108
-
109
-
110
- def test_register_reconstruction_morphology(client, httpx_mock, auth_token, morphology):
111
- httpx_mock.add_response(
112
- method="POST", json=morphology.model_dump(mode="json") | {"id": str(MOCK_UUID)}
113
- )
114
-
115
- registered = client.register_entity(entity=morphology, token=auth_token)
116
-
117
- assert registered.id == MOCK_UUID
118
- assert registered.name == morphology.name
119
-
120
-
121
- def test_update_reconstruction_morphology(client, httpx_mock, auth_token, morphology):
122
- morphology = morphology.evolve(id=1)
123
- httpx_mock.add_response(
124
- method="PATCH",
125
- json=morphology.model_dump(mode="json") | {"id": str(MOCK_UUID), "name": "foo"},
126
- )
127
-
128
- updated = client.update_entity(
129
- entity_id=MOCK_UUID,
130
- entity_type=ReconstructionMorphology,
131
- attrs_or_entity={
132
- "name": "foo",
133
- },
134
- token=auth_token,
135
- )
136
-
137
- assert updated.id == MOCK_UUID
138
- assert updated.name == "foo"
@@ -1,3 +0,0 @@
1
- import uuid
2
-
3
- MOCK_UUID = uuid.UUID("12341234-1234-1234-1234-123412341234")
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes