OpenGeodeWeb-Back 6.14.2rc1__tar.gz → 6.15.0__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 (118) hide show
  1. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/PKG-INFO +2 -2
  2. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/pyproject.toml +1 -1
  3. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/requirements.txt +1 -1
  4. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/OpenGeodeWeb_Back.egg-info/PKG-INFO +2 -2
  5. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/OpenGeodeWeb_Back.egg-info/requires.txt +1 -1
  6. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/blueprint_routes.py +81 -22
  7. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/schemas/cell_attribute_names.json +8 -1
  8. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/schemas/cell_attribute_names.py +1 -0
  9. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/schemas/edge_attribute_names.json +8 -1
  10. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/schemas/edge_attribute_names.py +1 -0
  11. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/schemas/model_component_edge_attribute_names.json +8 -1
  12. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/schemas/model_component_edge_attribute_names.py +1 -0
  13. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/schemas/model_component_polygon_attribute_names.json +8 -1
  14. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/schemas/model_component_polygon_attribute_names.py +1 -0
  15. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/schemas/model_component_polyhedron_attribute_names.json +8 -1
  16. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/schemas/model_component_polyhedron_attribute_names.py +1 -0
  17. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/schemas/model_component_vertex_attribute_names.json +8 -1
  18. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/schemas/model_component_vertex_attribute_names.py +1 -0
  19. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/schemas/polygon_attribute_names.json +8 -1
  20. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/schemas/polygon_attribute_names.py +1 -0
  21. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/schemas/polyhedron_attribute_names.json +8 -1
  22. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/schemas/polyhedron_attribute_names.py +1 -0
  23. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/schemas/vertex_attribute_names.json +8 -1
  24. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/schemas/vertex_attribute_names.py +1 -0
  25. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/tests/test_routes.py +33 -0
  26. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/LICENSE +0 -0
  27. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/README.md +0 -0
  28. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/setup.cfg +0 -0
  29. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/OpenGeodeWeb_Back.egg-info/SOURCES.txt +0 -0
  30. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/OpenGeodeWeb_Back.egg-info/dependency_links.txt +0 -0
  31. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/OpenGeodeWeb_Back.egg-info/entry_points.txt +0 -0
  32. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/OpenGeodeWeb_Back.egg-info/top_level.txt +0 -0
  33. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/__init__.py +0 -0
  34. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/app.py +0 -0
  35. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/app_config.py +0 -0
  36. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/geode_functions.py +0 -0
  37. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/geode_objects/__init__.py +0 -0
  38. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/geode_objects/geode_brep.py +0 -0
  39. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/geode_objects/geode_cross_section.py +0 -0
  40. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/geode_objects/geode_edged_curve2d.py +0 -0
  41. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/geode_objects/geode_edged_curve3d.py +0 -0
  42. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/geode_objects/geode_graph.py +0 -0
  43. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/geode_objects/geode_grid2d.py +0 -0
  44. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/geode_objects/geode_grid3d.py +0 -0
  45. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/geode_objects/geode_horizon_stack3d.py +0 -0
  46. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/geode_objects/geode_hybrid_solid3d.py +0 -0
  47. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/geode_objects/geode_implicit_cross_section.py +0 -0
  48. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/geode_objects/geode_implicit_structural_model.py +0 -0
  49. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/geode_objects/geode_light_regular_grid2d.py +0 -0
  50. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/geode_objects/geode_light_regular_grid3d.py +0 -0
  51. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/geode_objects/geode_mesh.py +0 -0
  52. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/geode_objects/geode_model.py +0 -0
  53. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/geode_objects/geode_object.py +0 -0
  54. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/geode_objects/geode_point_set2d.py +0 -0
  55. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/geode_objects/geode_point_set3d.py +0 -0
  56. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/geode_objects/geode_polygonal_surface2d.py +0 -0
  57. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/geode_objects/geode_polygonal_surface3d.py +0 -0
  58. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/geode_objects/geode_polyhedral_solid3d.py +0 -0
  59. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/geode_objects/geode_raster_image2d.py +0 -0
  60. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/geode_objects/geode_raster_image3d.py +0 -0
  61. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/geode_objects/geode_regular_grid2d.py +0 -0
  62. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/geode_objects/geode_regular_grid3d.py +0 -0
  63. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/geode_objects/geode_section.py +0 -0
  64. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/geode_objects/geode_solid_mesh3d.py +0 -0
  65. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/geode_objects/geode_structural_model.py +0 -0
  66. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/geode_objects/geode_surface_mesh2d.py +0 -0
  67. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/geode_objects/geode_surface_mesh3d.py +0 -0
  68. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/geode_objects/geode_tetrahedral_solid3d.py +0 -0
  69. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/geode_objects/geode_triangulated_surface2d.py +0 -0
  70. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/geode_objects/geode_triangulated_surface3d.py +0 -0
  71. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/geode_objects/geode_vertex_set.py +0 -0
  72. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/py.typed +0 -0
  73. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/__init__.py +0 -0
  74. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/create/__init__.py +0 -0
  75. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/create/blueprint_create.py +0 -0
  76. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/create/schemas/__init__.py +0 -0
  77. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/create/schemas/edged_curve.json +0 -0
  78. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/create/schemas/edged_curve.py +0 -0
  79. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/create/schemas/point_set.json +0 -0
  80. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/create/schemas/point_set.py +0 -0
  81. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/create/schemas/polygonal_surface.json +0 -0
  82. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/create/schemas/polygonal_surface.py +0 -0
  83. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/schemas/__init__.py +0 -0
  84. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/schemas/allowed_files.json +0 -0
  85. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/schemas/allowed_files.py +0 -0
  86. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/schemas/allowed_objects.json +0 -0
  87. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/schemas/allowed_objects.py +0 -0
  88. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/schemas/export_project.json +0 -0
  89. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/schemas/export_project.py +0 -0
  90. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/schemas/geode_object_inheritance.json +0 -0
  91. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/schemas/geode_object_inheritance.py +0 -0
  92. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/schemas/geode_objects_and_output_extensions.json +0 -0
  93. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/schemas/geode_objects_and_output_extensions.py +0 -0
  94. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/schemas/geographic_coordinate_systems.json +0 -0
  95. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/schemas/geographic_coordinate_systems.py +0 -0
  96. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/schemas/import_project.json +0 -0
  97. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/schemas/import_project.py +0 -0
  98. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/schemas/kill.json +0 -0
  99. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/schemas/kill.py +0 -0
  100. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/schemas/missing_files.json +0 -0
  101. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/schemas/missing_files.py +0 -0
  102. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/schemas/ping.json +0 -0
  103. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/schemas/ping.py +0 -0
  104. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/schemas/save_viewable_file.json +0 -0
  105. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/schemas/save_viewable_file.py +0 -0
  106. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/schemas/texture_coordinates.json +0 -0
  107. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/schemas/texture_coordinates.py +0 -0
  108. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/schemas/upload_file.json +0 -0
  109. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/schemas/upload_file.py +0 -0
  110. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/schemas/validate.json +0 -0
  111. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/routes/schemas/validate.py +0 -0
  112. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/test_utils.py +0 -0
  113. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/typed_route.py +0 -0
  114. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/src/opengeodeweb_back/utils_functions.py +0 -0
  115. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/tests/test_create_routes.py +0 -0
  116. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/tests/test_geode_functions.py +0 -0
  117. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/tests/test_typed_routes.py +0 -0
  118. {opengeodeweb_back-6.14.2rc1 → opengeodeweb_back-6.15.0}/tests/test_utils_functions.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: OpenGeodeWeb-Back
