synapse-sdk 1.0.0a28__tar.gz → 1.0.0a30__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.

Files changed (148) hide show
  1. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/.gitignore +3 -0
  2. {synapse_sdk-1.0.0a28/synapse_sdk.egg-info → synapse_sdk-1.0.0a30}/PKG-INFO +3 -1
  3. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/pyproject.toml +3 -1
  4. synapse_sdk-1.0.0a30/requirements.test.txt +1 -0
  5. synapse_sdk-1.0.0a30/requirements.txt +11 -0
  6. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/cli/plugin/__init__.py +2 -0
  7. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/clients/backend/integration.py +12 -0
  8. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/clients/backend/ml.py +4 -0
  9. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/clients/base.py +34 -8
  10. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/loggers.py +9 -2
  11. synapse_sdk-1.0.0a30/synapse_sdk/plugins/categories/export/actions/export.py +85 -0
  12. synapse_sdk-1.0.0a30/synapse_sdk/plugins/categories/export/actions/utils.py +5 -0
  13. synapse_sdk-1.0.0a30/synapse_sdk/plugins/categories/export/templates/config.yaml +3 -0
  14. synapse_sdk-1.0.0a30/synapse_sdk/plugins/categories/export/templates/plugin/export.py +126 -0
  15. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/plugins/categories/neural_net/actions/train.py +5 -0
  16. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/plugins/categories/neural_net/templates/config.yaml +3 -0
  17. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/plugins/models.py +2 -2
  18. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/utils/file.py +35 -0
  19. synapse_sdk-1.0.0a30/synapse_sdk/utils/pydantic/__init__.py +0 -0
  20. synapse_sdk-1.0.0a30/synapse_sdk/utils/storage/__init__.py +20 -0
  21. synapse_sdk-1.0.0a30/synapse_sdk/utils/storage/providers/__init__.py +42 -0
  22. synapse_sdk-1.0.0a30/synapse_sdk/utils/storage/providers/gcp.py +13 -0
  23. synapse_sdk-1.0.0a30/synapse_sdk/utils/storage/providers/s3.py +43 -0
  24. synapse_sdk-1.0.0a30/synapse_sdk/utils/storage/providers/sftp.py +16 -0
  25. synapse_sdk-1.0.0a30/synapse_sdk/utils/storage/registry.py +11 -0
  26. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30/synapse_sdk.egg-info}/PKG-INFO +3 -1
  27. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk.egg-info/SOURCES.txt +15 -2
  28. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk.egg-info/requires.txt +2 -0
  29. synapse_sdk-1.0.0a30/tests/__init__.py +0 -0
  30. synapse_sdk-1.0.0a30/tests/utils/__init__.py +0 -0
  31. synapse_sdk-1.0.0a30/tests/utils/test_debug.py +6 -0
  32. synapse_sdk-1.0.0a28/requirements.txt +0 -10
  33. synapse_sdk-1.0.0a28/synapse_sdk/plugins/categories/export/actions/export.py +0 -10
  34. synapse_sdk-1.0.0a28/synapse_sdk/utils/storage.py +0 -91
  35. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/.github/workflows/lint.yml +0 -0
  36. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/.github/workflows/pypi-publish.yml +0 -0
  37. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/.pre-commit-config.yaml +0 -0
  38. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/LICENSE +0 -0
  39. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/README.md +0 -0
  40. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/locale/en/LC_MESSAGES/messages.mo +0 -0
  41. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/locale/en/LC_MESSAGES/messages.po +0 -0
  42. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/locale/ko/LC_MESSAGES/messages.mo +0 -0
  43. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/locale/ko/LC_MESSAGES/messages.po +0 -0
  44. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/setup.cfg +0 -0
  45. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/__init__.py +0 -0
  46. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/cli/__init__.py +0 -0
  47. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/cli/alias/__init__.py +0 -0
  48. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/cli/alias/create.py +0 -0
  49. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/cli/alias/dataclass.py +0 -0
  50. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/cli/alias/default.py +0 -0
  51. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/cli/alias/delete.py +0 -0
  52. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/cli/alias/list.py +0 -0
  53. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/cli/alias/read.py +0 -0
  54. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/cli/alias/update.py +0 -0
  55. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/cli/alias/utils.py +0 -0
  56. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/cli/plugin/create.py +0 -0
  57. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/cli/plugin/publish.py +0 -0
  58. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/cli/plugin/run.py +0 -0
  59. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/clients/__init__.py +0 -0
  60. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/clients/agent/__init__.py +0 -0
  61. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/clients/agent/core.py +0 -0
  62. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/clients/agent/ray.py +0 -0
  63. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/clients/agent/service.py +0 -0
  64. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/clients/backend/__init__.py +0 -0
  65. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/clients/backend/annotation.py +0 -0
  66. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/clients/backend/core.py +0 -0
  67. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/clients/backend/dataset.py +0 -0
  68. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/clients/exceptions.py +0 -0
  69. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/clients/ray/__init__.py +0 -0
  70. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/clients/ray/core.py +0 -0
  71. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/clients/ray/serve.py +0 -0
  72. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/clients/utils.py +0 -0
  73. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/i18n.py +0 -0
  74. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/plugins/__init__.py +0 -0
  75. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/plugins/categories/__init__.py +0 -0
  76. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/plugins/categories/base.py +0 -0
  77. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/plugins/categories/data_validation/__init__.py +0 -0
  78. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/plugins/categories/data_validation/actions/__init__.py +0 -0
  79. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/plugins/categories/data_validation/actions/validation.py +0 -0
  80. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/plugins/categories/data_validation/templates/config.yaml +0 -0
  81. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/plugins/categories/data_validation/templates/plugin/__init__.py +0 -0
  82. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/plugins/categories/data_validation/templates/plugin/validation.py +0 -0
  83. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/plugins/categories/decorators.py +0 -0
  84. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/plugins/categories/export/__init__.py +0 -0
  85. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/plugins/categories/export/actions/__init__.py +0 -0
  86. {synapse_sdk-1.0.0a28/synapse_sdk/plugins/categories/import → synapse_sdk-1.0.0a30/synapse_sdk/plugins/categories/export/templates/plugin}/__init__.py +0 -0
  87. {synapse_sdk-1.0.0a28/synapse_sdk/plugins/categories/import/actions → synapse_sdk-1.0.0a30/synapse_sdk/plugins/categories/import}/__init__.py +0 -0
  88. {synapse_sdk-1.0.0a28/synapse_sdk/plugins/categories/neural_net → synapse_sdk-1.0.0a30/synapse_sdk/plugins/categories/import/actions}/__init__.py +0 -0
  89. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/plugins/categories/import/actions/import.py +0 -0
  90. {synapse_sdk-1.0.0a28/synapse_sdk/plugins/categories/neural_net/actions → synapse_sdk-1.0.0a30/synapse_sdk/plugins/categories/neural_net}/__init__.py +0 -0
  91. {synapse_sdk-1.0.0a28/synapse_sdk/plugins/categories/neural_net/base → synapse_sdk-1.0.0a30/synapse_sdk/plugins/categories/neural_net/actions}/__init__.py +0 -0
  92. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/plugins/categories/neural_net/actions/deployment.py +0 -0
  93. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/plugins/categories/neural_net/actions/inference.py +0 -0
  94. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/plugins/categories/neural_net/actions/test.py +0 -0
  95. {synapse_sdk-1.0.0a28/synapse_sdk/plugins/categories/neural_net/templates/plugin → synapse_sdk-1.0.0a30/synapse_sdk/plugins/categories/neural_net/base}/__init__.py +0 -0
  96. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/plugins/categories/neural_net/base/inference.py +0 -0
  97. {synapse_sdk-1.0.0a28/synapse_sdk/plugins/categories/post_annotation → synapse_sdk-1.0.0a30/synapse_sdk/plugins/categories/neural_net/templates/plugin}/__init__.py +0 -0
  98. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/plugins/categories/neural_net/templates/plugin/inference.py +0 -0
  99. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/plugins/categories/neural_net/templates/plugin/test.py +0 -0
  100. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/plugins/categories/neural_net/templates/plugin/train.py +0 -0
  101. {synapse_sdk-1.0.0a28/synapse_sdk/plugins/categories/post_annotation/actions → synapse_sdk-1.0.0a30/synapse_sdk/plugins/categories/post_annotation}/__init__.py +0 -0
  102. {synapse_sdk-1.0.0a28/synapse_sdk/plugins/categories/post_annotation/templates/plugin → synapse_sdk-1.0.0a30/synapse_sdk/plugins/categories/post_annotation/actions}/__init__.py +0 -0
  103. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/plugins/categories/post_annotation/actions/post_annotation.py +0 -0
  104. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/plugins/categories/post_annotation/templates/config.yaml +0 -0
  105. {synapse_sdk-1.0.0a28/synapse_sdk/plugins/categories/pre_annotation → synapse_sdk-1.0.0a30/synapse_sdk/plugins/categories/post_annotation/templates/plugin}/__init__.py +0 -0
  106. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/plugins/categories/post_annotation/templates/plugin/post_annotation.py +0 -0
  107. {synapse_sdk-1.0.0a28/synapse_sdk/plugins/categories/pre_annotation/actions → synapse_sdk-1.0.0a30/synapse_sdk/plugins/categories/pre_annotation}/__init__.py +0 -0
  108. {synapse_sdk-1.0.0a28/synapse_sdk/plugins/categories/pre_annotation/templates/plugin → synapse_sdk-1.0.0a30/synapse_sdk/plugins/categories/pre_annotation/actions}/__init__.py +0 -0
  109. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/plugins/categories/pre_annotation/actions/pre_annotation.py +0 -0
  110. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/plugins/categories/pre_annotation/templates/config.yaml +0 -0
  111. {synapse_sdk-1.0.0a28/synapse_sdk/plugins/categories/smart_tool → synapse_sdk-1.0.0a30/synapse_sdk/plugins/categories/pre_annotation/templates/plugin}/__init__.py +0 -0
  112. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/plugins/categories/pre_annotation/templates/plugin/pre_annotation.py +0 -0
  113. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/plugins/categories/registry.py +0 -0
  114. {synapse_sdk-1.0.0a28/synapse_sdk/plugins/categories/smart_tool/actions → synapse_sdk-1.0.0a30/synapse_sdk/plugins/categories/smart_tool}/__init__.py +0 -0
  115. {synapse_sdk-1.0.0a28/synapse_sdk/plugins/categories/smart_tool/templates/plugin → synapse_sdk-1.0.0a30/synapse_sdk/plugins/categories/smart_tool/actions}/__init__.py +0 -0
  116. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/plugins/categories/smart_tool/actions/auto_label.py +0 -0
  117. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/plugins/categories/smart_tool/templates/config.yaml +0 -0
  118. {synapse_sdk-1.0.0a28/synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin → synapse_sdk-1.0.0a30/synapse_sdk/plugins/categories/smart_tool/templates}/plugin/__init__.py +0 -0
  119. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/plugins/categories/smart_tool/templates/plugin/auto_label.py +0 -0
  120. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/plugins/categories/templates.py +0 -0
  121. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/plugins/enums.py +0 -0
  122. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/plugins/exceptions.py +0 -0
  123. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/plugins/templates/cookiecutter.json +0 -0
  124. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/plugins/templates/hooks/post_gen_project.py +0 -0
  125. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/plugins/templates/hooks/pre_prompt.py +0 -0
  126. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/.gitignore +0 -0
  127. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/.pre-commit-config.yaml +0 -0
  128. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/README.md +0 -0
  129. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/config.yaml +0 -0
  130. {synapse_sdk-1.0.0a28/synapse_sdk/shared → synapse_sdk-1.0.0a30/synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/plugin}/__init__.py +0 -0
  131. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/pyproject.toml +0 -0
  132. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/requirements.txt +0 -0
  133. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/plugins/upload.py +0 -0
  134. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/plugins/utils.py +0 -0
  135. {synapse_sdk-1.0.0a28/synapse_sdk/utils → synapse_sdk-1.0.0a30/synapse_sdk/shared}/__init__.py +0 -0
  136. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/shared/enums.py +0 -0
  137. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/types.py +0 -0
  138. {synapse_sdk-1.0.0a28/synapse_sdk/utils/pydantic → synapse_sdk-1.0.0a30/synapse_sdk/utils}/__init__.py +0 -0
  139. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/utils/debug.py +0 -0
  140. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/utils/module_loading.py +0 -0
  141. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/utils/network.py +0 -0
  142. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/utils/pydantic/config.py +0 -0
  143. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/utils/pydantic/errors.py +0 -0
  144. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/utils/pydantic/validators.py +0 -0
  145. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk/utils/string.py +0 -0
  146. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk.egg-info/dependency_links.txt +0 -0
  147. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk.egg-info/entry_points.txt +0 -0
  148. {synapse_sdk-1.0.0a28 → synapse_sdk-1.0.0a30}/synapse_sdk.egg-info/top_level.txt +0 -0
