Skip to content

Commit 81ea30c

Browse files
authored
Merge pull request #1262 from Sage-Bionetworks/SYNPY-1673
[SYNPY-1673] Add JSONSchema documentation, deprecate old classes
2 parents cbf384b + dee7214 commit 81ea30c

File tree

11 files changed

+156
-48
lines changed

11 files changed

+156
-48
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# JSONSchema
2+
3+
Contained within this file are experimental interfaces for working with the Synapse Python
4+
Client. Unless otherwise noted these interfaces are subject to change at any time. Use
5+
at your own risk.
6+
7+
## API Reference
8+
9+
::: synapseclient.models.JSONSchema
10+
options:
11+
inherited_members: true
12+
members:
13+
- get_async
14+
- store_async
15+
- delete_async
16+
- get_versions_async
17+
- get_body_async
18+
- from_uri
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# SchemaOrganization
2+
3+
Contained within this file are experimental interfaces for working with the Synapse Python
4+
Client. Unless otherwise noted these interfaces are subject to change at any time. Use
5+
at your own risk.
6+
7+
## API Reference
8+
9+
::: synapseclient.models.SchemaOrganization
10+
options:
11+
inherited_members: true
12+
members:
13+
- get_async
14+
- store_async
15+
- delete_async
16+
- get_json_schemas_async
17+
- get_acl_async
18+
- update_acl_async
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# JSONSchema
2+
3+
Contained within this file are experimental interfaces for working with the Synapse Python
4+
Client. Unless otherwise noted these interfaces are subject to change at any time. Use
5+
at your own risk.
6+
7+
## API Reference
8+
9+
::: synapseclient.models.JSONSchema
10+
options:
11+
inherited_members: true
12+
members:
13+
- get
14+
- store
15+
- delete
16+
- get_versions
17+
- get_body
18+
- from_uri
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# SchemaOrganization
2+
3+
Contained within this file are experimental interfaces for working with the Synapse Python
4+
Client. Unless otherwise noted these interfaces are subject to change at any time. Use
5+
at your own risk.
6+
7+
## API Reference
8+
9+
::: synapseclient.models.SchemaOrganization
10+
options:
11+
inherited_members: true
12+
members:
13+
- get
14+
- store
15+
- delete
16+
- get_json_schemas
17+
- get_acl
18+
- update_acl

docs/tutorials/python/json_schema.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,17 @@ By the end of this tutorial, you will:
2121
* You are familiar with [adding annotations](./annotation.md) to synapse entity.
2222

2323

24-
## 1. Set Up Synapse Python Client and Retrieve Project
24+
25+
## 1. Set Up Synapse Python Client
2526

2627
```python
27-
{!docs/tutorials/python/tutorial_scripts/json_schema.py!lines=1-19}
28+
{!docs/tutorials/python/tutorial_scripts/json_schema.py!lines=1-10}
2829
```
2930

3031
## 2. Take a Look at the Constants and Structure of the JSON Schema
3132

3233
```python
33-
{!docs/tutorials/python/tutorial_scripts/json_schema.py!lines=21-49}
34+
{!docs/tutorials/python/tutorial_scripts/json_schema.py!lines=13-43}
3435
```
3536