3
- Version: 6.14.2rc1
3
+ Version: 6.15.0
4
4
  Summary: OpenGeodeWeb-Back is an open source framework that proposes handy python functions and wrappers for the OpenGeode ecosystem
5
5
  Author-email: Geode-solutions <team-web@geode-solutions.com>
6
6
  Project-URL: Homepage, https://github.com/Geode-solutions/OpenGeodeWeb-Back
@@ -30,7 +30,7 @@ Requires-Dist: opengeode-inspector-geosciences==1.2.1
30
30
  Requires-Dist: opengeode-io==7.10.0
31
31
  Requires-Dist: types-defusedxml==0.7.0.20260504
32
32
  Requires-Dist: werkzeug==3.1.8
33
- Requires-Dist: opengeodeweb-microservice==1.*,>=1.3.2rc1
33
+ Requires-Dist: opengeodeweb-microservice==1.*,>=1.3.2
34
34
  Dynamic: license-file
35
35
 
36
36
  <h1 align="center">OpenGeodeWeb-Back<sup><i>by Geode-solutions</i></sup></h1>
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "OpenGeodeWeb-Back"
7
- version = "6.14.2-rc.1"
7
+ version = "6.15.0"
8
8
  dynamic = ["dependencies"]
9
9
  authors = [{ name = "Geode-solutions", email = "team-web@geode-solutions.com" }]
