OpenGeodeWeb-Back 4.3.1__tar.gz → 5.0.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 (30) hide show
  1. {opengeodeweb_back-4.3.1/src/OpenGeodeWeb_Back.egg-info → opengeodeweb_back-5.0.0}/PKG-INFO +18 -17
  2. {opengeodeweb_back-4.3.1 → opengeodeweb_back-5.0.0}/pyproject.toml +1 -1
  3. {opengeodeweb_back-4.3.1 → opengeodeweb_back-5.0.0}/requirements.txt +23 -18
  4. {opengeodeweb_back-4.3.1 → opengeodeweb_back-5.0.0/src/OpenGeodeWeb_Back.egg-info}/PKG-INFO +18 -17
  5. {opengeodeweb_back-4.3.1 → opengeodeweb_back-5.0.0}/src/OpenGeodeWeb_Back.egg-info/SOURCES.txt +6 -2
  6. opengeodeweb_back-5.0.0/src/OpenGeodeWeb_Back.egg-info/requires.txt +28 -0
  7. opengeodeweb_back-5.0.0/src/opengeodeweb_back/app_config.py +33 -0
  8. {opengeodeweb_back-4.3.1 → opengeodeweb_back-5.0.0}/src/opengeodeweb_back/geode_functions.py +4 -115
  9. {opengeodeweb_back-4.3.1 → opengeodeweb_back-5.0.0}/src/opengeodeweb_back/routes/blueprint_routes.py +39 -13
  10. opengeodeweb_back-5.0.0/src/opengeodeweb_back/routes/schemas/ping.json +10 -0
  11. opengeodeweb_back-5.0.0/src/opengeodeweb_back/utils_functions.py +131 -0
  12. opengeodeweb_back-4.3.1/tests/test_functions.py → opengeodeweb_back-5.0.0/tests/test_geode_functions.py +0 -30
  13. opengeodeweb_back-5.0.0/tests/test_utils_functions.py +50 -0
  14. opengeodeweb_back-4.3.1/src/OpenGeodeWeb_Back.egg-info/requires.txt +0 -27
  15. {opengeodeweb_back-4.3.1 → opengeodeweb_back-5.0.0}/LICENSE +0 -0
  16. {opengeodeweb_back-4.3.1 → opengeodeweb_back-5.0.0}/README.md +0 -0
  17. {opengeodeweb_back-4.3.1 → opengeodeweb_back-5.0.0}/setup.cfg +0 -0
  18. {opengeodeweb_back-4.3.1 → opengeodeweb_back-5.0.0}/src/OpenGeodeWeb_Back.egg-info/dependency_links.txt +0 -0
  19. {opengeodeweb_back-4.3.1 → opengeodeweb_back-5.0.0}/src/OpenGeodeWeb_Back.egg-info/top_level.txt +0 -0
  20. {opengeodeweb_back-4.3.1 → opengeodeweb_back-5.0.0}/src/opengeodeweb_back/__init__.py +0 -0
  21. {opengeodeweb_back-4.3.1 → opengeodeweb_back-5.0.0}/src/opengeodeweb_back/geode_objects.py +0 -0
  22. {opengeodeweb_back-4.3.1 → opengeodeweb_back-5.0.0}/src/opengeodeweb_back/routes/schemas/allowed_files.json +0 -0
  23. {opengeodeweb_back-4.3.1 → opengeodeweb_back-5.0.0}/src/opengeodeweb_back/routes/schemas/allowed_objects.json +0 -0
  24. {opengeodeweb_back-4.3.1 → opengeodeweb_back-5.0.0}/src/opengeodeweb_back/routes/schemas/geode_objects_and_output_extensions.json +0 -0
  25. {opengeodeweb_back-4.3.1 → opengeodeweb_back-5.0.0}/src/opengeodeweb_back/routes/schemas/geographic_coordinate_systems.json +0 -0
  26. {opengeodeweb_back-4.3.1 → opengeodeweb_back-5.0.0}/src/opengeodeweb_back/routes/schemas/inspect_file.json +0 -0
  27. {opengeodeweb_back-4.3.1 → opengeodeweb_back-5.0.0}/src/opengeodeweb_back/routes/schemas/missing_files.json +0 -0
  28. {opengeodeweb_back-4.3.1 → opengeodeweb_back-5.0.0}/src/opengeodeweb_back/routes/schemas/save_viewable_file.json +0 -0
  29. {opengeodeweb_back-4.3.1 → opengeodeweb_back-5.0.0}/src/opengeodeweb_back/routes/schemas/upload_file.json +0 -0
  30. {opengeodeweb_back-4.3.1 → opengeodeweb_back-5.0.0}/tests/test_routes.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: OpenGeodeWeb-Back
3
- Version: 4.3.1
3
+ Version: 5.0.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
@@ -12,31 +12,32 @@ Requires-Python: >=3.8
12
12
  Description-Content-Type: text/markdown
13
13
  License-File: LICENSE
14
14
  Requires-Dist: asgiref==3.8.1