@@ -7,6 +7,9 @@
7
7
  .idea
8
8
  *.iml
9
9
 
10
+ # vscode
11
+ .vscode
12
+
10
13
  # http
11
14
  /http/
12
15
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: synapse-sdk
3
- Version: 1.0.0a28
3
+ Version: 1.0.0a30
4
4
  Summary: synapse sdk
5
5
  Author-email: datamaker <developer@datamaker.io>
6
6
  License: MIT
@@ -17,6 +17,8 @@ Requires-Dist: python-dotenv
17
17
  Requires-Dist: pyyaml
18
18
  Requires-Dist: pydantic
19
19
  Requires-Dist: pyjwt
20
+ Requires-Dist: universal-pathlib
21
+ Requires-Dist: fsspec[gcs,s3,sftp]
20
22
  Provides-Extra: all
21
23
  Requires-Dist: ray[all]; extra == "all"
22
24
 
@@ -21,7 +21,9 @@ dependencies = [
21
21
  "python-dotenv",
22
22
  "pyyaml",
23
23
  "pydantic",
24
- "pyjwt"
24
+ "pyjwt",
25
+ "universal-pathlib",
26
+ "fsspec[gcs,s3,sftp]"
25
27
  ]
26
28
  dynamic = ["version"]
27
29
 