10
10
  description = "OpenGeodeWeb-Back is an open source framework that proposes handy python functions and wrappers for the OpenGeode ecosystem"
@@ -70,4 +70,4 @@ werkzeug==3.1.8
70
70
  # flask
71
71
  # flask-cors
72
72
 
73
- opengeodeweb-microservice==1.*,>=1.3.2rc1
73
+ opengeodeweb-microservice==1.*,>=1.3.2
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: OpenGeodeWeb-Back
3
- Version: 6.14.2rc1
3
+ Version: 6.15.0
4
4
  Summary: OpenGeodeWeb-Back is an open source framework that proposes handy python functions and wrappers for the OpenGeode ecosystem
5
5
  Author-email: Geode-solutions <team-web@geode-solutions.com>
6
6
  Project-URL: Homepage, https://github.com/Geode-solutions/OpenGeodeWeb-Back
@@ -30,7 +30,7 @@ Requires-Dist: opengeode-inspector-geosciences==1.2.1
30
30
  Requires-Dist: opengeode-io==7.10.0
31
31
  Requires-Dist: types-defusedxml==0.7.0.20260504
32
32
  Requires-Dist: werkzeug==3.1.8
33
- Requires-Dist: opengeodeweb-microservice==1.*,>=1.3.2rc1
33
+ Requires-Dist: opengeodeweb-microservice==1.*,>=1.3.2
34
34
  Dynamic: license-file
35
35
 
36
36
  <h1 align="center">OpenGeodeWeb-Back<sup><i>by Geode-solutions</i></sup></h1>
@@ -17,4 +17,4 @@ opengeode-inspector-geosciences==1.2.1
17
17
  opengeode-io==7.10.0
18
18
  types-defusedxml==0.7.0.20260504
19
19
  werkzeug==3.1.8