15
- Requires-Dist: attrs==23.2.0
15
+ Requires-Dist: attrs==24.2.0
16
16
  Requires-Dist: blinker==1.8.2
17
17
  Requires-Dist: click==8.1.7
18
18
  Requires-Dist: flask[async]==3.0.3
19
19
  Requires-Dist: flask-cors==4.0.1
20
- Requires-Dist: geode-background==7.12.0
21
- Requires-Dist: geode-common==31.2.1
22
- Requires-Dist: geode-conversion==5.4.1
23
- Requires-Dist: geode-explicit==4.8.3
24
- Requires-Dist: geode-implicit==2.8.7
25
- Requires-Dist: geode-numerics==4.4.0
26
- Requires-Dist: geode-simplex==6.8.3
27
- Requires-Dist: geode-viewables==2.2.3
20
+ Requires-Dist: geode-background==8.1.1
21
+ Requires-Dist: geode-common==32.0.8
22
+ Requires-Dist: geode-conversion==6.0.3
23
+ Requires-Dist: geode-explicit==6.0.1
24
+ Requires-Dist: geode-implicit==3.1.1
25
+ Requires-Dist: geode-numerics==5.0.2
26
+ Requires-Dist: geode-simplex==8.2.1
27
+ Requires-Dist: geode-viewables==3.0.0
28
28
  Requires-Dist: itsdangerous==2.2.0
29
29
  Requires-Dist: jinja2==3.1.4
30
- Requires-Dist: jsonschema==4.22.0
30
+ Requires-Dist: jsonschema==4.23.0
31
31
  Requires-Dist: jsonschema-specifications==2023.12.1
32
32
  Requires-Dist: markupsafe==2.1.5
33
- Requires-Dist: opengeode-core==14.21.3
34
- Requires-Dist: opengeode-geosciences==7.7.0
35
- Requires-Dist: opengeode-geosciencesio==4.7.7
36
- Requires-Dist: opengeode-inspector==5.1.4
37
- Requires-Dist: opengeode-io==6.5.1
33
+ Requires-Dist: opengeode-core==15.2.1
34
+ Requires-Dist: opengeode-geosciences==8.0.0
35
+ Requires-Dist: opengeode-geosciencesio==5.0.1
36
+ Requires-Dist: opengeode-inspector==6.0.0
37
+ Requires-Dist: opengeode-io==7.0.1
38
38
  Requires-Dist: referencing==0.35.1
39
- Requires-Dist: rpds-py==0.18.1
39
+ Requires-Dist: rpds-py==0.20.0
40
+ Requires-Dist: typing-extensions==4.12.2
40
41
  Requires-Dist: werkzeug==3.0.3
41
42
 
42
43
  <h1 align="center">OpenGeodeWeb-Back<sup><i>by Geode-solutions</i></sup></h1>
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
5
5
 
6
6
  [project]
7
7
  name = "OpenGeodeWeb-Back"
8
- version = "4.3.1"
8
+ version = "5.0.0"
9
9
  dynamic = ["dependencies"]
