Skip to content

Commit ade9566

Browse files
authored
Merge branch 'next' into feat/blueprint_create
2 parents 9e8d185 + 64248b8 commit ade9566

File tree

10 files changed

+123
-86
lines changed

10 files changed

+123
-86
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@ __pycache__
99
.vscode
1010
uploads
1111
node_modules
12-
schemas.json
1312
.mypy_cache
1413
*.db
14+
opengeodeweb_back_schemas.json

package-lock.json

Lines changed: 14 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

requirements.in

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,3 @@ geode-viewables==3.3.2
88
flask[async]==3.1.2
99
flask-cors==6.0.1
1010
werkzeug==3.1.2
11-
flask-sqlalchemy==3.1.1

requirements.txt

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,34 +4,29 @@
44
#
55
# pip-compile
66
#
7-
asgiref==3.10.0
7+
asgiref>=3
88
# via flask
9-
blinker==1.9.0
9+
blinker>=1
1010
# via flask
11-
click==8.3.0
11+
click>=8
1212
# via flask
13-
flask[async]==3.1.2
13+
flask[async]>=3
1414
# via
1515
# -r requirements.in
1616
# flask-cors
17-
# flask-sqlalchemy
1817
flask-cors==6.0.1
1918
# via -r requirements.in
20-
flask-sqlalchemy==3.1.1
21-
# via -r requirements.in
22-
geode-common==33.11.3
19+
geode-common==33.11.0
2320
# via
2421
# -r requirements.in
2522
# geode-viewables
2623
geode-viewables==3.3.2
2724
# via -r requirements.in
28-
greenlet==3.2.4
29-
# via sqlalchemy
30-
itsdangerous==2.2.0
25+
itsdangerous>=2
3126
# via flask
32-
jinja2==3.1.6
27+
jinja2>=3
3328
# via flask
34-
markupsafe==3.0.3
29+
markupsafe>=3
3530
# via
3631
# flask
3732
# jinja2
@@ -59,12 +54,9 @@ opengeode-io==7.4.2
5954
# -r requirements.in
6055
# geode-viewables
6156
# opengeode-geosciencesio
62-
sqlalchemy==2.0.44
63-
# via flask-sqlalchemy
64-
typing-extensions==4.15.0
65-
# via sqlalchemy
6657
werkzeug==3.1.2
6758
# via
6859
# -r requirements.in
6960
# flask
7061
# flask-cors
62+

src/opengeodeweb_back/app.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from opengeodeweb_back.routes import blueprint_routes
1414
from opengeodeweb_back.routes.models import blueprint_models
1515
from opengeodeweb_back.routes.create import blueprint_create
16-
from opengeodeweb_microservice.database.connection import init_database
16+
from opengeodeweb_microservice.database import connection
1717

1818
""" Global config """
1919
app: Flask = flask.Flask(__name__)
@@ -34,6 +34,17 @@
3434
app.config.get("SECONDS_BETWEEN_SHUTDOWNS") or 60.0
3535
)
3636

37+
38+
@app.before_request
39+
def before_request() -> None:
40+
utils_functions.before_request(flask.current_app)
41+
42+
43+
@app.teardown_request
44+
def teardown_request(exception: BaseException | None) -> None:
45+
utils_functions.teardown_request(flask.current_app, exception)
46+
47+
3748
app.register_blueprint(
3849
blueprint_routes.routes,
3950
url_prefix="/opengeodeweb_back",
@@ -140,12 +151,14 @@ def run_server() -> None:
140151
f"Origins: {args.allowed_origins}",
141152
flush=True,
142153
)
143-
db_filename: str = app.config.get("DATABASE_FILENAME") or "database.db"
154+
155+
db_filename: str = app.config.get("DATABASE_FILENAME") or "project.db"
144156
db_path = os.path.join(args.data_folder_path, db_filename)
145157
os.makedirs(os.path.dirname(db_path), exist_ok=True)
146158
app.config["SQLALCHEMY_DATABASE_URI"] = f"sqlite:///{db_path}"
147159
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
148-
init_database(app, db_filename)
160+
161+
connection.init_database(db_path)
149162
print(f"Database initialized at: {db_path}", flush=True)
150163
app.run(debug=args.debug, host=args.host, port=args.port, ssl_context=SSL)
151164