20
- opengeodeweb-microservice==1.*,>=1.3.2rc1
20
+ opengeodeweb-microservice==1.*,>=1.3.2
@@ -246,15 +246,24 @@ def texture_coordinates(
246
246
  return schemas.TextureCoordinatesResponse(texture_coordinates=texture_coordinates)
247
247
 
248
248
 
249
- def extract_valid_attribute_values(
249
+ def _attribute_ids_for_name(
250
+ attribute_manager: og.AttributeManager, attribute_name: str
251
+ ) -> list[og.uuid]:
252
+ time_steps = attribute_manager.time_steps(attribute_name)
253
+ if time_steps:
254
+ return [time_step.attribute_id for time_step in time_steps]
255
+ attribute_ids = attribute_manager.attribute_ids_matching_name(attribute_name)
256
+ if not isinstance(attribute_ids, list) or not attribute_ids:
257
+ return []
258
+ return attribute_ids[:1]
259
+
260
+
261
+ def _extract_valid_values_from_attribute(
250
262
  attribute_manager: og.AttributeManager,
251
- attribute_name: str,
263
+ attribute_id: og.uuid,
252
264
  item_index: int,
253
265
  ) -> tuple[list[float], bool]:
254
- attribute_ids = attribute_manager.attribute_ids_matching_name(attribute_name)
255
- if not isinstance(attribute_ids, list):
256
- return [], False
257
- attribute = attribute_manager.find_generic_attribute(attribute_ids[0])
266
+ attribute = attribute_manager.find_generic_attribute(attribute_id)
258
267
  if (
259
268
  attribute is None
260
269
  or not attribute.is_genericable()
@@ -287,48 +296,98 @@ def extract_valid_attribute_values(
287
296
  return valid_values, has_nan
288
297
 
289
298
 
299
+ def extract_valid_attribute_values(
300
+ attribute_manager: og.AttributeManager,
301
+ attribute_name: str,
302
+ item_index: int,
303
+ ) -> tuple[list[float], bool]:
304
+ valid_values: list[float] = []
305
+ has_nan = False
306
+ for attribute_id in _attribute_ids_for_name(attribute_manager, attribute_name):
307
+ step_values, step_has_nan = _extract_valid_values_from_attribute(
308
+ attribute_manager, attribute_id, item_index
309
+ )
310
+ valid_values.extend(step_values)
311
+ has_nan = has_nan or step_has_nan
312
+ return valid_values, has_nan
313
+
314
+
315
+ def _common_time_steps(
316
+ attribute_managers: list[og.AttributeManager], attribute_name: str
317
+ ) -> list[float] | None:
318
+ times = [time_step.time for time_step in attribute_managers[0].time_steps(attribute_name)]
319
+ for attribute_manager in attribute_managers[1:]:
320
+ other_times = [time_step.time for time_step in attribute_manager.time_steps(attribute_name)]
321
+ if other_times != times:
322
+ return None
323
+ return times
324
+
325
+
326
+ def _attribute_ranges(
327
+ attribute_managers: list[og.AttributeManager],
328
+ attribute_name: str,
329
+ nb_items: int,
330
+ ) -> tuple[list[float], list[float], bool]:
331
+ min_values: list[float] = []
332
+ max_values: list[float] = []
333
+ attribute_has_nan = False
334
+ for item_index in range(nb_items):
335
+ valid_values: list[float] = []
336
+ for attribute_manager in attribute_managers:
337
+ extracted_values, has_nan = extract_valid_attribute_values(
338
+ attribute_manager, attribute_name, item_index
339
+ )
340
+ valid_values.extend(extracted_values)
341
+ attribute_has_nan = attribute_has_nan or has_nan
342
+ if valid_values:
343
+ min_values.append(min(valid_values))
344
+ max_values.append(max(valid_values))
345
+ return min_values, max_values, attribute_has_nan
346
+
347
+
290
348
  def attributes_metadata(
291
349
  manager: og.AttributeManager | list[og.AttributeManager],
292
350
  ) -> list[dict[str, str | int | float | bool | list[float]]]:
293
351
  attribute_managers = manager if isinstance(manager, list) else [manager]
294
352
  attributes: list[dict[str, str | int | float | bool | list[float]]] = []
295
353
  first_manager = attribute_managers[0]
354
+ listed_time_series: set[str] = set()
296
355
  for attribute_id in first_manager.attribute_ids():
297
356
  attribute = first_manager.find_generic_attribute(attribute_id)
298
357
  if attribute is None:
299
358
  continue
300
359
  attribute_name = attribute.name()
301
- if attribute_name is None:
360
+ if attribute_name is None or attribute_name in listed_time_series:
302
361
  continue
303
362
  if not attribute.is_genericable() or not attribute.properties().transferable:
304
363
  continue
364
+ time_steps = _common_time_steps(attribute_managers, attribute_name)
365
+ if time_steps is None:
366
+ continue
367
+ if time_steps:
368
+ listed_time_series.add(attribute_name)
305
369
  nb_items = attribute.nb_items()
306
- min_values, max_values = [], []
307
- attribute_has_nan = False
308
- for item_index in range(nb_items):
309
- valid_values: list[float] = []
310
- for attribute_manager in attribute_managers:
311
- extracted_values, has_nan = extract_valid_attribute_values(
312
- attribute_manager, attribute_name, item_index
313
- )
314
- valid_values.extend(extracted_values)
315
- if has_nan:
316
- attribute_has_nan = True
317
- if valid_values:
318
- min_values.append(min(valid_values))
319
- max_values.append(max(valid_values))
370
+ min_values, max_values, attribute_has_nan = _attribute_ranges(
371
+ attribute_managers, attribute_name, nb_items
372
+ )
320
373
  if not min_values or not max_values:
321
374
  continue
375
+ series_id = (
376
+ first_manager.time_steps(attribute_name)[0].attribute_id.string()
377
+ if time_steps
378
+ else attribute_id.string()
379
+ )
322
380
  attributes.append(
323
381
  {
324
382
  "attribute_name": attribute_name,
325
- "attribute_id": attribute_id.string(),
383
+ "attribute_id": series_id,
326
384
  "nb_items": nb_items,
327
385
  "min_value": min(min_values),
328
386
  "max_value": max(max_values),
329
387
  "min_values": min_values,
330
388
  "max_values": max_values,
331
389
  "no_data": attribute_has_nan,
390
+ "time_steps": time_steps,
332
391
  }
333
392
  )
334
393
  return attributes
@@ -52,6 +52,12 @@
52
52
  },
53
53
  "no_data": {
54
54
  "type": "boolean"
55
+ },
56
+ "time_steps": {
57
+ "type": "array",
58
+ "items": {
59
+ "type": "number"
60
+ }
55
61
  }
56
62
  },
57
63
  "required": [
@@ -62,7 +68,8 @@
62
68
  "max_value",
63
69
  "min_values",
64
70
  "max_values",
65
- "no_data"
71
+ "no_data",
72
+ "time_steps"
66
73
  ],
67
74
  "additionalProperties": false
68
75
  }
@@ -27,6 +27,7 @@ class Attribute(DataClassJsonMixin):
27
27
  min_values: List[float]
28
28
  nb_items: int
29
29
  no_data: bool
30
+ time_steps: List[float]
30
31
 
31
32
 
32
33
  @dataclass
@@ -52,6 +52,12 @@
52
52
  },
