Skip to content

Comments

[SYNPY-1726] Add bind-jsonschema CLI command#1317

Merged
thomasyu888 merged 32 commits intoSage-Bionetworks:developfrom
aditigopalan:develop
Feb 18, 2026
Merged

[SYNPY-1726] Add bind-jsonschema CLI command#1317
thomasyu888 merged 32 commits intoSage-Bionetworks:developfrom
aditigopalan:develop

Conversation

@aditigopalan
Copy link
Contributor

@aditigopalan aditigopalan commented Feb 9, 2026

Problem:

The CLI didn't have a workflow for registering and binding JSON Schemas.

Specifically:

  • There was no register-json-schema CLI command
  • There was no bind-json-schema CLI command

Highlighted in SYNPY-1762

Solution:

  • Introduced a new schema_management.py module that provides thin wrapper functions (register_jsonschema() and bind_jsonschema()), keeping CLI logic minimal and consistent with previous work
  • Added a new register-json-schema CLI command that registers schemas using JSONSchema.store().
  • Added a new bind-json-schema CLI command that binds schemas to entities via Entity.bind_schema().
  • Updated CLI and Python tutorial documentation to reflect the new commands and recommended usage.

Testing:

  • Added unit tests covering both register-json-schema and bind-json-schema CLI commands.
  • Verified that schema registration and binding routes through JSONSchema.store() and Entity.bind_schema() respectively.
  • Manually tested the CLI commands to confirm expected behavior and alignment with the updated docs.

- Create schema_management.py with register_jsonschema and bind_jsonschema
- Export functions from curator extension __init__.py
- Update register_json_schema to use register_jsonschema wrapper
- Update bind_json_schema to use bind_jsonschema wrapper
- Add register-json-schema CLI command with argparse configuration
- Add register-json-schema to table of contents
- Add complete command documentation with usage and parameters
- Document schema registration workflow
- Update tutorial to cover complete JSON Schema workflow
- Add section 9: Register JSON Schema to Synapse
- Add section 10: Bind JSON Schema to entities
- Update tutorial script with register_jsonschema and bind_jsonschema examples
- Update imports and line references
- Add test for argument parsing
- Add test for --enable-derived-annotations flag
- Add test for API call invocation
Update test to mock bind_jsonschema wrapper instead of asyncio.run,
and verify correct arguments are passed to the wrapper function.
@aditigopalan aditigopalan requested a review from a team as a code owner February 9, 2026 20:54
@andrewelamb
Copy link
Contributor

Thanks for doing this @aditigopalan ! Could you add an integration test as well as the unit testing you did?

- Update register_jsonschema to log message and return only schema_uri
- Update CLI function to match new signature
- Update docstring and examples
- Update return type from str to JSONSchema
- Update docstring and examples to show accessing json_schema.uri
- Update tutorial script accordingly
Add comprehensive integration tests for register_jsonschema and bind_jsonschema
wrapper functions. Tests cover:
- Registering schemas with and without version
- Binding schemas to folders
- Enabling derived annotations
- Complete register + bind workflow
Add integration tests for register-json-schema and bind-json-schema
CLI commands in test_command_line_client.py.
Tests cover:
- Registering a schema via CLI
- Binding a schema to an entity via CLI
- Complete workflow of register and bind operations
Copy link
Contributor

@linglp linglp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your hard work @aditigopalan ! I left some comments about documentation and code style changes.

Arguments:
schema_path: Path to the JSON schema file to register
organization_name: Name of the organization to register the schema under
schema_name: The name of the JSON schema
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Name of the JSON Schema
This is to be consistent with organization_name

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean by this?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just meant that you have:
organization_name: Name of the organization to register the schema under
And similarly, we can do:
schema_name: Name of the JSON schema

Copy link
Member

@thomasyu888 thomasyu888 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your contribution @aditigopalan !

@andrewelamb or @linglp once all the changes are made, can one of you make sure the all the tests contributed here runs, since contributions via forks don't have CI tests.

Thanks all!

@aditigopalan
Copy link
Contributor Author

@linglp @andrewelamb thank you both for reviewing! Please let me know if I understood the documentation changes correctly.

