OpenGeodeWeb-Back 6.9.1__tar.gz → 6.9.2__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 (113) hide show
  1. {opengeodeweb_back-6.9.1/src/OpenGeodeWeb_Back.egg-info → opengeodeweb_back-6.9.2}/PKG-INFO +1 -1
  2. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/pyproject.toml +1 -1
  3. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2/src/OpenGeodeWeb_Back.egg-info}/PKG-INFO +1 -1
  4. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/app.py +56 -33
  5. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/app_config.py +10 -8
  6. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/geode_functions.py +1 -1
  7. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/blueprint_routes.py +27 -13
  8. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/tests/test_utils_functions.py +8 -6
  9. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/LICENSE +0 -0
  10. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/README.md +0 -0
  11. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/requirements.txt +0 -0
  12. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/setup.cfg +0 -0
  13. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/OpenGeodeWeb_Back.egg-info/SOURCES.txt +0 -0
  14. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/OpenGeodeWeb_Back.egg-info/dependency_links.txt +0 -0
  15. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/OpenGeodeWeb_Back.egg-info/entry_points.txt +0 -0
  16. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/OpenGeodeWeb_Back.egg-info/requires.txt +0 -0
  17. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/OpenGeodeWeb_Back.egg-info/top_level.txt +0 -0
  18. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/__init__.py +0 -0
  19. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/geode_objects/__init__.py +0 -0
  20. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/geode_objects/geode_brep.py +0 -0
  21. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/geode_objects/geode_cross_section.py +0 -0
  22. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/geode_objects/geode_edged_curve2d.py +0 -0
  23. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/geode_objects/geode_edged_curve3d.py +0 -0
  24. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/geode_objects/geode_graph.py +0 -0
  25. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/geode_objects/geode_grid2d.py +0 -0
  26. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/geode_objects/geode_grid3d.py +0 -0
  27. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/geode_objects/geode_hybrid_solid3d.py +0 -0
  28. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/geode_objects/geode_implicit_cross_section.py +0 -0
  29. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/geode_objects/geode_implicit_structural_model.py +0 -0
  30. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/geode_objects/geode_light_regular_grid2d.py +0 -0
  31. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/geode_objects/geode_light_regular_grid3d.py +0 -0
  32. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/geode_objects/geode_mesh.py +0 -0
  33. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/geode_objects/geode_model.py +0 -0
  34. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/geode_objects/geode_object.py +0 -0
  35. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/geode_objects/geode_point_set2d.py +0 -0
  36. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/geode_objects/geode_point_set3d.py +0 -0
  37. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/geode_objects/geode_polygonal_surface2d.py +0 -0
  38. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/geode_objects/geode_polygonal_surface3d.py +0 -0
  39. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/geode_objects/geode_polyhedral_solid3d.py +0 -0
  40. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/geode_objects/geode_raster_image2d.py +0 -0
  41. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/geode_objects/geode_raster_image3d.py +0 -0
  42. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/geode_objects/geode_regular_grid2d.py +0 -0
  43. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/geode_objects/geode_regular_grid3d.py +0 -0
  44. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/geode_objects/geode_section.py +0 -0
  45. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/geode_objects/geode_solid_mesh3d.py +0 -0
  46. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/geode_objects/geode_structural_model.py +0 -0
  47. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/geode_objects/geode_surface_mesh2d.py +0 -0
  48. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/geode_objects/geode_surface_mesh3d.py +0 -0
  49. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/geode_objects/geode_tetrahedral_solid3d.py +0 -0
  50. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/geode_objects/geode_triangulated_surface2d.py +0 -0
  51. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/geode_objects/geode_triangulated_surface3d.py +0 -0
  52. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/geode_objects/geode_vertex_set.py +0 -0
  53. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/py.typed +0 -0
  54. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/create/blueprint_create.py +0 -0
  55. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/create/schemas/__init__.py +0 -0
  56. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/create/schemas/edged_curve.json +0 -0
  57. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/create/schemas/edged_curve.py +0 -0
  58. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/create/schemas/point_set.json +0 -0
  59. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/create/schemas/point_set.py +0 -0
  60. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/create/schemas/polygonal_surface.json +0 -0
  61. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/create/schemas/polygonal_surface.py +0 -0
  62. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/schemas/__init__.py +0 -0
  63. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/schemas/allowed_files.json +0 -0
  64. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/schemas/allowed_files.py +0 -0
  65. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/schemas/allowed_objects.json +0 -0
  66. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/schemas/allowed_objects.py +0 -0
  67. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/schemas/cell_attribute_names.json +0 -0
  68. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/schemas/cell_attribute_names.py +0 -0
  69. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/schemas/edge_attribute_names.json +0 -0
  70. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/schemas/edge_attribute_names.py +0 -0
  71. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/schemas/export_project.json +0 -0
  72. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/schemas/export_project.py +0 -0
  73. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/schemas/geode_object_inheritance.json +0 -0
  74. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/schemas/geode_object_inheritance.py +0 -0
  75. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/schemas/geode_objects_and_output_extensions.json +0 -0
  76. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/schemas/geode_objects_and_output_extensions.py +0 -0
  77. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/schemas/geographic_coordinate_systems.json +0 -0
  78. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/schemas/geographic_coordinate_systems.py +0 -0
  79. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/schemas/import_project.json +0 -0
  80. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/schemas/import_project.py +0 -0
  81. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/schemas/inspect_file.json +0 -0
  82. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/schemas/inspect_file.py +0 -0
  83. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/schemas/kill.json +0 -0
  84. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/schemas/kill.py +0 -0
  85. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/schemas/missing_files.json +0 -0
  86. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/schemas/missing_files.py +0 -0
  87. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/schemas/model_component_edge_attribute_names.json +0 -0
  88. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/schemas/model_component_edge_attribute_names.py +0 -0
  89. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/schemas/model_component_polygon_attribute_names.json +0 -0
  90. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/schemas/model_component_polygon_attribute_names.py +0 -0
  91. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/schemas/model_component_polyhedron_attribute_names.json +0 -0
  92. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/schemas/model_component_polyhedron_attribute_names.py +0 -0
  93. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/schemas/model_component_vertex_attribute_names.json +0 -0
  94. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/schemas/model_component_vertex_attribute_names.py +0 -0
  95. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/schemas/ping.json +0 -0
  96. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/schemas/ping.py +0 -0
  97. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/schemas/polygon_attribute_names.json +0 -0
  98. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/schemas/polygon_attribute_names.py +0 -0
  99. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/schemas/polyhedron_attribute_names.json +0 -0
  100. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/schemas/polyhedron_attribute_names.py +0 -0
  101. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/schemas/save_viewable_file.json +0 -0
  102. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/schemas/save_viewable_file.py +0 -0
  103. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/schemas/texture_coordinates.json +0 -0
  104. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/schemas/texture_coordinates.py +0 -0
  105. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/schemas/upload_file.json +0 -0
  106. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/schemas/upload_file.py +0 -0
  107. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/schemas/vertex_attribute_names.json +0 -0
  108. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/routes/schemas/vertex_attribute_names.py +0 -0
  109. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/test_utils.py +0 -0
  110. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/src/opengeodeweb_back/utils_functions.py +0 -0
  111. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/tests/test_create_routes.py +0 -0
  112. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/tests/test_geode_functions.py +0 -0
  113. {opengeodeweb_back-6.9.1 → opengeodeweb_back-6.9.2}/tests/test_routes.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: OpenGeodeWeb-Back
3
- Version: 6.9.1
3
+ Version: 6.9.2
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
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "OpenGeodeWeb-Back"
7
- version = "6.9.1"
7
+ version = "6.9.2"
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"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: OpenGeodeWeb-Back
3
- Version: 6.9.1
3
+ Version: 6.9.2
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
@@ -18,15 +18,6 @@ from opengeodeweb_microservice.database import connection
18
18
  def create_app(name: str) -> flask.Flask:
19
19
  app = flask.Flask(name)
20
20
 
21
- """ Config variables """
22
- FLASK_DEBUG = (
23
- True if os.environ.get("FLASK_DEBUG", default=None) == "True" else False
24
- )
25
- if FLASK_DEBUG == False:
26
- app.config.from_object(app_config.ProdConfig)
27
- else:
28
- app.config.from_object(app_config.DevConfig)
29
-
30
21
  @app.before_request
31
22
  def before_request() -> flask.Response | None:
32
23
  if flask.request.method == "OPTIONS":
@@ -96,78 +87,110 @@ def register_ogw_back_blueprints(app: flask.Flask) -> None:
96
87
 
97
88
 
98
89
  def run_server(app: Flask) -> None:
90
+ pre_parser = argparse.ArgumentParser(add_help=False)
91
+ pre_parser.add_argument("-d", "--debug", action="store_true", default=False)
92
+ pre_parser.add_argument("-pfp", "--project_folder_path", type=str)
93
+ pre_args, _ = pre_parser.parse_known_args()
94
+
95
+ if pre_args.project_folder_path is None:
96
+ raise ValueError("project_folder_path must be provided")
97
+ project_folder_path = os.path.abspath(pre_args.project_folder_path)
98
+
99
+ if pre_args.debug:
100
+ app.config.from_object(app_config.DevConfig(project_folder_path))
101
+ else:
102
+ app.config.from_object(app_config.ProdConfig(project_folder_path))
103
+
99
104
  parser = argparse.ArgumentParser(
100
105
  prog="OpenGeodeWeb-Back", description="Backend server for OpenGeodeWeb"
101
106
  )