53
53
  "no_data": {
54
54
  "type": "boolean"
55
+ },
56
+ "time_steps": {
57
+ "type": "array",
58
+ "items": {
59
+ "type": "number"
60
+ }
55
61
  }
56
62
  },
57
63
  "required": [
@@ -62,7 +68,8 @@
62
68
  "max_value",
63
69
  "min_values",
64
70
  "max_values",
65
- "no_data"
71
+ "no_data",
72
+ "time_steps"
66
73
  ],
67
74
  "additionalProperties": false
68
75
  }
@@ -27,6 +27,7 @@ class Attribute(DataClassJsonMixin):
27
27
  min_values: List[float]
28
28
  nb_items: int
29
29
  no_data: bool
30
+ time_steps: List[float]
30
31
 
31
32
 
32
33
  @dataclass
@@ -62,6 +62,12 @@
62
62
  },
63
63
  "no_data": {
64
64
  "type": "boolean"
65
+ },
66
+ "time_steps": {
67
+ "type": "array",
68
+ "items": {
69
+ "type": "number"
70
+ }
65
71
  }
66
72
  },
67
73
  "required": [
@@ -72,7 +78,8 @@
72
78
  "max_value",
73
79
  "min_values",
74
80
  "max_values",
75
- "no_data"
81
+ "no_data",
82
+ "time_steps"
76
83
  ],
77
84
  "additionalProperties": false
78
85
  }
@@ -28,6 +28,7 @@ class Attribute(DataClassJsonMixin):
28
28
  min_values: List[float]
29
29
  nb_items: int
30
30
  no_data: bool