Regarding the organizations section, I’m not entirely sure what would make sense to include in the documentation. Since new organizations can be created, I’m not sure what it means for the JSON schemas to be “consistent with organization name.”

For example, for HTAN2Organization, we generate schemas like these:
https://github.com/ncihtan/htan2-data-model/tree/main/JSON_Schemas/v1.2.0

I’m also not sure what other DCCs are doing in this space, so I’ll defer to you both (and @thomasyu888) on what makes sense to describe in the documentation.

@aditigopalan aditigopalan requested a review from linglp February 12, 2026 18:55
@andrewelamb
Copy link
Contributor

@aditigopalan Thank you for adding the integration tests! However, they are not passing. These all need to be resolved:

ERROR tests/integration/synapseclient/test_command_line_client.py::TestSchemaManagementCommands::test_register_json_schema - ValueError: Name may be separated by periods, but each part must start with a letter and contain only letters and numbers: test.org.1e893b7b
ERROR tests/integration/synapseclient/test_command_line_client.py::TestSchemaManagementCommands::test_bind_json_schema - ValueError: Name may be separated by periods, but each part must start with a letter and contain only letters and numbers: test.org.3b8d5232
ERROR tests/integration/synapseclient/test_command_line_client.py::TestSchemaManagementCommands::test_register_and_bind_workflow - ValueError: Name may be separated by periods, but each part must start with a letter and contain only letters and numbers: test.org.193d052a
FAILED tests/integration/synapseclient/test_schema_management.py::TestRegisterJsonSchema::test_register_jsonschema_with_version - AttributeError: 'JSONSchema' object has no attribute 'version'
FAILED tests/integration/synapseclient/test_schema_management.py::TestRegisterJsonSchema::test_register_jsonschema_without_version - AttributeError: 'JSONSchema' object has no attribute 'version'
FAILED tests/integration/synapseclient/test_schema_management.py::TestBindJsonSchema::test_bind_jsonschema_to_folder - TypeError: argument of type 'JSONSchemaBinding' is not iterable
FAILED tests/integration/synapseclient/test_schema_management.py::TestBindJsonSchema::test_bind_jsonschema_with_derived_annotations - TypeError: argument of type 'JSONSchemaBinding' is not iterable
FAILED tests/integration/synapseclient/test_schema_management.py::TestRegisterAndBindWorkflow::test_complete_workflow - AttributeError: get_schema
ERROR tests/integration/synapseclient/test_schema_management.py::TestRegisterAndBindWorkflow::test_complete_workflow - synapseclient.core.exceptions.SynapseHTTPError: 400 Client Error: Cannot delete a schema that is bound to an object

- previously tried to test if that the binding result contains entity information (like entityId or entity_id)
- result is a JSONSchemaBinding object (a Python class instance), not a dictionary
- just checking that the result is not none should be sufficient
Resolved conflicts in schema_operations documentation:
- Kept display_label example from upstream
- Added register_jsonschema and bind_jsonschema documentation
- Updated line number references in markdown
"""Set up test state with organization and schema file"""
from synapseclient.models import SchemaOrganization

class SchemaState:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm confused by this class. Could you add documentation describing what it's for?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was originally just meant to be a container class to bundle everything, but on second thought I just decided to reuse test_state + separate fixtures for organization and schema_file. Let me know if this makes sense!

Now if cleanup fails, the test will fail
Add explicit schema unbinding before folder deletion to ensure schemas can be deleted (schemas cannot be deleted while bound - errors out)
- Remove SchemaState container class in favor of separate fixtures for schema_organization and schema_file.
- aligns with the existing test pattern where test_state provides the core Synapse client, project, and parser, while additional fixtures provide test-specific resources.
Copy link
Member

@BryanFauble BryanFauble left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are some items to fix, but this is great progress!

use class-scoped fixture, fix UUID naming, use addfinalizer
…ions

- Add register_jsonschema_async and bind_jsonschema_async functions
- Refactor sync functions to use wrap_async_to_sync pattern
- Export async functions from curator __init__.py
@andrewelamb
Copy link
Contributor

Thanks for all the work @aditigopalan !

Copy link
Member

@BryanFauble BryanFauble left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the updates!

@thomasyu888 thomasyu888 merged commit 184718b into Sage-Bionetworks:develop Feb 18, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants