aignostics 0.2.60__tar.gz → 0.2.62__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.60 → aignostics-0.2.62}/PKG-INFO +1 -1
- {aignostics-0.2.60 → aignostics-0.2.62}/examples/notebook.py +1 -1
- {aignostics-0.2.60 → aignostics-0.2.62}/pyproject.toml +2 -2
- aignostics-0.2.62/src/aignostics/bucket/_cli.py +345 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/platform/_cli.py +1 -3
- aignostics-0.2.60/src/aignostics/bucket/_cli.py +0 -148
- {aignostics-0.2.60 → aignostics-0.2.62}/.gitignore +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/LICENSE +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/README.md +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/codegen/out/.openapi-generator/FILES +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/codegen/out/.openapi-generator/VERSION +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/codegen/out/aignx/codegen/api/public_api.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/codegen/out/aignx/codegen/api_client.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/codegen/out/aignx/codegen/api_response.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/codegen/out/aignx/codegen/configuration.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/codegen/out/aignx/codegen/exceptions.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/codegen/out/aignx/codegen/models/__init__.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/codegen/out/aignx/codegen/models/application_read_response.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/codegen/out/aignx/codegen/models/application_run_status.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/codegen/out/aignx/codegen/models/application_version_read_response.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/codegen/out/aignx/codegen/models/http_validation_error.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/codegen/out/aignx/codegen/models/input_artifact_creation_request.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/codegen/out/aignx/codegen/models/input_artifact_read_response.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/codegen/out/aignx/codegen/models/item_creation_request.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/codegen/out/aignx/codegen/models/item_result_read_response.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/codegen/out/aignx/codegen/models/item_status.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/codegen/out/aignx/codegen/models/output_artifact_read_response.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/codegen/out/aignx/codegen/models/output_artifact_result_read_response.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/codegen/out/aignx/codegen/models/output_artifact_scope.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/codegen/out/aignx/codegen/models/payload_input_artifact.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/codegen/out/aignx/codegen/models/payload_item.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/codegen/out/aignx/codegen/models/payload_output_artifact.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/codegen/out/aignx/codegen/models/run_creation_request.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/codegen/out/aignx/codegen/models/run_creation_response.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/codegen/out/aignx/codegen/models/run_read_response.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/codegen/out/aignx/codegen/models/transfer_urls.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/codegen/out/aignx/codegen/models/user_payload.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/codegen/out/aignx/codegen/models/validation_error.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/codegen/out/aignx/codegen/models/validation_error_loc_inner.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/codegen/out/aignx/codegen/rest.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/codegen/out/docs/PublicApi.md +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/dist_native_all/dist_native-macos-13/aignostics/_internal/boto3/examples/cloudfront.rst +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/dist_native_all/dist_native-macos-13/aignostics/_internal/boto3/examples/s3.rst +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/dist_native_all/dist_native-macos-13/aignostics/_internal/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.jquery +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/dist_native_all/dist_native-macos-13/aignostics/_internal/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.openseadragon +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/dist_native_all/dist_native-macos-13/aignostics/_internal/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.openseadragon-scalebar +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/dist_native_all/dist_native-macos-13/aignostics.app/Contents/Frameworks/boto3/examples/cloudfront.rst +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/dist_native_all/dist_native-macos-13/aignostics.app/Contents/Frameworks/boto3/examples/s3.rst +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/dist_native_all/dist_native-macos-13/aignostics.app/Contents/Frameworks/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.jquery +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/dist_native_all/dist_native-macos-13/aignostics.app/Contents/Frameworks/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.openseadragon +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/dist_native_all/dist_native-macos-13/aignostics.app/Contents/Frameworks/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.openseadragon-scalebar +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/dist_native_all/dist_native-macos-13/aignostics.app/Contents/Resources/boto3/examples/cloudfront.rst +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/dist_native_all/dist_native-macos-13/aignostics.app/Contents/Resources/boto3/examples/s3.rst +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/dist_native_all/dist_native-macos-13/aignostics.app/Contents/Resources/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.jquery +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/dist_native_all/dist_native-macos-13/aignostics.app/Contents/Resources/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.openseadragon +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/dist_native_all/dist_native-macos-13/aignostics.app/Contents/Resources/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.openseadragon-scalebar +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/dist_native_all/dist_native-macos-latest/aignostics/_internal/boto3/examples/cloudfront.rst +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/dist_native_all/dist_native-macos-latest/aignostics/_internal/boto3/examples/s3.rst +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/dist_native_all/dist_native-macos-latest/aignostics/_internal/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.jquery +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/dist_native_all/dist_native-macos-latest/aignostics/_internal/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.openseadragon +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/dist_native_all/dist_native-macos-latest/aignostics/_internal/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.openseadragon-scalebar +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/dist_native_all/dist_native-macos-latest/aignostics.app/Contents/Frameworks/boto3/examples/cloudfront.rst +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/dist_native_all/dist_native-macos-latest/aignostics.app/Contents/Frameworks/boto3/examples/s3.rst +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/dist_native_all/dist_native-macos-latest/aignostics.app/Contents/Frameworks/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.jquery +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/dist_native_all/dist_native-macos-latest/aignostics.app/Contents/Frameworks/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.openseadragon +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/dist_native_all/dist_native-macos-latest/aignostics.app/Contents/Frameworks/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.openseadragon-scalebar +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/dist_native_all/dist_native-macos-latest/aignostics.app/Contents/Resources/boto3/examples/cloudfront.rst +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/dist_native_all/dist_native-macos-latest/aignostics.app/Contents/Resources/boto3/examples/s3.rst +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/dist_native_all/dist_native-macos-latest/aignostics.app/Contents/Resources/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.jquery +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/dist_native_all/dist_native-macos-latest/aignostics.app/Contents/Resources/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.openseadragon +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/dist_native_all/dist_native-macos-latest/aignostics.app/Contents/Resources/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.openseadragon-scalebar +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/dist_native_all/dist_native-ubuntu-24.04-arm/aignostics/_internal/boto3/examples/cloudfront.rst +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/dist_native_all/dist_native-ubuntu-24.04-arm/aignostics/_internal/boto3/examples/s3.rst +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/dist_native_all/dist_native-ubuntu-24.04-arm/aignostics/_internal/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.jquery +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/dist_native_all/dist_native-ubuntu-24.04-arm/aignostics/_internal/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.openseadragon +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/dist_native_all/dist_native-ubuntu-24.04-arm/aignostics/_internal/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.openseadragon-scalebar +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/dist_native_all/dist_native-ubuntu-latest/aignostics/_internal/boto3/examples/cloudfront.rst +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/dist_native_all/dist_native-ubuntu-latest/aignostics/_internal/boto3/examples/s3.rst +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/dist_native_all/dist_native-ubuntu-latest/aignostics/_internal/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.jquery +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/dist_native_all/dist_native-ubuntu-latest/aignostics/_internal/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.openseadragon +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/dist_native_all/dist_native-ubuntu-latest/aignostics/_internal/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.openseadragon-scalebar +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/dist_native_all/dist_native-windows-11-arm/aignostics/_internal/boto3/examples/cloudfront.rst +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/dist_native_all/dist_native-windows-11-arm/aignostics/_internal/boto3/examples/s3.rst +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/dist_native_all/dist_native-windows-11-arm/aignostics/_internal/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.jquery +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/dist_native_all/dist_native-windows-11-arm/aignostics/_internal/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.openseadragon +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/dist_native_all/dist_native-windows-11-arm/aignostics/_internal/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.openseadragon-scalebar +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/dist_native_all/dist_native-windows-latest/aignostics/_internal/boto3/examples/cloudfront.rst +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/dist_native_all/dist_native-windows-latest/aignostics/_internal/boto3/examples/s3.rst +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/dist_native_all/dist_native-windows-latest/aignostics/_internal/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.jquery +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/dist_native_all/dist_native-windows-latest/aignostics/_internal/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.openseadragon +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/dist_native_all/dist_native-windows-latest/aignostics/_internal/openslide_python-1.4.2.dist-info/licenses/examples/deepzoom/licenses/LICENSE.openseadragon-scalebar +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/examples/__init__.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/examples/notebook.ipynb +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/examples/script.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/__init__.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/application/__init__.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/application/_cli.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/application/_gui/_frame.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/application/_gui/_page_application_describe.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/application/_gui/_page_application_run_describe.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/application/_gui/_page_builder.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/application/_gui/_page_index.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/application/_gui/_utils.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/application/_gui/assets/canceled.lottie +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/application/_gui/assets/done.lottie +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/application/_gui/assets/empty.lottie +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/application/_gui/assets/error.lottie +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/application/_gui/assets/error_alt.lottie +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/application/_gui/assets/home-card-1.png +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/application/_gui/assets/home-card-2.png +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/application/_gui/assets/home-card-3.png +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/application/_gui/assets/home-card-4.png +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/application/_gui/assets/home-card-5.png +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/application/_gui/assets/image-not-found.png +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/application/_gui/assets/pending.lottie +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/application/_gui/assets/pending_alt.lottie +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/application/_gui/assets/ruo.png +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/application/_gui/assets/ruo.svg +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/application/_service.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/application/_settings.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/application/_utils.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/bucket/__init__.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/bucket/_gui.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/bucket/_service.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/bucket/_settings.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/bucket/assets/Google-Cloud-logo.png +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/bucket/assets/Google-Cloud-logo.svg +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/cli.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/constants.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/dataset/__init__.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/dataset/_cli.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/dataset/_gui.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/dataset/_service.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/dataset/assets/NIH-IDC-logo.svg +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/gui/__init__.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/gui/_frame.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/gui/_theme.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/gui/assets/cabin-v27-latin-regular.woff2 +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/gui/assets/logo.png +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/notebook/__init__.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/notebook/_gui.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/notebook/_notebook.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/notebook/_service.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/notebook/assets/python.lottie +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/platform/__init__.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/platform/_authentication.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/platform/_client.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/platform/_constants.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/platform/_messages.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/platform/_service.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/platform/_settings.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/platform/_utils.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/platform/resources/__init__.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/platform/resources/applications.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/platform/resources/runs.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/platform/resources/utils.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/qupath/__init__.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/qupath/_cli.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/qupath/_gui.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/qupath/_service.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/qupath/_settings.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/qupath/assets/download.lottie +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/qupath/assets/microscope.lottie +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/qupath/assets/update.lottie +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/qupath/scripts/add.groovy +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/qupath/scripts/annotate.groovy +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/qupath/scripts/inspect.groovy +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/qupath/scripts/test.groovy +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/system/__init__.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/system/_cli.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/system/_exceptions.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/system/_gui.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/system/_service.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/system/_settings.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/system/assets/system.lottie +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/third_party/bottle.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/third_party/idc_index.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/utils/__init__.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/utils/_cli.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/utils/_console.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/utils/_constants.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/utils/_di.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/utils/_fs.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/utils/_gui.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/utils/_health.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/utils/_log.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/utils/_logfire.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/utils/_notebook.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/utils/_process.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/utils/_sentry.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/utils/_service.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/utils/_settings.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/utils/boot.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/wsi/__init__.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/wsi/_cli.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/wsi/_gui.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/wsi/_openslide_handler.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/wsi/_pydicom_handler.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/wsi/_service.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/wsi/_utils.py +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/src/aignostics/wsi/assets/fallback.png +0 -0
- {aignostics-0.2.60 → aignostics-0.2.62}/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.62
|
|
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.62"
|
|
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 = [
|
|
@@ -352,7 +352,7 @@ source = ["src/"]
|
|
|
352
352
|
|
|
353
353
|
|
|
354
354
|
[tool.bumpversion]
|
|
355
|
-
current_version = "0.2.
|
|
355
|
+
current_version = "0.2.62"
|
|
356
356
|
parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)"
|
|
357
357
|
serialize = ["{major}.{minor}.{patch}"]
|
|
358
358
|
search = "{current_version}"
|
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
"""CLI of bucket module."""
|
|
2
|
+
|
|
3
|
+
import datetime
|
|
4
|
+
import json
|
|
5
|
+
import re
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from typing import TYPE_CHECKING, Annotated
|
|
8
|
+
|
|
9
|
+
import humanize
|
|
10
|
+
import requests
|
|
11
|
+
import typer
|
|
12
|
+
|
|
13
|
+
from aignostics.utils import console, get_logger
|
|
14
|
+
|
|
15
|
+
from ._service import Service
|
|
16
|
+
|
|
17
|
+
if TYPE_CHECKING:
|
|
18
|
+
from rich.progress import Progress
|
|
19
|
+
|
|
20
|
+
MESSAGE_NOT_YET_IMPLEMENTED = "NOT YET IMPLEMENTED"
|
|
21
|
+
|
|
22
|
+
logger = get_logger(__name__)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
cli = typer.Typer(
|
|
26
|
+
name="bucket",
|
|
27
|
+
help="Operations on cloud bucket on Aignostics Platform.",
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def _find_matching_objects(source_pattern: str) -> list[dict[str, str]]:
|
|
32
|
+
"""Find objects in bucket matching the given pattern.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
source_pattern: Regular expression pattern to match object keys against.
|
|
36
|
+
|
|
37
|
+
Returns:
|
|
38
|
+
List of dictionaries containing object key and signed download URL.
|
|
39
|
+
"""
|
|
40
|
+
all_objects = Service().find()
|
|
41
|
+
logger.debug("Found %d objects in bucket, matching against '%s'...", len(all_objects), source_pattern)
|
|
42
|
+
|
|
43
|
+
matched = []
|
|
44
|
+
for obj in all_objects:
|
|
45
|
+
object_key = obj if isinstance(obj, str) else obj.get("key", "")
|
|
46
|
+
if re.match(source_pattern, object_key):
|
|
47
|
+
matched.append({
|
|
48
|
+
"key": object_key,
|
|
49
|
+
"signed_download_url": Service().create_signed_download_url(object_key),
|
|
50
|
+
})
|
|
51
|
+
return matched
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def _download_single_file(
|
|
55
|
+
obj: dict[str, str],
|
|
56
|
+
destination: Path,
|
|
57
|
+
file_progress: "Progress",
|
|
58
|
+
) -> Path | None:
|
|
59
|
+
"""Download a single file and return the output path on success, None on failure.
|
|
60
|
+
|
|
61
|
+
Args:
|
|
62
|
+
obj: Dictionary containing object key and signed download URL.
|
|
63
|
+
destination: Destination directory for the downloaded file.
|
|
64
|
+
file_progress: Rich Progress instance for tracking individual file progress.
|
|
65
|
+
|
|
66
|
+
Returns:
|
|
67
|
+
Path to the downloaded file on success, None on failure.
|
|
68
|
+
"""
|
|
69
|
+
object_key = obj["key"]
|
|
70
|
+
source_url_signed = obj["signed_download_url"]
|
|
71
|
+
filename = object_key.split("/")[-1]
|
|
72
|
+
output_path = destination / filename
|
|
73
|
+
|
|
74
|
+
try:
|
|
75
|
+
response = requests.get(source_url_signed, stream=True, timeout=60)
|
|
76
|
+
response.raise_for_status()
|
|
77
|
+
total_size = int(response.headers.get("content-length", 0))
|
|
78
|
+
|
|
79
|
+
# Create a task for individual file progress
|
|
80
|
+
file_task = file_progress.add_task(
|
|
81
|
+
f"Downloading {filename}", total=total_size, extra_description=f"from {object_key}"
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
# Write the file
|
|
85
|
+
with open(output_path, "wb") as f:
|
|
86
|
+
for chunk in response.iter_content(chunk_size=8192):
|
|
87
|
+
if chunk: # filter out keep-alive new chunks
|
|
88
|
+
f.write(chunk)
|
|
89
|
+
file_progress.update(file_task, advance=len(chunk))
|
|
90
|
+
|
|
91
|
+
# Remove the completed file task
|
|
92
|
+
file_progress.remove_task(file_task)
|
|
93
|
+
return output_path
|
|
94
|
+
|
|
95
|
+
except requests.RequestException:
|
|
96
|
+
logger.exception("Failed to download %s", object_key)
|
|
97
|
+
return None
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def _create_progress_ui() -> tuple["Progress", "Progress", type, type, type]:
|
|
101
|
+
"""Create the progress UI components.
|
|
102
|
+
|
|
103
|
+
Returns:
|
|
104
|
+
Tuple of (main_progress, file_progress, panel_class, group_class, live_class) components.
|
|
105
|
+
"""
|
|
106
|
+
from rich.console import Group # noqa: PLC0415
|
|
107
|
+
from rich.live import Live # noqa: PLC0415
|
|
108
|
+
from rich.panel import Panel # noqa: PLC0415
|
|
109
|
+
from rich.progress import ( # noqa: PLC0415
|
|
110
|
+
BarColumn,
|
|
111
|
+
FileSizeColumn,
|
|
112
|
+
Progress,
|
|
113
|
+
TaskProgressColumn,
|
|
114
|
+
TextColumn,
|
|
115
|
+
TimeElapsedColumn,
|
|
116
|
+
TimeRemainingColumn,
|
|
117
|
+
TotalFileSizeColumn,
|
|
118
|
+
TransferSpeedColumn,
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
# Create main progress bar for overall download progress
|
|
122
|
+
main_progress = Progress(
|
|
123
|
+
BarColumn(),
|
|
124
|
+
TaskProgressColumn(),
|
|
125
|
+
TextColumn("[progress.description]{task.description}"),
|
|
126
|
+
TimeElapsedColumn(),
|
|
127
|
+
TextColumn("{task.fields[extra_description]}"),
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
# Create individual file progress bar
|
|
131
|
+
file_progress = Progress(
|
|
132
|
+
BarColumn(),
|
|
133
|
+
TaskProgressColumn(),
|
|
134
|
+
TextColumn("[progress.description]{task.description}"),
|
|
135
|
+
TimeElapsedColumn(),
|
|
136
|
+
TimeRemainingColumn(),
|
|
137
|
+
FileSizeColumn(),
|
|
138
|
+
TotalFileSizeColumn(),
|
|
139
|
+
TransferSpeedColumn(),
|
|
140
|
+
TextColumn("{task.fields[extra_description]}"),
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
return main_progress, file_progress, Panel, Group, Live
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def _download_with_progress(matched: list[dict[str, str]], destination: Path, source_pattern: str) -> None:
|
|
147
|
+
"""Download files with progress tracking."""
|
|
148
|
+
main_progress, file_progress, panel_class, group_class, live_class = _create_progress_ui()
|
|
149
|
+
|
|
150
|
+
# Create main task for overall progress
|
|
151
|
+
main_task = main_progress.add_task(
|
|
152
|
+
f"Downloading {len(matched)} files", total=len(matched), extra_description=f"matching '{source_pattern}'"
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
# Create progress group
|
|
156
|
+
progress_group = group_class(
|
|
157
|
+
panel_class(main_progress, title="Overall Progress"),
|
|
158
|
+
panel_class(file_progress, title="Current File"),
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
downloaded_count = 0
|
|
162
|
+
failed_count = 0
|
|
163
|
+
|
|
164
|
+
with live_class(progress_group, console=console, refresh_per_second=10):
|
|
165
|
+
for obj in matched:
|
|
166
|
+
result = _download_single_file(obj, destination, file_progress)
|
|
167
|
+
|
|
168
|
+
if result:
|
|
169
|
+
downloaded_count += 1
|
|
170
|
+
console.print(f"[green]✓[/green] Downloaded: {result.name}")
|
|
171
|
+
else:
|
|
172
|
+
failed_count += 1
|
|
173
|
+
console.print(f"[red]✗[/red] Failed: {obj['key']}")
|
|
174
|
+
|
|
175
|
+
# Update main progress
|
|
176
|
+
main_progress.update(main_task, advance=1)
|
|
177
|
+
|
|
178
|
+
# Final summary
|
|
179
|
+
if downloaded_count > 0:
|
|
180
|
+
console.print(f"[green]Successfully downloaded {downloaded_count} files to {destination}[/green]")
|
|
181
|
+
|
|
182
|
+
if failed_count > 0:
|
|
183
|
+
console.print(f"[red]Failed to download {failed_count} files[/red]")
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
@cli.command()
|
|
187
|
+
def upload(
|
|
188
|
+
source: Annotated[
|
|
189
|
+
Path,
|
|
190
|
+
typer.Argument(
|
|
191
|
+
help="Source file or directory to upload",
|
|
192
|
+
exists=True,
|
|
193
|
+
file_okay=True,
|
|
194
|
+
dir_okay=True,
|
|
195
|
+
writable=False,
|
|
196
|
+
readable=True,
|
|
197
|
+
resolve_path=False,
|
|
198
|
+
),
|
|
199
|
+
],
|
|
200
|
+
destination_prefix: Annotated[
|
|
201
|
+
str,
|
|
202
|
+
typer.Option(
|
|
203
|
+
help="Destination layout. Supports {username}, {timestamp}. "
|
|
204
|
+
'E.g. you might want to use "{username}/myproject/"'
|
|
205
|
+
),
|
|
206
|
+
] = "{username}",
|
|
207
|
+
) -> None:
|
|
208
|
+
"""Upload file or directory to bucket in Aignostics platform."""
|
|
209
|
+
import psutil # noqa: PLC0415
|
|
210
|
+
from rich.progress import ( # noqa: PLC0415
|
|
211
|
+
BarColumn,
|
|
212
|
+
FileSizeColumn,
|
|
213
|
+
Progress,
|
|
214
|
+
TaskProgressColumn,
|
|
215
|
+
TextColumn,
|
|
216
|
+
TimeRemainingColumn,
|
|
217
|
+
TotalFileSizeColumn,
|
|
218
|
+
TransferSpeedColumn,
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
console.print(f"Uploading {source} to bucket...")
|
|
222
|
+
|
|
223
|
+
total_bytes = 0
|
|
224
|
+
files_count = 0
|
|
225
|
+
|
|
226
|
+
if source.is_file():
|
|
227
|
+
total_bytes = source.stat().st_size
|
|
228
|
+
files_count = 1
|
|
229
|
+
else:
|
|
230
|
+
for file_path in source.glob("**/*"):
|
|
231
|
+
if file_path.is_file():
|
|
232
|
+
total_bytes += file_path.stat().st_size
|
|
233
|
+
files_count += 1
|
|
234
|
+
|
|
235
|
+
console.print(f"Found {files_count} files with total size of {humanize.naturalsize(total_bytes)}")
|
|
236
|
+
|
|
237
|
+
username = psutil.Process().username()
|
|
238
|
+
timestamp = datetime.datetime.now(tz=datetime.UTC).strftime("%Y%m%d_%H%M%S")
|
|
239
|
+
base_prefix = destination_prefix.format(username=username, timestamp=timestamp)
|
|
240
|
+
base_prefix = base_prefix.strip("/")
|
|
241
|
+
|
|
242
|
+
with Progress(
|
|
243
|
+
TextColumn(
|
|
244
|
+
f"[progress.description]Uploading from {source.name} to "
|
|
245
|
+
f"{Service().get_bucket_protocol()}:/{Service().get_bucket_name()}/{base_prefix}"
|
|
246
|
+
),
|
|
247
|
+
BarColumn(),
|
|
248
|
+
TaskProgressColumn(),
|
|
249
|
+
TimeRemainingColumn(),
|
|
250
|
+
FileSizeColumn(),
|
|
251
|
+
TotalFileSizeColumn(),
|
|
252
|
+
TransferSpeedColumn(),
|
|
253
|
+
TextColumn("[progress.description]{task.description}"),
|
|
254
|
+
) as progress:
|
|
255
|
+
task = progress.add_task(f"Uploading to {base_prefix}/...", total=total_bytes)
|
|
256
|
+
|
|
257
|
+
def update_progress(bytes_uploaded: int, file: Path) -> None:
|
|
258
|
+
relpath = file.relative_to(source)
|
|
259
|
+
progress.update(task, advance=bytes_uploaded, description=f"{relpath}")
|
|
260
|
+
|
|
261
|
+
results = Service().upload(source, base_prefix, update_progress)
|
|
262
|
+
|
|
263
|
+
if results["success"]:
|
|
264
|
+
console.print(f"[green]Successfully uploaded {len(results['success'])} files:[/green]")
|
|
265
|
+
for key in results["success"]:
|
|
266
|
+
console.print(f" [green]- {key}[/green]")
|
|
267
|
+
|
|
268
|
+
if results["failed"]:
|
|
269
|
+
console.print(f"[red]Failed to upload {len(results['failed'])} files:[/red]")
|
|
270
|
+
for key in results["failed"]:
|
|
271
|
+
console.print(f" [red]- {key}[/red]")
|
|
272
|
+
|
|
273
|
+
if not results["failed"]:
|
|
274
|
+
console.print("[green]All files uploaded successfully![/green]")
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
@cli.command()
|
|
278
|
+
def download(
|
|
279
|
+
source: Annotated[
|
|
280
|
+
str,
|
|
281
|
+
typer.Argument(
|
|
282
|
+
help="Interpreted as a regular expression keys of objects in bucket are matched against."
|
|
283
|
+
"All matching objects are downloaded",
|
|
284
|
+
),
|
|
285
|
+
],
|
|
286
|
+
destination: Annotated[
|
|
287
|
+
Path,
|
|
288
|
+
typer.Option(
|
|
289
|
+
help="Destination directory to download the matching objects to.",
|
|
290
|
+
exists=False,
|
|
291
|
+
file_okay=False,
|
|
292
|
+
dir_okay=True,
|
|
293
|
+
writable=True,
|
|
294
|
+
readable=True,
|
|
295
|
+
resolve_path=True,
|
|
296
|
+
),
|
|
297
|
+
] = Path.cwd(), # noqa: B008
|
|
298
|
+
) -> None:
|
|
299
|
+
"""Download objects from bucket in Aignsotics platform to local directory."""
|
|
300
|
+
logger.debug("Creating directory '%s' if it does not exist...", destination)
|
|
301
|
+
destination.mkdir(parents=True, exist_ok=True)
|
|
302
|
+
|
|
303
|
+
matched = _find_matching_objects(source)
|
|
304
|
+
|
|
305
|
+
if not matched:
|
|
306
|
+
console.print(f"[yellow]No objects found matching pattern '{source}'[/yellow]")
|
|
307
|
+
return
|
|
308
|
+
|
|
309
|
+
logger.debug("Found %d objects matching '%s' in bucket, downloading to '%s'...", len(matched), source, destination)
|
|
310
|
+
|
|
311
|
+
_download_with_progress(matched, destination, source)
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
@cli.command()
|
|
315
|
+
def ls(
|
|
316
|
+
detail: Annotated[bool, typer.Option(help="Show details")] = False,
|
|
317
|
+
) -> None:
|
|
318
|
+
"""List objects in bucket on Aignostics Platform."""
|
|
319
|
+
console.print_json(json=json.dumps(Service().ls(detail=detail), default=str))
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
@cli.command()
|
|
323
|
+
def find(
|
|
324
|
+
detail: Annotated[bool, typer.Option(help="Show details")] = False,
|
|
325
|
+
) -> None:
|
|
326
|
+
"""Find objects in bucket on Aignostics Platform."""
|
|
327
|
+
console.print_json(json=json.dumps(Service().find(detail=detail), default=str))
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
@cli.command()
|
|
331
|
+
def delete(
|
|
332
|
+
key: Annotated[str, typer.Argument(help="key of object in object")],
|
|
333
|
+
) -> None:
|
|
334
|
+
"""Find objects in bucket on Aignostics Platform."""
|
|
335
|
+
deleted = Service().delete_objects([key])
|
|
336
|
+
if deleted:
|
|
337
|
+
console.print(f"Deleted object with key '{key}'")
|
|
338
|
+
else:
|
|
339
|
+
console.print(f"Object with key '{key}' not found")
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+
@cli.command()
|
|
343
|
+
def purge() -> None:
|
|
344
|
+
"""Purge all objects in bucket on Aignostics Platform."""
|
|
345
|
+
console.print(MESSAGE_NOT_YET_IMPLEMENTED)
|
|
@@ -10,11 +10,9 @@ from aignostics.utils import console, get_logger
|
|
|
10
10
|
|
|
11
11
|
from ._service import Service
|
|
12
12
|
|
|
13
|
-
MESSAGE_NOT_YET_IMPLEMENTED = "NOT YET IMPLEMENTED"
|
|
14
|
-
|
|
15
13
|
logger = get_logger(__name__)
|
|
16
14
|
|
|
17
|
-
cli = typer.Typer(name="
|
|
15
|
+
cli = typer.Typer(name="user", help="User operations such as login, logout and whoami.")
|
|
18
16
|
|
|
19
17
|
service: Service | None = None
|
|
20
18
|
|
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
"""CLI of bucket module."""
|
|
2
|
-
|
|
3
|
-
import datetime
|
|
4
|
-
import json
|
|
5
|
-
from pathlib import Path
|
|
6
|
-
from typing import Annotated
|
|
7
|
-
|
|
8
|
-
import humanize
|
|
9
|
-
import typer
|
|
10
|
-
|
|
11
|
-
from aignostics.utils import console, get_logger
|
|
12
|
-
|
|
13
|
-
from ._service import Service
|
|
14
|
-
|
|
15
|
-
MESSAGE_NOT_YET_IMPLEMENTED = "NOT YET IMPLEMENTED"
|
|
16
|
-
|
|
17
|
-
logger = get_logger(__name__)
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
cli = typer.Typer(
|
|
21
|
-
name="bucket",
|
|
22
|
-
help="Operations on cloud bucket on Aignostics Platform.",
|
|
23
|
-
)
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
@cli.command()
|
|
27
|
-
def upload(
|
|
28
|
-
source: Annotated[
|
|
29
|
-
Path,
|
|
30
|
-
typer.Argument(
|
|
31
|
-
help="Source file or directory to upload",
|
|
32
|
-
exists=True,
|
|
33
|
-
file_okay=True,
|
|
34
|
-
dir_okay=True,
|
|
35
|
-
writable=False,
|
|
36
|
-
readable=True,
|
|
37
|
-
resolve_path=False,
|
|
38
|
-
),
|
|
39
|
-
],
|
|
40
|
-
destination_prefix: Annotated[
|
|
41
|
-
str,
|
|
42
|
-
typer.Option(
|
|
43
|
-
help="Destination layout. Supports {username}, {timestamp}. "
|
|
44
|
-
'E.g. you might want to use "{username}/myproject/"'
|
|
45
|
-
),
|
|
46
|
-
] = "{username}",
|
|
47
|
-
) -> None:
|
|
48
|
-
"""Upload file or directory to bucket in Aignostics platform."""
|
|
49
|
-
import psutil # noqa: PLC0415
|
|
50
|
-
from rich.progress import ( # noqa: PLC0415
|
|
51
|
-
BarColumn,
|
|
52
|
-
FileSizeColumn,
|
|
53
|
-
Progress,
|
|
54
|
-
TaskProgressColumn,
|
|
55
|
-
TextColumn,
|
|
56
|
-
TimeRemainingColumn,
|
|
57
|
-
TotalFileSizeColumn,
|
|
58
|
-
TransferSpeedColumn,
|
|
59
|
-
)
|
|
60
|
-
|
|
61
|
-
console.print(f"Uploading {source} to bucket...")
|
|
62
|
-
|
|
63
|
-
total_bytes = 0
|
|
64
|
-
files_count = 0
|
|
65
|
-
|
|
66
|
-
if source.is_file():
|
|
67
|
-
total_bytes = source.stat().st_size
|
|
68
|
-
files_count = 1
|
|
69
|
-
else:
|
|
70
|
-
for file_path in source.glob("**/*"):
|
|
71
|
-
if file_path.is_file():
|
|
72
|
-
total_bytes += file_path.stat().st_size
|
|
73
|
-
files_count += 1
|
|
74
|
-
|
|
75
|
-
console.print(f"Found {files_count} files with total size of {humanize.naturalsize(total_bytes)}")
|
|
76
|
-
|
|
77
|
-
username = psutil.Process().username()
|
|
78
|
-
timestamp = datetime.datetime.now(tz=datetime.UTC).strftime("%Y%m%d_%H%M%S")
|
|
79
|
-
base_prefix = destination_prefix.format(username=username, timestamp=timestamp)
|
|
80
|
-
base_prefix = base_prefix.strip("/")
|
|
81
|
-
|
|
82
|
-
with Progress(
|
|
83
|
-
TextColumn(
|
|
84
|
-
f"[progress.description]Uploading from {source.name} to "
|
|
85
|
-
f"{Service().get_bucket_protocol()}:/{Service().get_bucket_name()}/{base_prefix}"
|
|
86
|
-
),
|
|
87
|
-
BarColumn(),
|
|
88
|
-
TaskProgressColumn(),
|
|
89
|
-
TimeRemainingColumn(),
|
|
90
|
-
FileSizeColumn(),
|
|
91
|
-
TotalFileSizeColumn(),
|
|
92
|
-
TransferSpeedColumn(),
|
|
93
|
-
TextColumn("[progress.description]{task.description}"),
|
|
94
|
-
) as progress:
|
|
95
|
-
task = progress.add_task(f"Uploading to {base_prefix}/...", total=total_bytes)
|
|
96
|
-
|
|
97
|
-
def update_progress(bytes_uploaded: int, file: Path) -> None:
|
|
98
|
-
relpath = file.relative_to(source)
|
|
99
|
-
progress.update(task, advance=bytes_uploaded, description=f"{relpath}")
|
|
100
|
-
|
|
101
|
-
results = Service().upload(source, base_prefix, update_progress)
|
|
102
|
-
|
|
103
|
-
if results["success"]:
|
|
104
|
-
console.print(f"[green]Successfully uploaded {len(results['success'])} files:[/green]")
|
|
105
|
-
for key in results["success"]:
|
|
106
|
-
console.print(f" [green]- {key}[/green]")
|
|
107
|
-
|
|
108
|
-
if results["failed"]:
|
|
109
|
-
console.print(f"[red]Failed to upload {len(results['failed'])} files:[/red]")
|
|
110
|
-
for key in results["failed"]:
|
|
111
|
-
console.print(f" [red]- {key}[/red]")
|
|
112
|
-
|
|
113
|
-
if not results["failed"]:
|
|
114
|
-
console.print("[green]All files uploaded successfully![/green]")
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
@cli.command()
|
|
118
|
-
def ls(
|
|
119
|
-
detail: Annotated[bool, typer.Option(help="Show details")] = False,
|
|
120
|
-
) -> None:
|
|
121
|
-
"""List objects in bucket on Aignostics Platform."""
|
|
122
|
-
console.print_json(json=json.dumps(Service().ls(detail=detail), default=str))
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
@cli.command()
|
|
126
|
-
def find(
|
|
127
|
-
detail: Annotated[bool, typer.Option(help="Show details")] = False,
|
|
128
|
-
) -> None:
|
|
129
|
-
"""Find objects in bucket on Aignostics Platform."""
|
|
130
|
-
console.print_json(json=json.dumps(Service().find(detail=detail), default=str))
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
@cli.command()
|
|
134
|
-
def delete(
|
|
135
|
-
key: Annotated[str, typer.Argument(help="key of object in object")],
|
|
136
|
-
) -> None:
|
|
137
|
-
"""Find objects in bucket on Aignostics Platform."""
|
|
138
|
-
deleted = Service().delete_objects([key])
|
|
139
|
-
if deleted:
|
|
140
|
-
console.print(f"Deleted object with key '{key}'")
|
|
141
|
-
else:
|
|
142
|
-
console.print(f"Object with key '{key}' not found")
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
@cli.command()
|
|
146
|
-
def purge() -> None:
|
|
147
|
-
"""Purge all objects in bucket on Aignostics Platform."""
|
|
148
|
-
console.print(MESSAGE_NOT_YET_IMPLEMENTED)
|
|
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.60 → aignostics-0.2.62}/codegen/out/aignx/codegen/models/application_run_status.py
RENAMED
|
File without changes
|
|
File without changes
|
{aignostics-0.2.60 → aignostics-0.2.62}/codegen/out/aignx/codegen/models/http_validation_error.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{aignostics-0.2.60 → aignostics-0.2.62}/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.60 → aignostics-0.2.62}/codegen/out/aignx/codegen/models/output_artifact_scope.py
RENAMED
|
File without changes
|
{aignostics-0.2.60 → aignostics-0.2.62}/codegen/out/aignx/codegen/models/payload_input_artifact.py
RENAMED
|
File without changes
|
|
File without changes
|
{aignostics-0.2.60 → aignostics-0.2.62}/codegen/out/aignx/codegen/models/payload_output_artifact.py
RENAMED
|
File without changes
|
{aignostics-0.2.60 → aignostics-0.2.62}/codegen/out/aignx/codegen/models/run_creation_request.py
RENAMED
|
File without changes
|
{aignostics-0.2.60 → aignostics-0.2.62}/codegen/out/aignx/codegen/models/run_creation_response.py
RENAMED
|
File without changes
|
{aignostics-0.2.60 → aignostics-0.2.62}/codegen/out/aignx/codegen/models/run_read_response.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{aignostics-0.2.60 → aignostics-0.2.62}/codegen/out/aignx/codegen/models/validation_error.py
RENAMED
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|