@@ -0,0 +1 @@
1
+ pytest
@@ -0,0 +1,11 @@
1
+ click
2
+ cookiecutter
3
+ requests
4
+ tqdm
5
+ pyyaml
6
+ pydantic
7
+ pyjwt
8
+ python-dotenv
9
+ ray[all]>=2.43.0
10
+ fsspec[gcs,s3,sftp]==2025.2.0
11
+ universal-pathlib==0.2.6
@@ -1,4 +1,5 @@
1
1
  import os
2
+ import sys
2
3
 
3
4
  import click
4
5
  from dotenv import load_dotenv
@@ -12,6 +13,7 @@ from .run import run
12
13
 
13
14
  load_dotenv_default_alias()
14
15
  load_dotenv(os.path.join(os.getcwd(), '.env'), override=True)
16
+ sys.path.append(os.getcwd())
15
17
 
16
18
 
17
19
  @click.group(context_settings={'obj': {}, 'auto_envvar_prefix': 'SYNAPSE_PLUGIN'})
@@ -1,4 +1,5 @@
1
1
  from synapse_sdk.clients.base import BaseClient
2
+ from synapse_sdk.utils.file import convert_file_to_base64
2
3
 
3
4
 
4
5
  class IntegrationClientMixin(BaseClient):
@@ -60,6 +61,13 @@ class IntegrationClientMixin(BaseClient):
60
61
 
61
62
  def create_logs(self, data):
62
63
  path = 'logs/'
64
+ if not isinstance(data, list):
65
+ data = [data]
66
+
67
+ for item in data:
68
+ if 'file' in item:
69
+ item['file'] = convert_file_to_base64(item['file'])
70
+
63
71
  return self._post(path, data=data)
64
72
 
65
73
  def create_serve_application(self, data):
@@ -69,3 +77,7 @@ class IntegrationClientMixin(BaseClient):
69
77
  def list_serve_applications(self, params=None, list_all=False):
70
78
  path = 'serve_applications/'
71
79
  return self._list(path, params=params, list_all=list_all)
80
+
81
+ def get_storage(self, pk):
82
+ path = f'storages/{pk}/'
83
+ return self._get(path)
@@ -22,3 +22,7 @@ class MLClientMixin(BaseClient):
22
22
  path = 'ground_truth_events/'
23
23
  url_conversion = get_default_url_conversion(url_conversion, files_fields=['files'])
24
24
  return self._list(path, params=params, url_conversion=url_conversion, list_all=list_all)
25
+
26
+ def get_ground_truth_version(self, pk):
27
+ path = f'ground_truth_dataset_versions/{pk}/'
28
+ return self._get(path)
@@ -25,20 +25,46 @@ class BaseClient:
25
25
  def _get_headers(self):
26
26
  return {}
27
27
 
28
- def _request(self, method, path, **kwargs):
28
+ def _request(self, method: str, path: str, **kwargs) -> dict | str:
29
+ """Request handler for all HTTP methods.
30
+
31
+ Args:
32
+ method (str): HTTP method to use.
33
+ path (str): URL path to request.
34
+ **kwargs: Additional keyword arguments to pass to the request.
35
+
36
+ Returns:
37
+ dict | str: JSON response or text response.
38
+ """
29
39
  url = self._get_url(path)
30
40
  headers = self._get_headers()
31
41
  headers.update(kwargs.pop('headers', {}))
32
42
 
33
43
  if method in ['post', 'put', 'patch']:
44
+ # If files are included in the request, open them as binary files
34
45
  if kwargs.get('files') is not None:
35
- for name, file in kwargs['files'].items():
36
- if isinstance(file, (str, Path)):
37
- kwargs['files'][name] = Path(str(file)).open(mode='rb')
38
- if 'data' in kwargs:
39
- for name, value in kwargs['data'].items():
40
- if isinstance(value, dict):
41
- kwargs['data'][name] = json.dumps(value)
46
+ opened_files = [] # List to store opened files
47
+ try:
48
+ for name, file in kwargs['files'].items():
49
+ # If file is a path string, bind it as a Path object and open
50
+ if isinstance(file, str):
51
+ opened_file = open(Path(file), mode='rb')
52
+ kwargs['files'][name] = opened_file
53
+ opened_files.append(opened_file)
54
+ # If file is a Path object, open it directly
55
+ elif isinstance(file, Path):
56
+ opened_file = open(file, mode='rb')
57
+ kwargs['files'][name] = opened_file
58
+ opened_files.append(opened_file)
59
+ if 'data' in kwargs:
60
+ for name, value in kwargs['data'].items():
61
+ if isinstance(value, dict):
62
+ kwargs['data'][name] = json.dumps(value)
63
+ finally:
64
+ # Close all opened files
65
+ for opened_file in opened_files:
66
+ opened_file.close()
67
+
42
68
  else:
43
69
  headers['Content-Type'] = 'application/json'
44
70
  if 'data' in kwargs:
@@ -68,13 +68,16 @@ class BaseLogger:
68
68
 
69
69
  return progress
70
70
 
71
+ def log(self, action, data, file=None):
72
+ raise NotImplementedError
73
+
71
74
 
72
75
  class ConsoleLogger(BaseLogger):
73
76
  def set_progress(self, current, total, category=None):
74
77
  super().set_progress(current, total, category=category)
75
78
  print(self.get_current_progress())
76
79
 
77
- def log(self, action, data):
80
+ def log(self, action, data, file=None):
78
81
  print(action, data)
79
82
 
80
83
 
@@ -99,7 +102,7 @@ class BackendLogger(BaseLogger):
99
102
  except ClientError:
100
103
  pass
101
104
 
102
- def log(self, event, data):
105
+ def log(self, event, data, file=None):
103
106
  print(event, data)
104
107
 
105
108
  log = {
@@ -108,7 +111,11 @@ class BackendLogger(BaseLogger):
108
111
  'datetime': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f'),
109
112
  'job': self.job_id,
110
113
  }
114
+ if file:
115
+ log['file'] = file
116
+
111
117
  self.logs_queue.append(log)
118
+
112
119
  try:
113
120
  self.client.create_logs(self.logs_queue)
114
121
  self.logs_queue.clear()