102
107
  parser.add_argument(
103
- "--host",
104
- type=str,
105
- default=app.config.get("DEFAULT_HOST"),
106
- help="Host to run on",
108
+ "--host", default=app.config.get("HOST"), type=str, help="Host to run on"
107
109
  )
108
110
  parser.add_argument(
109
111
  "-p",
110
112
  "--port",
111
- type=int,
112
- default=app.config.get("DEFAULT_PORT"),
113
+ default=app.config.get("PORT"),
114
+ type=str,
113
115
  help="Port to listen on",
114
116
  )
115
117
  parser.add_argument(
116
118
  "-d",
117
119
  "--debug",
118
- default=app.config.get("FLASK_DEBUG"),
119
- help="Whether to run in debug mode",
120
+ default=pre_args.debug,
120
121
  action="store_true",
122
+ help="Whether to run in debug mode",
123
+ )
124
+ parser.add_argument(
125
+ "-pfp",
126
+ "--project_folder_path",
127
+ default=project_folder_path,
128
+ type=str,
129
+ help="Path to the folder where the project is stored",
121
130
  )
122
131
  parser.add_argument(
123
132
  "-dfp",
124
133
  "--data_folder_path",
134
+ default=app.config.get("DATA_FOLDER_PATH"),
125
135
  type=str,
126
- default=app.config.get("DEFAULT_DATA_FOLDER_PATH"),
127
- help="Path to the folder where data is stored",
136
+ help="Path to the folder where the data is stored",
128
137
  )
129
138
  parser.add_argument(
130
139
  "-ufp",
131
140
  "--upload_folder_path",
141
+ default=app.config.get("UPLOAD_FOLDER_PATH"),
132
142
  type=str,
133
- default=app.config.get("UPLOAD_FOLDER"),
134
143
  help="Path to the folder where uploads are stored",
135
144
  )
136
145
  parser.add_argument(
137
146
  "-origins",
138
147
  "--allowed_origins",
139
- nargs="+",
140
148
  default=app.config.get("ORIGINS"),
149
+ nargs="+",
141
150
  help="Origins that are allowed to connect to the server",
142
151
  )
143
152
  parser.add_argument(
144
153
  "-t",
145
154
  "--timeout",
146
155
  default=app.config.get("MINUTES_BEFORE_TIMEOUT"),
156
+ type=int,
147
157
  help="Number of minutes before the server times out",
148
158
  )