31
+ time_steps: List[float]
31
32
 
32
33
 
33
34
  @dataclass
@@ -62,6 +62,12 @@
62
62
  },
63
63
  "no_data": {
64
64
  "type": "boolean"
65
+ },
66
+ "time_steps": {
67
+ "type": "array",
68
+ "items": {
69
+ "type": "number"
70
+ }
65
71
  }
66
72
  },
67
73
  "required": [
@@ -72,7 +78,8 @@
72
78
  "max_value",
73
79
  "min_values",
74
80
  "max_values",
75
- "no_data"
81
+ "no_data",
82
+ "time_steps"
76
83
  ],
77
84
  "additionalProperties": false
78
85
  }
@@ -28,6 +28,7 @@ class Attribute(DataClassJsonMixin):
28
28
  min_values: List[float]
29
29
  nb_items: int
30
30
  no_data: bool
31
+ time_steps: List[float]
31
32
 
32
33
 
33
34
  @dataclass
@@ -62,6 +62,12 @@
62
62
  },
63
63
  "no_data": {
64
64
  "type": "boolean"
65
+ },
66
+ "time_steps": {
67
+ "type": "array",
68
+ "items": {
69
+ "type": "number"
70
+ }
65
71
  }
66
72
  },
67
73
  "required": [
@@ -72,7 +78,8 @@
72
78
  "max_value",
73
79
  "min_values",
74
80
  "max_values",
75
- "no_data"
81
+ "no_data",
82
+ "time_steps"
76
83
  ],
77
84
  "additionalProperties": false
78
85
  }
@@ -28,6 +28,7 @@ class Attribute(DataClassJsonMixin):
28
28
  min_values: List[float]
29
29
  nb_items: int
30
30
  no_data: bool
31
+ time_steps: List[float]
31
32
 
32
33
 
33
34
  @dataclass
@@ -62,6 +62,12 @@
62
62
  },
63
63
  "no_data": {
64
64
  "type": "boolean"
65
+ },
66
+ "time_steps": {
67
+ "type": "array",
68
+ "items": {
69
+ "type": "number"
70
+ }
65
71
  }
66
72
  },
67
73
  "required": [
@@ -72,7 +78,8 @@
72
78
  "max_value",
73
79
  "min_values",
74
80
  "max_values",
75
- "no_data"
81
+ "no_data",
82
+ "time_steps"
76
83
  ],
77
84
  "additionalProperties": false
78
85
  }
@@ -28,6 +28,7 @@ class Attribute(DataClassJsonMixin):
28
28
  min_values: List[float]
29
29
  nb_items: int
30
30
  no_data: bool
31
+ time_steps: List[float]
31
32
 
32
33
 
33
34
  @dataclass
@@ -52,6 +52,12 @@
52
52
  },
53
53
  "no_data": {
54
54
  "type": "boolean"
55
+ },
56
+ "time_steps": {
57
+ "type": "array",
58
+ "items": {
59
+ "type": "number"
60
+ }
55
61
  }
56
62
  },
57
63
  "required": [
@@ -62,7 +68,8 @@
62
68
  "max_value",
63
69
  "min_values",
64
70
  "max_values",
65
- "no_data"
71
+ "no_data",
72
+ "time_steps"
66
73
  ],
67
74
  "additionalProperties": false
68
75
  }
@@ -27,6 +27,7 @@ class Attribute(DataClassJsonMixin):
27
27
  min_values: List[float]
28
28
  nb_items: int
29
29
  no_data: bool
30
+ time_steps: List[float]
30
31
 
31
32
 
32
33
  @dataclass
@@ -52,6 +52,12 @@
52
52
  },
53
53
  "no_data": {
54
54
  "type": "boolean"
55
+ },
56
+ "time_steps": {
57
+ "type": "array",
58
+ "items": {
59
+ "type": "number"
60
+ }
55
61
  }
56
62
  },