@@ -0,0 +1,85 @@
1
+ from pydantic import BaseModel, field_validator
2
+ from pydantic_core import PydanticCustomError
3
+
4
+ from synapse_sdk.clients.exceptions import ClientError
5
+ from synapse_sdk.i18n import gettext as _
6
+ from synapse_sdk.plugins.categories.base import Action
7
+ from synapse_sdk.plugins.categories.decorators import register_action
8
+ from synapse_sdk.plugins.enums import PluginCategory, RunMethod
9
+ from synapse_sdk.utils.storage import get_pathlib
10
+
11
+
12
+ class ExportParams(BaseModel):
13
+ storage: int
14
+ save_original_file: bool = True
15
+ path: str
16
+ ground_truth_dataset_version: int
17
+ filter: dict
18
+
19
+ @field_validator('storage')
20
+ @staticmethod
21
+ def check_storage_exists(value, info):
22
+ action = info.context['action']
23
+ client = action.client
24
+ try:
25
+ client.get_storage(value)
26
+ except ClientError:
27
+ raise PydanticCustomError('client_error', _('Unable to get storage from Synapse backend.'))
28
+ return value
29
+
30
+ @field_validator('ground_truth_dataset_version')
31
+ @staticmethod
32
+ def check_ground_truth_dataset_version_exists(value, info):
33
+ action = info.context['action']
34
+ client = action.client
35
+ try:
36
+ client.get_ground_truth_version(value)
37
+ except ClientError:
38
+ raise PydanticCustomError('client_error', _('Unable to get Ground Truth dataset version.'))
39
+ return value
40
+
41
+
42
+ @register_action
43
+ class ExportAction(Action):
44
+ name = 'export'
45
+ category = PluginCategory.EXPORT
46
+ method = RunMethod.JOB
47
+ params_model = ExportParams
48
+ progress_categories = {
49
+ 'dataset_conversion': {
50
+ 'proportion': 100,
51
+ }
52
+ }
53
+
54
+ def get_dataset(self, results):
55
+ """Get dataset for export."""
56
+ for result in results:
57
+ yield {
58
+ 'data': result['data'],
59
+ 'files': result['data_unit']['files'],
60
+ 'id': result['ground_truth'],
61
+ }
62
+
63
+ def get_filtered_results(self):
64
+ """Get filtered ground truth."""
65
+ ground_truth_dataset_version = self.params['ground_truth_dataset_version']
66
+ self.params['filter']['ground_truth_dataset'] = self.client.get_ground_truth_version(
67
+ ground_truth_dataset_version
68
+ )['ground_truth_dataset']
69
+ filters = {'expand': 'data', **self.params['filter']}
70
+
71
+ try:
72
+ gt_dataset_events_list = self.client.list_ground_truth_events(params=filters, list_all=True)
73
+ results = gt_dataset_events_list[0]
74
+ count = gt_dataset_events_list[1]
75
+ except ClientError:
76
+ raise PydanticCustomError('client_error', _('Unable to get Ground Truth dataset.'))
77
+ return results, count
78
+
79
+ def start(self):
80
+ self.params['results'], self.params['count'] = self.get_filtered_results()
81
+ dataset = self.get_dataset(self.params['results'])
82
+
83
+ storage = self.client.get_storage(self.params['storage'])
84
+ pathlib_cwd = get_pathlib(storage, self.params['path'])
85
+ return self.entrypoint(self.run, dataset, pathlib_cwd, **self.params)
@@ -0,0 +1,5 @@
1
+ from pathlib import Path
2
+
3
+
4
+ def get_original_file_path(files):
5
+ return Path(next(iter(files.values()))['meta']['path_original'])
@@ -0,0 +1,3 @@
1
+ actions:
2
+ export:
3
+ entrypoint: plugin.export.export
@@ -0,0 +1,126 @@
1
+ import json
2
+
3
+ import requests
4
+
5
+ from synapse_sdk.plugins.categories.export.actions.utils import get_original_file_path
6
+
7
+
8
+ def export(run, input_dataset, path_root, **params):
9
+ """Executes the export task.
10
+
11
+ Args:
12
+ run : Execution object
13
+ input_dataset (generator):
14
+ - data (dict): dm_schema_data information.
15
+ - files (dict): File information. Includes file URL, original file path, metadata, etc.
16
+ - id (int): ground_truth ID
17
+ path_root : Save path
18
+ **params: Additional parameters
19
+
20
+ Returns:
21
+ dict: Result
22
+ """
23
+
24
+ path_root.mkdir(parents=True, exist_ok=True)
25
+ run.log_message('Starting export process.')
26
+
27
+ # results: Contains all information fetched through the list API.
28
+ results = params.get('results', [])
29
+
30
+ save_original_file = params.get('save_original_file')
31
+ errors_json_file_list = []
32
+ errors_original_file_list = []
33
+
34
+ # Path to save JSON files
35
+ json_output_path = path_root / 'json'
36
+ json_output_path.mkdir(parents=True, exist_ok=True)
37
+
38
+ # Path to save original files
39
+ origin_files_output_path = path_root / 'origin_files'
40
+ origin_files_output_path.mkdir(parents=True, exist_ok=True)
41
+
42
+ total = len(results)
43
+ for no, input_data in enumerate(input_dataset):
44
+ run.set_progress(no, total, category='dataset_conversion')
45
+ preprocessed_data = before_convert(input_data)
46
+ converted_data = convert_data(preprocessed_data)
47
+ final_data = after_convert(converted_data)
48
+
49
+ # Call if original file extraction is needed
50
+ if save_original_file:
51
+ save_original_file(final_data, origin_files_output_path, errors_original_file_list)
52
+
53
+ # Extract data as JSON files
54
+ save_as_json(final_data, json_output_path, errors_json_file_list)
55
+
56
+ run.log_message('Saving converted dataset.')
57
+ run.end_log()
58
+
59
+ # Save error list files
60
+ if len(errors_json_file_list) > 0 or len(errors_original_file_list) > 0:
61
+ export_error_file = {'json_file_name': errors_json_file_list, 'origin_file_name': errors_original_file_list}
62
+ with (path_root / 'error_file_list.json').open('w', encoding='utf-8') as f:
63
+ json.dump(export_error_file, f, indent=4, ensure_ascii=False)
64
+
65
+ return {'export_path': path_root}
66
+
67
+
68
+ def convert_data(data):
69
+ """Converts the data."""
70
+ return data
71
+
72
+
73
+ def before_convert(data):
74
+ """Preprocesses the data before conversion."""
75
+ return data
76
+
77
+
78
+ def after_convert(data):
79
+ """Post-processes the data after conversion."""
80
+ return data
81
+
82
+
83
+ def save_original_file(result, base_path, error_file_list):
84
+ """Saves the original file.
85
+
86
+ Args:
87
+ result (dict): Result data
88
+ base_path (Path): Save path
89
+ error_file_list (list): List of error files
90
+
91
+ Returns:
92
+ base_path (str): Save path
93
+ """
94
+ file_url = next(iter(result['files'].values()))['url']
95
+ file_name = get_original_file_path(result['files']).name
96
+ response = requests.get(file_url)
97
+ try:
98
+ with (base_path / file_name).open('wb') as file:
99
+ file.write(response.content)
100
+ except Exception as e:
101
+ error_file_list.append([file_name, str(e)])
102
+
103
+ return base_path
104
+
105
+
106
+ def save_as_json(result, base_path, error_file_list):
107
+ """Saves the data as a JSON file.
108
+
109
+ Args:
110
+ result (dict): Result data
111
+ base_path (Path): Save path
112
+ error_file_list (list): List of error files
113
+
114
+ Returns:
115
+ base_path (str): Save path
116
+ """
117
+ # Default save file name: original file name
118
+ file_name = get_original_file_path(result['files']).stem
119
+ json_data = result['data']
120
+ try:
121
+ with (base_path / f'{file_name}.json').open('w', encoding='utf-8') as f:
122
+ json.dump(json_data, f, indent=4, ensure_ascii=False)
123
+ except Exception as e:
124
+ error_file_list.append([f'{file_name}.json', str(e)])
125
+
126
+ return base_path
@@ -18,8 +18,13 @@ from synapse_sdk.utils.pydantic.validators import non_blank
18
18
 
