expops 0.1.17.dev0__tar.gz → 0.1.19.dev0__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.
Files changed (156) hide show
  1. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/PKG-INFO +1 -1
  2. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/expops.egg-info/PKG-INFO +1 -1
  3. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/expops.egg-info/SOURCES.txt +8 -9
  4. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/_version.py +3 -3
  5. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/core/executor_worker.py +17 -6
  6. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/platform.py +17 -7
  7. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/web/server.py +0 -13
  8. expops-0.1.17.dev0/premier-league/firestore.json +0 -1
  9. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/.github/workflows/ci.yml +0 -0
  10. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/.github/workflows/release.yml +0 -0
  11. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/.gitignore +0 -0
  12. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/LICENSE +0 -0
  13. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/README.md +0 -0
  14. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/docs/advanced/backends.md +0 -0
  15. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/docs/features/caching.md +0 -0
  16. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/docs/features/data-parallelism.md +0 -0
  17. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/docs/features/distributed.md +0 -0
  18. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/docs/features/environments.md +0 -0
  19. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/docs/features/pipelines.md +0 -0
  20. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/docs/features/reporting.md +0 -0
  21. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/docs/features/seed-parallelism.md +0 -0
  22. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/docs/getting-started/creating-a-project.md +0 -0
  23. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/docs/getting-started/quick-start.md +0 -0
  24. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/docs/index.md +0 -0
  25. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/docs/project-structure/configuration.md +0 -0
  26. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/docs/project-structure/model-code.md +0 -0
  27. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/docs/project-structure/overview.md +0 -0
  28. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/docs/requirements.txt +0 -0
  29. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/docs/templates/premier-league.md +0 -0
  30. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/docs/templates/sklearn-basic.md +0 -0
  31. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/docs/web-ui/local-ui.md +0 -0
  32. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/pyproject.toml +0 -0
  33. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/setup.cfg +0 -0
  34. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/__init__.py +0 -0
  35. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/expops/__init__.py +0 -0
  36. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/expops/__main__.py +0 -0
  37. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/expops/core/__init__.py +0 -0
  38. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/expops/main.py +0 -0
  39. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/expops/reporting/__init__.py +0 -0
  40. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/expops/reporting/context.py +0 -0
  41. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/expops/reporting/registry.py +0 -0
  42. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/expops/web/__init__.py +0 -0
  43. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/expops/web/server.py +0 -0
  44. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/expops.egg-info/dependency_links.txt +0 -0
  45. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/expops.egg-info/entry_points.txt +0 -0
  46. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/expops.egg-info/requires.txt +0 -0
  47. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/expops.egg-info/top_level.txt +0 -0
  48. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/__init__.py +0 -0
  49. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/__main__.py +0 -0
  50. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/adapters/__init__.py +0 -0
  51. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/adapters/base.py +0 -0
  52. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/adapters/config_schema.py +0 -0
  53. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/adapters/custom/__init__.py +0 -0
  54. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/adapters/custom/custom_adapter.py +0 -0
  55. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/adapters/plugin_manager.py +0 -0
  56. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/adapters/sklearn/__init__.py +0 -0
  57. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/adapters/sklearn/adapter.py +0 -0
  58. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/cluster/__init__.py +0 -0
  59. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/cluster/controller.py +0 -0
  60. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/cluster/process_runner.py +0 -0
  61. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/cluster/providers.py +0 -0
  62. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/core/__init__.py +0 -0
  63. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/core/compute_config.py +0 -0
  64. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/core/custom_model_base.py +0 -0
  65. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/core/dask_networkx_executor.py +0 -0
  66. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/core/data_hashing.py +0 -0
  67. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/core/graph_expansion.py +0 -0
  68. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/core/graph_types.py +0 -0
  69. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/core/networkx_parser.py +0 -0
  70. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/core/payload_spill.py +0 -0
  71. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/core/pipeline_tree.py +0 -0
  72. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/core/pipeline_utils.py +0 -0
  73. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/core/probe_path_selectors.py +0 -0
  74. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/core/process_hashing.py +0 -0
  75. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/core/step_state_manager.py +0 -0
  76. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/core/step_system.py +0 -0
  77. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/core/workspace.py +0 -0
  78. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/environment/__init__.py +0 -0
  79. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/environment/base.py +0 -0
  80. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/environment/conda_manager.py +0 -0
  81. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/environment/factory.py +0 -0
  82. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/environment/pyenv_manager.py +0 -0
  83. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/environment/setup_env.py +0 -0
  84. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/environment/system_manager.py +0 -0
  85. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/environment/utils.py +0 -0
  86. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/environment/venv_manager.py +0 -0
  87. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/main.py +0 -0
  88. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/managers/project_manager.py +0 -0
  89. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/managers/reproducibility_manager.py +0 -0
  90. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/reporting/__init__.py +0 -0
  91. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/reporting/context.py +0 -0
  92. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/reporting/entrypoint.py +0 -0
  93. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/reporting/kv_utils.py +0 -0
  94. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/reporting/registry.py +0 -0
  95. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/runtime/__init__.py +0 -0
  96. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/runtime/context.py +0 -0
  97. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/runtime/env_export.py +0 -0
  98. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/storage/__init__.py +0 -0
  99. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/storage/adapters/__init__.py +0 -0
  100. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/storage/adapters/gcp_kv_store.py +0 -0
  101. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/storage/adapters/gcs_object_store.py +0 -0
  102. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/storage/adapters/memory_store.py +0 -0
  103. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/storage/adapters/redis_store.py +0 -0
  104. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/storage/adapters/sqlite_store.py +0 -0
  105. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/storage/factory.py +0 -0
  106. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/storage/interfaces/__init__.py +0 -0
  107. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/storage/interfaces/kv_store.py +0 -0
  108. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/storage/path_utils.py +0 -0
  109. {expops-0.1.17.dev0 → expops-0.1.19.dev0/src/mlops/templates}/premier-league/charts/plot_metrics.js +0 -0
  110. {expops-0.1.17.dev0 → expops-0.1.19.dev0/src/mlops/templates}/premier-league/charts/plot_metrics.py +0 -0
  111. {expops-0.1.17.dev0 → expops-0.1.19.dev0/src/mlops/templates}/premier-league/charts/requirements.txt +0 -0
  112. {expops-0.1.17.dev0 → expops-0.1.19.dev0/src/mlops/templates}/premier-league/configs/compute_config.yaml +0 -0
  113. {expops-0.1.17.dev0 → expops-0.1.19.dev0/src/mlops/templates}/premier-league/configs/project_config.yaml +0 -0
  114. {expops-0.1.17.dev0 → expops-0.1.19.dev0/src/mlops/templates}/premier-league/data/England CSV.csv +0 -0
  115. {expops-0.1.17.dev0 → expops-0.1.19.dev0/src/mlops/templates}/premier-league/models/premier_league_model.py +0 -0
  116. {expops-0.1.17.dev0 → expops-0.1.19.dev0/src/mlops/templates}/premier-league/requirements.txt +0 -0
  117. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/templates/sklearn-basic/README.md +0 -0
  118. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/templates/sklearn-basic/charts/plot_metrics.py +0 -0
  119. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/templates/sklearn-basic/charts/requirements.txt +0 -0
  120. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/templates/sklearn-basic/configs/compute_config.yaml +0 -0
  121. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/templates/sklearn-basic/configs/project_config.yaml +0 -0
  122. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/templates/sklearn-basic/data/train.csv +0 -0
  123. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/templates/sklearn-basic/models/model.py +0 -0
  124. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/templates/sklearn-basic/requirements.txt +0 -0
  125. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/web/__init__.py +0 -0
  126. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/web/ui/index.html +0 -0
  127. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/web/ui/mlops-charts.js +0 -0
  128. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/web/ui/script.js +0 -0
  129. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/src/mlops/web/ui/styles.css +0 -0
  130. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/tests/conftest.py +0 -0
  131. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/tests/testing-plan.md +0 -0
  132. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/tests/unit/__init__.py +0 -0
  133. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/tests/unit/test_core/__init__.py +0 -0
  134. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/tests/unit/test_core/test_dask_networkx_executor.py +0 -0
  135. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/tests/unit/test_core/test_data_hashing.py +0 -0
  136. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/tests/unit/test_core/test_executor_worker.py +0 -0
  137. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/tests/unit/test_core/test_graph_expansion.py +0 -0
  138. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/tests/unit/test_core/test_networkx_parser.py +0 -0
  139. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/tests/unit/test_core/test_networkx_parser_code_field.py +0 -0
  140. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/tests/unit/test_core/test_payload_spill.py +0 -0
  141. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/tests/unit/test_core/test_pipeline_tree_steps.py +0 -0
  142. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/tests/unit/test_core/test_prepare_runner_kwargs.py +0 -0
  143. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/tests/unit/test_core/test_probe_path_selectors_xpath.py +0 -0
  144. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/tests/unit/test_core/test_process_hashing.py +0 -0
  145. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/tests/unit/test_core/test_step_state_manager.py +0 -0
  146. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/tests/unit/test_core/test_step_system.py +0 -0
  147. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/tests/unit/test_managers/__init__.py +0 -0
  148. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/tests/unit/test_managers/test_reproducibility_manager.py +0 -0
  149. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/tests/unit/test_platform/test_dynamic_js_charts.py +0 -0
  150. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/tests/unit/test_platform/test_project_metadata_resilience.py +0 -0
  151. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/tests/unit/test_reporting/test_entrypoint.py +0 -0
  152. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/tests/unit/test_storage/__init__.py +0 -0
  153. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/tests/unit/test_storage/test_factory.py +0 -0
  154. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/tests/unit/test_storage/test_gcp_kv_store.py +0 -0
  155. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/tests/unit/test_storage/test_gcs_object_store.py +0 -0
  156. {expops-0.1.17.dev0 → expops-0.1.19.dev0}/tests/unit/test_storage/test_sqlite_store.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: expops
3
- Version: 0.1.17.dev0
3
+ Version: 0.1.19.dev0
4
4
  Summary: MLOps Platform with step-based pipeline execution
5
5
  License: GNU GENERAL PUBLIC LICENSE
6
6
  Version 3, 29 June 2007
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: expops
3
- Version: 0.1.17.dev0
3
+ Version: 0.1.19.dev0
4
4
  Summary: MLOps Platform with step-based pipeline execution
5
5
  License: GNU GENERAL PUBLIC LICENSE
6
6
  Version 3, 29 June 2007
@@ -22,15 +22,6 @@ docs/project-structure/overview.md
22
22
  docs/templates/premier-league.md
23
23
  docs/templates/sklearn-basic.md
24
24
  docs/web-ui/local-ui.md
25
- premier-league/firestore.json
26
- premier-league/requirements.txt
27
- premier-league/charts/plot_metrics.js
28
- premier-league/charts/plot_metrics.py
29
- premier-league/charts/requirements.txt
30
- premier-league/configs/compute_config.yaml
31
- premier-league/configs/project_config.yaml
32
- premier-league/data/England CSV.csv
33
- premier-league/models/premier_league_model.py
34
25
  src/__init__.py
35
26
  src/expops/__init__.py
36
27
  src/expops/__main__.py
@@ -111,6 +102,14 @@ src/mlops/storage/adapters/redis_store.py
111
102
  src/mlops/storage/adapters/sqlite_store.py
112
103
  src/mlops/storage/interfaces/__init__.py
113
104
  src/mlops/storage/interfaces/kv_store.py
105
+ src/mlops/templates/premier-league/requirements.txt
106
+ src/mlops/templates/premier-league/charts/plot_metrics.js
107
+ src/mlops/templates/premier-league/charts/plot_metrics.py
108
+ src/mlops/templates/premier-league/charts/requirements.txt
109
+ src/mlops/templates/premier-league/configs/compute_config.yaml
110
+ src/mlops/templates/premier-league/configs/project_config.yaml
111
+ src/mlops/templates/premier-league/data/England CSV.csv
112
+ src/mlops/templates/premier-league/models/premier_league_model.py
114
113
  src/mlops/templates/sklearn-basic/README.md
115
114
  src/mlops/templates/sklearn-basic/requirements.txt
116
115
  src/mlops/templates/sklearn-basic/charts/plot_metrics.py
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '0.1.17.dev0'
32
- __version_tuple__ = version_tuple = (0, 1, 17, 'dev0')
31
+ __version__ = version = '0.1.19.dev0'
32
+ __version_tuple__ = version_tuple = (0, 1, 19, 'dev0')
33
33
 
34
- __commit_id__ = commit_id = 'g8934518e8'
34
+ __commit_id__ = commit_id = 'g4b7fdd9d1'
@@ -109,12 +109,21 @@ def _record_chart_artifacts(
109
109
  except Exception:
110
110
  pngs = []
111
111
 
112
+ # Always use full gs:// URI for chart uploads so the store's prefix is never applied
113
+ # (avoids creating projects/<project_id>/charts when prefix is "projects").
112
114
  abs_charts_root = None
113
115
  try:
114
- if obj_store and hasattr(obj_store, "_bucket") and getattr(obj_store, "_bucket") is not None:
115
- bname = getattr(getattr(obj_store, "_bucket"), "name", None)
116
+ if obj_store:
117
+ bname = None
118
+ bucket = getattr(obj_store, "_bucket", None)
119
+ if bucket is not None:
120
+ bname = getattr(bucket, "name", None)
121
+ if not bname:
122
+ bname = getattr(obj_store, "_bucket_name", None)
116
123
  if bname:
117
- abs_charts_root = f"gs://{bname}/projects/{project_id}/charts/{run_id}"
124
+ # Store charts directly under the project namespace (no prefix):
125
+ # gs://<bucket>/<project_id>/charts/<run_id>/...
126
+ abs_charts_root = f"gs://{bname}/{project_id}/charts/{run_id}"
118
127
  except Exception:
119
128
  abs_charts_root = None
120
129
 
@@ -128,10 +137,12 @@ def _record_chart_artifacts(
128
137
  obj_path = None
129
138
  if obj_store:
130
139
  try:
131
- base = f"projects/{project_id}/charts/{run_id}/{chart_name}"
132
140
  if abs_charts_root:
133
- base = f"{abs_charts_root}/{chart_name}"
134
- remote = obj_store.build_uri(base, p.name)
141
+ # Full URI so prefix is never applied
142
+ remote = obj_store.build_uri(f"{abs_charts_root}/{chart_name}", p.name)
143
+ else:
144
+ base = f"{project_id}/charts/{run_id}/{chart_name}"
145
+ remote = obj_store.build_uri(base, p.name)
135
146
  with open(p, "rb") as f:
136
147
  obj_store.put_bytes(remote, f.read(), content_type="image/png")
137
148
  obj_path = remote
@@ -987,13 +987,21 @@ class MLPlatform:
987
987
  project_ns = os.environ.get('MLOPS_PROJECT_ID', '')
988
988
  except Exception:
989
989
  project_ns = ''
990
- # If bucket known, build absolute gs:// directory prefix for improved UX
990
+ # Always use full gs:// URI for chart uploads so the store's prefix is never applied
991
+ # (avoids creating projects/<project_id>/charts when prefix is "projects").
991
992
  abs_charts_root = None
992
993
  try:
993
- if obj_store and hasattr(obj_store, '_bucket') and getattr(obj_store, '_bucket') is not None:
994
- bname = getattr(getattr(obj_store, '_bucket'), 'name', None)
994
+ if obj_store:
995
+ bname = None
996
+ bucket = getattr(obj_store, "_bucket", None)
997
+ if bucket is not None:
998
+ bname = getattr(bucket, "name", None)
999
+ if not bname:
1000
+ bname = getattr(obj_store, "_bucket_name", None)
995
1001
  if bname:
996
- abs_charts_root = f"gs://{bname}/projects/{project_ns}/charts/{run_id}"
1002
+ # Store charts directly under the project namespace (no prefix):
1003
+ # gs://<bucket>/<project_ns>/charts/<run_id>/...
1004
+ abs_charts_root = f"gs://{bname}/{project_ns}/charts/{run_id}"
997
1005
  except Exception:
998
1006
  abs_charts_root = None
999
1007
  import time as _time
@@ -1008,10 +1016,12 @@ class MLPlatform:
1008
1016
  local_path = str(p)
1009
1017
  if obj_store:
1010
1018
  try:
1011
- base = f"projects/{project_ns}/charts/{run_id}/{name}"
1012
1019
  if abs_charts_root:
1013
- base = f"{abs_charts_root}/{name}"
1014
- remote = obj_store.build_uri(base, p.name)
1020
+ # Full URI so prefix is never applied
1021
+ remote = obj_store.build_uri(f"{abs_charts_root}/{name}", p.name)
1022
+ else:
1023
+ base = f"{project_ns}/charts/{run_id}/{name}"
1024
+ remote = obj_store.build_uri(base, p.name)
1015
1025
  with open(p, 'rb') as f:
1016
1026
  obj_store.put_bytes(remote, f.read(), content_type="image/png")
1017
1027
  obj_path = remote
@@ -159,19 +159,6 @@ def _norm_backend_type(value: Any) -> str:
159
159
  return aliases.get(s, s)
160
160
 
161
161
 
162
- def _list_runs_fs(project_id: str) -> List[str]:
163
- # Fallback: list charts folders which are created per run
164
- charts_dir = PROJECTS_DIR / project_id / "artifacts" / "charts"
165
- runs: List[str] = []
166
- if charts_dir.exists():
167
- for child in sorted(charts_dir.iterdir()):
168
- if child.is_dir():
169
- runs.append(child.name)
170
- # Also scan logs for the latest timestamped files as run hints (no ID inside logs guaranteed)
171
- # We will not parse logs; keep simple.
172
- return runs
173
-
174
-
175
162
  @app.get("/api/projects")
176
163
  def list_projects() -> Dict[str, Any]:
177
164
  idx = _read_projects_index()
@@ -1 +0,0 @@
1
- {"type":"service_account","project_id":"mlops-platform-470017","private_key_id":"0a5f97bd39814e45553c7ddca399e504c4821f04","private_key":"-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDBDxZkEB6KTMyS\n4/KKOHlbzwTLFTAXYWyKY15X6hhetwrRzAMWoGX1/fopvkf3u60gevrJq4R+UOTe\nZ1XGhySrpAyEtr2KPD9Zz0H+EgdLlBM+SZHfKkrM3Iln08LV501EF+miouaZ+Pn4\naNBYcQH5ry9BAADfysHj9fS92OVvGQ1cfj/RMUVOA9wHTBoFUzzwDVyGgUv6oA6K\nJLWzx4Z9Uh5W1PpkBVxaFrvzGMIQ/YOlgN6Ii67mR3RvYdXsEgNoRudiiG0djNDP\n/NnRm3D8Eo93Kxv5K9dJeKGX3lobSGfGPvqe6FqeUOlTDb8PS3LbTsQj3vW/EZ8Y\nsOcGnSmxAgMBAAECggEADUDO5bGhlxbsmEzjso9r7VyJ1LMwqPo8LEfkCx7760yf\nhoV91MjQFxIHYWQ5po0QtoEaxEts/grpm0b2wXk3kDzjyxyMaHf4VV8ABcQREiQp\nKgZ86BgMKIIfQKxt3KdTS5BkrpCGSh2oc2AmpVukqhJXqRup87MEmnShB4NjRLwR\n80jaYHOsTul4fDxcofzgUWTd+wou6fTWNrPPGDP3bvGUD2ktuXwmJ1Ye8wXfuiaW\nVgTa5dNsY/DoRqfXe9QagJ9cdmm0SjQppAxY8+FcHheSuwzp7XWAUegzc8rCqQp5\nlKW47CL6UdTN7jx2AEadannZiYgN4A51yu0bX0vd0QKBgQDtPTj3OSG61LxJSycb\n6SnoO+2jBskDsbnWFSaPj88GFiitLPegH9kr54uoea5mOtpNSt7mW3iTy/V3zABc\nf+KK/5l6ZpV+CVaVndd6LRBt3aFBbEx3MZGcPeIoZDEqYTkROQlJKBRYrDpHJAAe\nQhbHl0XP+4EmbMTqNPL4kD9f/QKBgQDQU3XlkWaABwispE+7r58K8Z+7Uzapzlj7\nM0UsdLXj/FtmwEx5PWiVFCDEiy3F17aAsJmcEhXEl3yYARdES5q1/fAcBrGguxQK\n0Uzc+958oodV+SL70V147k+NvmPtrOhwYMCdRavAk5/zUrVNrvS6rk/aMFscwheR\ns9YnkY08xQKBgFHUFSsI1L6JlCw/tMymvuKwkQXzWDBjA/N4tiU8eC7kQ8F/yiW7\n9n9zTTOeTO5MDHIuifWwxUVNS2y3u8QsBCrngLu8WIHxnKDcoa8tjgYnNPDI9xMB\n0PSwT6qY7HBuum1bW/2UynfPaAaTv0qwhwTvA5B6cpCbYcxa2RetQX7NAoGBALm3\n/d23vvIZ0zDdlrtSeG2wNF8ycwP0kjz3Ww6jyVfDLNSwUDyxcx+b/w5YqWi7wtZ9\nGaQaN0+4YPm91zkqUXU3OiwyB36r6NUv+97xp0njNtV9MiPeZP8fLMrHVZyYTeuJ\nRY2vg8s9kBXCwSDM/R3Dsipoe4FqwspA0YUa7BelAoGAOOLY6E7sdE76Tuzd7jxh\nWrO1vY0H6PO3SWns14J3/ZcpXPda2RvpResoDLQ2BDSdWO8oRcWkv8IctODkKLkb\nCCf+n82KnZmaAd9mBW9mdX+1djkBiEjYBW6XPAP3QUZLsf+jxTlIu/20X+iUo/LC\nlVoi6u3ZyJbX90OIkIWkOiA=\n-----END PRIVATE KEY-----\n","client_email":"platform@mlops-platform-470017.iam.gserviceaccount.com","client_id":"102504406075317026901","auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://oauth2.googleapis.com/token","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs","client_x509_cert_url":"https://www.googleapis.com/robot/v1/metadata/x509/platform%40mlops-platform-470017.iam.gserviceaccount.com","universe_domain":"googleapis.com"}
File without changes
File without changes
File without changes
File without changes
File without changes