57
63
  "required": [
@@ -62,7 +68,8 @@
62
68
  "max_value",
63
69
  "min_values",
64
70
  "max_values",
65
- "no_data"
71
+ "no_data",
72
+ "time_steps"
66
73
  ],
67
74
  "additionalProperties": false
68
75
  }
@@ -27,6 +27,7 @@ class Attribute(DataClassJsonMixin):
27
27
  min_values: List[float]
28
28
  nb_items: int
29
29
  no_data: bool
30
+ time_steps: List[float]
30
31
 
31
32
 
32
33
  @dataclass
@@ -52,6 +52,12 @@
52
52
  },
53
53
  "no_data": {
54
54
  "type": "boolean"
55
+ },
56
+ "time_steps": {
57
+ "type": "array",
58
+ "items": {
59
+ "type": "number"
60
+ }
55
61
  }
56
62
  },
57
63
  "required": [
@@ -62,7 +68,8 @@
62
68
  "max_value",
63
69
  "min_values",
64
70
  "max_values",
65
- "no_data"
71
+ "no_data",
72
+ "time_steps"
66
73
  ],
67
74
  "additionalProperties": false
68
75
  }
@@ -27,6 +27,7 @@ class Attribute(DataClassJsonMixin):
27
27
  min_values: List[float]
28
28
  nb_items: int
29
29
  no_data: bool
30
+ time_steps: List[float]
30
31
 
31
32
 
32
33
  @dataclass
@@ -350,6 +350,8 @@ def test_vertex_attribute_names(client: FlaskClient) -> None:
350
350
  assert "max_values" in attribute
351
351
  assert "no_data" in attribute
352
352
  assert isinstance(attribute["no_data"], bool)
353
+ assert "time_steps" in attribute
354
+ assert isinstance(attribute["time_steps"], list)
353
355
 
354
356
 
355
357
  def test_cell_attribute_names(client: FlaskClient) -> None:
@@ -733,6 +735,8 @@ def _assert_attributes_response(response: TestResponse) -> None:
733
735
  assert "max_values" in attribute
734
736
  assert "no_data" in attribute
735
737
  assert isinstance(attribute["no_data"], bool)
738
+ assert "time_steps" in attribute
739
+ assert isinstance(attribute["time_steps"], list)
736
740
 
737
741
 
738
742
  def test_model_component_vertex_attribute_names(client: FlaskClient) -> None:
@@ -853,3 +857,32 @@ def test_component_id_length_is_strict(client: FlaskClient) -> None:
853
857
  model_id, _ = _load_brep_components(client)
854
858
  response = client.post(route, json={"id": model_id, "component_ids": ["a" * 32]})
855
859
  assert response.status_code == 400
860
+
861
+
862
+ def test_vertex_attribute_names_time_series(client: FlaskClient) -> None:
863
+ route = "/opengeodeweb_back/vertex_attribute_names"
864
+
865
+ with client.application.app_context():
866
+ file = str(data_dir / "time_series.og_psf3d")
867
+ data = Data.create(
868
+ geode_id=DUMMY_GEODE_ID,
869
+ geode_object=GeodePolygonalSurface3D.geode_object_type(),
870
+ viewer_object=GeodePolygonalSurface3D.viewer_type(),
871
+ viewer_elements_type=GeodePolygonalSurface3D.viewer_elements_type(),
872
+ )
873
+ data.native_file = file
874
+ session = get_session()
875
+ if session:
876
+ session.commit()
877
+
878
+ data_path = Path(geode_functions.data_file_path(data.id, data.native_file))
879
+ data_path.parent.mkdir(parents=True, exist_ok=True)
880
+ assert data_path.exists(), f"File not found at {data_path}"
881
+ response = client.post(route, json={"id": data.id})
882
+ assert response.status_code == 200
883
+ attributes = response.get_json()["attributes"]
884
+ temperature = [
885
+ attribute for attribute in attributes if attribute["attribute_name"] == "temperature"
886
+ ]
887
+ assert len(temperature) == 1
888
+ assert temperature[0]["time_steps"] == [0.5, 1.0, 2.0]