10
10
  authors = [
11
11
  { name="Geode-solutions", email="team-web@geode-solutions.com" },
@@ -1,12 +1,12 @@
1
1
  #
2
- # This file is autogenerated by pip-compile with Python 3.11
2
+ # This file is autogenerated by pip-compile with Python 3.10
3
3
  # by the following command:
4
4
  #
5
5
  # pip-compile requirements.in
6
6
  #
7
7
  asgiref==3.8.1
8
8
  # via flask
9
- attrs==23.2.0
9
+ attrs==24.2.0
10
10
  # via
11
11
  # jsonschema
12
12
  # referencing
@@ -20,44 +20,47 @@ flask[async]==3.0.3
20
20
  # flask-cors
21
21
  flask-cors==4.0.1
22
22
  # via -r requirements.in
23
- geode-background==7.12.0
23
+ geode-background==8.1.1
24
24
  # via
25
25
  # geode-explicit
26
26
  # geode-implicit
27
27
  # geode-simplex
28
- geode-common==31.2.1
28
+ geode-common==32.0.8
29
29
  # via
30
30
  # -r requirements.in
31
31
  # geode-background
32
+ # geode-conversion
32
33
  # geode-explicit
33
34
  # geode-implicit
34
35
  # geode-numerics
35
36
  # geode-simplex
36
37
  # geode-viewables
37
- geode-conversion==5.4.1
38
+ geode-conversion==6.0.3
38
39
  # via
39
40
  # geode-explicit
40
41
  # geode-implicit
41
- geode-explicit==4.8.3
42
+ geode-explicit==6.0.1
42
43
  # via
43
44
  # -r requirements.in
44
45
  # geode-implicit
45
- geode-implicit==2.8.7
46
+ geode-implicit==3.1.1
46
47
  # via -r requirements.in
47
- geode-numerics==4.4.0
48
+ geode-numerics==5.0.2
48
49
  # via
49
50
  # -r requirements.in
50
51
  # geode-implicit
51
52
  # geode-simplex
52
- geode-simplex==6.8.3
53
- # via -r requirements.in
54
- geode-viewables==2.2.3
53
+ geode-simplex==8.2.1
54
+ # via
55
+ # -r requirements.in
56
+ # geode-implicit
57
+ geode-viewables==3.0.0
55
58
  # via -r requirements.in
56
59
  itsdangerous==2.2.0
57
60
  # via flask
58
61
  jinja2==3.1.4
59
62
  # via flask
60
- jsonschema==4.22.0
63
+ jsonschema==4.23.0
61
64
  # via -r requirements.in
62
65
  jsonschema-specifications==2023.12.1
63
66
  # via jsonschema
@@ -65,7 +68,7 @@ markupsafe==2.1.5
65
68
  # via
66
69
  # jinja2
67
70
  # werkzeug
68
- opengeode-core==14.21.3
71
+ opengeode-core==15.2.1
69
72
  # via
70
73
  # -r requirements.in
71
74
  # geode-background
@@ -80,23 +83,23 @@ opengeode-core==14.21.3
80
83
  # opengeode-geosciencesio
81
84
  # opengeode-inspector
82
85
  # opengeode-io
83
- opengeode-geosciences==7.7.0
86
+ opengeode-geosciences==8.0.0
84
87
  # via
85
88
  # -r requirements.in
86
89
  # geode-implicit
87
90
  # geode-viewables
88
91
  # opengeode-geosciencesio
89
- opengeode-geosciencesio==4.7.7
92
+ opengeode-geosciencesio==5.0.1
90
93
  # via
91
94
  # -r requirements.in
92
95
  # geode-implicit
93
- opengeode-inspector==5.1.4
96
+ opengeode-inspector==6.0.0
94
97
  # via
95
98
  # -r requirements.in
96
99
  # geode-explicit
97
100
  # geode-implicit
98
101
  # geode-simplex
99
- opengeode-io==6.5.1
102
+ opengeode-io==7.0.1
100
103
  # via
101
104
  # -r requirements.in
102
105
  # geode-implicit
@@ -106,10 +109,12 @@ referencing==0.35.1
106
109
  # via
107
110
  # jsonschema
108
111
  # jsonschema-specifications
109
- rpds-py==0.18.1
112
+ rpds-py==0.20.0
110
113
  # via
111
114
  # jsonschema
112
115
  # referencing
116
+ typing-extensions==4.12.2
117
+ # via asgiref
113
118
  werkzeug==3.0.3
114
119
  # via
115
120
  # -r requirements.in
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: OpenGeodeWeb-Back
3
- Version: 4.3.1
3
+ Version: 5.0.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
@@ -12,31 +12,32 @@ Requires-Python: >=3.8
12
12
  Description-Content-Type: text/markdown
13
13
  License-File: LICENSE
14
14
  Requires-Dist: asgiref==3.8.1
15
- Requires-Dist: attrs==23.2.0
15
+ Requires-Dist: attrs==24.2.0
16
16
  Requires-Dist: blinker==1.8.2
17
17
  Requires-Dist: click==8.1.7
18
18
  Requires-Dist: flask[async]==3.0.3
19
19
  Requires-Dist: flask-cors==4.0.1
20
- Requires-Dist: geode-background==7.12.0
21
- Requires-Dist: geode-common==31.2.1
22
- Requires-Dist: geode-conversion==5.4.1
23
- Requires-Dist: geode-explicit==4.8.3
24
- Requires-Dist: geode-implicit==2.8.7
25
- Requires-Dist: geode-numerics==4.4.0
26
- Requires-Dist: geode-simplex==6.8.3
27
- Requires-Dist: geode-viewables==2.2.3
20
+ Requires-Dist: geode-background==8.1.1
21
+ Requires-Dist: geode-common==32.0.8
22
+ Requires-Dist: geode-conversion==6.0.3
23
+ Requires-Dist: geode-explicit==6.0.1
24
+ Requires-Dist: geode-implicit==3.1.1
25
+ Requires-Dist: geode-numerics==5.0.2
26
+ Requires-Dist: geode-simplex==8.2.1
27
+ Requires-Dist: geode-viewables==3.0.0
28
28
  Requires-Dist: itsdangerous==2.2.0
29
29
  Requires-Dist: jinja2==3.1.4
30
- Requires-Dist: jsonschema==4.22.0
30
+ Requires-Dist: jsonschema==4.23.0
31
31
  Requires-Dist: jsonschema-specifications==2023.12.1
32
32
  Requires-Dist: markupsafe==2.1.5
33
- Requires-Dist: opengeode-core==14.21.3
34
- Requires-Dist: opengeode-geosciences==7.7.0
35
- Requires-Dist: opengeode-geosciencesio==4.7.7
36
- Requires-Dist: opengeode-inspector==5.1.4
37
- Requires-Dist: opengeode-io==6.5.1
33
+ Requires-Dist: opengeode-core==15.2.1
34
+ Requires-Dist: opengeode-geosciences==8.0.0
35
+ Requires-Dist: opengeode-geosciencesio==5.0.1
36
+ Requires-Dist: opengeode-inspector==6.0.0
37
+ Requires-Dist: opengeode-io==7.0.1
38
38
  Requires-Dist: referencing==0.35.1
39
- Requires-Dist: rpds-py==0.18.1
39
+ Requires-Dist: rpds-py==0.20.0
40
+ Requires-Dist: typing-extensions==4.12.2
40
41
  Requires-Dist: werkzeug==3.0.3
41
42
 
42
43
  <h1 align="center">OpenGeodeWeb-Back<sup><i>by Geode-solutions</i></sup></h1>
@@ -8,8 +8,10 @@ src/OpenGeodeWeb_Back.egg-info/dependency_links.txt
8
8
  src/OpenGeodeWeb_Back.egg-info/requires.txt
9
9
  src/OpenGeodeWeb_Back.egg-info/top_level.txt
10
10
  src/opengeodeweb_back/__init__.py
11
+ src/opengeodeweb_back/app_config.py
11
12
  src/opengeodeweb_back/geode_functions.py
12
13
  src/opengeodeweb_back/geode_objects.py
14
+ src/opengeodeweb_back/utils_functions.py
13
15
  src/opengeodeweb_back/routes/blueprint_routes.py
14
16
  src/opengeodeweb_back/routes/schemas/allowed_files.json
15
17
  src/opengeodeweb_back/routes/schemas/allowed_objects.json
@@ -17,7 +19,9 @@ src/opengeodeweb_back/routes/schemas/geode_objects_and_output_extensions.json
17
19
  src/opengeodeweb_back/routes/schemas/geographic_coordinate_systems.json
18
20
  src/opengeodeweb_back/routes/schemas/inspect_file.json
19
21
  src/opengeodeweb_back/routes/schemas/missing_files.json
22
+ src/opengeodeweb_back/routes/schemas/ping.json
20
23
  src/opengeodeweb_back/routes/schemas/save_viewable_file.json
21
24
  src/opengeodeweb_back/routes/schemas/upload_file.json
22
- tests/test_functions.py
23
- tests/test_routes.py
25
+ tests/test_geode_functions.py
26
+ tests/test_routes.py
27
+ tests/test_utils_functions.py
@@ -0,0 +1,28 @@
1
+ asgiref==3.8.1
2
+ attrs==24.2.0
3
+ blinker==1.8.2
4
+ click==8.1.7
5
+ flask[async]==3.0.3
6
+ flask-cors==4.0.1
7
+ geode-background==8.1.1
8
+ geode-common==32.0.8
9
+ geode-conversion==6.0.3
10
+ geode-explicit==6.0.1
11
+ geode-implicit==3.1.1
12
+ geode-numerics==5.0.2
13
+ geode-simplex==8.2.1
14
+ geode-viewables==3.0.0
15
+ itsdangerous==2.2.0
16
+ jinja2==3.1.4
17
+ jsonschema==4.23.0
18
+ jsonschema-specifications==2023.12.1
19
+ markupsafe==2.1.5
20
+ opengeode-core==15.2.1
21
+ opengeode-geosciences==8.0.0
22
+ opengeode-geosciencesio==5.0.1
23
+ opengeode-inspector==6.0.0
24
+ opengeode-io==7.0.1
25
+ referencing==0.35.1
26
+ rpds-py==0.20.0
27
+ typing-extensions==4.12.2
28
+ werkzeug==3.0.3
@@ -0,0 +1,33 @@
1
+ # Standard library imports
2
+ import os
3
+ import time
4
+
5
+ # Third party imports
6
+ # Local application imports
7
+
8
+
9
+ class Config(object):
10
+ FLASK_DEBUG = os.environ.get("FLASK_DEBUG", default=False)
11
+ DEFAULT_PORT = "5000"
12
+ CORS_HEADERS = "Content-Type"
13
+ UPLOAD_FOLDER = "./uploads"
14
+ DESKTOP_APP = False
15
+ REQUEST_COUNTER = 0
16
+ LAST_REQUEST_TIME = time.time()
17
+ LAST_PING_TIME = time.time()
18
+
19
+
20
+ class ProdConfig(Config):
21
+ SSL = None
22
+ ORIGINS = ""
23
+ MINUTES_BEFORE_TIMEOUT = "1"
24
+ SECONDS_BETWEEN_SHUTDOWNS = "10"
25
+ DATA_FOLDER_PATH = "/data/"
26
+
27
+
28
+ class DevConfig(Config):
29
+ SSL = None
30
+ ORIGINS = "*"
31
+ MINUTES_BEFORE_TIMEOUT = "1"
32
+ SECONDS_BETWEEN_SHUTDOWNS = "10"
33
+ DATA_FOLDER_PATH = "./data/"
@@ -1,20 +1,14 @@
1
1
  # Standard library imports
2
2
  import os
3
- import time
4
- import threading
5
- import uuid
6
- import zipfile
7
3
 
8
4
  # Third party imports
9
5
  import flask
10
6
  import opengeode_geosciences as og_gs
11
7
  import opengeode as og
12
- import pkg_resources
13
- from jsonschema import validate
14
- from jsonschema.exceptions import ValidationError
15
8
 
16
9
  # Local application imports
17
10
  from .geode_objects import geode_objects_dict
11
+ from . import utils_functions
18
12
 
19
13
 
20
14
  def geode_object_value(geode_object: str):
@@ -147,7 +141,9 @@ def list_geode_objects(
147
141
  key: str = None,
148
142
  ):
149
143
  return_dict = {}
150
- file_extension = extension_from_filename(os.path.basename(file_absolute_path))
144
+ file_extension = utils_functions.extension_from_filename(
145
+ os.path.basename(file_absolute_path)
146
+ )
151
147
  geode_objects_filtered_list = filter_geode_objects(key)
152
148
 
153
149
  for geode_object in geode_objects_filtered_list:
@@ -200,75 +196,6 @@ def get_inspector_children(obj):
200
196
  return new_object
201
197
 
202
198
 
203
- def versions(list_packages: list):
204
- list_with_versions = []
205
- for package in list_packages:
206
- list_with_versions.append(
207
- {
208
- "package": package,
209
- "version": pkg_resources.get_distribution(package).version,
210
- }
211
- )
212
- return list_with_versions
213
-
214
-
215
- def create_lock_file(
216
- folder_absolute_path,
217
- ):
218
- if not os.path.exists(folder_absolute_path):
219
- os.mkdir(folder_absolute_path)
220
- id = uuid.uuid4()
221
- file_absolute_path = f"{folder_absolute_path}/{str(id)}.txt"
222
- f = open(file_absolute_path, "a")
223
- f.close()
224
- flask.g.UUID = id
225
-
226
-
227
- def create_time_file(folder_absolute_path):
228
- if not os.path.exists(folder_absolute_path):
229
- os.mkdir(folder_absolute_path)
230
- file_path = f"{folder_absolute_path}/time.txt"
231
- if not os.path.isfile(file_path):
232
- f = open(file_path, "w")
233
- f.close()
234
-
235
- f = open(folder_absolute_path + "/time.txt", "w")
236
- f.write(str(time.time()))
237
- f.close()
238
-
239
-
240
- def remove_lock_file(folder_absolute_path):
241
- id = flask.g.UUID
242
- os.remove(f"{folder_absolute_path}/{str(id)}.txt")
243
-
244
-
245
- def set_interval(func, sec):
246
- def func_wrapper():
247
- set_interval(func, sec)
248
- func()
249
-
250
- t = threading.Timer(sec, func_wrapper)
251
- t.daemon = True
252
- t.start()
253
- return t
254
-
255
-
256
- def extension_from_filename(filename):
257
- return os.path.splitext(filename)[1][1:]
258
-
259
-
260
- def validate_request(request, schema):
261
- json_data = request.get_json(force=True, silent=True)
262
-
263
- if json_data is None:
264
- json_data = {}
265
-
266
- try:
267
- validate(instance=json_data, schema=schema)
268
- except ValidationError as e:
269
- flask.abort(400, f"Validation error: {e.message}")
270
-
271
-
272
199
  def geographic_coordinate_systems(geode_object: str):
273
200
  if is_3D(geode_object):
274
201
  return og_gs.GeographicCoordinateSystem3D.geographic_coordinate_systems()
@@ -329,41 +256,3 @@ def create_coordinate_system(
329
256
  create_crs(
330
257
  geode_object, data, name, input_coordiante_system, output_coordiante_system
331
258
  )
332
-
333
-
334
- def send_file(upload_folder, saved_files, new_file_name):
335
- if len(saved_files) == 1:
336
- mimetype = "application/octet-binary"
337
- else:
338
- mimetype = "application/zip"
339
- new_file_name = os.path.splitext(new_file_name)[0] + ".zip"
340
- with zipfile.ZipFile(os.path.join(upload_folder, new_file_name), "w") as zipObj:
341
- for saved_file_path in saved_files:
342
- zipObj.write(
343
- saved_file_path,
344
- os.path.basename(saved_file_path),
345
- )
346
-
347
- response = flask.send_from_directory(
348
- directory=upload_folder,
349
- path=new_file_name,
350
- as_attachment=True,
351
- mimetype=mimetype,
352
- )
353
- response.headers["new-file-name"] = new_file_name
354
- response.headers["Access-Control-Expose-Headers"] = "new-file-name"
355
-
356
- return response
357
-
358
-
359
- def handle_exception(e):
360
- response = e.get_response()
361
- response.data = flask.json.dumps(
362
- {
363
- "code": e.code,
364
- "name": e.name,
365
- "description": e.description,
366
- }
367
- )
368
- response.content_type = "application/json"
369
- return response
@@ -1,17 +1,28 @@
1
1
  # Standard library imports
2
2
  import json
3
3
  import os
4
+ import time
4
5
 
5
6
  # Third party imports
6
7
  import flask
7
- import flask_cors
8
- from .. import geode_functions
8
+ from .. import geode_functions, utils_functions
9
9
  import werkzeug
10
10
  import uuid
11
11
 
12
-
13
12
  routes = flask.Blueprint("routes", __name__)
14
- flask_cors.CORS(routes)
13
+
14
+
15
+ @routes.before_request
16
+ def before_request():
17
+ if "ping" not in flask.request.path:
18
+ utils_functions.increment_request_counter(flask.current_app)
19
+
20
+
21
+ @routes.teardown_request
22
+ def teardown_request(exception):
23
+ if "ping" not in flask.request.path:
24
+ utils_functions.decrement_request_counter(flask.current_app)
25
+ utils_functions.update_last_request_time(flask.current_app)
15
26
 
16
27
 
17
28
  schemas = os.path.join(os.path.dirname(__file__), "schemas")
@@ -28,7 +39,7 @@ with open(
28
39
  methods=allowed_files_json["methods"],
29
40
  )
30
41
  def allowed_files():
31
- geode_functions.validate_request(flask.request, allowed_files_json)
42
+ utils_functions.validate_request(flask.request, allowed_files_json)
32
43
  extensions = geode_functions.list_input_extensions(
33
44
  flask.request.json["supported_feature"]
34
45
  )
@@ -75,7 +86,7 @@ def allowed_objects():
75
86
  return flask.make_response({}, 200)
76
87
 
77
88
  UPLOAD_FOLDER = flask.current_app.config["UPLOAD_FOLDER"]
78
- geode_functions.validate_request(flask.request, allowed_objects_json)
89
+ utils_functions.validate_request(flask.request, allowed_objects_json)
79
90
  file_absolute_path = os.path.join(UPLOAD_FOLDER, flask.request.json["filename"])
80
91
  allowed_objects = geode_functions.list_geode_objects(
81
92
  file_absolute_path, flask.request.json["supported_feature"]
@@ -96,7 +107,7 @@ with open(
96
107
  )
97
108
  def missing_files():
98
109
  UPLOAD_FOLDER = flask.current_app.config["UPLOAD_FOLDER"]
99
- geode_functions.validate_request(flask.request, missing_files_json)
110
+ utils_functions.validate_request(flask.request, missing_files_json)
100
111
 
101
112
  missing_files = geode_functions.missing_files(
102
113
  flask.request.json["input_geode_object"],
@@ -134,13 +145,11 @@ with open(
134
145
  methods=geographic_coordinate_systems_json["methods"],
135
146
  )
136
147
  def crs_converter_geographic_coordinate_systems():
137
- geode_functions.validate_request(flask.request, geographic_coordinate_systems_json)
148
+ utils_functions.validate_request(flask.request, geographic_coordinate_systems_json)
138
149
  infos = geode_functions.geographic_coordinate_systems(
139
150
  flask.request.json["input_geode_object"]
140
151
  )
141
152
  crs_list = []
142
- print(infos)
143
- print(flask.request.json["input_geode_object"])
144
153
  for info in infos:
145
154
  crs = {}
146
155
  crs["name"] = info.name
@@ -164,7 +173,7 @@ with open(
164
173
  )
165
174
  def inspect_file():
166
175
  UPLOAD_FOLDER = flask.current_app.config["UPLOAD_FOLDER"]
167
- geode_functions.validate_request(flask.request, inspect_file_json)
176
+ utils_functions.validate_request(flask.request, inspect_file_json)
168
177
 
169
178
  secure_filename = werkzeug.utils.secure_filename(flask.request.json["filename"])
170
179
  file_path = os.path.abspath(os.path.join(UPLOAD_FOLDER, secure_filename))
@@ -189,7 +198,7 @@ with open(
189
198
  )
190
199
  def geode_objects_and_output_extensions():
191
200
  UPLOAD_FOLDER = flask.current_app.config["UPLOAD_FOLDER"]
192
- geode_functions.validate_request(
201
+ utils_functions.validate_request(
193
202
  flask.request, geode_objects_and_output_extensions_json
194
203
  )
195
204
  data = geode_functions.load(
@@ -221,7 +230,7 @@ with open(
221
230
  def save_viewable_file():
222
231
  UPLOAD_FOLDER = flask.current_app.config["UPLOAD_FOLDER"]
223
232
  DATA_FOLDER_PATH = flask.current_app.config["DATA_FOLDER_PATH"]
224
- geode_functions.validate_request(flask.request, save_viewable_file_json)
233
+ utils_functions.validate_request(flask.request, save_viewable_file_json)
225
234
 
226
235
  secure_filename = werkzeug.utils.secure_filename(flask.request.json["filename"])
227
236
  file_path = os.path.abspath(os.path.join(UPLOAD_FOLDER, secure_filename))
@@ -260,3 +269,20 @@ def save_viewable_file():
260
269
  },
261
270
  200,
262
271
  )
272
+
273
+
274
+ with open(
275
+ os.path.join(schemas, "ping.json"),
276
+ "r",
277
+ ) as file:
278
+ ping_json = json.load(file)
279
+
280
+
281
+ @routes.route(
282
+ ping_json["route"],
283
+ methods=ping_json["methods"],
284
+ )
285
+ def ping():
286
+ utils_functions.validate_request(flask.request, ping_json)
287
+ flask.current_app.config.update(LAST_PING_TIME=time.time())
288
+ return flask.make_response({"message": "Flask server is running"}, 200)
@@ -0,0 +1,10 @@
1
+ {
2
+ "route": "/ping",
3
+ "methods": [
4
+ "POST"
5
+ ],
6
+ "type": "object",
7
+ "properties": {},
8
+ "required": [],
9
+ "additionalProperties": false
10
+ }
@@ -0,0 +1,131 @@
1
+ # Standard library imports
2
+ import os
3
+ import threading
4
+ import time
5
+ import zipfile
6
+
7
+ # Third party imports
8
+ import flask
9
+ from jsonschema import validate
10
+ from jsonschema.exceptions import ValidationError
11
+ import pkg_resources
12
+
13
+ # Local application imports
14
+
15
+
16
+ def increment_request_counter(current_app):
17
+ if "REQUEST_COUNTER" in current_app.config:
18
+ REQUEST_COUNTER = int(current_app.config.get("REQUEST_COUNTER"))
19
+ REQUEST_COUNTER += 1
20
+ current_app.config.update(REQUEST_COUNTER=REQUEST_COUNTER)
21
+
22
+
23
+ def decrement_request_counter(current_app):
24
+ if "REQUEST_COUNTER" in current_app.config:
25
+ REQUEST_COUNTER = int(current_app.config.get("REQUEST_COUNTER"))
26
+ REQUEST_COUNTER -= 1
27
+ current_app.config.update(REQUEST_COUNTER=REQUEST_COUNTER)
28
+
29
+
30
+ def update_last_request_time(current_app):
31
+ if "LAST_REQUEST_TIME" in current_app.config:
32
+ LAST_REQUEST_TIME = time.time()
33
+ current_app.config.update(LAST_REQUEST_TIME=LAST_REQUEST_TIME)
34
+
35
+
36
+ def kill_task(current_app):
37
+ DESKTOP_APP = bool(current_app.config.get("DESKTOP_APP"))
38
+ REQUEST_COUNTER = int(current_app.config.get("REQUEST_COUNTER"))
39
+ LAST_PING_TIME = float(current_app.config.get("LAST_PING_TIME"))
40
+ LAST_REQUEST_TIME = float(current_app.config.get("LAST_REQUEST_TIME"))
41
+ MINUTES_BEFORE_TIMEOUT = float(current_app.config.get("MINUTES_BEFORE_TIMEOUT"))
42
+ current_time = time.time()
43
+ minutes_since_last_request = (current_time - LAST_REQUEST_TIME) / 60
44
+ minutes_since_last_ping = (current_time - LAST_PING_TIME) / 60
45
+
46
+ if (
47
+ (
48
+ (minutes_since_last_request > MINUTES_BEFORE_TIMEOUT)
49
+ and (DESKTOP_APP == False)
50
+ )
51
+ or (minutes_since_last_ping > MINUTES_BEFORE_TIMEOUT)
52
+ ) and (REQUEST_COUNTER == 0):
53
+ print("Server timed out due to inactivity, shutting down...", flush=True)
54
+ os._exit(0)
55
+
56
+
57
+ def versions(list_packages: list):
58
+ list_with_versions = []
59
+ for package in list_packages:
60
+ list_with_versions.append(
61
+ {
62
+ "package": package,
63
+ "version": pkg_resources.get_distribution(package).version,
64
+ }
65
+ )
66
+ return list_with_versions
67
+
68
+
69
+ def validate_request(request, schema):
70
+ json_data = request.get_json(force=True, silent=True)
71
+
72
+ if json_data is None:
73
+ json_data = {}
74
+
75
+ try:
76
+ validate(instance=json_data, schema=schema)
77
+ except ValidationError as e:
78
+ flask.abort(400, f"Validation error: {e.message}")
79
+
80
+
81
+ def set_interval(func, sec, args=None):
82
+ def func_wrapper():
83
+ set_interval(func, sec, args)
84
+ func(args)
85
+
86
+ t = threading.Timer(sec, func_wrapper)
87
+ t.daemon = True
88
+ t.start()
89
+ return t
90
+
91
+
92
+ def extension_from_filename(filename):
93
+ return os.path.splitext(filename)[1][1:]
94
+
95
+
96
+ def send_file(upload_folder, saved_files, new_file_name):
97
+ if len(saved_files) == 1:
98
+ mimetype = "application/octet-binary"
99
+ else:
100
+ mimetype = "application/zip"
101
+ new_file_name = os.path.splitext(new_file_name)[0] + ".zip"
102
+ with zipfile.ZipFile(os.path.join(upload_folder, new_file_name), "w") as zipObj:
103
+ for saved_file_path in saved_files:
104
+ zipObj.write(
105
+ saved_file_path,
106
+ os.path.basename(saved_file_path),
107
+ )
108
+
109
+ response = flask.send_from_directory(
110
+ directory=upload_folder,
111
+ path=new_file_name,
112
+ as_attachment=True,
113
+ mimetype=mimetype,
114
+ )
115
+ response.headers["new-file-name"] = new_file_name
116
+ response.headers["Access-Control-Expose-Headers"] = "new-file-name"
117
+
118
+ return response
119
+
120
+
121
+ def handle_exception(e):
122
+ response = e.get_response()
123
+ response.data = flask.json.dumps(
124
+ {
125
+ "code": e.code,
126
+ "name": e.name,
127
+ "description": e.description,
128
+ }
129
+ )
130
+ response.content_type = "application/json"
131
+ return response
@@ -310,33 +310,3 @@ def test_geode_objects_output_extensions():
310
310
  output_extension_value,
311
311
  ) in output_geode_object_value.items():
312
312
  assert type(output_extension_value["is_saveable"]) is bool
313
-
314
-
315
- def test_versions():
316
- list_packages = [
317
- "OpenGeode-core",
318
- "OpenGeode-IO",
319
- "OpenGeode-Geosciences",
320
- "OpenGeode-GeosciencesIO",
321
- ]
322
- versions = geode_functions.versions(list_packages)
323
- assert type(versions) is list
324
- for version in versions:
325
- assert type(version) is dict
326
-
327
-
328
- def test_extension_from_filename():
329
- extension = geode_functions.extension_from_filename("test.toto")
330
- assert type(extension) is str
331
- assert extension.count(".") == 0
332
-
333
-
334
- def test_handle_exception(client):
335
- route = "/error"
336
- response = client.post(route)
337
- assert response.status_code == 500
338
- data = response.get_json()
339
- assert type(data) is dict
340
- assert type(data["description"]) is str
341
- assert type(data["name"]) is str
342
- assert type(data["code"]) is int
@@ -0,0 +1,50 @@
1
+ import flask
2
+ from src.opengeodeweb_back import utils_functions
3
+
4
+
5
+ def test_increment_request_counter(app_context):
6
+ assert flask.current_app.config.get("REQUEST_COUNTER") == 0
7
+ utils_functions.increment_request_counter(flask.current_app)
8
+ assert flask.current_app.config.get("REQUEST_COUNTER") == 1
9
+
10
+
11
+ def test_decrement_request_counter(app_context):
12
+ assert flask.current_app.config.get("REQUEST_COUNTER") == 1
13
+ utils_functions.decrement_request_counter(flask.current_app)
14
+ assert flask.current_app.config.get("REQUEST_COUNTER") == 0
15
+
16
+
17
+ def test_update_last_request_time(app_context):
18
+ LAST_REQUEST_TIME = flask.current_app.config.get("LAST_REQUEST_TIME")
19
+ utils_functions.update_last_request_time(flask.current_app)
20
+ assert flask.current_app.config.get("LAST_REQUEST_TIME") >= LAST_REQUEST_TIME
21
+
22
+
23
+ def test_versions():
24
+ list_packages = [
25
+ "OpenGeode-core",
26
+ "OpenGeode-IO",
27
+ "OpenGeode-Geosciences",
28
+ "OpenGeode-GeosciencesIO",
29
+ ]
30
+ versions = utils_functions.versions(list_packages)
31
+ assert type(versions) is list
32
+ for version in versions:
33
+ assert type(version) is dict
34
+
35
+
36
+ def test_extension_from_filename():
37
+ extension = utils_functions.extension_from_filename("test.toto")
38
+ assert type(extension) is str
39
+ assert extension.count(".") == 0
40
+
41
+
42
+ def test_handle_exception(client):
43
+ route = "/error"
44
+ response = client.post(route)
45
+ assert response.status_code == 500
46
+ data = response.get_json()
47
+ assert type(data) is dict
48
+ assert type(data["description"]) is str
49
+ assert type(data["name"]) is str
50
+ assert type(data["code"]) is int
@@ -1,27 +0,0 @@
1
- asgiref==3.8.1
2
- attrs==23.2.0
3
- blinker==1.8.2
4
- click==8.1.7
5
- flask[async]==3.0.3
6
- flask-cors==4.0.1
7
- geode-background==7.12.0
8
- geode-common==31.2.1
9
- geode-conversion==5.4.1
10
- geode-explicit==4.8.3
11
- geode-implicit==2.8.7
12
- geode-numerics==4.4.0
13
- geode-simplex==6.8.3
14
- geode-viewables==2.2.3
15
- itsdangerous==2.2.0
16
- jinja2==3.1.4
17
- jsonschema==4.22.0
18
- jsonschema-specifications==2023.12.1
19
- markupsafe==2.1.5
20
- opengeode-core==14.21.3
21
- opengeode-geosciences==7.7.0
22
- opengeode-geosciencesio==4.7.7
23
- opengeode-inspector==5.1.4
24
- opengeode-io==6.5.1
25
- referencing==0.35.1
26
- rpds-py==0.18.1
27
- werkzeug==3.0.3