3637
Derived annotations allow you to define default values for annotations based on schema rules, ensuring consistency and reducing manual input errors. As you can see here, you could use derived annotations to prescribe default annotation values. Please read more about derived annotations [here](https://help.synapse.org/docs/JSON-Schemas.3107291536.html#JSONSchemas-DerivedAnnotations).
@@ -39,12 +40,12 @@ Derived annotations allow you to define default values for annotations based on
3940
## 3. Try Create Test Organization and JSON Schema if They Do Not Exist
4041
Next, try creating a test organization and register a schema if they do not already exist:
4142
```python
42-
{!docs/tutorials/python/tutorial_scripts/json_schema.py!lines=51-65}
43+
{!docs/tutorials/python/tutorial_scripts/json_schema.py!lines=46-62}
4344
```
4445

4546
Note: If you update your schema, you can re-register it with the organization by assigning a new version number to reflect the changes. Synapse does not allow re-creating a schema with the same version number, so please ensure that each schema version within an organization is unique:
4647
```python
47-
{!docs/tutorials/python/tutorial_scripts/json_schema.py!lines=67-99}
48+
{!docs/tutorials/python/tutorial_scripts/json_schema.py!lines=64-97}
4849
```
4950

5051
## 4. Bind the JSON Schema to the Folder
@@ -53,7 +54,7 @@ After creating the organization, you can now bind your json schema to a test fol
5354
When you bind the schema, you may also include the boolean property `enable_derived_annotations` to have Synapse automatically calculate derived annotations based on the schema:
5455

5556
```python
56-
{!docs/tutorials/python/tutorial_scripts/json_schema.py!lines=101-108}
57+
{!docs/tutorials/python/tutorial_scripts/json_schema.py!lines=100-108}
5758
```
5859

5960
<details class="example">

docs/tutorials/python/tutorial_scripts/json_schema.py

Lines changed: 31 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,24 @@
33

44
import synapseclient
55
from synapseclient.core.utils import make_bogus_data_file
6-
from synapseclient.models import File, Folder
6+
from synapseclient.models import File, Folder, JSONSchema, Project, SchemaOrganization
77

8-
# 1. Set up Synapse Python client and retrieve project
8+
# 1. Set up Synapse Python client
99
syn = synapseclient.Synapse()
1010
syn.login()
1111

12-
# Retrieve test project
13-
PROJECT_ID = syn.findEntityId(
14-
name="My uniquely named project about Alzheimer's Disease"
15-
)
16-
17-
# Create a test folder for JSON schema experiments
18-
test_folder = Folder(name="clinical_data_folder", parent_id=PROJECT_ID).store()
19-
2012
# 2. Take a look at the constants and structure of the JSON schema
13+
# Replace your own project name here
14+
PROJECT_ENT = Project(name="My uniquely named project about Alzheimer's Disease").get()
15+
# Replace your own json schema organization name here
2116
ORG_NAME = "myUniqueAlzheimersResearchOrgTutorial"
2217
VERSION = "0.0.1"
2318
NEW_VERSION = "0.0.2"
2419

2520
SCHEMA_NAME = "clinicalObservations"
2621

2722
title = "Alzheimer's Clinical Observation Schema"
28-
schema = {
23+
schema_body = {
2924
"$schema": "http://json-schema.org/draft-07/schema#",
3025
"$id": "https://example.com/schema/alzheimers_observation.json",
3126
"title": title,
@@ -48,20 +43,23 @@
4843
}
4944

5045
# 3. Try create test organization and json schema if they do not exist
51-
js = syn.service("json_schema")
52-
all_orgs = js.list_organizations()
53-
for org in all_orgs:
54-
if org["name"] == ORG_NAME:
55-
syn.logger.info(f"Organization {ORG_NAME} already exists.")
56-
break
57-
else:
58-
syn.logger.info(f"Creating organization {ORG_NAME}.")
59-
js.create_organization(ORG_NAME)
60-
61-
my_test_org = js.JsonSchemaOrganization(ORG_NAME)
62-
test_schema = my_test_org.get_json_schema(SCHEMA_NAME)
63-
if not test_schema:
64-
test_schema = my_test_org.create_json_schema(schema, SCHEMA_NAME, VERSION)
46+
organization = SchemaOrganization(name=ORG_NAME)
47+
try:
48+
organization.store()
49+
except Exception as e:
50+
organization.get()
51+
52+
schemas = list(organization.get_json_schemas())
53+
for schema in schemas:
54+
print(schema)
55+
56+
schema = JSONSchema(name=SCHEMA_NAME, organization_name=ORG_NAME)
57+
try:
58+
schema.get()
59+
except Exception as e:
60+
schema.store(schema_body=schema_body, version=VERSION)
61+
62+
schema.get_body()
6563

6664
# If you want to make an update, you can re-register your schema with the organization:
6765
updated_schema = {
@@ -86,9 +84,7 @@
8684
}
8785

8886
try:
89-
new_test_schema = my_test_org.create_json_schema(
90-
updated_schema, SCHEMA_NAME, VERSION
91-
)
87+
schema.store(schema_body=updated_schema, version=VERSION)
9288
except synapseclient.core.exceptions.SynapseHTTPError as e:
9389
if e.response.status_code == 400 and "already exists" in e.response.text:
9490
syn.logger.warning(
@@ -97,10 +93,15 @@
9793
else:
9894
raise e
9995

96+
schema.store(schema_body=updated_schema, version=NEW_VERSION)
97+
schema.get_body(version=VERSION)
10098
# 4. Bind the JSON schema to the folder
101-
schema_uri = ORG_NAME + "-" + SCHEMA_NAME + "-" + VERSION
99+
100+
# Create a test folder for JSON schema experiments
101+
test_folder = Folder(name="test_folder", parent_id=PROJECT_ENT.id).store()
102+
102103
bound_schema = test_folder.bind_schema(
103-
json_schema_uri=schema_uri, enable_derived_annotations=True
104+
json_schema_uri=schema.uri, enable_derived_annotations=True
104105
)
105106
json_schema_version_info = bound_schema.json_schema_version_info
106107
syn.logger.info("JSON schema was bound successfully. Please see details below:")

mkdocs.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ nav:
102102
- Curator: reference/experimental/sync/curator.md
103103
- Link: reference/experimental/sync/link_entity.md
104104
- Functional Interfaces: reference/experimental/functional_interfaces.md
105+
- SchemaOrganization: reference/experimental/sync/schema_organization.md
106+
- JSONSchema: reference/experimental/sync/json_schema.md
105107
- Extensions:
106108
- Curator: reference/extensions/curator.md
107109
- Asynchronous:
@@ -123,6 +125,8 @@ nav:
123125
- UserProfile: reference/experimental/async/user_profile.md
124126
- Curator: reference/experimental/async/curator.md
125127
- Link: reference/experimental/async/link_entity.md
128+
- SchemaOrganization: reference/experimental/async/schema_organization.md
129+
- JSONSchema: reference/experimental/async/json_schema.md
126130
- Mixins:
127131
- AccessControllable: reference/experimental/mixins/access_controllable.md
128132
- StorableContainer: reference/experimental/mixins/storable_container.md

synapseclient/client.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1627,7 +1627,10 @@ def _print_transfer_progress(self, *args, **kwargs) -> None:
16271627
"json_schema": "JsonSchemaService",
16281628
}
16291629

1630-
# TODO: Deprecate method in https://sagebionetworks.jira.com/browse/SYNPY-1583
1630+
@deprecated(
1631+
version="4.11.0",
1632+
reason="To be removed in 5.0.0.",
1633+
)
16311634
def get_available_services(self) -> typing.List[str]:
16321635
"""Get available Synapse services
16331636
This is a beta feature and is subject to change
@@ -1638,7 +1641,10 @@ def get_available_services(self) -> typing.List[str]:
16381641
services = self._services.keys()
16391642
return list(services)
16401643

1641-
# TODO: Deprecate method in https://sagebionetworks.jira.com/browse/SYNPY-1583
1644+
@deprecated(
1645+
version="4.11.0",
1646+
reason="To be removed in 5.0.0.",
1647+
)
16421648
def service(self, service_name: str):
16431649
"""Get available Synapse services
16441650
This is a beta feature and is subject to change

synapseclient/models/schema_organization.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,12 @@ def update_acl(
229229
class SchemaOrganization(SchemaOrganizationProtocol):
230230
"""
231231
Represents an [Organization](https://rest-docs.synapse.org/rest/org/sagebionetworks/repo/model/schema/Organization.html).
232+
233+
Attributes:
234+
name: The name of the organization
235+
id: The ID of the organization
236+
created_on: The date this organization was created
237+
created_by: The ID of the user that created this organization
232238
"""
233239

234240
name: Optional[str] = None
@@ -347,9 +353,8 @@ async def delete_async(self, synapse_client: Optional["Synapse"] = None) -> None
347353
`Synapse.allow_client_caching(False)` this will use the last created
348354
instance from the Synapse class constructor
349355
350-
Example: Delete a SchemaOrganization
351-
352-
Delete using a name
356+
Example: Delete a SchemaOrganization using a name
357+
&nbsp;
353358
354359
```python
355360
from synapseclient.models import SchemaOrganization
@@ -367,7 +372,8 @@ async def delete_org():
367372
asyncio.run(delete_org())
368373
```
369374
370-
Delete using an id
375+
Example: Delete a SchemaOrganization using an id
376+
&nbsp;
371377
372378
```python
373379
from synapseclient.models import SchemaOrganization
@@ -383,6 +389,7 @@ async def delete_org():
383389
await org.delete_async()
384390
385391
asyncio.run(delete_org())
392+
```
386393
"""
387394
if not self.id:
388395
await self.get_async(synapse_client=synapse_client)
@@ -771,8 +778,7 @@ def get_body(
771778
@async_to_sync
772779
class JSONSchema(JSONSchemaProtocol):
773780
"""
774-
Represents a:
775-
[JSON Schema](https://rest-docs.synapse.org/rest/org/sagebionetworks/repo/model/schema/JsonSchemaInfo.html)
781+
Represents a [JSON Schema](https://rest-docs.synapse.org/rest/org/sagebionetworks/repo/model/schema/JsonSchemaInfo.html)
776782
777783
Attributes:
778784
name: The name of the schema
@@ -949,7 +955,6 @@ async def store_schema():
949955
)
950956
new_version_info = completed_request.new_version_info
951957
self.organization_id = new_version_info.organization_id
952-
self.id = new_version_info.id
953958
self.created_by = new_version_info.created_by
954959
self.created_on = new_version_info.created_on
955960
return self

synapseclient/services/json_schema.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
***********
55
66
!!! warning
7-
This is a beta implementation and is subject to change. Use at your own risk.
7+
Everything in this module has been deprecated.
8+
Use synapseclient.models.SchemaOrganization and synapseclient.models.JSONSchema instead.
89
"""
910

1011
from __future__ import annotations
@@ -13,6 +14,8 @@
1314
from functools import wraps
1415
from typing import Mapping, Optional, Sequence, Union
1516

17+
from deprecated import deprecated
18+
1619
from synapseclient.client import Synapse
1720
from synapseclient.core.exceptions import SynapseAuthenticationError, SynapseHTTPError
1821
from synapseclient.core.utils import id_of
@@ -21,6 +24,10 @@
2124
DEFAULT_ACCESS = ("CHANGE_PERMISSIONS", "DELETE", "READ", "CREATE", "UPDATE")
2225

2326

27+
@deprecated(
28+
version="4.11.0",
29+
reason="To be removed in 5.0.0. Use synapseclient.models.JSONSchema instead.",
30+
)
2431
class JsonSchemaVersion:
2532
"""Json schema version response object
2633
@@ -149,6 +156,10 @@ def bind_to_object(self, synapse_id: str):
149156
return response
150157

151158

159+
@deprecated(
160+
version="4.11.0",
161+
reason="To be removed in 5.0.0. Use synapseclient.models.JSONSchema instead.",
162+
)
152163
class JsonSchema:
153164
"""Json schema response object
154165
@@ -272,6 +283,10 @@ def create(
272283
return version
273284

274285

286+
@deprecated(
287+
version="4.11.0",
288+
reason="To be removed in 5.0.0. Use synapseclient.models.SchemaOrganization instead.",
289+
)
275290
class JsonSchemaOrganization:
276291
"""Json Schema Organization
277292
@@ -484,6 +499,10 @@ def create_json_schema(
484499
return json_schema
485500

486501

502+
@deprecated(
503+
version="4.11.0",
504+
reason="To be removed in 5.0.0.",
505+
)
487506
class JsonSchemaService:
488507
"""Json Schema Service
489508

0 commit comments

Comments
 (0)