src/opengeodeweb_back/routes/blueprint_routes.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,6 @@
1717
routes = flask.Blueprint("routes", __name__, url_prefix="/opengeodeweb_back")
1818

1919

20-
@routes.before_request
21-
def before_request():
22-
if "ping" not in flask.request.path:
23-
utils_functions.increment_request_counter(flask.current_app)
24-
25-
26-
@routes.teardown_request
27-
def teardown_request(exception):
28-
29-
if "ping" not in flask.request.path:
30-
utils_functions.decrement_request_counter(flask.current_app)
31-
utils_functions.update_last_request_time(flask.current_app)
32-
33-
3420
routes.register_blueprint(
3521
blueprint_models.routes,
3622
url_prefix=blueprint_models.routes.url_prefix,
@@ -357,3 +343,17 @@ def ping():
357343
utils_functions.validate_request(flask.request, ping_json)
358344
flask.current_app.config.update(LAST_PING_TIME=time.time())
359345
return flask.make_response({"message": "Flask server is running"}, 200)
346+
347+
348+
with open(
349+
os.path.join(schemas, "kill.json"),
350+
"r",
351+
) as file:
352+
kill_json = json.load(file)
353+
354+
355+
@routes.route(kill_json["route"], methods=kill_json["methods"])
356+
def kill() -> flask.Response:
357+
print("Manual server kill, shutting down...", flush=True)
358+
os._exit(0)
359+
return flask.make_response({"message": "Flask server is dead"}, 200)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"route": "/kill",
3+
"methods": [
4+
"POST"
5+
],
6+
"type": "object",
7+
"properties": {},
8+
"required": [],
9+
"additionalProperties": false
10+
}

src/opengeodeweb_back/utils_functions.py

Lines changed: 38 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import time
55
import zipfile
66
from collections.abc import Callable
7-
from typing import Any
87
from concurrent.futures import ThreadPoolExecutor
98

109
# Third party imports
@@ -41,13 +40,28 @@ def update_last_request_time(current_app: flask.Flask) -> None:
4140
current_app.config.update(LAST_REQUEST_TIME=LAST_REQUEST_TIME)
4241

4342

43+
def terminate_session(exception: BaseException | None) -> None:
44+
session = flask.g.pop("session", None)
45+
if session is None:
46+
return
47+
if exception is None:
48+
session.commit()
49+
else:
50+
session.rollback()
51+
session.close()
52+
53+
4454
def before_request(current_app: flask.Flask) -> None:
4555
increment_request_counter(current_app)
56+
flask.g.session = get_session()
4657

4758

48-
def teardown_request(current_app: flask.Flask) -> None:
59+
def teardown_request(
60+
current_app: flask.Flask, exception: BaseException | None = None
61+
) -> None:
4962
decrement_request_counter(current_app)
5063
update_last_request_time(current_app)
64+
terminate_session(exception)
5165

5266

5367
def kill_task(current_app: flask.Flask) -> None:
@@ -97,7 +111,7 @@ def validate_request(request: flask.Request, schema: dict[str, str]) -> None:
97111

98112

99113
def set_interval(
100-
function: Callable[[Any], None], seconds: float, args: Any
114+
function: Callable[[flask.Flask], None], seconds: float, args: flask.Flask
101115
) -> threading.Timer:
102116
def function_wrapper() -> None:
103117
set_interval(function, seconds, args)
@@ -114,7 +128,7 @@ def extension_from_filename(filename: str) -> str:
114128

115129

