synapse-sdk 1.0.0a32__tar.gz → 1.0.0a34__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.
Potentially problematic release.
This version of synapse-sdk might be problematic. Click here for more details.
- {synapse_sdk-1.0.0a32/synapse_sdk.egg-info → synapse_sdk-1.0.0a34}/PKG-INFO +1 -1
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/clients/backend/__init__.py +2 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/clients/backend/annotation.py +4 -4
- synapse_sdk-1.0.0a34/synapse_sdk/clients/backend/hitl.py +17 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/clients/backend/integration.py +3 -1
- synapse_sdk-1.0.0a34/synapse_sdk/clients/backend/models.py +44 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/clients/base.py +56 -9
- synapse_sdk-1.0.0a34/synapse_sdk/clients/validators/collections.py +31 -0
- synapse_sdk-1.0.0a34/synapse_sdk/plugins/categories/export/actions/export.py +222 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/plugins/categories/export/templates/plugin/export.py +6 -6
- synapse_sdk-1.0.0a34/synapse_sdk/plugins/categories/neural_net/actions/deployment.py +107 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/plugins/categories/smart_tool/templates/config.yaml +2 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/plugins/categories/upload/actions/upload.py +6 -5
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/utils/storage/__init__.py +9 -1
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34/synapse_sdk.egg-info}/PKG-INFO +1 -1
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk.egg-info/SOURCES.txt +9 -1
- synapse_sdk-1.0.0a34/tests/clients/__init__.py +0 -0
- synapse_sdk-1.0.0a34/tests/clients/test_backend_models.py +74 -0
- synapse_sdk-1.0.0a34/tests/clients/test_base_client.py +46 -0
- synapse_sdk-1.0.0a34/tests/clients/test_collection_validators.py +149 -0
- synapse_sdk-1.0.0a34/tests/utils/__init__,py +0 -0
- synapse_sdk-1.0.0a32/synapse_sdk/plugins/categories/export/actions/export.py +0 -82
- synapse_sdk-1.0.0a32/synapse_sdk/plugins/categories/neural_net/actions/deployment.py +0 -53
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/.github/workflows/lint.yml +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/.github/workflows/pypi-publish.yml +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/.gitignore +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/.pre-commit-config.yaml +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/LICENSE +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/README.md +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/locale/en/LC_MESSAGES/messages.mo +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/locale/en/LC_MESSAGES/messages.po +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/locale/ko/LC_MESSAGES/messages.mo +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/locale/ko/LC_MESSAGES/messages.po +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/pyproject.toml +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/requirements.test.txt +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/requirements.txt +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/setup.cfg +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/__init__.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/cli/__init__.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/cli/alias/__init__.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/cli/alias/create.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/cli/alias/dataclass.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/cli/alias/default.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/cli/alias/delete.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/cli/alias/list.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/cli/alias/read.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/cli/alias/update.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/cli/alias/utils.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/cli/plugin/__init__.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/cli/plugin/create.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/cli/plugin/publish.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/cli/plugin/run.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/clients/__init__.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/clients/agent/__init__.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/clients/agent/core.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/clients/agent/ray.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/clients/agent/service.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/clients/backend/core.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/clients/backend/dataset.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/clients/backend/ml.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/clients/exceptions.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/clients/ray/__init__.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/clients/ray/core.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/clients/ray/serve.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/clients/utils.py +0 -0
- {synapse_sdk-1.0.0a32/synapse_sdk/plugins → synapse_sdk-1.0.0a34/synapse_sdk/clients/validators}/__init__.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/i18n.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/loggers.py +0 -0
- {synapse_sdk-1.0.0a32/synapse_sdk/plugins/categories → synapse_sdk-1.0.0a34/synapse_sdk/plugins}/__init__.py +0 -0
- {synapse_sdk-1.0.0a32/synapse_sdk/plugins/categories/data_validation → synapse_sdk-1.0.0a34/synapse_sdk/plugins/categories}/__init__.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/plugins/categories/base.py +0 -0
- {synapse_sdk-1.0.0a32/synapse_sdk/plugins/categories/data_validation/actions → synapse_sdk-1.0.0a34/synapse_sdk/plugins/categories/data_validation}/__init__.py +0 -0
- {synapse_sdk-1.0.0a32/synapse_sdk/plugins/categories/data_validation/templates/plugin → synapse_sdk-1.0.0a34/synapse_sdk/plugins/categories/data_validation/actions}/__init__.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/plugins/categories/data_validation/actions/validation.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/plugins/categories/data_validation/templates/config.yaml +0 -0
- {synapse_sdk-1.0.0a32/synapse_sdk/plugins/categories/export → synapse_sdk-1.0.0a34/synapse_sdk/plugins/categories/data_validation/templates/plugin}/__init__.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/plugins/categories/data_validation/templates/plugin/validation.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/plugins/categories/decorators.py +0 -0
- {synapse_sdk-1.0.0a32/synapse_sdk/plugins/categories/export/actions → synapse_sdk-1.0.0a34/synapse_sdk/plugins/categories/export}/__init__.py +0 -0
- {synapse_sdk-1.0.0a32/synapse_sdk/plugins/categories/export/templates/plugin → synapse_sdk-1.0.0a34/synapse_sdk/plugins/categories/export/actions}/__init__.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/plugins/categories/export/templates/config.yaml +0 -0
- {synapse_sdk-1.0.0a32/synapse_sdk/plugins/categories/neural_net → synapse_sdk-1.0.0a34/synapse_sdk/plugins/categories/export/templates/plugin}/__init__.py +0 -0
- {synapse_sdk-1.0.0a32/synapse_sdk/plugins/categories/neural_net/actions → synapse_sdk-1.0.0a34/synapse_sdk/plugins/categories/neural_net}/__init__.py +0 -0
- {synapse_sdk-1.0.0a32/synapse_sdk/plugins/categories/neural_net/base → synapse_sdk-1.0.0a34/synapse_sdk/plugins/categories/neural_net/actions}/__init__.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/plugins/categories/neural_net/actions/inference.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/plugins/categories/neural_net/actions/test.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/plugins/categories/neural_net/actions/train.py +0 -0
- {synapse_sdk-1.0.0a32/synapse_sdk/plugins/categories/neural_net/templates/plugin → synapse_sdk-1.0.0a34/synapse_sdk/plugins/categories/neural_net/base}/__init__.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/plugins/categories/neural_net/base/inference.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/plugins/categories/neural_net/templates/config.yaml +0 -0
- {synapse_sdk-1.0.0a32/synapse_sdk/plugins/categories/post_annotation → synapse_sdk-1.0.0a34/synapse_sdk/plugins/categories/neural_net/templates/plugin}/__init__.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/plugins/categories/neural_net/templates/plugin/inference.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/plugins/categories/neural_net/templates/plugin/test.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/plugins/categories/neural_net/templates/plugin/train.py +0 -0
- {synapse_sdk-1.0.0a32/synapse_sdk/plugins/categories/post_annotation/actions → synapse_sdk-1.0.0a34/synapse_sdk/plugins/categories/post_annotation}/__init__.py +0 -0
- {synapse_sdk-1.0.0a32/synapse_sdk/plugins/categories/post_annotation/templates/plugin → synapse_sdk-1.0.0a34/synapse_sdk/plugins/categories/post_annotation/actions}/__init__.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/plugins/categories/post_annotation/actions/post_annotation.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/plugins/categories/post_annotation/templates/config.yaml +0 -0
- {synapse_sdk-1.0.0a32/synapse_sdk/plugins/categories/pre_annotation → synapse_sdk-1.0.0a34/synapse_sdk/plugins/categories/post_annotation/templates/plugin}/__init__.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/plugins/categories/post_annotation/templates/plugin/post_annotation.py +0 -0
- {synapse_sdk-1.0.0a32/synapse_sdk/plugins/categories/pre_annotation/actions → synapse_sdk-1.0.0a34/synapse_sdk/plugins/categories/pre_annotation}/__init__.py +0 -0
- {synapse_sdk-1.0.0a32/synapse_sdk/plugins/categories/pre_annotation/templates/plugin → synapse_sdk-1.0.0a34/synapse_sdk/plugins/categories/pre_annotation/actions}/__init__.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/plugins/categories/pre_annotation/actions/pre_annotation.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/plugins/categories/pre_annotation/templates/config.yaml +0 -0
- {synapse_sdk-1.0.0a32/synapse_sdk/plugins/categories/smart_tool → synapse_sdk-1.0.0a34/synapse_sdk/plugins/categories/pre_annotation/templates/plugin}/__init__.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/plugins/categories/pre_annotation/templates/plugin/pre_annotation.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/plugins/categories/registry.py +0 -0
- {synapse_sdk-1.0.0a32/synapse_sdk/plugins/categories/smart_tool/actions → synapse_sdk-1.0.0a34/synapse_sdk/plugins/categories/smart_tool}/__init__.py +0 -0
- {synapse_sdk-1.0.0a32/synapse_sdk/plugins/categories/smart_tool/templates/plugin → synapse_sdk-1.0.0a34/synapse_sdk/plugins/categories/smart_tool/actions}/__init__.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/plugins/categories/smart_tool/actions/auto_label.py +0 -0
- {synapse_sdk-1.0.0a32/synapse_sdk/plugins/categories/upload → synapse_sdk-1.0.0a34/synapse_sdk/plugins/categories/smart_tool/templates/plugin}/__init__.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/plugins/categories/smart_tool/templates/plugin/auto_label.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/plugins/categories/templates.py +0 -0
- {synapse_sdk-1.0.0a32/synapse_sdk/plugins/categories/upload/actions → synapse_sdk-1.0.0a34/synapse_sdk/plugins/categories/upload}/__init__.py +0 -0
- {synapse_sdk-1.0.0a32/synapse_sdk/plugins/categories/upload/templates/plugin → synapse_sdk-1.0.0a34/synapse_sdk/plugins/categories/upload/actions}/__init__.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/plugins/categories/upload/templates/config.yaml +0 -0
- {synapse_sdk-1.0.0a32/synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin → synapse_sdk-1.0.0a34/synapse_sdk/plugins/categories/upload/templates}/plugin/__init__.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/plugins/categories/upload/templates/plugin/upload.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/plugins/enums.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/plugins/exceptions.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/plugins/models.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/plugins/templates/cookiecutter.json +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/plugins/templates/hooks/post_gen_project.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/plugins/templates/hooks/pre_prompt.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/.gitignore +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/.pre-commit-config.yaml +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/README.md +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/config.yaml +0 -0
- {synapse_sdk-1.0.0a32/synapse_sdk/shared → synapse_sdk-1.0.0a34/synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/plugin}/__init__.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/pyproject.toml +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/requirements.txt +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/plugins/upload.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/plugins/utils.py +0 -0
- {synapse_sdk-1.0.0a32/synapse_sdk/utils → synapse_sdk-1.0.0a34/synapse_sdk/shared}/__init__.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/shared/enums.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/types.py +0 -0
- {synapse_sdk-1.0.0a32/synapse_sdk/utils/pydantic → synapse_sdk-1.0.0a34/synapse_sdk/utils}/__init__.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/utils/debug.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/utils/file.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/utils/module_loading.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/utils/network.py +0 -0
- {synapse_sdk-1.0.0a32/tests → synapse_sdk-1.0.0a34/synapse_sdk/utils/pydantic}/__init__.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/utils/pydantic/config.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/utils/pydantic/errors.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/utils/pydantic/validators.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/utils/storage/providers/__init__.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/utils/storage/providers/gcp.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/utils/storage/providers/s3.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/utils/storage/providers/sftp.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/utils/storage/registry.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk/utils/string.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk.egg-info/dependency_links.txt +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk.egg-info/entry_points.txt +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk.egg-info/requires.txt +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/synapse_sdk.egg-info/top_level.txt +0 -0
- {synapse_sdk-1.0.0a32/tests/utils → synapse_sdk-1.0.0a34/tests}/__init__.py +0 -0
- {synapse_sdk-1.0.0a32 → synapse_sdk-1.0.0a34}/tests/utils/test_debug.py +0 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from synapse_sdk.clients.backend.annotation import AnnotationClientMixin
|
|
2
2
|
from synapse_sdk.clients.backend.core import CoreClientMixin
|
|
3
3
|
from synapse_sdk.clients.backend.dataset import DatasetClientMixin
|
|
4
|
+
from synapse_sdk.clients.backend.hitl import HITLClientMixin
|
|
4
5
|
from synapse_sdk.clients.backend.integration import IntegrationClientMixin
|
|
5
6
|
from synapse_sdk.clients.backend.ml import MLClientMixin
|
|
6
7
|
|
|
@@ -11,6 +12,7 @@ class BackendClient(
|
|
|
11
12
|
DatasetClientMixin,
|
|
12
13
|
IntegrationClientMixin,
|
|
13
14
|
MLClientMixin,
|
|
15
|
+
HITLClientMixin,
|
|
14
16
|
):
|
|
15
17
|
name = 'Backend'
|
|
16
18
|
token = None
|
|
@@ -11,14 +11,14 @@ class AnnotationClientMixin(BaseClient):
|
|
|
11
11
|
path = f'task_tags/{pk}/'
|
|
12
12
|
return self._get(path)
|
|
13
13
|
|
|
14
|
-
def list_task_tags(self,
|
|
14
|
+
def list_task_tags(self, params):
|
|
15
15
|
path = 'task_tags/'
|
|
16
|
-
return self._list(path,
|
|
16
|
+
return self._list(path, params=params)
|
|
17
17
|
|
|
18
|
-
def list_tasks(self,
|
|
18
|
+
def list_tasks(self, params=None, url_conversion=None, list_all=False):
|
|
19
19
|
path = 'tasks/'
|
|
20
20
|
url_conversion = get_default_url_conversion(url_conversion, files_fields=['files'])
|
|
21
|
-
return self._list(path,
|
|
21
|
+
return self._list(path, params=params, url_conversion=url_conversion, list_all=list_all)
|
|
22
22
|
|
|
23
23
|
def create_tasks(self, data):
|
|
24
24
|
path = 'tasks/'
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
from synapse_sdk.clients.base import BaseClient
|
|
2
|
+
from synapse_sdk.clients.utils import get_default_url_conversion
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class HITLClientMixin(BaseClient):
|
|
6
|
+
def get_assignment(self, pk):
|
|
7
|
+
path = f'assignments/{pk}/'
|
|
8
|
+
return self._get(path)
|
|
9
|
+
|
|
10
|
+
def list_assignments(self, params=None, url_conversion=None, list_all=False):
|
|
11
|
+
path = 'assignments/'
|
|
12
|
+
url_conversion = get_default_url_conversion(url_conversion, files_fields=['files'])
|
|
13
|
+
return self._list(path, params=params, url_conversion=url_conversion, list_all=list_all)
|
|
14
|
+
|
|
15
|
+
def set_tags_assignments(self, data, params=None):
|
|
16
|
+
path = 'assignments/set_tags/'
|
|
17
|
+
return self._post(path, payload=data, params=params)
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from synapse_sdk.clients.backend.models import Storage
|
|
1
2
|
from synapse_sdk.clients.base import BaseClient
|
|
2
3
|
from synapse_sdk.utils.file import convert_file_to_base64
|
|
3
4
|
|
|
@@ -79,5 +80,6 @@ class IntegrationClientMixin(BaseClient):
|
|
|
79
80
|
return self._list(path, params=params, list_all=list_all)
|
|
80
81
|
|
|
81
82
|
def get_storage(self, pk):
|
|
83
|
+
"""Get specific storage data from synapse backend."""
|
|
82
84
|
path = f'storages/{pk}/'
|
|
83
|
-
return self._get(path)
|
|
85
|
+
return self._get(path, pydantic_model=Storage)
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
from enum import Enum
|
|
2
|
+
from typing import Dict
|
|
3
|
+
|
|
4
|
+
from pydantic import BaseModel
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class StorageCategory(str, Enum):
|
|
8
|
+
"""Synapse Backend Storage Category Enum."""
|
|
9
|
+
|
|
10
|
+
INTERNAL = 'internal'
|
|
11
|
+
EXTERNAL = 'external'
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class StorageProvider(str, Enum):
|
|
15
|
+
"""Synapse Backend Storage Provider Enum."""
|
|
16
|
+
|
|
17
|
+
AMAZON_S3 = 'amazon_s3'
|
|
18
|
+
AZURE = 'azure'
|
|
19
|
+
DIGITAL_OCEAN = 'digital_ocean'
|
|
20
|
+
FILE_SYSTEM = 'file_system'
|
|
21
|
+
FTP = 'ftp'
|
|
22
|
+
SFTP = 'sftp'
|
|
23
|
+
MINIO = 'minio'
|
|
24
|
+
GCP = 'gcp'
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class Storage(BaseModel):
|
|
28
|
+
"""Synapse Backend Storage Model.
|
|
29
|
+
|
|
30
|
+
Attrs:
|
|
31
|
+
id (int): The storage pk.
|
|
32
|
+
name (str): The storage name.
|
|
33
|
+
category (str): The storage category. (ex: internal, external)
|
|
34
|
+
provider (str): The storage provider. (ex: s3, gcp)
|
|
35
|
+
configuration (Dict): The storage configuration.
|
|
36
|
+
is_default (bool): The storage is default for Synapse backend workspace.
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
id: int
|
|
40
|
+
name: str
|
|
41
|
+
category: StorageCategory
|
|
42
|
+
provider: StorageProvider
|
|
43
|
+
configuration: Dict
|
|
44
|
+
is_default: bool
|
|
@@ -85,26 +85,59 @@ class BaseClient:
|
|
|
85
85
|
except ValueError:
|
|
86
86
|
return response.text
|
|
87
87
|
|
|
88
|
-
def _get(self, path, url_conversion=None, **kwargs):
|
|
88
|
+
def _get(self, path, url_conversion=None, pydantic_model=None, **kwargs):
|
|
89
|
+
"""
|
|
90
|
+
Perform a GET request and optionally convert response to a pydantic model.
|
|
91
|
+
|
|
92
|
+
Args:
|
|
93
|
+
path (str): URL path to request.
|
|
94
|
+
url_conversion (dict, optional): Configuration for URL to path conversion.
|
|
95
|
+
pydantic_model (Type, optional): Pydantic model to convert the response to.
|
|
96
|
+
**kwargs: Additional keyword arguments to pass to the request.
|
|
97
|
+
|
|
98
|
+
Returns:
|
|
99
|
+
The response data, optionally converted to a pydantic model.
|
|
100
|
+
"""
|
|
89
101
|
response = self._request('get', path, **kwargs)
|
|
102
|
+
|
|
90
103
|
if url_conversion:
|
|
91
104
|
if url_conversion['is_list']:
|
|
92
105
|
files_url_to_path_from_objs(response['results'], **url_conversion, is_async=True)
|
|
93
106
|
else:
|
|
94
107
|
files_url_to_path_from_objs(response, **url_conversion)
|
|
108
|
+
|
|
109
|
+
if pydantic_model:
|
|
110
|
+
return self._validate_response_with_pydantic_model(response, pydantic_model)
|
|
111
|
+
|
|
95
112
|
return response
|
|
96
113
|
|
|
97
|
-
def _post(self, path, **kwargs):
|
|
98
|
-
|
|
114
|
+
def _post(self, path, pydantic_model=None, **kwargs):
|
|
115
|
+
response = self._request('post', path, **kwargs)
|
|
116
|
+
if pydantic_model:
|
|
117
|
+
return self._validate_response_with_pydantic_model(response, pydantic_model)
|
|
118
|
+
else:
|
|
119
|
+
return response
|
|
99
120
|
|
|
100
|
-
def _put(self, path, **kwargs):
|
|
101
|
-
|
|
121
|
+
def _put(self, path, pydantic_model=None, **kwargs):
|
|
122
|
+
response = self._request('put', path, **kwargs)
|
|
123
|
+
if pydantic_model:
|
|
124
|
+
return self._validate_response_with_pydantic_model(response, pydantic_model)
|
|
125
|
+
else:
|
|
126
|
+
return response
|
|
102
127
|
|
|
103
|
-
def _patch(self, path, **kwargs):
|
|
104
|
-
|
|
128
|
+
def _patch(self, path, pydantic_model=None, **kwargs):
|
|
129
|
+
response = self._request('patch', path, **kwargs)
|
|
130
|
+
if pydantic_model:
|
|
131
|
+
return self._validate_response_with_pydantic_model(response, pydantic_model)
|
|
132
|
+
else:
|
|
133
|
+
return response
|
|
105
134
|
|
|
106
|
-
def _delete(self, path, **kwargs):
|
|
107
|
-
|
|
135
|
+
def _delete(self, path, pydantic_model=None, **kwargs):
|
|
136
|
+
response = self._request('delete', path, **kwargs)
|
|
137
|
+
if pydantic_model:
|
|
138
|
+
return self._validate_response_with_pydantic_model(response, pydantic_model)
|
|
139
|
+
else:
|
|
140
|
+
return response
|
|
108
141
|
|
|
109
142
|
def _list(self, path, url_conversion=None, list_all=False, **kwargs):
|
|
110
143
|
response = self._get(path, **kwargs)
|
|
@@ -121,3 +154,17 @@ class BaseClient:
|
|
|
121
154
|
|
|
122
155
|
def exists(self, api, *args, **kwargs):
|
|
123
156
|
return getattr(self, api)(*args, **kwargs)['count'] > 0
|
|
157
|
+
|
|
158
|
+
def _validate_response_with_pydantic_model(self, response, pydantic_model):
|
|
159
|
+
"""Validate a response with a pydantic model."""
|
|
160
|
+
# Check if model is a pydantic model (has the __pydantic_model__ attribute)
|
|
161
|
+
if (
|
|
162
|
+
hasattr(pydantic_model, '__pydantic_model__')
|
|
163
|
+
or hasattr(pydantic_model, 'model_validate')
|
|
164
|
+
or hasattr(pydantic_model, 'parse_obj')
|
|
165
|
+
):
|
|
166
|
+
pydantic_model.model_validate(response)
|
|
167
|
+
return response
|
|
168
|
+
else:
|
|
169
|
+
# Not a pydantic model
|
|
170
|
+
raise TypeError('The provided model is not a pydantic model')
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
class FileSpecificationValidator:
|
|
2
|
+
"""File specification validator class for synapse backend collection.
|
|
3
|
+
|
|
4
|
+
Args:
|
|
5
|
+
file_spec_template (list):
|
|
6
|
+
* List of dictionaries containing file specification template
|
|
7
|
+
* This is from synapse-backend file specification data.
|
|
8
|
+
organized_files (list): List of dictionaries containing organized files.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
def __init__(self, file_spec_template, organized_files):
|
|
12
|
+
self.file_spec_template = file_spec_template
|
|
13
|
+
self.organized_files = organized_files
|
|
14
|
+
|
|
15
|
+
def validate(self):
|
|
16
|
+
"""Validate the file specification template with organized files.
|
|
17
|
+
|
|
18
|
+
Returns:
|
|
19
|
+
bool: True if the file specification template is valid, False otherwise.
|
|
20
|
+
"""
|
|
21
|
+
for spec in self.file_spec_template:
|
|
22
|
+
spec_name = spec['name']
|
|
23
|
+
is_required = spec['is_required']
|
|
24
|
+
|
|
25
|
+
for file_group in self.organized_files:
|
|
26
|
+
files = file_group['files']
|
|
27
|
+
if is_required and spec_name not in files:
|
|
28
|
+
return False
|
|
29
|
+
if spec_name in files and not files[spec_name]:
|
|
30
|
+
return False
|
|
31
|
+
return True
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
from typing import Any, Literal
|
|
3
|
+
|
|
4
|
+
from pydantic import BaseModel, field_validator
|
|
5
|
+
from pydantic_core import PydanticCustomError
|
|
6
|
+
|
|
7
|
+
from synapse_sdk.clients.exceptions import ClientError
|
|
8
|
+
from synapse_sdk.i18n import gettext as _
|
|
9
|
+
from synapse_sdk.plugins.categories.base import Action
|
|
10
|
+
from synapse_sdk.plugins.categories.decorators import register_action
|
|
11
|
+
from synapse_sdk.plugins.enums import PluginCategory, RunMethod
|
|
12
|
+
from synapse_sdk.utils.storage import get_pathlib
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class ExportTargetHandler(ABC):
|
|
16
|
+
"""
|
|
17
|
+
Abstract base class for handling export targets.
|
|
18
|
+
|
|
19
|
+
This class defines the blueprint for export target handlers, requiring the implementation
|
|
20
|
+
of methods to validate filters, retrieve results, and process collections of results.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
@abstractmethod
|
|
24
|
+
def validate_filter(self, value: dict, client: Any):
|
|
25
|
+
"""
|
|
26
|
+
Validate filter query params to request original data from api.
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
value (dict): The filter criteria to validate.
|
|
30
|
+
client (Any): The client used to validate the filter.
|
|
31
|
+
|
|
32
|
+
Raises:
|
|
33
|
+
PydanticCustomError: If the filter criteria are invalid.
|
|
34
|
+
|
|
35
|
+
Returns:
|
|
36
|
+
dict: The validated filter criteria.
|
|
37
|
+
"""
|
|
38
|
+
pass
|
|
39
|
+
|
|
40
|
+
@abstractmethod
|
|
41
|
+
def get_results(self, client: Any, filters: dict):
|
|
42
|
+
"""
|
|
43
|
+
Retrieve original data from target sources.
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
client (Any): The client used to retrieve the results.
|
|
47
|
+
filters (dict): The filter criteria to apply.
|
|
48
|
+
|
|
49
|
+
Returns:
|
|
50
|
+
tuple: A tuple containing the results and the total count of results.
|
|
51
|
+
"""
|
|
52
|
+
pass
|
|
53
|
+
|
|
54
|
+
@abstractmethod
|
|
55
|
+
def get_export_item(self, results):
|
|
56
|
+
"""
|
|
57
|
+
Providing elements to build export data.
|
|
58
|
+
|
|
59
|
+
Args:
|
|
60
|
+
results (list): The results to process.
|
|
61
|
+
|
|
62
|
+
Yields:
|
|
63
|
+
generator: A generator that yields processed data items.
|
|
64
|
+
"""
|
|
65
|
+
pass
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class AssignmentExportTargetHandler(ExportTargetHandler):
|
|
69
|
+
def validate_filter(self, value: dict, client: Any):
|
|
70
|
+
if 'project' not in value:
|
|
71
|
+
raise PydanticCustomError('missing_field', _('Project is required for Assignment.'))
|
|
72
|
+
try:
|
|
73
|
+
client.list_assignments(params=value)
|
|
74
|
+
except ClientError:
|
|
75
|
+
raise PydanticCustomError('client_error', _('Unable to get Assignment.'))
|
|
76
|
+
return value
|
|
77
|
+
|
|
78
|
+
def get_results(self, client: Any, filters: dict):
|
|
79
|
+
return client.list_assignments(params=filters, list_all=True)
|
|
80
|
+
|
|
81
|
+
def get_export_item(self, results):
|
|
82
|
+
for result in results:
|
|
83
|
+
yield {
|
|
84
|
+
'data': result['data'],
|
|
85
|
+
'files': result['file'],
|
|
86
|
+
'id': result['id'],
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class GroundTruthExportTargetHandler(ExportTargetHandler):
|
|
91
|
+
def validate_filter(self, value: dict, client: Any):
|
|
92
|
+
if 'ground_truth_dataset_version' not in value:
|
|
93
|
+
raise PydanticCustomError('missing_field', _('Ground Truth dataset version is required.'))
|
|
94
|
+
try:
|
|
95
|
+
client.get_ground_truth_version(value['ground_truth_dataset_version'])
|
|
96
|
+
except ClientError:
|
|
97
|
+
raise PydanticCustomError('client_error', _('Unable to get Ground Truth dataset version.'))
|
|
98
|
+
return value
|
|
99
|
+
|
|
100
|
+
def get_results(self, client: Any, filters: dict):
|
|
101
|
+
filters['ground_truth_dataset_versions'] = filters.pop('ground_truth_dataset_version')
|
|
102
|
+
return client.list_ground_truth_events(params=filters, list_all=True)
|
|
103
|
+
|
|
104
|
+
def get_export_item(self, results):
|
|
105
|
+
for result in results:
|
|
106
|
+
files_key = next(iter(result['data_unit']['files']))
|
|
107
|
+
yield {
|
|
108
|
+
'data': result['data'],
|
|
109
|
+
'files': result['data_unit']['files'][files_key],
|
|
110
|
+
'id': result['ground_truth'],
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
class TaskExportTargetHandler(ExportTargetHandler):
|
|
115
|
+
def validate_filter(self, value: dict, client: Any):
|
|
116
|
+
if 'project' not in value:
|
|
117
|
+
raise PydanticCustomError('missing_field', _('Project is required for Task.'))
|
|
118
|
+
try:
|
|
119
|
+
client.list_tasks(params=value)
|
|
120
|
+
except ClientError:
|
|
121
|
+
raise PydanticCustomError('client_error', _('Unable to get Task.'))
|
|
122
|
+
return value
|
|
123
|
+
|
|
124
|
+
def get_results(self, client: Any, filters: dict):
|
|
125
|
+
filters['expand'] = 'data_unit'
|
|
126
|
+
return client.list_tasks(params=filters, list_all=True)
|
|
127
|
+
|
|
128
|
+
def get_export_item(self, results):
|
|
129
|
+
for result in results:
|
|
130
|
+
files_key = next(iter(result['data_unit']['files']))
|
|
131
|
+
yield {
|
|
132
|
+
'data': result['data'],
|
|
133
|
+
'files': result['data_unit']['files'][files_key],
|
|
134
|
+
'id': result['id'],
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
class TargetHandlerFactory:
|
|
139
|
+
@staticmethod
|
|
140
|
+
def get_handler(target: str) -> ExportTargetHandler:
|
|
141
|
+
if target == 'assignment':
|
|
142
|
+
return AssignmentExportTargetHandler()
|
|
143
|
+
elif target == 'ground_truth':
|
|
144
|
+
return GroundTruthExportTargetHandler()
|
|
145
|
+
elif target == 'task':
|
|
146
|
+
return TaskExportTargetHandler()
|
|
147
|
+
else:
|
|
148
|
+
raise ValueError(f'Unknown target: {target}')
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
class ExportParams(BaseModel):
|
|
152
|
+
"""
|
|
153
|
+
Parameters for the export action.
|
|
154
|
+
|
|
155
|
+
Attributes:
|
|
156
|
+
storage (int): The storage ID to save the exported data.
|
|
157
|
+
save_original_file (bool): Whether to save the original file.
|
|
158
|
+
path (str): The path to save the exported data.
|
|
159
|
+
target (str): The target source to export data from. (ex. ground_truth, assignment, task)
|
|
160
|
+
filter (dict): The filter criteria to apply.
|
|
161
|
+
"""
|
|
162
|
+
|
|
163
|
+
storage: int
|
|
164
|
+
save_original_file: bool = True
|
|
165
|
+
path: str
|
|
166
|
+
target: Literal['assignment', 'ground_truth', 'task']
|
|
167
|
+
filter: dict
|
|
168
|
+
|
|
169
|
+
@field_validator('storage')
|
|
170
|
+
@staticmethod
|
|
171
|
+
def check_storage_exists(value, info):
|
|
172
|
+
action = info.context['action']
|
|
173
|
+
client = action.client
|
|
174
|
+
try:
|
|
175
|
+
client.get_storage(value)
|
|
176
|
+
except ClientError:
|
|
177
|
+
raise PydanticCustomError('client_error', _('Unable to get storage from Synapse backend.'))
|
|
178
|
+
return value
|
|
179
|
+
|
|
180
|
+
@field_validator('filter')
|
|
181
|
+
@staticmethod
|
|
182
|
+
def check_filter_by_target(value, info):
|
|
183
|
+
action = info.context['action']
|
|
184
|
+
client = action.client
|
|
185
|
+
target = action.params['target']
|
|
186
|
+
handler = TargetHandlerFactory.get_handler(target)
|
|
187
|
+
return handler.validate_filter(value, client)
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
@register_action
|
|
191
|
+
class ExportAction(Action):
|
|
192
|
+
name = 'export'
|
|
193
|
+
category = PluginCategory.EXPORT
|
|
194
|
+
method = RunMethod.JOB
|
|
195
|
+
params_model = ExportParams
|
|
196
|
+
progress_categories = {
|
|
197
|
+
'dataset_conversion': {
|
|
198
|
+
'proportion': 100,
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
def get_filtered_results(self, filters, handler):
|
|
203
|
+
"""Get filtered target results."""
|
|
204
|
+
try:
|
|
205
|
+
result_list = handler.get_results(self.client, filters)
|
|
206
|
+
results = result_list[0]
|
|
207
|
+
count = result_list[1]
|
|
208
|
+
except ClientError:
|
|
209
|
+
raise PydanticCustomError('client_error', _('Unable to get Ground Truth dataset.'))
|
|
210
|
+
return results, count
|
|
211
|
+
|
|
212
|
+
def start(self):
|
|
213
|
+
filters = {'expand': 'data', **self.params['filter']}
|
|
214
|
+
target = self.params['target']
|
|
215
|
+
handler = TargetHandlerFactory.get_handler(target)
|
|
216
|
+
|
|
217
|
+
self.params['results'], self.params['count'] = self.get_filtered_results(filters, handler)
|
|
218
|
+
export_items = handler.get_export_item(self.params['results'])
|
|
219
|
+
|
|
220
|
+
storage = self.client.get_storage(self.params['storage'])
|
|
221
|
+
pathlib_cwd = get_pathlib(storage, self.params['path'])
|
|
222
|
+
return self.entrypoint(self.run, export_items, pathlib_cwd, **self.params)
|
|
@@ -4,12 +4,12 @@ from pathlib import Path
|
|
|
4
4
|
import requests
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
def export(run,
|
|
7
|
+
def export(run, export_items, path_root, **params):
|
|
8
8
|
"""Executes the export task.
|
|
9
9
|
|
|
10
10
|
Args:
|
|
11
11
|
run : Execution object
|
|
12
|
-
|
|
12
|
+
export_items (generator):
|
|
13
13
|
- data (dict): dm_schema_data information.
|
|
14
14
|
- files (dict): File information. Includes file URL, original file path, metadata, etc.
|
|
15
15
|
- id (int): ground_truth ID
|
|
@@ -42,11 +42,11 @@ def export(run, input_dataset, path_root, **params):
|
|
|
42
42
|
total = params['count']
|
|
43
43
|
# progress init
|
|
44
44
|
run.set_progress(0, total, category='dataset_conversion')
|
|
45
|
-
for no,
|
|
45
|
+
for no, export_item in enumerate(export_items, start=1):
|
|
46
46
|
run.set_progress(no, total, category='dataset_conversion')
|
|
47
47
|
if no == 1:
|
|
48
48
|
run.log_message('Converting dataset.')
|
|
49
|
-
preprocessed_data = before_convert(
|
|
49
|
+
preprocessed_data = before_convert(export_item)
|
|
50
50
|
converted_data = convert_data(preprocessed_data)
|
|
51
51
|
final_data = after_convert(converted_data)
|
|
52
52
|
|
|
@@ -97,7 +97,7 @@ def get_original_file_pathlib(files):
|
|
|
97
97
|
Returns:
|
|
98
98
|
pathlib.Path: The original file path extracted from the metadata.
|
|
99
99
|
"""
|
|
100
|
-
return Path(
|
|
100
|
+
return Path(files['meta']['path_original'])
|
|
101
101
|
|
|
102
102
|
|
|
103
103
|
def save_original_file(result, base_path, error_file_list):
|
|
@@ -108,7 +108,7 @@ def save_original_file(result, base_path, error_file_list):
|
|
|
108
108
|
base_path (Path): The directory where the file will be saved.
|
|
109
109
|
error_file_list (list): A list to store error files.
|
|
110
110
|
"""
|
|
111
|
-
file_url =
|
|
111
|
+
file_url = result['files']['url']
|
|
112
112
|
file_name = get_original_file_pathlib(result['files']).name
|
|
113
113
|
response = requests.get(file_url)
|
|
114
114
|
try:
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
from packaging import version
|
|
2
|
+
|
|
3
|
+
from synapse_sdk.clients.exceptions import ClientError
|
|
4
|
+
from synapse_sdk.i18n import gettext as _
|
|
5
|
+
from synapse_sdk.plugins.categories.base import Action
|
|
6
|
+
from synapse_sdk.plugins.categories.decorators import register_action
|
|
7
|
+
from synapse_sdk.plugins.enums import PluginCategory, RunMethod
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@register_action
|
|
11
|
+
class DeploymentAction(Action):
|
|
12
|
+
name = 'deployment'
|
|
13
|
+
category = PluginCategory.NEURAL_NET
|
|
14
|
+
method = RunMethod.JOB
|
|
15
|
+
|
|
16
|
+
def get_actor_options(self):
|
|
17
|
+
options = {'runtime_env': self.get_runtime_env()}
|
|
18
|
+
for option in ['num_cpus', 'num_gpus']:
|
|
19
|
+
option_value = self.params.get(option)
|
|
20
|
+
if option_value:
|
|
21
|
+
options[option] = option_value
|
|
22
|
+
return options
|
|
23
|
+
|
|
24
|
+
def start(self):
|
|
25
|
+
from ray import serve
|
|
26
|
+
|
|
27
|
+
from synapse_sdk.plugins.categories.neural_net.base.inference import app
|
|
28
|
+
|
|
29
|
+
self.ray_init()
|
|
30
|
+
|
|
31
|
+
ray_actor_options = self.get_actor_options()
|
|
32
|
+
|
|
33
|
+
if self.is_gradio_deployment:
|
|
34
|
+
from ray.serve.gradio_integrations import GradioServer
|
|
35
|
+
|
|
36
|
+
self.assert_gradio_version()
|
|
37
|
+
|
|
38
|
+
# GradioIngress differs from serve.ingress(app), thus the difference in self.entrypoint callable
|
|
39
|
+
try:
|
|
40
|
+
entrypoint = self.entrypoint().app
|
|
41
|
+
except (TypeError, ImportError):
|
|
42
|
+
raise ClientError(
|
|
43
|
+
400,
|
|
44
|
+
_(
|
|
45
|
+
'Gradio app is not callable.'
|
|
46
|
+
'Please ensure that your Deployment class defines a callable `app` function'
|
|
47
|
+
),
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
deployment = GradioServer.options(ray_actor_options=ray_actor_options).bind(entrypoint)
|
|
51
|
+
else:
|
|
52
|
+
deployment = serve.deployment(ray_actor_options=ray_actor_options)(
|
|
53
|
+
serve.ingress(app)(self.entrypoint)
|
|
54
|
+
).bind(self.envs['SYNAPSE_PLUGIN_RUN_HOST'])
|
|
55
|
+
|
|
56
|
+
serve.delete(self.plugin_release.code)
|
|
57
|
+
|
|
58
|
+
# TODO add run object
|
|
59
|
+
serve.run(
|
|
60
|
+
deployment,
|
|
61
|
+
name=self.plugin_release.code,
|
|
62
|
+
route_prefix=f'/{self.plugin_release.checksum}',
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
# 백엔드에 ServeApplication 추가
|
|
66
|
+
serve_application = self.create_serve_application()
|
|
67
|
+
return {'serve_application': serve_application['id'] if serve_application else None}
|
|
68
|
+
|
|
69
|
+
def create_serve_application(self):
|
|
70
|
+
if self.job_id:
|
|
71
|
+
try:
|
|
72
|
+
serve_application = self.ray_client.get_serve_application(self.plugin_release.code)
|
|
73
|
+
return self.client.create_serve_application({
|
|
74
|
+
'job': self.job_id,
|
|
75
|
+
'status': serve_application['status'],
|
|
76
|
+
'data': serve_application,
|
|
77
|
+
})
|
|
78
|
+
except ClientError:
|
|
79
|
+
pass
|
|
80
|
+
return None
|
|
81
|
+
|
|
82
|
+
@property
|
|
83
|
+
def is_gradio_deployment(self):
|
|
84
|
+
return self.config.get('gradio_app', False)
|
|
85
|
+
|
|
86
|
+
def assert_gradio_version(self):
|
|
87
|
+
"""Assert gradio version is not greater than 3.50.2.
|
|
88
|
+
Ray Serve cannot pickle gradio endpoints, thus gradio version greater than 3.50.2 is not supported (SSE Issues)
|
|
89
|
+
"""
|
|
90
|
+
GRADIO_VERSION_MAX_ALLOWED = '3.50.2'
|
|
91
|
+
|
|
92
|
+
gradio_installed = False
|
|
93
|
+
gradio_version = None
|
|
94
|
+
for req in self.requirements:
|
|
95
|
+
if req.startswith('gradio=='):
|
|
96
|
+
gradio_installed = True
|
|
97
|
+
gradio_version = req.split('==')[1]
|
|
98
|
+
break
|
|
99
|
+
|
|
100
|
+
assert gradio_installed, _(
|
|
101
|
+
'Gradio is not installed or version is not specified. Please install gradio==3.50.2 to use this feature.'
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
if version.parse(gradio_version) > version.parse(GRADIO_VERSION_MAX_ALLOWED):
|
|
105
|
+
raise AssertionError(
|
|
106
|
+
f'Gradio version {gradio_version} is greater than maximum allowed version {GRADIO_VERSION_MAX_ALLOWED}'
|
|
107
|
+
)
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
from enum import Enum
|
|
2
1
|
from typing import Annotated, Dict, List
|
|
3
2
|
|
|
4
3
|
from pydantic import AfterValidator, BaseModel, field_validator
|
|
@@ -6,6 +5,7 @@ from pydantic_core import PydanticCustomError
|
|
|
6
5
|
|
|
7
6
|
from synapse_sdk.clients.exceptions import ClientError
|
|
8
7
|
from synapse_sdk.clients.utils import get_batched_list
|
|
8
|
+
from synapse_sdk.clients.validators.collections import FileSpecificationValidator
|
|
9
9
|
from synapse_sdk.i18n import gettext as _
|
|
10
10
|
from synapse_sdk.plugins.categories.base import Action
|
|
11
11
|
from synapse_sdk.plugins.categories.decorators import register_action
|
|
@@ -145,7 +145,7 @@ class UploadAction(Action):
|
|
|
145
145
|
|
|
146
146
|
# Analyze Collection file specifications to determine the data structure for upload.
|
|
147
147
|
self.run.set_progress(0, 1, category='analyze_collection')
|
|
148
|
-
|
|
148
|
+
file_specification_template = self._analyze_collection()
|
|
149
149
|
self.run.set_progress(1, 1, category='analyze_collection')
|
|
150
150
|
|
|
151
151
|
# Setup result dict.
|
|
@@ -153,7 +153,7 @@ class UploadAction(Action):
|
|
|
153
153
|
|
|
154
154
|
# Organize data according to Collection file specification structure.
|
|
155
155
|
organized_files = uploader.handle_upload_files()
|
|
156
|
-
if not self._validate_organized_files(
|
|
156
|
+
if not self._validate_organized_files(file_specification_template, organized_files):
|
|
157
157
|
self.run.log_message('Validate organized files failed.')
|
|
158
158
|
return result
|
|
159
159
|
|
|
@@ -219,9 +219,10 @@ class UploadAction(Action):
|
|
|
219
219
|
collection = client.get_dataset(collection_id)
|
|
220
220
|
return collection['file_specifications']
|
|
221
221
|
|
|
222
|
-
def _validate_organized_files(self,
|
|
222
|
+
def _validate_organized_files(self, file_specification_template: Dict, organized_files: List) -> bool:
|
|
223
223
|
"""Validate organized files from Uploader."""
|
|
224
|
-
|
|
224
|
+
validator = FileSpecificationValidator(file_specification_template, organized_files)
|
|
225
|
+
return validator.validate()
|
|
225
226
|
|
|
226
227
|
def _upload_files(self, organized_files) -> List:
|
|
227
228
|
"""Upload files to synapse-backend.
|