[SYNPY-1869] Add SearchIndex entity + search-management APIs; rename SchemaOrganization to Organization - #1422
[SYNPY-1869] Add SearchIndex entity + search-management APIs; rename SchemaOrganization to Organization#1422BryanFauble wants to merge 36 commits into
Conversation
…SchemaOrganization to Organization Build the OOP method surface for search-management resources (TextAnalyzer, ColumnAnalyzerOverride, SynonymSet, SearchConfiguration, SearchConfigBinding) and the SearchIndex entity with autocomplete/query support, following the async-first @async_to_sync pattern with protocol classes and unit tests. Hard-rename the SchemaOrganization model to Organization (class, protocol, module helper list_json_schema_organizations -> list_organizations, files, docs, and mkdocs nav) so it consistently reads as an "Organization" that holds resources. No backwards-compatible alias.
…ne_keys
- Return SearchIndex children from sync_from_synapse/walk/get_children by
adding searchindex dispatch to StorableContainer and searchindexes fields
on Project and Folder
- Include searchindex in access_control ENTITY_TYPE_MAPPING so ACL/permission
cascades reach SearchIndex children
- Replace `{k: v ... if v is not None}` comprehensions with delete_none_keys()
in search_services list functions
- Fix async docstring examples in search_index to use async form
There was a problem hiding this comment.
Pull request overview
Adds first-class OOP support for Synapse search-management resources and the new SearchIndex entity, and completes the rename of the JSON-schema “SchemaOrganization” model to Organization across the SDK surface (models, operations routing, docs, and tests).
Changes:
- Introduces
SearchIndexentity model plus org-scoped search-management models (analyzers/config/binding) and REST API wrappers. - Wires
SearchIndexinto entity factory/concrete types/async-job routing and container sync/walk surfaces. - Renames
SchemaOrganization→Organizationacross models, operations, docs, and test suites.
Reviewed changes
Copilot reviewed 39 out of 39 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/unit/synapseutils/unit_test_synapseutils_sync.py | Extends include-types coverage to include searchindex in sync/walk tests. |
| tests/unit/synapseclient/operations/unit_test_store_operations.py | Updates store routing tests for Organization rename. |
| tests/unit/synapseclient/operations/unit_test_delete_operations.py | Updates delete routing tests for Organization rename. |
| tests/unit/synapseclient/models/async/unit_test_search_management_async.py | Adds unit tests for search-management dataclasses and query/autocomplete flows. |
| tests/unit/synapseclient/models/async/unit_test_project_async.py | Adds coverage for project sync populating searchindexes. |
| tests/unit/synapseclient/models/async/unit_test_organization_async.py | Renames/updates unit tests for Organization and JSONSchema behaviors. |
| tests/unit/synapseclient/extensions/test_schema_management.py | Updates extension tests to patch organization.JSONSchema. |
| tests/integration/synapseclient/test_command_line_client.py | Updates CLI integration fixture to use Organization. |
| tests/integration/synapseclient/operations/async/test_factory_operations_store_async.py | Updates integration store/delete coverage for renamed Organization. |
| tests/integration/synapseclient/models/async/test_search_management_async.py | Adds integration coverage for org-scoped search-management resources and binding lifecycle. |
| tests/integration/synapseclient/models/async/test_search_index_async.py | Adds integration coverage for SearchIndex create/query/autocomplete/delete flows. |
| tests/integration/synapseclient/models/async/test_organization_async.py | Updates integration tests to Organization and list_organizations. |
| tests/integration/synapseclient/extensions/curator/test_schema_management.py | Updates curator integration tests to use Organization. |
| synapseclient/services/json_schema.py | Updates deprecated-service docstrings to point to models.Organization. |
| synapseclient/operations/store_operations.py | Updates operations routing/allowed-types messaging for Organization. |
| synapseclient/operations/delete_operations.py | Updates delete operations routing/docs for Organization. |
| synapseclient/models/search_management.py | New: search-management models (analyzers, configs, bindings, query DTOs) and dispatch helpers. |
| synapseclient/models/search_index.py | New: SearchIndex entity model with autocomplete support and table-like mixins. |
| synapseclient/models/protocols/search_management_protocol.py | New: sync protocol for SearchConfigBinding (async-to-sync generated methods). |
| synapseclient/models/protocols/search_index_protocol.py | New: sync protocol for SearchIndex (async-to-sync generated methods). |
| synapseclient/models/project.py | Adds searchindexes collection to Project. |
| synapseclient/models/organization.py | Renamed model file and class: SchemaOrganization → Organization; helper list_organizations. |
| synapseclient/models/mixins/table_components.py | Marks SearchIndex as read-only schema in table mixin logic. |
| synapseclient/models/mixins/storable_container.py | Extends container sync/walk to recognize and hydrate SearchIndex children. |
| synapseclient/models/mixins/asynchronous_job.py | Adds async-job route for SEARCH_INDEX_QUERY. |
| synapseclient/models/mixins/access_control.py | Extends entity-type mapping to include searchindex. |
| synapseclient/models/folder.py | Adds searchindexes collection to Folder. |
| synapseclient/models/init.py | Exports Organization, SearchIndex, and search-management model surface. |
| synapseclient/extensions/curator/schema_management.py | Updates curator extension imports for renamed Organization module. |
| synapseclient/core/constants/concrete_types.py | Adds concrete types for SearchIndex and SearchIndexQuery. |
| synapseclient/api/search_services.py | New: REST API functions for search-management resources and autocomplete. |
| synapseclient/api/entity_services.py | Adds searchindex to include-types example list. |
| synapseclient/api/entity_factory.py | Registers SearchIndex in concrete-type → model dispatch. |
| synapseclient/api/init.py | Exports search services in API surface. |
| mkdocs.yml | Updates docs nav to Organization reference pages. |
| docs/tutorials/python/tutorial_scripts/json_schema.py | Updates tutorial script imports/usage to Organization. |
| docs/reference/json_schema.md | Updates deprecation notice to refer to Organization. |
| docs/reference/experimental/sync/organization.md | Renamed reference page to Organization and updates mkdocstrings target. |
| docs/reference/experimental/async/organization.md | Renamed reference page to Organization and updates mkdocstrings target. |
Comments suppressed due to low confidence (4)
synapseclient/models/search_management.py:1018
SearchConfigBinding.get_async()has the same potential issue asstore_async(): ifobject_idon the instance is un-prefixed (as returned by the service), this will build an invalid/entity/{entityId}/...URI. Normalize to a Synapse ID when calling the API.
if not self.object_id:
raise ValueError("SearchConfigBinding must have an object_id set.")
result = await get_search_config_binding(
self.object_id, synapse_client=synapse_client
)
return self.fill_from_dict(result)
synapseclient/models/search_management.py:1047
SearchConfigBinding.delete_async()can also be called on an instance whoseobject_idcame fromfill_from_dict()(and may not include thesynprefix). Normalize to a Synapse ID when calling the clear endpoint.
if not self.object_id:
raise ValueError("SearchConfigBinding must have an object_id set.")
await clear_search_config_binding(self.object_id, synapse_client=synapse_client)
synapseclient/models/organization.py:355
- Grammar in docstring: use “an Organization” (not “a Organization”).
This issue also appears on line 374 of the same file.
synapseclient/models/organization.py:374
- Grammar in docstring: use “an Organization” (not “a Organization”).
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…; added unit test for search index
… include_columns parameter
|
The rename of |
|
These tests fail: |
|
@andrewelamb those tests failed because searchIndex was not added to |
Shouldn't they be part of this ticket? |
This ticket already has a lot going on, including deprecating SchemaOrganization. If I could just get these changes cross the finish line and worry about other improvements later, that would greatly help. |
…ionality (#1433) * Review fixes for SearchIndex entity and supporting functionality - Fix store_async crash when upserting onto an existing SearchIndex: a freshly-constructed instance has no _last_persistent_instance, which store_entity dereferenced unconditionally for the version_label check. - Guard force_version in store_entity for models that do not define it. - Add SearchIndex to the get_id() type union in services/search.py. - Flatten SearchIndex.to_synapse_request() to return the entity body directly instead of a single-key {"entity": ...} wrapper the only caller immediately unwrapped. - Add reference docs for SearchIndex and the search configuration resources, resolving the dangling mkdocstrings cross-references to SearchQuery, SearchIndexQuery, search_dsl.Query, TextAnalyzer, and SynonymSet. - Rewrite point-in-time comments as durable descriptions of what the code is. - Add unit coverage for the upsert-onto-existing-index path. * Fix class docstring examples not rendering in docs The SearchIndex and SearchIndexQuery class docstrings opened their ```python fence directly under `Example:`, with no ` ` description line. griffe only parses an Examples section when the title line is followed by body text, so both blocks fell through as literal markdown and the fence leaked onto the rendered page instead of becoming a collapsible example admonition. * add docstring * remove searchIndexStatus class * remove SearchIndexState after SearchIndexStatus gets removed * update the link in docstring * added supported class; fix docstring * fix formatting * avoid exporting the mixin because they are only for internal use * fix docstring * fix docstring * no need to export EnumCoercionMixin and ForwardCompatibleStrEnum because they are internal use * remove version and related fields; fix integration tests * add type searchIndex * updated example to use Query class instead of dict from search_dsl; also expose Query class in doc * move searchIndex to non-version block * update constants after creating test resources in dev --------- Co-authored-by: Lingling Peng <linglp@umich.edu>
…networks/synapsePythonClient into synpy-1869-search-index
Problem:
Two related gaps in the OOP model layer:
SearchIndex / search-management surface was incomplete. The
SearchManagementControllerin Synapse-Repository-Services exposes a family of resources —SearchIndex(an OpenSearch index built from a defining SQL query), plus the configuration resources that control how indexes are built:TextAnalyzer,ColumnAnalyzerOverride,SynonymSet,SearchConfiguration, andSearchConfigBinding— as well as index query and autocomplete endpoints. The Python client only had a partial, not-fully-correct starting point for these.SchemaOrganizationnaming was inconsistent. The model that holds JSON-schema resources was namedSchemaOrganization, but conceptually it's just an "Organization" that holds resources. The name should read consistently.Solution:
Search management (new):
SearchIndexentity model (models/search_index.py) following the async-first@async_to_syncpattern —store/get/delete/autocomplete, columns derived read-only fromdefining_sql, registered concrete typeorg.sagebionetworks.repo.model.search.table.SearchIndex.models/search_management.py):TextAnalyzer,ColumnAnalyzerOverride,SynonymSet,SearchConfiguration,SearchConfigBinding, plus query/autocomplete request+hit types.api/search_services.py) and wired it intoapi/__init__.py.concrete_types.py,entity_factory.py,mixins/asynchronous_job.py, and markedSearchIndexread-only-schema inmixins/table_components.py.Rename (hard, no back-compat alias):
SchemaOrganization→Organization(class +SchemaOrganizationProtocol→OrganizationProtocol), module helperlist_json_schema_organizations→list_organizations.git mvto preserve history:models/schema_organization.py→models/organization.py, the unit/integration test modules, anddocs/reference/experimental/{async,sync}/schema_organization.md→organization.md; updatedmkdocs.ymlnav.models/__init__.py,operations/{store,delete}_operations.py, mixins, curator extension, and the deprecatedservices/json_schema.pydocstring pointers.JsonSchemaOrganizationclass inservices/json_schema.pyis intentionally left unchanged — it is a separate deprecated API, not the model being renamed.Testing:
Organization; existing store/delete/factory routing unit tests updated for the rename.142 passedacross json_schema services, organization, search-management, and store/delete operations.SearchIndex(create/retrieve, match-all query, autocomplete, delete) — kept minimal to limit CI/Synapse-server load; index-creation tests skip gracefully on a 403 where creation is restricted.ruffandblackclean on all changed files (the 2 remainingF841flags in the renamed org test module and the json_schema tutorial are pre-existing debt, left untouched per surgical-change scope).