116130
def send_file(
117-
upload_folder: str, saved_files: str, new_file_name: str
131+
upload_folder: str, saved_files: list[str], new_file_name: str
118132
) -> flask.Response:
119133
if len(saved_files) == 1:
120134
mimetype = "application/octet-binary"
@@ -162,19 +176,10 @@ def create_data_folder_from_id(data_id: str) -> str:
162176

163177
def save_all_viewables_and_return_info(
164178
geode_object: str,
165-
data: Any,
166-
input_file: str | None = None,
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-
geode_object=geode_object,
174-
input_file=input_file,
175-
additional_files=additional_files,
176-
)
177-
data_path = create_data_folder_from_id(data_entry.id)
179+
data: object,
180+
data_entry: Data,
181+
data_path: str,
182+
) -> dict[str, str | list[str]]:
178183
with ThreadPoolExecutor() as executor:
179184
native_future = executor.submit(
180185
geode_functions.save,
@@ -202,38 +207,40 @@ def save_all_viewables_and_return_info(
202207
data_entry.viewable_file_name = os.path.basename(saved_viewable_file_path)
203208
data_entry.light_viewable = os.path.basename(saved_light_viewable_file_path)
204209

205-
session = get_session()
206-
if session:
207-
session.commit()
208-
209210
return {
210211
"native_file_name": data_entry.native_file_name,
211212
"viewable_file_name": data_entry.viewable_file_name,
212213
"id": data_entry.id,
213214
"object_type": geode_functions.get_object_type(geode_object),
214215
"binary_light_viewable": binary_light_viewable.decode("utf-8"),
215216
"geode_object": data_entry.geode_object,
216-
"input_files": data_entry.input_file,
217+
"input_file": data_entry.input_file,
217218
"additional_files": data_entry.additional_files,
218219
}
219220

220221

221222
def generate_native_viewable_and_light_viewable_from_object(
222-
geode_object: str, data: Any
223-
) -> dict[str, Any]:
224-
return save_all_viewables_and_return_info(geode_object, data, input_file="")
223+
geode_object: str, data: object
224+
) -> dict[str, str | list[str]]:
225+
data_entry = Data.create(
226+
geode_object=geode_object,
227+
input_file="",
228+
additional_files=[],
229+
)
230+
data_path = create_data_folder_from_id(data_entry.id)
231+
return save_all_viewables_and_return_info(geode_object, data, data_entry, data_path)
225232

226233

227234
def generate_native_viewable_and_light_viewable_from_file(
228235
geode_object: str, input_filename: str
229-
) -> dict[str, Any]:
230-
temp_data_entry = Data.create(
236+
) -> dict[str, str | list[str]]:
237+
data_entry = Data.create(
231238
geode_object=geode_object,
232239
input_file=input_filename,
233240
additional_files=[],
234241
)
235242

236-
data_path = create_data_folder_from_id(temp_data_entry.id)
243+
data_path = create_data_folder_from_id(data_entry.id)
237244

238245
full_input_filename = geode_functions.upload_file_path(input_filename)
239246
copied_full_path = os.path.join(
@@ -258,14 +265,10 @@ def generate_native_viewable_and_light_viewable_from_file(
258265

259266
data = geode_functions.load(geode_object, copied_full_path)
260267

261-
session = get_session()
262-
if session:
263-
session.delete(temp_data_entry)
264-
session.flush()
265-
268+
data_entry.additional_files = additional_files_copied
266269
return save_all_viewables_and_return_info(
267270
geode_object,
268271
data,
269-
input_file=input_filename,
270-
additional_files=additional_files_copied,
272+
data_entry,
273+
data_path,
271274
)

tests/conftest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ def configure_test_environment() -> Generator[None, None, None]:
3636
print("Current working directory:", os.getcwd())
3737
print("Directory contents:", os.listdir("."))
3838

39-
init_database(app, db_path)
39+
init_database(db_path)
4040
os.environ["TEST_DB_PATH"] = str(db_path)
4141

4242
yield

0 commit comments

Comments
 (0)