aignostics 0.2.232__tar.gz → 0.2.234__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.
- {aignostics-0.2.232 → aignostics-0.2.234}/PKG-INFO +1 -1
- {aignostics-0.2.232 → aignostics-0.2.234}/examples/notebook.py +1 -1
- {aignostics-0.2.232 → aignostics-0.2.234}/pyproject.toml +2 -2
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/gui/_frame.py +35 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/qupath/_service.py +47 -35
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/utils/__init__.py +7 -1
- aignostics-0.2.234/src/aignostics/utils/_di.py +113 -0
- aignostics-0.2.234/src/aignostics/utils/_nav.py +162 -0
- aignostics-0.2.232/src/aignostics/utils/_di.py +0 -76
- {aignostics-0.2.232 → aignostics-0.2.234}/.gitignore +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/LICENSE +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/README.md +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/codegen/out/.openapi-generator/FILES +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/codegen/out/.openapi-generator/VERSION +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/codegen/out/aignx/codegen/api/public_api.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/codegen/out/aignx/codegen/api_client.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/codegen/out/aignx/codegen/api_response.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/codegen/out/aignx/codegen/configuration.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/codegen/out/aignx/codegen/exceptions.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/codegen/out/aignx/codegen/models/__init__.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/codegen/out/aignx/codegen/models/application_read_response.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/codegen/out/aignx/codegen/models/application_read_short_response.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/codegen/out/aignx/codegen/models/application_version.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/codegen/out/aignx/codegen/models/artifact_output.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/codegen/out/aignx/codegen/models/artifact_state.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/codegen/out/aignx/codegen/models/artifact_termination_reason.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/codegen/out/aignx/codegen/models/auth0_organization.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/codegen/out/aignx/codegen/models/auth0_user.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/codegen/out/aignx/codegen/models/custom_metadata_update_request.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/codegen/out/aignx/codegen/models/http_validation_error.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/codegen/out/aignx/codegen/models/input_artifact.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/codegen/out/aignx/codegen/models/input_artifact_creation_request.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/codegen/out/aignx/codegen/models/item_creation_request.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/codegen/out/aignx/codegen/models/item_output.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/codegen/out/aignx/codegen/models/item_result_read_response.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/codegen/out/aignx/codegen/models/item_state.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/codegen/out/aignx/codegen/models/item_termination_reason.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/codegen/out/aignx/codegen/models/me_read_response.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/codegen/out/aignx/codegen/models/organization_read_response.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/codegen/out/aignx/codegen/models/output_artifact.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/codegen/out/aignx/codegen/models/output_artifact_result_read_response.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/codegen/out/aignx/codegen/models/output_artifact_scope.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/codegen/out/aignx/codegen/models/output_artifact_visibility.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/codegen/out/aignx/codegen/models/run_creation_request.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/codegen/out/aignx/codegen/models/run_creation_response.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/codegen/out/aignx/codegen/models/run_item_statistics.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/codegen/out/aignx/codegen/models/run_output.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/codegen/out/aignx/codegen/models/run_read_response.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/codegen/out/aignx/codegen/models/run_state.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/codegen/out/aignx/codegen/models/run_termination_reason.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/codegen/out/aignx/codegen/models/user_read_response.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/codegen/out/aignx/codegen/models/validation_error.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/codegen/out/aignx/codegen/models/validation_error_loc_inner.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/codegen/out/aignx/codegen/models/version_read_response.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/codegen/out/aignx/codegen/rest.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/codegen/out/docs/PublicApi.md +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/dist_native_all/dist_native-macos-15-intel/extracted/aignostics.app/Contents/Frameworks/boto3/examples/cloudfront.rst +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/dist_native_all/dist_native-macos-15-intel/extracted/aignostics.app/Contents/Frameworks/boto3/examples/s3.rst +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/dist_native_all/dist_native-macos-latest/extracted/aignostics.app/Contents/Frameworks/boto3/examples/cloudfront.rst +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/dist_native_all/dist_native-macos-latest/extracted/aignostics.app/Contents/Frameworks/boto3/examples/s3.rst +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/dist_native_all/dist_native-ubuntu-24.04-arm/extracted/aignostics/_internal/boto3/examples/cloudfront.rst +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/dist_native_all/dist_native-ubuntu-24.04-arm/extracted/aignostics/_internal/boto3/examples/s3.rst +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/dist_native_all/dist_native-ubuntu-latest/extracted/aignostics/_internal/boto3/examples/cloudfront.rst +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/dist_native_all/dist_native-ubuntu-latest/extracted/aignostics/_internal/boto3/examples/s3.rst +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/dist_native_all/dist_native-windows-latest/extracted/aignostics/_internal/boto3/examples/cloudfront.rst +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/dist_native_all/dist_native-windows-latest/extracted/aignostics/_internal/boto3/examples/s3.rst +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/examples/__init__.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/examples/notebook.ipynb +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/examples/script.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/CLAUDE.md +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/__init__.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/application/CLAUDE.md +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/application/__init__.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/application/_cli.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/application/_download.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/application/_gui/_frame.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/application/_gui/_page_application_describe.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/application/_gui/_page_application_run_describe.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/application/_gui/_page_builder.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/application/_gui/_page_index.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/application/_gui/_utils.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/application/_gui/assets/.gitignore +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/application/_gui/assets/canceled.lottie +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/application/_gui/assets/done.lottie +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/application/_gui/assets/empty.lottie +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/application/_gui/assets/error.lottie +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/application/_gui/assets/error_alt.lottie +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/application/_gui/assets/home-card-1.png +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/application/_gui/assets/home-card-2.png +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/application/_gui/assets/home-card-3.png +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/application/_gui/assets/home-card-4.png +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/application/_gui/assets/home-card-5.png +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/application/_gui/assets/image-not-found.png +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/application/_gui/assets/pending.lottie +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/application/_gui/assets/processing.lottie +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/application/_gui/assets/ruo.png +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/application/_gui/assets/ruo.svg +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/application/_models.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/application/_service.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/application/_settings.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/application/_utils.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/bucket/CLAUDE.md +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/bucket/__init__.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/bucket/_cli.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/bucket/_gui.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/bucket/_service.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/bucket/_settings.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/bucket/assets/Google-Cloud-logo.png +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/bucket/assets/Google-Cloud-logo.svg +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/cli.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/constants.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/dataset/CLAUDE.md +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/dataset/__init__.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/dataset/_cli.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/dataset/_gui.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/dataset/_service.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/dataset/assets/NIH-IDC-logo.svg +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/gui/CLAUDE.md +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/gui/__init__.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/gui/_error.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/gui/_theme.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/gui/assets/cabin-v27-latin-regular.woff2 +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/gui/assets/cat.lottie +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/gui/assets/logo.png +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/notebook/CLAUDE.md +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/notebook/__init__.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/notebook/_gui.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/notebook/_notebook.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/notebook/_service.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/notebook/assets/python.lottie +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/platform/CLAUDE.md +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/platform/__init__.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/platform/_authentication.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/platform/_cli.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/platform/_client.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/platform/_constants.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/platform/_messages.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/platform/_operation_cache.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/platform/_sdk_metadata.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/platform/_service.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/platform/_settings.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/platform/_utils.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/platform/resources/__init__.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/platform/resources/applications.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/platform/resources/runs.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/platform/resources/utils.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/qupath/CLAUDE.md +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/qupath/__init__.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/qupath/_cli.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/qupath/_gui.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/qupath/_settings.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/qupath/assets/download.lottie +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/qupath/assets/microscope.lottie +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/qupath/assets/update.lottie +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/qupath/scripts/add.groovy +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/qupath/scripts/annotate.groovy +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/qupath/scripts/inspect.groovy +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/qupath/scripts/test.groovy +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/system/CLAUDE.md +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/system/__init__.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/system/_cli.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/system/_exceptions.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/system/_gui.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/system/_service.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/system/_settings.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/system/assets/system.lottie +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/third_party/bottle.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/third_party/idc_index.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/third_party/showinfm/__init__.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/third_party/showinfm/argumentsparse.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/third_party/showinfm/constants.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/third_party/showinfm/py.typed +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/third_party/showinfm/showinfm.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/third_party/showinfm/system/__init__.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/third_party/showinfm/system/linux.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/third_party/showinfm/system/tools.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/third_party/showinfm/system/urivalidate.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/third_party/showinfm/system/windows.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/utils/CLAUDE.md +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/utils/_cli.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/utils/_console.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/utils/_constants.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/utils/_fs.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/utils/_gui.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/utils/_health.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/utils/_log.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/utils/_notebook.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/utils/_process.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/utils/_sentry.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/utils/_service.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/utils/_settings.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/utils/_user_agent.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/utils/boot.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/wsi/CLAUDE.md +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/wsi/__init__.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/wsi/_cli.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/wsi/_gui.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/wsi/_openslide_handler.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/wsi/_pydicom_handler.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/wsi/_service.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/wsi/_utils.py +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics/wsi/assets/fallback.png +0 -0
- {aignostics-0.2.232 → aignostics-0.2.234}/src/aignostics.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: aignostics
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.234
|
|
4
4
|
Summary: 🔬 Python SDK providing access to the Aignostics Platform. Includes Aignostics Launchpad (Desktop Application), Aignostics CLI (Command-Line Interface), example notebooks, and Aignostics Client Library.
|
|
5
5
|
Project-URL: Homepage, https://aignostics.readthedocs.io/en/latest/
|
|
6
6
|
Project-URL: Documentation, https://aignostics.readthedocs.io/en/latest/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "aignostics"
|
|
3
|
-
version = "0.2.
|
|
3
|
+
version = "0.2.234"
|
|
4
4
|
description = "🔬 Python SDK providing access to the Aignostics Platform. Includes Aignostics Launchpad (Desktop Application), Aignostics CLI (Command-Line Interface), example notebooks, and Aignostics Client Library."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
authors = [
|
|
@@ -395,7 +395,7 @@ source = ["src/"]
|
|
|
395
395
|
|
|
396
396
|
|
|
397
397
|
[tool.bumpversion]
|
|
398
|
-
current_version = "0.2.
|
|
398
|
+
current_version = "0.2.234"
|
|
399
399
|
parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)"
|
|
400
400
|
serialize = ["{major}.{minor}.{patch}"]
|
|
401
401
|
search = "{current_version}"
|
|
@@ -20,6 +20,11 @@ FLAT_COLOR_WHITE = "flat color=white"
|
|
|
20
20
|
|
|
21
21
|
HEALTH_UPDATE_INTERVAL = 30
|
|
22
22
|
USERINFO_UPDATE_INTERVAL = 60 * 60
|
|
23
|
+
PROPS_CLICKABLE = "clickable"
|
|
24
|
+
PROPS_AVATAR = "avatar"
|
|
25
|
+
CLASSES_FULL_WIDTH = "w-full"
|
|
26
|
+
CLASSES_FULL_HEIGHT = "h-full"
|
|
27
|
+
CLASSES_FULL_SIZE = f"{CLASSES_FULL_WIDTH} {CLASSES_FULL_HEIGHT}"
|
|
23
28
|
|
|
24
29
|
|
|
25
30
|
@contextmanager
|
|
@@ -47,9 +52,38 @@ def frame( # noqa: C901, PLR0915
|
|
|
47
52
|
from aignostics.platform import Service as PlatformService # noqa: PLC0415
|
|
48
53
|
from aignostics.platform import UserInfo, settings # noqa: PLC0415
|
|
49
54
|
from aignostics.system import Service as SystemService # noqa: PLC0415
|
|
55
|
+
from aignostics.utils import NavItem, gui_get_nav_groups # noqa: PLC0415
|
|
50
56
|
|
|
51
57
|
theme()
|
|
52
58
|
|
|
59
|
+
def _nav_item(icon: str, label: str, target: str, marker: str, new_tab: bool = True) -> None:
|
|
60
|
+
"""Create a navigation item with icon and link."""
|
|
61
|
+
with ui.item().props(PROPS_CLICKABLE).classes(CLASSES_FULL_WIDTH):
|
|
62
|
+
with ui.item_section().props(PROPS_AVATAR):
|
|
63
|
+
ui.icon(icon, color="primary")
|
|
64
|
+
with ui.item_section():
|
|
65
|
+
ui.link(label, target, new_tab=new_tab).mark(marker)
|
|
66
|
+
|
|
67
|
+
def _render_nav_item(item: NavItem) -> None:
|
|
68
|
+
"""Render a single NavItem."""
|
|
69
|
+
_nav_item(item.icon, item.label, item.target, item.marker or "", item.new_tab)
|
|
70
|
+
|
|
71
|
+
def _render_nav_groups() -> None:
|
|
72
|
+
"""Render all navigation groups from discovered NavBuilders."""
|
|
73
|
+
nav_groups = gui_get_nav_groups()
|
|
74
|
+
for group in nav_groups:
|
|
75
|
+
if group.use_expansion:
|
|
76
|
+
with (
|
|
77
|
+
ui.expansion(group.name, icon=group.icon, group="nav").classes(CLASSES_FULL_WIDTH),
|
|
78
|
+
ui.list().props("dense").classes(CLASSES_FULL_WIDTH),
|
|
79
|
+
):
|
|
80
|
+
for item in group.items:
|
|
81
|
+
_render_nav_item(item)
|
|
82
|
+
else:
|
|
83
|
+
# Render items flat without expansion
|
|
84
|
+
for item in group.items:
|
|
85
|
+
_render_nav_item(item)
|
|
86
|
+
|
|
53
87
|
user_info: UserInfo | None = None
|
|
54
88
|
launchpad_healthy: bool | None = None
|
|
55
89
|
|
|
@@ -247,6 +281,7 @@ def frame( # noqa: C901, PLR0915
|
|
|
247
281
|
ui.label("Manage Cloud Bucket").classes(
|
|
248
282
|
"font-bold" if context.client.page.path == "/bucket" else "font-normal"
|
|
249
283
|
)
|
|
284
|
+
_render_nav_groups()
|
|
250
285
|
with ui.item(on_click=lambda _: ui.navigate.to("/system")).props("clickable"):
|
|
251
286
|
with ui.item_section().props("avatar"):
|
|
252
287
|
health_icon()
|
|
@@ -42,6 +42,7 @@ QUPATH_SCRIPT_MAX_EXECUTION_TIME = 60 * 60 * 2 # seconds, maximum wait time for
|
|
|
42
42
|
|
|
43
43
|
PROJECT_FILENAME = "project.qpproj"
|
|
44
44
|
ANNOTATIONS_BATCH_SIZE = 500000
|
|
45
|
+
JSON_SUFFIX = ".json"
|
|
45
46
|
|
|
46
47
|
|
|
47
48
|
class QuPathVersion(BaseModel):
|
|
@@ -1124,40 +1125,46 @@ class Service(BaseService):
|
|
|
1124
1125
|
progress_callable(progress)
|
|
1125
1126
|
|
|
1126
1127
|
# We communicate via file I/O with the Groovy script running within QuPath
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
):
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1128
|
+
# Use delete=False to avoid Windows file locking issues - the file must be closed
|
|
1129
|
+
# before QuPath can read it, but NamedTemporaryFile keeps files locked while open on Windows
|
|
1130
|
+
paths_file = tempfile.NamedTemporaryFile(mode="w", suffix=JSON_SUFFIX, encoding="utf-8", delete=False) # noqa: SIM115
|
|
1131
|
+
output_file = tempfile.NamedTemporaryFile(mode="w", suffix=JSON_SUFFIX, encoding="utf-8", delete=False) # noqa: SIM115
|
|
1132
|
+
try:
|
|
1133
|
+
# Write paths and close file so QuPath can read it
|
|
1134
|
+
json.dump([str(path.resolve()) for path in paths], paths_file)
|
|
1135
|
+
paths_file.close()
|
|
1136
|
+
output_file.close()
|
|
1134
1137
|
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1138
|
+
pid = Service.execute_qupath(
|
|
1139
|
+
script=Service._find_groovy_script("add"),
|
|
1140
|
+
script_args=[str(project), paths_file.name, output_file.name],
|
|
1141
|
+
)
|
|
1139
1142
|
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1143
|
+
if not pid:
|
|
1144
|
+
message = "Failed to execute QuPath script for adding images."
|
|
1145
|
+
logger.error(message)
|
|
1146
|
+
raise RuntimeError(message) # noqa: TRY301
|
|
1147
|
+
|
|
1148
|
+
with Path(output_file.name).open("r", encoding="utf-8") as f:
|
|
1149
|
+
result_data = json.load(f)
|
|
1150
|
+
added_count = int(result_data.get("added_count", 0))
|
|
1151
|
+
errors = result_data.get("errors", [])
|
|
1152
|
+
for error in errors:
|
|
1153
|
+
logger.warning(f"QuPath add script error: {error}")
|
|
1154
|
+
|
|
1155
|
+
if progress_callable:
|
|
1156
|
+
progress.status = AddProgressState.COMPLETED
|
|
1157
|
+
progress_callable(progress)
|
|
1158
|
+
|
|
1159
|
+
return added_count
|
|
1160
|
+
except Exception as e:
|
|
1161
|
+
message = f"Failed to add images to QuPath project: {e!s}"
|
|
1162
|
+
logger.exception(message)
|
|
1163
|
+
raise RuntimeError(message) from e
|
|
1164
|
+
finally:
|
|
1165
|
+
# Clean up temp files
|
|
1166
|
+
Path(paths_file.name).unlink(missing_ok=True)
|
|
1167
|
+
Path(output_file.name).unlink(missing_ok=True)
|
|
1161
1168
|
|
|
1162
1169
|
@staticmethod
|
|
1163
1170
|
def annotate(
|
|
@@ -1246,9 +1253,12 @@ class Service(BaseService):
|
|
|
1246
1253
|
RuntimeError: If there is an error inspecting the project.
|
|
1247
1254
|
"""
|
|
1248
1255
|
# We communicate via file I/O with the Groovy script running within QuPath
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1256
|
+
# Use delete=False to avoid Windows file locking issues - the file must be closed
|
|
1257
|
+
# before QuPath can write to it, but NamedTemporaryFile keeps files locked while open on Windows
|
|
1258
|
+
temp_file = tempfile.NamedTemporaryFile(mode="w+", suffix=JSON_SUFFIX, encoding="utf-8", delete=False) # noqa: SIM115
|
|
1259
|
+
output_file = Path(temp_file.name).resolve()
|
|
1260
|
+
temp_file.close()
|
|
1261
|
+
try:
|
|
1252
1262
|
pid = Service.execute_qupath(
|
|
1253
1263
|
quiet=True,
|
|
1254
1264
|
project=project,
|
|
@@ -1267,3 +1277,5 @@ class Service(BaseService):
|
|
|
1267
1277
|
raise RuntimeError(message)
|
|
1268
1278
|
|
|
1269
1279
|
return QuPathProject.model_validate_json(output_file.read_text(encoding="utf-8"))
|
|
1280
|
+
finally:
|
|
1281
|
+
output_file.unlink(missing_ok=True)
|
|
@@ -22,10 +22,11 @@ from ._constants import (
|
|
|
22
22
|
__version__,
|
|
23
23
|
__version_full__,
|
|
24
24
|
)
|
|
25
|
-
from ._di import load_modules, locate_implementations, locate_subclasses
|
|
25
|
+
from ._di import discover_plugin_packages, load_modules, locate_implementations, locate_subclasses
|
|
26
26
|
from ._fs import get_user_data_directory, open_user_data_directory, sanitize_path, sanitize_path_component
|
|
27
27
|
from ._health import Health
|
|
28
28
|
from ._log import LogSettings
|
|
29
|
+
from ._nav import BaseNavBuilder, NavGroup, NavItem, gui_get_nav_groups
|
|
29
30
|
from ._process import SUBPROCESS_CREATION_FLAGS, ProcessInfo, get_process_info
|
|
30
31
|
from ._service import BaseService
|
|
31
32
|
from ._settings import UNHIDE_SENSITIVE_INFO, OpaqueSettings, load_settings, strip_to_none_before_validator
|
|
@@ -35,9 +36,12 @@ from .boot import boot
|
|
|
35
36
|
__all__ = [
|
|
36
37
|
"SUBPROCESS_CREATION_FLAGS",
|
|
37
38
|
"UNHIDE_SENSITIVE_INFO",
|
|
39
|
+
"BaseNavBuilder",
|
|
38
40
|
"BaseService",
|
|
39
41
|
"Health",
|
|
40
42
|
"LogSettings",
|
|
43
|
+
"NavGroup",
|
|
44
|
+
"NavItem",
|
|
41
45
|
"OpaqueSettings",
|
|
42
46
|
"ProcessInfo",
|
|
43
47
|
"__author_email__",
|
|
@@ -60,8 +64,10 @@ __all__ = [
|
|
|
60
64
|
"__version_full__",
|
|
61
65
|
"boot",
|
|
62
66
|
"console",
|
|
67
|
+
"discover_plugin_packages",
|
|
63
68
|
"get_process_info",
|
|
64
69
|
"get_user_data_directory",
|
|
70
|
+
"gui_get_nav_groups",
|
|
65
71
|
"load_modules",
|
|
66
72
|
"load_settings",
|
|
67
73
|
"locate_implementations",
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"""Module for dynamic import and discovery of implementations and subclasses."""
|
|
2
|
+
|
|
3
|
+
import importlib
|
|
4
|
+
import pkgutil
|
|
5
|
+
from functools import lru_cache
|
|
6
|
+
from importlib.metadata import entry_points
|
|
7
|
+
from inspect import isclass
|
|
8
|
+
from typing import Any
|
|
9
|
+
|
|
10
|
+
from ._constants import __project_name__
|
|
11
|
+
|
|
12
|
+
_implementation_cache: dict[Any, list[Any]] = {}
|
|
13
|
+
_subclass_cache: dict[Any, list[Any]] = {}
|
|
14
|
+
|
|
15
|
+
# Entry point group name for aignostics plugins
|
|
16
|
+
PLUGIN_ENTRY_POINT_GROUP = "aignostics.plugins"
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@lru_cache(maxsize=1)
|
|
20
|
+
def discover_plugin_packages() -> tuple[str, ...]:
|
|
21
|
+
"""
|
|
22
|
+
Discover plugin packages using entry points.
|
|
23
|
+
|
|
24
|
+
Plugins register themselves in their pyproject.toml:
|
|
25
|
+
|
|
26
|
+
[project.entry-points."aignostics.plugins"]
|
|
27
|
+
my_plugin = "my_plugin"
|
|
28
|
+
|
|
29
|
+
Results are cached after the first call.
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
tuple[str, ...]: Tuple of discovered plugin package names.
|
|
33
|
+
"""
|
|
34
|
+
eps = entry_points(group=PLUGIN_ENTRY_POINT_GROUP)
|
|
35
|
+
return tuple(ep.value for ep in eps)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def load_modules() -> None:
|
|
39
|
+
package = importlib.import_module(__project_name__)
|
|
40
|
+
for _, name, _ in pkgutil.iter_modules(package.__path__):
|
|
41
|
+
importlib.import_module(f"{__project_name__}.{name}")
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def locate_implementations(_class: type[Any]) -> list[Any]:
|
|
45
|
+
"""
|
|
46
|
+
Dynamically discover all instances of some class.
|
|
47
|
+
|
|
48
|
+
Searches in the main project and all plugins registered via entry points.
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
_class (type[Any]): Class to search for.
|
|
52
|
+
|
|
53
|
+
Returns:
|
|
54
|
+
list[Any]: List of discovered implementations of the given class.
|
|
55
|
+
"""
|
|
56
|
+
if _class in _implementation_cache:
|
|
57
|
+
return _implementation_cache[_class]
|
|
58
|
+
|
|
59
|
+
plugin_packages = discover_plugin_packages()
|
|
60
|
+
|
|
61
|
+
implementations = []
|
|
62
|
+
for package_name in [*plugin_packages, __project_name__]:
|
|
63
|
+
package = importlib.import_module(package_name)
|
|
64
|
+
|
|
65
|
+
for _, name, _ in pkgutil.iter_modules(package.__path__):
|
|
66
|
+
module = importlib.import_module(f"{package_name}.{name}")
|
|
67
|
+
# Check all members of the module
|
|
68
|
+
for member_name in dir(module):
|
|
69
|
+
member = getattr(module, member_name)
|
|
70
|
+
if isinstance(member, _class):
|
|
71
|
+
implementations.append(member)
|
|
72
|
+
|
|
73
|
+
_implementation_cache[_class] = implementations
|
|
74
|
+
return implementations
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def locate_subclasses(_class: type[Any]) -> list[Any]:
|
|
78
|
+
"""
|
|
79
|
+
Dynamically discover all classes that are subclasses of some type.
|
|
80
|
+
|
|
81
|
+
Searches in the main project and all plugins registered via entry points.
|
|
82
|
+
|
|
83
|
+
Args:
|
|
84
|
+
_class (type[Any]): Parent class of subclasses to search for.
|
|
85
|
+
|
|
86
|
+
Returns:
|
|
87
|
+
list[type[Any]]: List of discovered subclasses of the given class.
|
|
88
|
+
"""
|
|
89
|
+
if _class in _subclass_cache:
|
|
90
|
+
return _subclass_cache[_class]
|
|
91
|
+
|
|
92
|
+
plugin_packages = discover_plugin_packages()
|
|
93
|
+
|
|
94
|
+
subclasses = []
|
|
95
|
+
for package_name in [*plugin_packages, __project_name__]:
|
|
96
|
+
try:
|
|
97
|
+
package = importlib.import_module(package_name)
|
|
98
|
+
except ImportError:
|
|
99
|
+
continue
|
|
100
|
+
|
|
101
|
+
for _, name, _ in pkgutil.iter_modules(package.__path__):
|
|
102
|
+
try:
|
|
103
|
+
module = importlib.import_module(f"{package_name}.{name}")
|
|
104
|
+
# Check all members of the module
|
|
105
|
+
for member_name in dir(module):
|
|
106
|
+
member = getattr(module, member_name)
|
|
107
|
+
if isclass(member) and issubclass(member, _class) and member != _class:
|
|
108
|
+
subclasses.append(member)
|
|
109
|
+
except ImportError:
|
|
110
|
+
continue
|
|
111
|
+
|
|
112
|
+
_subclass_cache[_class] = subclasses
|
|
113
|
+
return subclasses
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
"""Navigation infrastructure for NiceGUI sidebar.
|
|
2
|
+
|
|
3
|
+
This module provides:
|
|
4
|
+
- NavItem: Individual navigation item dataclass
|
|
5
|
+
- NavGroup: Group of navigation items
|
|
6
|
+
- BaseNavBuilder: Abstract base class for module navigation builders
|
|
7
|
+
- gui_get_nav_groups: Collect and sort navigation groups from all NavBuilders
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from abc import ABC, abstractmethod
|
|
11
|
+
from dataclasses import dataclass, field
|
|
12
|
+
|
|
13
|
+
from ._di import locate_subclasses
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass
|
|
17
|
+
class NavItem:
|
|
18
|
+
"""Navigation item for sidebar.
|
|
19
|
+
|
|
20
|
+
Attributes:
|
|
21
|
+
icon: Material icon name (e.g., 'waving_hand', 'settings').
|
|
22
|
+
label: Display label for the navigation item.
|
|
23
|
+
target: URL path or external URL for the link.
|
|
24
|
+
marker: Test marker for the item. Auto-generated from label if None.
|
|
25
|
+
new_tab: Whether to open the link in a new tab. Defaults to False (same tab).
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
icon: str
|
|
29
|
+
label: str
|
|
30
|
+
target: str
|
|
31
|
+
marker: str | None = None
|
|
32
|
+
new_tab: bool = False
|
|
33
|
+
|
|
34
|
+
def __post_init__(self) -> None:
|
|
35
|
+
"""Auto-generate marker from label if not provided."""
|
|
36
|
+
if self.marker is None:
|
|
37
|
+
# Convert label to SCREAMING_SNAKE_CASE marker
|
|
38
|
+
self.marker = "LINK_" + self.label.upper().replace(" ", "_").replace("(", "").replace(")", "")
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@dataclass
|
|
42
|
+
class NavGroup:
|
|
43
|
+
"""Group of navigation items from a NavBuilder.
|
|
44
|
+
|
|
45
|
+
Used internally for rendering navigation in the sidebar.
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
name: str
|
|
49
|
+
icon: str = "folder"
|
|
50
|
+
items: list[NavItem] = field(default_factory=list)
|
|
51
|
+
position: int = 1000
|
|
52
|
+
use_expansion: bool = True
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class BaseNavBuilder(ABC):
|
|
56
|
+
"""Base class for navigation builders.
|
|
57
|
+
|
|
58
|
+
Each module should have ONE NavBuilder that defines its navigation items.
|
|
59
|
+
NavBuilders are auto-discovered and used to populate the sidebar.
|
|
60
|
+
|
|
61
|
+
Example:
|
|
62
|
+
class NavBuilder(BaseNavBuilder):
|
|
63
|
+
@staticmethod
|
|
64
|
+
def get_nav_name() -> str:
|
|
65
|
+
return "My Module"
|
|
66
|
+
|
|
67
|
+
@staticmethod
|
|
68
|
+
def get_nav_items() -> list[NavItem]:
|
|
69
|
+
return [
|
|
70
|
+
NavItem(icon="home", label="Home", target="/my-module"),
|
|
71
|
+
NavItem(icon="settings", label="Settings", target="/my-module/settings"),
|
|
72
|
+
]
|
|
73
|
+
|
|
74
|
+
@staticmethod
|
|
75
|
+
def get_nav_position() -> int:
|
|
76
|
+
return 200 # Lower = higher in sidebar
|
|
77
|
+
"""
|
|
78
|
+
|
|
79
|
+
@staticmethod
|
|
80
|
+
@abstractmethod
|
|
81
|
+
def get_nav_name() -> str:
|
|
82
|
+
"""Return the display name for this module's navigation group.
|
|
83
|
+
|
|
84
|
+
Returns:
|
|
85
|
+
str: Display name shown in sidebar (e.g., 'Hello World', 'System').
|
|
86
|
+
"""
|
|
87
|
+
|
|
88
|
+
@staticmethod
|
|
89
|
+
@abstractmethod
|
|
90
|
+
def get_nav_items() -> list[NavItem]:
|
|
91
|
+
"""Return navigation items for the sidebar.
|
|
92
|
+
|
|
93
|
+
Items are rendered in list order within the module's group.
|
|
94
|
+
|
|
95
|
+
Returns:
|
|
96
|
+
list[NavItem]: Navigation items for this module.
|
|
97
|
+
"""
|
|
98
|
+
|
|
99
|
+
@staticmethod
|
|
100
|
+
def get_nav_position() -> int:
|
|
101
|
+
"""Return position in sidebar (lower = higher).
|
|
102
|
+
|
|
103
|
+
Convention:
|
|
104
|
+
- 100-199: Core demo/example pages
|
|
105
|
+
- 200-499: Feature modules
|
|
106
|
+
- 500-799: Default (unspecified)
|
|
107
|
+
- 800-899: System/admin pages
|
|
108
|
+
- 900-999: External links (API docs, status, repo)
|
|
109
|
+
|
|
110
|
+
Returns:
|
|
111
|
+
int: Position value. Defaults to 1000.
|
|
112
|
+
"""
|
|
113
|
+
return 1000
|
|
114
|
+
|
|
115
|
+
@staticmethod
|
|
116
|
+
def get_nav_icon() -> str:
|
|
117
|
+
"""Return the icon for the navigation group expansion panel.
|
|
118
|
+
|
|
119
|
+
Uses Material Icons names. See: https://fonts.google.com/icons
|
|
120
|
+
|
|
121
|
+
Returns:
|
|
122
|
+
str: Material icon name. Defaults to 'folder'.
|
|
123
|
+
"""
|
|
124
|
+
return "folder"
|
|
125
|
+
|
|
126
|
+
@staticmethod
|
|
127
|
+
def get_nav_use_expansion() -> bool:
|
|
128
|
+
"""Return whether to render items in an expansion panel.
|
|
129
|
+
|
|
130
|
+
If True, items are grouped in a collapsible expansion with get_nav_name().
|
|
131
|
+
If False, items are rendered flat without grouping.
|
|
132
|
+
|
|
133
|
+
Returns:
|
|
134
|
+
bool: Use expansion panel. Defaults to True.
|
|
135
|
+
"""
|
|
136
|
+
return True
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def gui_get_nav_groups() -> list[NavGroup]:
|
|
140
|
+
"""Collect navigation groups from all NavBuilders.
|
|
141
|
+
|
|
142
|
+
Returns:
|
|
143
|
+
list[NavGroup]: Navigation groups sorted by position.
|
|
144
|
+
"""
|
|
145
|
+
nav_builders = locate_subclasses(BaseNavBuilder)
|
|
146
|
+
groups: list[NavGroup] = []
|
|
147
|
+
|
|
148
|
+
for nav_builder in nav_builders:
|
|
149
|
+
items = nav_builder.get_nav_items()
|
|
150
|
+
if items: # Only include builders with nav items
|
|
151
|
+
groups.append(
|
|
152
|
+
NavGroup(
|
|
153
|
+
name=nav_builder.get_nav_name(),
|
|
154
|
+
icon=nav_builder.get_nav_icon(),
|
|
155
|
+
items=items,
|
|
156
|
+
position=nav_builder.get_nav_position(),
|
|
157
|
+
use_expansion=nav_builder.get_nav_use_expansion(),
|
|
158
|
+
)
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
# Sort by position (lower = higher in sidebar)
|
|
162
|
+
return sorted(groups, key=lambda g: g.position)
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
"""Module for dynamic import and discovery of implementations and subclasses."""
|
|
2
|
-
|
|
3
|
-
import importlib
|
|
4
|
-
import pkgutil
|
|
5
|
-
from inspect import isclass
|
|
6
|
-
from typing import Any
|
|
7
|
-
|
|
8
|
-
from ._constants import __project_name__
|
|
9
|
-
|
|
10
|
-
_implementation_cache: dict[Any, list[Any]] = {}
|
|
11
|
-
_subclass_cache: dict[Any, list[Any]] = {}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
def load_modules() -> None:
|
|
15
|
-
package = importlib.import_module(__project_name__)
|
|
16
|
-
for _, name, _ in pkgutil.iter_modules(package.__path__):
|
|
17
|
-
importlib.import_module(f"{__project_name__}.{name}")
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
def locate_implementations(_class: type[Any]) -> list[Any]:
|
|
21
|
-
"""
|
|
22
|
-
Dynamically discover all instances of some class.
|
|
23
|
-
|
|
24
|
-
Args:
|
|
25
|
-
_class (type[Any]): Class to search for.
|
|
26
|
-
|
|
27
|
-
Returns:
|
|
28
|
-
list[Any]: List of discovered implementations of the given class.
|
|
29
|
-
"""
|
|
30
|
-
if _class in _implementation_cache:
|
|
31
|
-
return _implementation_cache[_class]
|
|
32
|
-
|
|
33
|
-
implementations = []
|
|
34
|
-
package = importlib.import_module(__project_name__)
|
|
35
|
-
|
|
36
|
-
for _, name, _ in pkgutil.iter_modules(package.__path__):
|
|
37
|
-
module = importlib.import_module(f"{__project_name__}.{name}")
|
|
38
|
-
# Check all members of the module
|
|
39
|
-
for member_name in dir(module):
|
|
40
|
-
member = getattr(module, member_name)
|
|
41
|
-
if isinstance(member, _class):
|
|
42
|
-
implementations.append(member)
|
|
43
|
-
|
|
44
|
-
_implementation_cache[_class] = implementations
|
|
45
|
-
return implementations
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
def locate_subclasses(_class: type[Any]) -> list[Any]:
|
|
49
|
-
"""
|
|
50
|
-
Dynamically discover all classes that are subclasses of some type.
|
|
51
|
-
|
|
52
|
-
Args:
|
|
53
|
-
_class (type[Any]): Parent class of subclasses to search for.
|
|
54
|
-
|
|
55
|
-
Returns:
|
|
56
|
-
list[type[Any]]: List of discovered subclasses of the given class.
|
|
57
|
-
"""
|
|
58
|
-
if _class in _subclass_cache:
|
|
59
|
-
return _subclass_cache[_class]
|
|
60
|
-
|
|
61
|
-
subclasses = []
|
|
62
|
-
package = importlib.import_module(__project_name__)
|
|
63
|
-
|
|
64
|
-
for _, name, _ in pkgutil.iter_modules(package.__path__):
|
|
65
|
-
try:
|
|
66
|
-
module = importlib.import_module(f"{__project_name__}.{name}")
|
|
67
|
-
# Check all members of the module
|
|
68
|
-
for member_name in dir(module):
|
|
69
|
-
member = getattr(module, member_name)
|
|
70
|
-
if isclass(member) and issubclass(member, _class) and member != _class:
|
|
71
|
-
subclasses.append(member)
|
|
72
|
-
except ImportError:
|
|
73
|
-
continue
|
|
74
|
-
|
|
75
|
-
_subclass_cache[_class] = subclasses
|
|
76
|
-
return subclasses
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{aignostics-0.2.232 → aignostics-0.2.234}/codegen/out/aignx/codegen/models/application_version.py
RENAMED
|
File without changes
|
{aignostics-0.2.232 → aignostics-0.2.234}/codegen/out/aignx/codegen/models/artifact_output.py
RENAMED
|
File without changes
|
{aignostics-0.2.232 → aignostics-0.2.234}/codegen/out/aignx/codegen/models/artifact_state.py
RENAMED
|
File without changes
|
|
File without changes
|
{aignostics-0.2.232 → aignostics-0.2.234}/codegen/out/aignx/codegen/models/auth0_organization.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{aignostics-0.2.232 → aignostics-0.2.234}/codegen/out/aignx/codegen/models/http_validation_error.py
RENAMED
|
File without changes
|
{aignostics-0.2.232 → aignostics-0.2.234}/codegen/out/aignx/codegen/models/input_artifact.py
RENAMED
|
File without changes
|
|
File without changes
|
{aignostics-0.2.232 → aignostics-0.2.234}/codegen/out/aignx/codegen/models/item_creation_request.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{aignostics-0.2.232 → aignostics-0.2.234}/codegen/out/aignx/codegen/models/me_read_response.py
RENAMED
|
File without changes
|