19
19
  class TrainRun(Run):
20
20
  def log_metric(self, category, key, value, **metrics):
21
+ # TODO validate input via plugin config
21
22
  self.log('metric', {'category': category, 'key': key, 'value': value, 'metrics': metrics})
22
23
 
24
+ def log_visualization(self, category, group, image, **meta):
25
+ # TODO validate input via plugin config
26
+ self.log('visualization', {'category': category, 'group': group, **meta}, file=image)
27
+
23
28
 
24
29
  class Hyperparameter(BaseModel):
25
30
  batch_size: int
@@ -8,6 +8,9 @@ actions:
8
8
  epoch:
9
9
  - loss
10
10
  - miou
11
+ hyperparameters:
12
+ ui_schema: |
13
+ Dumped FormKit Schema for hyperparameters
11
14
  deployment:
12
15
  entrypoint: plugin.inference.MockNetInference
13
16
  inference:
@@ -113,8 +113,8 @@ class Run:
113
113
  def set_progress(self, current, total, category=''):
114
114
  self.logger.set_progress(current, total, category)
115
115
 
116
- def log(self, event, data):
117
- self.logger.log(event, data)
116
+ def log(self, event, data, file=None):
117
+ self.logger.log(event, data, file=file)
118
118
 
119
119
  def log_message(self, message, context=Context.INFO.value):
120
120
  self.logger.log('message', {'context': context, 'content': message})
@@ -1,6 +1,8 @@
1
1
  import asyncio
2
+ import base64
2
3
  import hashlib
3
4
  import json
5
+ import mimetypes
4
6
  import operator
5
7
  import zipfile
6
8
  from functools import reduce
@@ -182,3 +184,36 @@ def get_temp_path(sub_path=None):
182
184
  if sub_path:
183
185
  path = path / sub_path
184
186
  return path
