OpenGeodeWeb-Back 5.10.0rc6__py3-none-any.whl → 5.10.0rc8__py3-none-any.whl
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.
- opengeodeweb_back/app_config.py +11 -2
- opengeodeweb_back/data.py +44 -0
- opengeodeweb_back/database.py +19 -0
- opengeodeweb_back/utils_functions.py +53 -24
- {opengeodeweb_back-5.10.0rc6.dist-info → opengeodeweb_back-5.10.0rc8.dist-info}/METADATA +5 -1
- {opengeodeweb_back-5.10.0rc6.dist-info → opengeodeweb_back-5.10.0rc8.dist-info}/RECORD +9 -7
- {opengeodeweb_back-5.10.0rc6.dist-info → opengeodeweb_back-5.10.0rc8.dist-info}/WHEEL +0 -0
- {opengeodeweb_back-5.10.0rc6.dist-info → opengeodeweb_back-5.10.0rc8.dist-info}/licenses/LICENSE +0 -0
- {opengeodeweb_back-5.10.0rc6.dist-info → opengeodeweb_back-5.10.0rc8.dist-info}/top_level.txt +0 -0
opengeodeweb_back/app_config.py
CHANGED
@@ -4,6 +4,7 @@ import time
|
|
4
4
|
|
5
5
|
# Third party imports
|
6
6
|
# Local application imports
|
7
|
+
from .database import DATABASE_FILENAME
|
7
8
|
|
8
9
|
|
9
10
|
class Config(object):
|
@@ -15,6 +16,7 @@ class Config(object):
|
|
15
16
|
REQUEST_COUNTER = 0
|
16
17
|
LAST_REQUEST_TIME = time.time()
|
17
18
|
LAST_PING_TIME = time.time()
|
19
|
+
SQLALCHEMY_TRACK_MODIFICATIONS = False
|
18
20
|
|
19
21
|
|
20
22
|
class ProdConfig(Config):
|
@@ -22,7 +24,10 @@ class ProdConfig(Config):
|
|
22
24
|
ORIGINS = ""
|
23
25
|
MINUTES_BEFORE_TIMEOUT = "1"
|
24
26
|
SECONDS_BETWEEN_SHUTDOWNS = "10"
|
25
|
-
DATA_FOLDER_PATH = "/data
|
27
|
+
DATA_FOLDER_PATH = "/data"
|
28
|
+
SQLALCHEMY_DATABASE_URI = f"sqlite:///{os.path.abspath(
|
29
|
+
os.path.join(DATA_FOLDER_PATH, DATABASE_FILENAME)
|
30
|
+
)}"
|
26
31
|
|
27
32
|
|
28
33
|
class DevConfig(Config):
|
@@ -30,4 +35,8 @@ class DevConfig(Config):
|
|
30
35
|
ORIGINS = "*"
|
31
36
|
MINUTES_BEFORE_TIMEOUT = "1"
|
32
37
|
SECONDS_BETWEEN_SHUTDOWNS = "10"
|
33
|
-
|
38
|
+
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
39
|
+
DATA_FOLDER_PATH = os.path.join(BASE_DIR, "data")
|
40
|
+
SQLALCHEMY_DATABASE_URI = f"sqlite:///{os.path.join(
|
41
|
+
BASE_DIR, DATA_FOLDER_PATH, DATABASE_FILENAME
|
42
|
+
)}"
|
@@ -0,0 +1,44 @@
|
|
1
|
+
from sqlalchemy import String, JSON
|
2
|
+
from sqlalchemy.orm import Mapped, mapped_column
|
3
|
+
from .database import database, Base
|
4
|
+
import uuid
|
5
|
+
|
6
|
+
|
7
|
+
class Data(Base):
|
8
|
+
__tablename__ = "datas"
|
9
|
+
|
10
|
+
id: Mapped[str] = mapped_column(
|
11
|
+
String, primary_key=True, default=lambda: str(uuid.uuid4()).replace("-", "")
|
12
|
+
)
|
13
|
+
name: Mapped[str] = mapped_column(String, nullable=False)
|
14
|
+
native_file_name: Mapped[str] = mapped_column(String, nullable=False)
|
15
|
+
viewable_file_name: Mapped[str] = mapped_column(String, nullable=False)
|
16
|
+
geode_object: Mapped[str] = mapped_column(String, nullable=False)
|
17
|
+
|
18
|
+
light_viewable: Mapped[str | None] = mapped_column(String, nullable=True)
|
19
|
+
input_file: Mapped[str | None] = mapped_column(String, nullable=True)
|
20
|
+
additional_files: Mapped[list[str] | None] = mapped_column(JSON, nullable=True)
|
21
|
+
|
22
|
+
@staticmethod
|
23
|
+
def create(
|
24
|
+
name: str,
|
25
|
+
geode_object: str,
|
26
|
+
input_file: str | None = None,
|
27
|
+
additional_files: list[str] | None = None,
|
28
|
+
) -> "Data":
|
29
|
+
input_file = input_file if input_file is not None else ""
|
30
|
+
additional_files = additional_files if additional_files is not None else []
|
31
|
+
|
32
|
+
data_entry = Data(
|
33
|
+
name=name,
|
34
|
+
geode_object=geode_object,
|
35
|
+
input_file=input_file,
|
36
|
+
additional_files=additional_files,
|
37
|
+
native_file_name="",
|
38
|
+
viewable_file_name="",
|
39
|
+
light_viewable=None,
|
40
|
+
)
|
41
|
+
|
42
|
+
database.session.add(data_entry)
|
43
|
+
database.session.flush()
|
44
|
+
return data_entry
|
@@ -0,0 +1,19 @@
|
|
1
|
+
from flask import Flask
|
2
|
+
from flask_sqlalchemy import SQLAlchemy
|
3
|
+
from sqlalchemy.orm import DeclarativeBase
|
4
|
+
|
5
|
+
DATABASE_FILENAME = "project.db"
|
6
|
+
|
7
|
+
|
8
|
+
class Base(DeclarativeBase):
|
9
|
+
pass
|
10
|
+
|
11
|
+
|
12
|
+
database = SQLAlchemy(model_class=Base)
|
13
|
+
|
14
|
+
|
15
|
+
def initialize_database(app: Flask) -> SQLAlchemy:
|
16
|
+
database.init_app(app)
|
17
|
+
with app.app_context():
|
18
|
+
database.create_all()
|
19
|
+
return database
|
@@ -2,7 +2,6 @@
|
|
2
2
|
import os
|
3
3
|
import threading
|
4
4
|
import time
|
5
|
-
import uuid
|
6
5
|
import zipfile
|
7
6
|
from collections.abc import Callable
|
8
7
|
from typing import Any
|
@@ -17,6 +16,8 @@ import werkzeug
|
|
17
16
|
|
18
17
|
# Local application imports
|
19
18
|
from . import geode_functions
|
19
|
+
from .data import Data
|
20
|
+
from .database import database
|
20
21
|
|
21
22
|
|
22
23
|
def increment_request_counter(current_app: flask.Flask) -> None:
|
@@ -152,17 +153,29 @@ def handle_exception(exception: HTTPException) -> flask.Response:
|
|
152
153
|
return response
|
153
154
|
|
154
155
|
|
155
|
-
def
|
156
|
+
def create_data_folder_from_id(data_id: str) -> str:
|
156
157
|
base_data_folder = flask.current_app.config["DATA_FOLDER_PATH"]
|
157
|
-
|
158
|
-
data_path = os.path.join(base_data_folder, generated_id)
|
158
|
+
data_path = os.path.join(base_data_folder, data_id)
|
159
159
|
os.makedirs(data_path, exist_ok=True)
|
160
|
-
return
|
160
|
+
return data_path
|
161
161
|
|
162
162
|
|
163
163
|
def save_all_viewables_and_return_info(
|
164
|
-
geode_object
|
165
|
-
|
164
|
+
geode_object: str,
|
165
|
+
data: Any,
|
166
|
+
input_file: str,
|
167
|
+
additional_files: list[str] | None = None,
|
168
|
+
) -> dict[str, Any]:
|
169
|
+
if additional_files is None:
|
170
|
+
additional_files = []
|
171
|
+
|
172
|
+
data_entry = Data.create(
|
173
|
+
name=data.name(),
|
174
|
+
geode_object=geode_object,
|
175
|
+
input_file=input_file,
|
176
|
+
additional_files=additional_files,
|
177
|
+
)
|
178
|
+
data_path = create_data_folder_from_id(data_entry.id)
|
166
179
|
saved_native_file_path = geode_functions.save(
|
167
180
|
geode_object,
|
168
181
|
data,
|
@@ -177,28 +190,42 @@ def save_all_viewables_and_return_info(
|
|
177
190
|
)
|
178
191
|
with open(saved_light_viewable_file_path, "rb") as f:
|
179
192
|
binary_light_viewable = f.read()
|
193
|
+
data_entry.native_file_name = os.path.basename(saved_native_file_path[0])
|
194
|
+
data_entry.viewable_file_name = os.path.basename(saved_viewable_file_path)
|
195
|
+
data_entry.light_viewable = os.path.basename(saved_light_viewable_file_path)
|
196
|
+
|
197
|
+
database.session.commit()
|
180
198
|
|
181
199
|
return {
|
182
|
-
"name":
|
183
|
-
"native_file_name":
|
184
|
-
"viewable_file_name":
|
185
|
-
"id":
|
200
|
+
"name": data_entry.name,
|
201
|
+
"native_file_name": data_entry.native_file_name,
|
202
|
+
"viewable_file_name": data_entry.viewable_file_name,
|
203
|
+
"id": data_entry.id,
|
186
204
|
"object_type": geode_functions.get_object_type(geode_object),
|
187
205
|
"binary_light_viewable": binary_light_viewable.decode("utf-8"),
|
188
|
-
"geode_object": geode_object,
|
189
|
-
"input_files":
|
206
|
+
"geode_object": data_entry.geode_object,
|
207
|
+
"input_files": data_entry.input_file,
|
208
|
+
"additional_files": data_entry.additional_files,
|
190
209
|
}
|
191
210
|
|
192
211
|
|
193
|
-
def generate_native_viewable_and_light_viewable_from_object(
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
)
|
212
|
+
def generate_native_viewable_and_light_viewable_from_object(
|
213
|
+
geode_object: str, data: Any
|
214
|
+
) -> dict[str, Any]:
|
215
|
+
return save_all_viewables_and_return_info(geode_object, data, input_file="")
|
198
216
|
|
199
217
|
|
200
|
-
def generate_native_viewable_and_light_viewable_from_file(
|
201
|
-
|
218
|
+
def generate_native_viewable_and_light_viewable_from_file(
|
219
|
+
geode_object: str, input_filename: str
|
220
|
+
) -> dict[str, Any]:
|
221
|
+
temp_data_entry = Data.create(
|
222
|
+
name="temp",
|
223
|
+
geode_object=geode_object,
|
224
|
+
input_file=input_filename,
|
225
|
+
additional_files=[],
|
226
|
+
)
|
227
|
+
|
228
|
+
data_path = create_data_folder_from_id(temp_data_entry.id)
|
202
229
|
|
203
230
|
full_input_filename = geode_functions.upload_file_path(input_filename)
|
204
231
|
copied_full_path = os.path.join(
|
@@ -206,7 +233,7 @@ def generate_native_viewable_and_light_viewable_from_file(geode_object, input_fi
|
|
206
233
|
)
|
207
234
|
shutil.copy2(full_input_filename, copied_full_path)
|
208
235
|
|
209
|
-
additional_files_copied = []
|
236
|
+
additional_files_copied: list[str] = []
|
210
237
|
additional = geode_functions.additional_files(geode_object, full_input_filename)
|
211
238
|
for additional_file in additional.mandatory_files + additional.optional_files:
|
212
239
|
if additional_file.is_missing:
|
@@ -221,12 +248,14 @@ def generate_native_viewable_and_light_viewable_from_file(geode_object, input_fi
|
|
221
248
|
shutil.copy2(source_path, dest_path)
|
222
249
|
additional_files_copied.append(additional_file.filename)
|
223
250
|
|
224
|
-
data = geode_functions.load_data(geode_object,
|
251
|
+
data = geode_functions.load_data(geode_object, temp_data_entry.id, input_filename)
|
252
|
+
|
253
|
+
database.session.delete(temp_data_entry)
|
254
|
+
database.session.flush()
|
225
255
|
|
226
256
|
return save_all_viewables_and_return_info(
|
227
257
|
geode_object,
|
228
258
|
data,
|
229
|
-
|
230
|
-
data_path,
|
259
|
+
input_file=input_filename,
|
231
260
|
additional_files=additional_files_copied,
|
232
261
|
)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: OpenGeodeWeb-Back
|
3
|
-
Version: 5.10.
|
3
|
+
Version: 5.10.0rc8
|
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
|
@@ -17,8 +17,10 @@ Requires-Dist: click==8.2.1
|
|
17
17
|
Requires-Dist: fastjsonschema==2.16.2
|
18
18
|
Requires-Dist: flask[async]==3.0.3
|
19
19
|
Requires-Dist: flask-cors==6.0.1
|
20
|
+
Requires-Dist: flask-sqlalchemy==3.1.1
|
20
21
|
Requires-Dist: geode-common==33.9.0
|
21
22
|
Requires-Dist: geode-viewables==3.2.0
|
23
|
+
Requires-Dist: greenlet==3.2.4
|
22
24
|
Requires-Dist: itsdangerous==2.2.0
|
23
25
|
Requires-Dist: jinja2==3.1.6
|
24
26
|
Requires-Dist: markupsafe==3.0.2
|
@@ -27,6 +29,8 @@ Requires-Dist: opengeode-geosciences==9.2.2
|
|
27
29
|
Requires-Dist: opengeode-geosciencesio==5.7.2
|
28
30
|
Requires-Dist: opengeode-inspector==6.7.0
|
29
31
|
Requires-Dist: opengeode-io==7.3.2
|
32
|
+
Requires-Dist: sqlalchemy==2.0.43
|
33
|
+
Requires-Dist: typing-extensions==4.15.0
|
30
34
|
Requires-Dist: werkzeug==3.0.3
|
31
35
|
Dynamic: license-file
|
32
36
|
|
@@ -1,9 +1,11 @@
|
|
1
1
|
opengeodeweb_back/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
-
opengeodeweb_back/app_config.py,sha256=
|
2
|
+
opengeodeweb_back/app_config.py,sha256=XFl5KqrOWifVxdudiLm-LXmczYDBCbZtNboSYnNbLf8,1142
|
3
|
+
opengeodeweb_back/data.py,sha256=6705K-Z6amrsCYxeYFEbYJa6d4SjvPbqZbr7X7ziZCU,1552
|
4
|
+
opengeodeweb_back/database.py,sha256=lXbbJRZCdqLcQU-Xqi1jPmo8cIitbHOqUJW5uLBF85w,381
|
3
5
|
opengeodeweb_back/geode_functions.py,sha256=1Y7o3NjGJxoW1O2s4KEIZ1C5tN5x-EqPNGVnIPzi-Ak,10208
|
4
6
|
opengeodeweb_back/geode_objects.py,sha256=uXCKX8AOdXkItqmYItLnFfHcIBiMFaeN_WmGs4j64Ro,27782
|
5
7
|
opengeodeweb_back/test_utils.py,sha256=18AbRW9-tfKkPcmRGilTTHXI7S3armYyV7Vdy5UvUKM,794
|
6
|
-
opengeodeweb_back/utils_functions.py,sha256=
|
8
|
+
opengeodeweb_back/utils_functions.py,sha256=KAlXp689N-51RXSAdBiDylVBeeozY_rzDBGH1VgqH6w,8543
|
7
9
|
opengeodeweb_back/routes/blueprint_routes.py,sha256=3fxMR9fs0BqnOiYhKFacGdxWm7JFLz5i5PvUqYgB5z4,11308
|
8
10
|
opengeodeweb_back/routes/models/blueprint_models.py,sha256=PAyHSKjsvVm5gGfjUyWAnODmE0BJMsIWc1AWl0F3bO0,1955
|
9
11
|
opengeodeweb_back/routes/models/schemas/mesh_components.json,sha256=3OQvI4pUCe77WGC46tEr37rEWigQ6n2nsfGUTZRY074,419
|
@@ -22,8 +24,8 @@ opengeodeweb_back/routes/schemas/save_viewable_file.json,sha256=pvvEdaC7bNASPMrl
|
|
22
24
|
opengeodeweb_back/routes/schemas/texture_coordinates.json,sha256=oW84Vh34KfleK935fmMXnqJXy-vaLDd7g87O_PtSzfY,429
|
23
25
|
opengeodeweb_back/routes/schemas/upload_file.json,sha256=LJ3U3L5ApKuQDVFIpVT_y2alq4HW_suTvZ3HUucNbhg,219
|
24
26
|
opengeodeweb_back/routes/schemas/vertex_attribute_names.json,sha256=bmXG0pzVHMUTZY_0iu6ruX7eMUVk8wr2H1o4eEtBlg0,432
|
25
|
-
opengeodeweb_back-5.10.
|
26
|
-
opengeodeweb_back-5.10.
|
27
|
-
opengeodeweb_back-5.10.
|
28
|
-
opengeodeweb_back-5.10.
|
29
|
-
opengeodeweb_back-5.10.
|
27
|
+
opengeodeweb_back-5.10.0rc8.dist-info/licenses/LICENSE,sha256=LoTB-aqQvzTGxoTRXNnhNV0LKiqdk2bQv6MB34l8zkI,1079
|
28
|
+
opengeodeweb_back-5.10.0rc8.dist-info/METADATA,sha256=Ra3r2pMEyjKTkKGk7vNfOk54CJb5Kmmn8S1xNqEex5Y,2821
|
29
|
+
opengeodeweb_back-5.10.0rc8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
30
|
+
opengeodeweb_back-5.10.0rc8.dist-info/top_level.txt,sha256=tN1FZeLIVBrdja2-pbmhg5-tK-JILmmT9OeIBnhlUrQ,18
|
31
|
+
opengeodeweb_back-5.10.0rc8.dist-info/RECORD,,
|
File without changes
|
{opengeodeweb_back-5.10.0rc6.dist-info → opengeodeweb_back-5.10.0rc8.dist-info}/licenses/LICENSE
RENAMED
File without changes
|
{opengeodeweb_back-5.10.0rc6.dist-info → opengeodeweb_back-5.10.0rc8.dist-info}/top_level.txt
RENAMED
File without changes
|