149
- args, _ = parser.parse_known_args()
150
- app.config.update(DATA_FOLDER_PATH=args.data_folder_path)
159
+ args = parser.parse_args()
160
+
161
+ args.project_folder_path = os.path.abspath(args.project_folder_path)
162
+
163
+ print(f"{args=}", flush=True)
164
+
151
165
  app.config.update(
152
- EXTENSIONS_FOLDER_PATH=os.path.join(str(args.data_folder_path), "extensions")
166
+ HOST=args.host,
167
+ PORT=args.port,
168
+ FLASK_DEBUG=args.debug,
169
+ PROJECT_FOLDER_PATH=args.project_folder_path,
170
+ DATA_FOLDER_PATH=args.data_folder_path,
171
+ UPLOAD_FOLDER_PATH=args.upload_folder_path,
172
+ ALLOWED_ORIGINS=args.allowed_origins,
173
+ MINUTES_BEFORE_TIMEOUT=args.timeout,
153
174
  )
154
- app.config.update(UPLOAD_FOLDER=args.upload_folder_path)
155
- app.config.update(MINUTES_BEFORE_TIMEOUT=args.timeout)
156
- flask_cors.CORS(app, origins=args.allowed_origins)
157
- print(f"{args=}", flush=True)
158
175
 
159
- db_filename: str = app.config.get("DATABASE_FILENAME") or "project.db"
160
- db_path = os.path.join(str(args.data_folder_path), db_filename)
176
+ db_filename = app.config.get("DATABASE_FILENAME")
177
+ if not isinstance(db_filename, str):
178
+ raise TypeError(
179
+ f"DATABASE_FILENAME config must be a string, got {db_filename!r}"
180
+ )
181
+ db_path = os.path.join(str(app.config.get("DATA_FOLDER_PATH")), db_filename)
161
182
  os.makedirs(os.path.dirname(db_path), exist_ok=True)
162
183
  app.config["SQLALCHEMY_DATABASE_URI"] = f"sqlite:///{db_path}"
163
184
  app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
164
185
 
165
186
  connection.init_database(db_path)
166
187
  print(f"Database initialized at: {db_path}", flush=True)
188
+
189
+ flask_cors.CORS(app, origins=args.allowed_origins)
167
190
  app.run(
168
- debug=args.debug,
169
- host=args.host,
170
- port=args.port,
191
+ debug=app.config.get("FLASK_DEBUG"),
192
+ host=app.config.get("HOST"),
193
+ port=app.config.get("PORT"),
171
194
  ssl_context=app.config.get("SSL"),
172
195
  )
173
196
 
@@ -5,26 +5,31 @@ import time
5
5
  # Third party imports
6
6
  # Local application imports
7
7
 
8
+ base_dir = os.path.dirname(os.path.abspath(__file__))
9
+
8
10
 
9
11
  class Config(object):
10
12
  FLASK_DEBUG = os.environ.get("FLASK_DEBUG", default=False)
11
- DEFAULT_HOST = "localhost"
12
- DEFAULT_PORT = "5000"
13
+ HOST = "localhost"
14
+ PORT = "5000"
13
15
  CORS_HEADERS = "Content-Type"
14
- UPLOAD_FOLDER = "./uploads"
15
16
  REQUEST_COUNTER = 0
16
17
  LAST_REQUEST_TIME = time.time()
17
18
  LAST_PING_TIME = time.time()
18
19
  DATABASE_FILENAME = "project.db"
19
20
 
21
+ def __init__(self, project_folder_path: str):
22
+ self.PROJECT_FOLDER_PATH = project_folder_path
23
+ self.DATA_FOLDER_PATH = os.path.join(project_folder_path, "data")
24
+ self.EXTENSIONS_FOLDER_PATH = os.path.join(project_folder_path, "extensions")
25
+ self.UPLOAD_FOLDER_PATH = os.path.join(project_folder_path, "uploads")
26
+
20
27
 
21
28
  class ProdConfig(Config):
22
29
  SSL = None
23
30
  ORIGINS = ""
24
31
  MINUTES_BEFORE_TIMEOUT = "1"
25
32
  SECONDS_BETWEEN_SHUTDOWNS = "10"
26
- DATA_FOLDER_PATH = "/data"
27
- EXTENSIONS_FOLDER_PATH = os.path.join(DATA_FOLDER_PATH, "extensions")
28
33
 
29
34
 
30
35
  class DevConfig(Config):
@@ -32,6 +37,3 @@ class DevConfig(Config):
32
37
  ORIGINS = "*"