187
+
188
+
189
+ def convert_file_to_base64(file_path):
190
+ """
191
+ Convert a file to base64 using pathlib.
192
+
193
+ Args:
194
+ file_path (str): Path to the file to convert
195
+
196
+ Returns:
197
+ str: Base64 encoded string of the file contents
198
+ """
199
+ # Convert string path to Path object
200
+ path = Path(file_path)
201
+
202
+ try:
203
+ # Read binary content of the file
204
+ binary_content = path.read_bytes()
205
+
206
+ # Convert to base64
207
+ base64_encoded = base64.b64encode(binary_content).decode('utf-8')
208
+
209
+ # Get the MIME type of the file
210
+ mime_type, _ = mimetypes.guess_type(path)
211
+ assert mime_type is not None, 'MIME type cannot be guessed'
212
+
213
+ # Convert bytes to string for readable output
214
+ return f'data:{mime_type};base64,{base64_encoded}'
215
+
216
+ except FileNotFoundError:
217
+ raise FileNotFoundError(f'File not found: {file_path}')
218
+ except Exception as e:
219
+ raise Exception(f'Error converting file to base64: {str(e)}')
@@ -0,0 +1,20 @@
1
+ from urllib.parse import urlparse
2
+
3
+ from synapse_sdk.i18n import gettext as _
4
+ from synapse_sdk.utils.storage.registry import STORAGE_PROVIDERS
5
+
6
+
7
+ def get_storage(connection_param: str | dict):
8
+ storage_scheme = None
9
+ if isinstance(connection_param, dict):
10
+ storage_scheme = connection_param['provider']
11
+ else:
12
+ storage_scheme = urlparse(connection_param).scheme
13
+
14
+ assert storage_scheme in STORAGE_PROVIDERS.keys(), _('지원하지 않는 저장소입니다.')
15
+ return STORAGE_PROVIDERS[storage_scheme](connection_param)
16
+
17
+
18
+ def get_pathlib(storage_config, path_root):
19
+ storage_class = get_storage(storage_config)
20
+ return storage_class.get_pathlib(path_root)
@@ -0,0 +1,42 @@
1
+ from urllib.parse import parse_qs, urlparse
2
+
3
+
4
+ class BaseStorage:
5
+ url = None
6
+ options = None
7
+ OPTION_CASTS = {}
8
+
9
+ def __init__(self, connection_params: str | dict):
10
+ self.url = None
11
+
12
+ if isinstance(connection_params, dict):
13
+ self.query_params = connection_params['configuration']
14
+ else:
15
+ self.url = urlparse(connection_params)
16
+ self.query_params = self.url_querystring_to_dict()
17
+
18
+ def url_querystring_to_dict(self):
19
+ query_string = self.url.query
20
+
21
+ query_dict = parse_qs(query_string)
22
+
23
+ for key, value in query_dict.items():
24
+ if len(value) == 1:
25
+ query_dict[key] = value[0]
26
+
27
+ return {
28
+ key: self.OPTION_CASTS[key](value) if key in self.OPTION_CASTS else value
29
+ for key, value in query_dict.items()
30
+ }
31
+
32
+ def upload(self, source, target):
33
+ raise NotImplementedError
34
+
35
+ def exists(self, target):
36
+ raise NotImplementedError
37
+
38
+ def get_url(self, target):
39
+ raise NotImplementedError
40
+
41
+ def get_pathlib(self, path):
42
+ raise NotImplementedError
@@ -0,0 +1,13 @@
1
+ from upath import UPath
2
+
3
+ from synapse_sdk.utils.storage.providers import BaseStorage
4
+
5
+
6
+ class GCPStorage(BaseStorage):
7
+ def __init__(self, url):
8
+ super().__init__(url)
9
+
10
+ self.upath = UPath(f'gs://{self.query_params["bucket_name"]}', token=self.query_params['credentials'])
11
+
12
+ def get_pathlib(self, path):
13
+ return self.upath.joinuri(path)
@@ -0,0 +1,43 @@
1
+ from upath import UPath
2
+
3
+ from synapse_sdk.utils.storage.providers import BaseStorage
4
+
5
+
6
+ class S3Storage(BaseStorage):
7
+ ENDPOINT_URL = 'https://s3.amazonaws.com'
8
+ DEFAULT_REGION = 'us-east-1'
9
+
10
+ def __init__(self, url):
11
+ super().__init__(url)
12
+
13
+ self.upath = self._get_upath()
14
+
15
+ def _get_upath(self):
16
+ upath_kwargs = {
17
+ 'key': self.query_params['access_key'],
18
+ 'secret': self.query_params['secret_key'],
19
+ 'client_kwargs': {'region_name': self.query_params.get('region_name')},
20
+ }
21
+
22
+ if self.query_params.get('endpoint_url'):
23
+ upath_kwargs['endpoint_url'] = self.query_params['endpoint_url']
24
+
25
+ return UPath(
26
+ f's3://{self.query_params["bucket_name"]}',
27
+ **upath_kwargs,
28
+ )
29
+
30
+ def upload(self, source, target):
31
+ with open(source, 'rb') as file:
32
+ self.upath.write_text(file.read(), target)
33
+
34
+ return self.get_url(target)
35
+
36
+ def exists(self, target):
37
+ return self.upath.exists(target)
38
+
39
+ def get_url(self, target):
40
+ return str(self.upath.joinuri(target))
41
+
42
+ def get_pathlib(self, path):
43
+ return self.upath.joinuri(path)
@@ -0,0 +1,16 @@
1
+ from upath import UPath
2
+
3
+ from synapse_sdk.utils.storage.providers import BaseStorage
4
+
5
+
6
+ class SFTPStorage(BaseStorage):
7
+ def get_pathlib(self, path):
8
+ credentials = self.query_params['params']
9
+ host = self.query_params['host']
10
+ root_path = self.query_params['root_path']
11
+
12
+ username = credentials['username']
13
+ password = credentials['password']
14
+ if path == '/':
15
+ path = ''
16
+ return UPath(f'sftp://{host}', username=username, password=password) / root_path / path
@@ -0,0 +1,11 @@
1
+ from synapse_sdk.utils.storage.providers.gcp import GCPStorage
2
+ from synapse_sdk.utils.storage.providers.s3 import S3Storage
3
+ from synapse_sdk.utils.storage.providers.sftp import SFTPStorage
4
+
5
+ STORAGE_PROVIDERS = {
6
+ 's3': S3Storage,
7
+ 'amazon_s3': S3Storage,
8
+ 'minio': S3Storage,
9
+ 'gcp': GCPStorage,
10
+ 'sftp': SFTPStorage,
11
+ }