33
38
  MINUTES_BEFORE_TIMEOUT = "1"
34
39
  SECONDS_BETWEEN_SHUTDOWNS = "10"
35
- BASE_DIR = os.path.dirname(os.path.abspath(__file__))
36
- DATA_FOLDER_PATH = os.path.join(BASE_DIR, "data")
37
- EXTENSIONS_FOLDER_PATH = os.path.join(DATA_FOLDER_PATH, "extensions")
@@ -46,7 +46,7 @@ def get_data_info(data_id: str) -> Data:
46
46
 
47
47
 
48
48
  def upload_file_path(filename: str) -> str:
49
- upload_folder = flask.current_app.config["UPLOAD_FOLDER"]
49
+ upload_folder = flask.current_app.config["UPLOAD_FOLDER_PATH"]
50
50
  secure_filename = werkzeug.utils.secure_filename(filename)
51
51
  return os.path.abspath(os.path.join(upload_folder, secure_filename))
52
52
 
@@ -66,20 +66,22 @@ def allowed_files() -> flask.Response:
66
66
  methods=schemas_dict["upload_file"]["methods"],
67
67
  )
68
68
  def upload_file() -> flask.Response:
69
- UPLOAD_FOLDER = flask.current_app.config["UPLOAD_FOLDER"]
70
- print(f"{UPLOAD_FOLDER=}", flush=True)
71
- if not os.path.exists(UPLOAD_FOLDER):
72
- os.makedirs(UPLOAD_FOLDER, exist_ok=True)
69
+ UPLOAD_FOLDER_PATH = flask.current_app.config["UPLOAD_FOLDER_PATH"]
70
+ print(f"{UPLOAD_FOLDER_PATH=}", flush=True)
71
+ if not os.path.exists(UPLOAD_FOLDER_PATH):
72
+ os.makedirs(UPLOAD_FOLDER_PATH, exist_ok=True)
73
73
 
74
74
  file = flask.request.files["file"]
75
75
  if file.filename is None:
76
76
  flask.abort(400, "Filename is required")
77
77
  filename = werkzeug.utils.secure_filename(os.path.basename(file.filename))
78
78
  print(f"{filename=}", flush=True)
79
- file_path = os.path.join(UPLOAD_FOLDER, filename)
79
+ file_path = os.path.join(UPLOAD_FOLDER_PATH, filename)
80
80
  file.save(file_path)
81
81
  if filename.lower().endswith(".csv.json"):
82
- shutil.copyfile(file_path, os.path.join(UPLOAD_FOLDER, filename[:-9] + ".json"))
82
+ shutil.copyfile(
83
+ file_path, os.path.join(UPLOAD_FOLDER_PATH, filename[:-9] + ".json")
84
+ )
83
85
  return flask.make_response({"message": "File uploaded"}, 201)
84
86
 
85
87
 
@@ -547,10 +549,11 @@ def export_project() -> flask.Response:
547
549
  for data_id, native_file in rows:
548
550
  base_dir = os.path.join(project_folder, data_id)
549
551
  if os.path.isdir(base_dir):
550
- for f_name in os.listdir(base_dir):
551
- file_path = os.path.join(base_dir, f_name)
552
- if os.path.isfile(file_path):
553
- zip_file.write(file_path, os.path.join(data_id, f_name))
552
+ for root, directories, files in os.walk(base_dir):
553
+ for file_name in files:
554
+ file_path = os.path.join(root, file_name)
555
+ relative_path = os.path.relpath(file_path, base_dir)
556
+ zip_file.write(file_path, os.path.join(data_id, relative_path))
554
557
 
555
558
  zip_file.writestr("snapshot.json", flask.json.dumps(params.snapshot))
556
559
 
@@ -584,8 +587,13 @@ def import_project() -> flask.Response:
584
587
 
585
588
  try:
586
589
  if os.path.exists(data_folder_path):
587
- shutil.rmtree(data_folder_path)
588
- os.makedirs(data_folder_path, exist_ok=True)
590
+ for item in os.scandir(data_folder_path):
591
+ if item.is_dir(follow_symlinks=False):
592
+ shutil.rmtree(item.path)
593
+ else:
594
+ os.remove(item.path)
595
+ else:
596
+ os.makedirs(data_folder_path, exist_ok=True)
589
597
  except PermissionError:
590
598
  flask.abort(423, "Project files are locked; cannot overwrite")
591
599
 
@@ -622,7 +630,13 @@ def import_project() -> flask.Response:
622
630
  viewable_name = data.viewable_file
623
631
  if viewable_name:
624
632
  vpath = geode_functions.data_file_path(data.id, viewable_name)
625
- if os.path.isfile(vpath):
633
+ viewable_dir = os.path.join(data_path, "viewable")
634
+ has_components = os.path.isdir(viewable_dir) and bool(
635
+ os.listdir(viewable_dir)
636
+ )
637
+ if os.path.isfile(vpath) and (
638
+ data.viewer_object != "model" or has_components
639
+ ):
626
640
  continue
627
641
 
628
642
  native_file = str(data.native_file or "")
@@ -232,7 +232,7 @@ def test_generate_native_viewable_and_light_viewable_from_file_with_multi_dots(
232
232
  def test_send_file_multiple_returns_zip(client: FlaskClient, tmp_path: Path) -> None:
233
233
  app = client.application
234
234
  with app.app_context():
235
- app.config["UPLOAD_FOLDER"] = str(tmp_path)
235
+ app.config["UPLOAD_FOLDER_PATH"] = str(tmp_path)
236
236
  file_paths = []
237
237
  for i, content in [(1, b"hello 1"), (2, b"hello 2")]:
238
238
  file_path = tmp_path / f"tmp_send_file_{i}.txt"
@@ -240,13 +240,13 @@ def test_send_file_multiple_returns_zip(client: FlaskClient, tmp_path: Path) ->
240
240
  file_paths.append(str(file_path))
241
241
  with app.test_request_context():
242
242
  response = utils_functions.send_file(
243
- app.config["UPLOAD_FOLDER"], file_paths, "bundle"
243
+ app.config["UPLOAD_FOLDER_PATH"], file_paths, "bundle"
244
244
  )
245
245
  assert response.status_code == 200
246
246
  assert response.mimetype == "application/zip"
247
247
  new_file_name = response.headers.get("new-file-name")
248
248
  assert new_file_name == "bundle.zip"
249
- zip_path = os.path.join(app.config["UPLOAD_FOLDER"], new_file_name)
249
+ zip_path = os.path.join(app.config["UPLOAD_FOLDER_PATH"], new_file_name)
250
250
  with zipfile.ZipFile(zip_path, "r") as zip_file:
251
251
  zip_entries = zip_file.namelist()
252
252
  assert "tmp_send_file_1.txt" in zip_entries
@@ -259,18 +259,20 @@ def test_send_file_single_returns_octet_binary(
259
259
  ) -> None:
260
260
  app = client.application
261
261
  with app.app_context():
262
- app.config["UPLOAD_FOLDER"] = str(tmp_path)
262
+ app.config["UPLOAD_FOLDER_PATH"] = str(tmp_path)
263
263
  file_path = tmp_path / "tmp_send_file_1.txt"
264
264
  file_path.write_bytes(b"hello 1")
265
265
  with app.test_request_context():
266
266
  response = utils_functions.send_file(
267
- app.config["UPLOAD_FOLDER"], [str(file_path)], "tmp_send_file_1.txt"
267
+ app.config["UPLOAD_FOLDER_PATH"],
268
+ [str(file_path)],
269
+ "tmp_send_file_1.txt",
268
270
  )
269
271
  assert response.status_code == 200
270
272
  assert response.mimetype == "application/octet-binary"
271
273
  new_file_name = response.headers.get("new-file-name")
272
274
  assert new_file_name == "tmp_send_file_1.txt"
273
- zip_path = os.path.join(app.config["UPLOAD_FOLDER"], new_file_name)
275
+ zip_path = os.path.join(app.config["UPLOAD_FOLDER_PATH"], new_file_name)
274
276
  with open(zip_path, "rb") as f:
275
277
  file_bytes = f.read()
276
278
  assert file_bytes == b"hello 1"