From 711dce97df2e409a1cf678a5aed482d7f40bcd4c Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Wed, 3 Sep 2025 11:55:12 +0200 Subject: [PATCH 01/29] fix(Mypy): add support for type checking --- .vscode/settings.json | 3 ++- mypy.ini | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 mypy.ini diff --git a/.vscode/settings.json b/.vscode/settings.json index 3e99ede3..9a4342b6 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,5 +3,6 @@ "." ], "python.testing.unittestEnabled": false, - "python.testing.pytestEnabled": true + "python.testing.pytestEnabled": true, + "mypy-type-checker.args": ["--config-file=mypy.ini"] } \ No newline at end of file diff --git a/mypy.ini b/mypy.ini new file mode 100644 index 00000000..789aa98a --- /dev/null +++ b/mypy.ini @@ -0,0 +1,2 @@ +strict = True +files = src/ \ No newline at end of file From 5e924fdbd8ab22fa97be86118ee70bf55b59cc90 Mon Sep 17 00:00:00 2001 From: BotellaA <3213882+BotellaA@users.noreply.github.com> Date: Wed, 3 Sep 2025 09:56:09 +0000 Subject: [PATCH 02/29] Apply prepare changes --- commitlint.config.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 commitlint.config.js diff --git a/commitlint.config.js b/commitlint.config.js new file mode 100644 index 00000000..3a29484e --- /dev/null +++ b/commitlint.config.js @@ -0,0 +1,16 @@ +export default { + extends: ["@commitlint/config-angular"], + rules: { + "scope-empty": [2, "never"], + "subject-empty": [2, "never"], + "subject-max-length": [0], + "body-leading-blank": [0], + "footer-leading-blank": [0], + "header-max-length": [0], + "scope-case": [0], + "subject-case": [0], + "subject-full-stop": [0], + "type-case": [0], + "type-empty": [0], + }, +} From a882cd380e2633ed2350df0d0cfb74d54ee8cd7d Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Wed, 3 Sep 2025 12:02:48 +0200 Subject: [PATCH 03/29] empty From e14f64d9f26e8fdd5ee98eba2aa2d773be373b30 Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Wed, 3 Sep 2025 12:07:23 +0200 Subject: [PATCH 04/29] [mypy] --- mypy.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/mypy.ini b/mypy.ini index 789aa98a..82403124 100644 --- a/mypy.ini +++ b/mypy.ini @@ -1,2 +1,3 @@ +[mypy] strict = True files = src/ \ No newline at end of file From bc156ace571ff6f8da7a651884096ebd7a4dbaa9 Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Wed, 3 Sep 2025 12:17:09 +0200 Subject: [PATCH 05/29] trigger From 0d895703c1155f8eeb716029e91496d050c9a04b Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Wed, 3 Sep 2025 12:23:14 +0200 Subject: [PATCH 06/29] skip install type From dc2d1e9e3669c164105de1cf408d32199ab73bbd Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Wed, 3 Sep 2025 13:11:08 +0200 Subject: [PATCH 07/29] fail From 26947f2924df73b4d897200a780b8cde58cd7797 Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Wed, 3 Sep 2025 13:13:36 +0200 Subject: [PATCH 08/29] fail_on_error From 6937f6ba50b0829aa52f3fc99e2f9dfa254902b0 Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Wed, 3 Sep 2025 13:25:25 +0200 Subject: [PATCH 09/29] output_json From dc2116d0e7562629aa89327b19abf1807ed3d306 Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Wed, 3 Sep 2025 13:35:15 +0200 Subject: [PATCH 10/29] test From 703ceb42e8bf3bde3f9645c4b3511376f77f7980 Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Wed, 3 Sep 2025 13:40:13 +0200 Subject: [PATCH 11/29] v4 From 007a6be9aa5585bb562c146c7d496fa6837f2811 Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Wed, 3 Sep 2025 13:47:01 +0200 Subject: [PATCH 12/29] no review From 3f2605dd166a08da0553fe8a34b68aadee66d595 Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Wed, 3 Sep 2025 13:50:09 +0200 Subject: [PATCH 13/29] test From 41e807ee9eb5dca402d5a9f76f96d3307b719ed3 Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Wed, 3 Sep 2025 13:52:23 +0200 Subject: [PATCH 14/29] any From 87f04d7990c0b1d4edea1ce6fd97c6ac449295bc Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Wed, 3 Sep 2025 13:55:02 +0200 Subject: [PATCH 15/29] again From 3a64de1539add912f4092635c9cd5acd24369ac2 Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Wed, 3 Sep 2025 13:58:06 +0200 Subject: [PATCH 16/29] trigger From dd80201838a1870bc555a9b9e99e63ceb01be16b Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Wed, 3 Sep 2025 14:04:33 +0200 Subject: [PATCH 17/29] twice From 5b8f084d3416568184422b990cd860f8a29882d5 Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Wed, 3 Sep 2025 14:08:56 +0200 Subject: [PATCH 18/29] new file --- src/opengeodeweb_back/geode_functions copy.py | 301 ++++++++++++++++++ 1 file changed, 301 insertions(+) create mode 100644 src/opengeodeweb_back/geode_functions copy.py diff --git a/src/opengeodeweb_back/geode_functions copy.py b/src/opengeodeweb_back/geode_functions copy.py new file mode 100644 index 00000000..763a4a7e --- /dev/null +++ b/src/opengeodeweb_back/geode_functions copy.py @@ -0,0 +1,301 @@ +# Standard library imports +import os + +# Third party imports +import opengeode_geosciences as og_gs +import opengeode as og +import werkzeug +import flask + +# Local application imports +from .geode_objects import geode_objects_dict +from . import utils_functions + + +def geode_object_value(geode_object: str): + return geode_objects_dict()[geode_object] + + +def geode_object_class(geode_object: str): + return geode_object_value(geode_object)["class"] + + +def input_factory(geode_object: str): + return geode_object_value(geode_object)["input_factory"] + + +def output_factory(geode_object: str): + return geode_object_value(geode_object)["output_factory"] + + +def additional_files(geode_object: str, file_absolute_path: str): + return geode_object_value(geode_object)["additional_files"](file_absolute_path) + + +def is_loadable(geode_object: str, file_absolute_path: str) -> float: + percentage = geode_object_value(geode_object)["is_loadable"](file_absolute_path) + return percentage.value() + + +def object_priority(geode_object: str, file_absolute_path: str) -> int: + return geode_object_value(geode_object)["object_priority"](file_absolute_path) + + +def load(geode_object: str, file_absolute_path: str): + return geode_object_value(geode_object)["load"](file_absolute_path) + + +def data_file_path(data_id: str, filename: str) -> str: + data_folder_path = flask.current_app.config["DATA_FOLDER_PATH"] + return os.path.join( + data_folder_path, + data_id, + werkzeug.utils.secure_filename(filename), + ) + + +def load_data(geode_object: str, data_id: str, filename: str): + file_absolute_path = data_file_path(data_id, filename) + return load(geode_object, file_absolute_path) + + +def upload_file_path(filename): + upload_folder = flask.current_app.config["UPLOAD_FOLDER"] + secure_filename = werkzeug.utils.secure_filename(filename) + return os.path.abspath(os.path.join(upload_folder, secure_filename)) + + +def is_saveable(geode_object: str, data, filename: str): + return geode_object_value(geode_object)["is_saveable"](data, filename) + + +def save(geode_object: str, data, folder_absolute_path: str, filename: str): + return geode_object_value(geode_object)["save"]( + data, os.path.join(folder_absolute_path, filename) + ) + + +def create_builder(geode_object: str, data): + return geode_object_value(geode_object)["builder"](data) + + +def assign_crs(geode_object: str, data, crs_name: str, info): + builder = create_builder(geode_object, data) + geode_object_value(geode_object)["crs"]["assign"](data, builder, crs_name, info) + + +def convert_crs(geode_object: str, data, crs_name: str, info): + builder = create_builder(geode_object, data) + geode_object_value(geode_object)["crs"]["convert"](data, builder, crs_name, info) + + +def create_crs( + geode_object: str, + data, + name: str, + input_coordiante_system, + output_coordiante_system, +): + builder = create_builder(geode_object, data) + geode_object_value(geode_object)["crs"]["create"]( + data, builder, name, input_coordiante_system, output_coordiante_system + ) + + +def get_object_type(geode_object: str): + return geode_object_value(geode_object)["object_type"] + + +def get_elements(geode_object: str): + return geode_object_value(geode_object)["elements"] + + +def is_3D(geode_object: str): + return geode_object_value(geode_object)["is_3D"] + + +def is_viewable(geode_object: str): + return geode_object_value(geode_object)["is_viewable"] + + +def inspect(geode_object: str, data): + return geode_object_value(geode_object)["inspector"](data) + + +def save_viewable(geode_object: str, data, folder_absolute_path: str, id: str): + return geode_object_value(geode_object)["save_viewable"]( + data, os.path.join(folder_absolute_path, id) + ) + + +def save_light_viewable(geode_object: str, data, folder_absolute_path: str, id: str): + return geode_object_value(geode_object)["save_light_viewable"]( + data, os.path.join(folder_absolute_path, id) + ) + + +def geode_object_input_extensions(geode_object: str): + geode_object_input_list_creators = input_factory(geode_object).list_creators() + geode_object_input_list_creators.sort() + return geode_object_input_list_creators + + +def geode_object_output_extensions(geode_object: str): + geode_object_output_list_creators = output_factory(geode_object).list_creators() + geode_object_output_list_creators.sort() + return geode_object_output_list_creators + + +def filter_geode_objects(key: str = None): + geode_objects_filtered_list = [] + for geode_object, value in geode_objects_dict().items(): + if key != None and key != "": + if key in value: + if type(value[key]) == bool: + geode_objects_filtered_list.append(geode_object) + else: + geode_objects_filtered_list.append(geode_object) + else: + geode_objects_filtered_list.append(geode_object) + geode_objects_filtered_list.sort() + return geode_objects_filtered_list + + +def list_input_extensions(key: str = None): + extensions_list = [] + geode_objects_filtered_list = filter_geode_objects(key) + for geode_object in geode_objects_filtered_list: + extensions_list += geode_object_input_extensions(geode_object) + + extensions_list = list(set(extensions_list)) + extensions_list.sort() + return extensions_list + + +def has_creator(geode_object: str, extension: str): + return input_factory(geode_object).has_creator(extension) + + +def list_geode_objects( + file_absolute_path: str, + key: str = None, +): + return_dict = {} + file_extension = utils_functions.extension_from_filename( + os.path.basename(file_absolute_path) + ) + geode_objects_filtered_list = filter_geode_objects(key) + for geode_object in geode_objects_filtered_list: + if has_creator(geode_object, file_extension): + loadability_score = is_loadable(geode_object, file_absolute_path) + priority_score = object_priority(geode_object, file_absolute_path) + return_dict[geode_object] = { + "is_loadable": loadability_score, + "object_priority": priority_score, + } + return return_dict + + +def geode_objects_output_extensions(geode_object: str, data): + geode_objects_output_extensions_dict = {} + output_extensions = geode_object_output_extensions(geode_object) + extensions_dict = {} + for output_extension in output_extensions: + bool_is_saveable = is_saveable(geode_object, data, f"test.{output_extension}") + extensions_dict[output_extension] = {"is_saveable": bool_is_saveable} + geode_objects_output_extensions_dict[geode_object] = extensions_dict + + if "parent" in geode_object_value(geode_object).keys(): + parent_geode_object = geode_object_value(geode_object)["parent"] + geode_objects_output_extensions_dict.update( + geode_objects_output_extensions(parent_geode_object, data) + ) + return geode_objects_output_extensions_dict + + +def get_inspector_children(obj): + new_object = {} + + if "inspection_type" in dir(obj): + new_object["title"] = obj.inspection_type() + new_object["nb_issues"] = 0 + new_object["children"] = [] + for child in dir(obj): + if not child.startswith("__") and not child in [ + "inspection_type", + "string", + ]: + child_instance = obj.__getattribute__(child) + child_object = get_inspector_children(child_instance) + new_object["children"].append(child_object) + new_object["nb_issues"] += child_object["nb_issues"] + else: + new_object["title"] = obj.description() + nb_issues = obj.nb_issues() + new_object["nb_issues"] = nb_issues + if nb_issues > 0: + issues = obj.string().split("\n") + new_object["issues"] = issues + return new_object + + +def geographic_coordinate_systems(geode_object: str): + if is_3D(geode_object): + return og_gs.GeographicCoordinateSystem3D.geographic_coordinate_systems() + else: + return og_gs.GeographicCoordinateSystem2D.geographic_coordinate_systems() + + +def geographic_coordinate_systems_info(geode_object: str, crs): + if is_3D(geode_object): + return og_gs.GeographicCoordinateSystemInfo3D( + crs["authority"], crs["code"], crs["name"] + ) + else: + return og_gs.GeographicCoordinateSystemInfo2D( + crs["authority"], crs["code"], crs["name"] + ) + + +def coordinate_system(geode_object: str, coordinate_system): + return og.CoordinateSystem2D( + [ + og.Vector2D( + og.Point2D( + [coordinate_system["origin_x"], coordinate_system["origin_y"]] + ), + og.Point2D( + [coordinate_system["point_1_x"], coordinate_system["point_1_y"]] + ), + ), + og.Vector2D( + og.Point2D( + [coordinate_system["origin_x"], coordinate_system["origin_y"]] + ), + og.Point2D( + [coordinate_system["point_2_x"], coordinate_system["point_2_y"]] + ), + ), + ], + og.Point2D([coordinate_system["origin_x"], coordinate_system["origin_y"]]), + ) + + +def assign_geographic_coordinate_system_info(geode_object: str, data, input_crs): + info = geographic_coordinate_systems_info(geode_object, input_crs) + assign_crs(geode_object, data, input_crs["name"], info) + + +def convert_geographic_coordinate_system_info(geode_object: str, data, output_crs): + info = geographic_coordinate_systems_info(geode_object, output_crs) + convert_crs(geode_object, data, output_crs["name"], info) + + +def create_coordinate_system( + geode_object: str, data, name, input_coordinate_points, output_coordinate_points +): + input_coordiante_system = coordinate_system(geode_object, input_coordinate_points) + output_coordiante_system = coordinate_system(geode_object, output_coordinate_points) + create_crs( + geode_object, data, name, input_coordiante_system, output_coordiante_system + ) From b08b65f56091cc74898f3840c77bb77f60fc211c Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Wed, 3 Sep 2025 14:12:37 +0200 Subject: [PATCH 19/29] nofilter From d1eca3f517f9aabe667140dbd265b68c8394e879 Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Wed, 3 Sep 2025 14:55:28 +0200 Subject: [PATCH 20/29] filter_mode --- .../{geode_functions copy.py => geode_functionscopy.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/opengeodeweb_back/{geode_functions copy.py => geode_functionscopy.py} (100%) diff --git a/src/opengeodeweb_back/geode_functions copy.py b/src/opengeodeweb_back/geode_functionscopy.py similarity index 100% rename from src/opengeodeweb_back/geode_functions copy.py rename to src/opengeodeweb_back/geode_functionscopy.py From 12f5521ddc43ffee02bb0ff89a8bea5a0d96e143 Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Wed, 3 Sep 2025 14:59:43 +0200 Subject: [PATCH 21/29] github-pr-check From 9d4ea0ee23c67d6e4856968da433e67dfde4c807 Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Wed, 3 Sep 2025 15:02:34 +0200 Subject: [PATCH 22/29] revert --- src/opengeodeweb_back/geode_functionscopy.py | 301 ------------------- 1 file changed, 301 deletions(-) delete mode 100644 src/opengeodeweb_back/geode_functionscopy.py diff --git a/src/opengeodeweb_back/geode_functionscopy.py b/src/opengeodeweb_back/geode_functionscopy.py deleted file mode 100644 index 763a4a7e..00000000 --- a/src/opengeodeweb_back/geode_functionscopy.py +++ /dev/null @@ -1,301 +0,0 @@ -# Standard library imports -import os - -# Third party imports -import opengeode_geosciences as og_gs -import opengeode as og -import werkzeug -import flask - -# Local application imports -from .geode_objects import geode_objects_dict -from . import utils_functions - - -def geode_object_value(geode_object: str): - return geode_objects_dict()[geode_object] - - -def geode_object_class(geode_object: str): - return geode_object_value(geode_object)["class"] - - -def input_factory(geode_object: str): - return geode_object_value(geode_object)["input_factory"] - - -def output_factory(geode_object: str): - return geode_object_value(geode_object)["output_factory"] - - -def additional_files(geode_object: str, file_absolute_path: str): - return geode_object_value(geode_object)["additional_files"](file_absolute_path) - - -def is_loadable(geode_object: str, file_absolute_path: str) -> float: - percentage = geode_object_value(geode_object)["is_loadable"](file_absolute_path) - return percentage.value() - - -def object_priority(geode_object: str, file_absolute_path: str) -> int: - return geode_object_value(geode_object)["object_priority"](file_absolute_path) - - -def load(geode_object: str, file_absolute_path: str): - return geode_object_value(geode_object)["load"](file_absolute_path) - - -def data_file_path(data_id: str, filename: str) -> str: - data_folder_path = flask.current_app.config["DATA_FOLDER_PATH"] - return os.path.join( - data_folder_path, - data_id, - werkzeug.utils.secure_filename(filename), - ) - - -def load_data(geode_object: str, data_id: str, filename: str): - file_absolute_path = data_file_path(data_id, filename) - return load(geode_object, file_absolute_path) - - -def upload_file_path(filename): - upload_folder = flask.current_app.config["UPLOAD_FOLDER"] - secure_filename = werkzeug.utils.secure_filename(filename) - return os.path.abspath(os.path.join(upload_folder, secure_filename)) - - -def is_saveable(geode_object: str, data, filename: str): - return geode_object_value(geode_object)["is_saveable"](data, filename) - - -def save(geode_object: str, data, folder_absolute_path: str, filename: str): - return geode_object_value(geode_object)["save"]( - data, os.path.join(folder_absolute_path, filename) - ) - - -def create_builder(geode_object: str, data): - return geode_object_value(geode_object)["builder"](data) - - -def assign_crs(geode_object: str, data, crs_name: str, info): - builder = create_builder(geode_object, data) - geode_object_value(geode_object)["crs"]["assign"](data, builder, crs_name, info) - - -def convert_crs(geode_object: str, data, crs_name: str, info): - builder = create_builder(geode_object, data) - geode_object_value(geode_object)["crs"]["convert"](data, builder, crs_name, info) - - -def create_crs( - geode_object: str, - data, - name: str, - input_coordiante_system, - output_coordiante_system, -): - builder = create_builder(geode_object, data) - geode_object_value(geode_object)["crs"]["create"]( - data, builder, name, input_coordiante_system, output_coordiante_system - ) - - -def get_object_type(geode_object: str): - return geode_object_value(geode_object)["object_type"] - - -def get_elements(geode_object: str): - return geode_object_value(geode_object)["elements"] - - -def is_3D(geode_object: str): - return geode_object_value(geode_object)["is_3D"] - - -def is_viewable(geode_object: str): - return geode_object_value(geode_object)["is_viewable"] - - -def inspect(geode_object: str, data): - return geode_object_value(geode_object)["inspector"](data) - - -def save_viewable(geode_object: str, data, folder_absolute_path: str, id: str): - return geode_object_value(geode_object)["save_viewable"]( - data, os.path.join(folder_absolute_path, id) - ) - - -def save_light_viewable(geode_object: str, data, folder_absolute_path: str, id: str): - return geode_object_value(geode_object)["save_light_viewable"]( - data, os.path.join(folder_absolute_path, id) - ) - - -def geode_object_input_extensions(geode_object: str): - geode_object_input_list_creators = input_factory(geode_object).list_creators() - geode_object_input_list_creators.sort() - return geode_object_input_list_creators - - -def geode_object_output_extensions(geode_object: str): - geode_object_output_list_creators = output_factory(geode_object).list_creators() - geode_object_output_list_creators.sort() - return geode_object_output_list_creators - - -def filter_geode_objects(key: str = None): - geode_objects_filtered_list = [] - for geode_object, value in geode_objects_dict().items(): - if key != None and key != "": - if key in value: - if type(value[key]) == bool: - geode_objects_filtered_list.append(geode_object) - else: - geode_objects_filtered_list.append(geode_object) - else: - geode_objects_filtered_list.append(geode_object) - geode_objects_filtered_list.sort() - return geode_objects_filtered_list - - -def list_input_extensions(key: str = None): - extensions_list = [] - geode_objects_filtered_list = filter_geode_objects(key) - for geode_object in geode_objects_filtered_list: - extensions_list += geode_object_input_extensions(geode_object) - - extensions_list = list(set(extensions_list)) - extensions_list.sort() - return extensions_list - - -def has_creator(geode_object: str, extension: str): - return input_factory(geode_object).has_creator(extension) - - -def list_geode_objects( - file_absolute_path: str, - key: str = None, -): - return_dict = {} - file_extension = utils_functions.extension_from_filename( - os.path.basename(file_absolute_path) - ) - geode_objects_filtered_list = filter_geode_objects(key) - for geode_object in geode_objects_filtered_list: - if has_creator(geode_object, file_extension): - loadability_score = is_loadable(geode_object, file_absolute_path) - priority_score = object_priority(geode_object, file_absolute_path) - return_dict[geode_object] = { - "is_loadable": loadability_score, - "object_priority": priority_score, - } - return return_dict - - -def geode_objects_output_extensions(geode_object: str, data): - geode_objects_output_extensions_dict = {} - output_extensions = geode_object_output_extensions(geode_object) - extensions_dict = {} - for output_extension in output_extensions: - bool_is_saveable = is_saveable(geode_object, data, f"test.{output_extension}") - extensions_dict[output_extension] = {"is_saveable": bool_is_saveable} - geode_objects_output_extensions_dict[geode_object] = extensions_dict - - if "parent" in geode_object_value(geode_object).keys(): - parent_geode_object = geode_object_value(geode_object)["parent"] - geode_objects_output_extensions_dict.update( - geode_objects_output_extensions(parent_geode_object, data) - ) - return geode_objects_output_extensions_dict - - -def get_inspector_children(obj): - new_object = {} - - if "inspection_type" in dir(obj): - new_object["title"] = obj.inspection_type() - new_object["nb_issues"] = 0 - new_object["children"] = [] - for child in dir(obj): - if not child.startswith("__") and not child in [ - "inspection_type", - "string", - ]: - child_instance = obj.__getattribute__(child) - child_object = get_inspector_children(child_instance) - new_object["children"].append(child_object) - new_object["nb_issues"] += child_object["nb_issues"] - else: - new_object["title"] = obj.description() - nb_issues = obj.nb_issues() - new_object["nb_issues"] = nb_issues - if nb_issues > 0: - issues = obj.string().split("\n") - new_object["issues"] = issues - return new_object - - -def geographic_coordinate_systems(geode_object: str): - if is_3D(geode_object): - return og_gs.GeographicCoordinateSystem3D.geographic_coordinate_systems() - else: - return og_gs.GeographicCoordinateSystem2D.geographic_coordinate_systems() - - -def geographic_coordinate_systems_info(geode_object: str, crs): - if is_3D(geode_object): - return og_gs.GeographicCoordinateSystemInfo3D( - crs["authority"], crs["code"], crs["name"] - ) - else: - return og_gs.GeographicCoordinateSystemInfo2D( - crs["authority"], crs["code"], crs["name"] - ) - - -def coordinate_system(geode_object: str, coordinate_system): - return og.CoordinateSystem2D( - [ - og.Vector2D( - og.Point2D( - [coordinate_system["origin_x"], coordinate_system["origin_y"]] - ), - og.Point2D( - [coordinate_system["point_1_x"], coordinate_system["point_1_y"]] - ), - ), - og.Vector2D( - og.Point2D( - [coordinate_system["origin_x"], coordinate_system["origin_y"]] - ), - og.Point2D( - [coordinate_system["point_2_x"], coordinate_system["point_2_y"]] - ), - ), - ], - og.Point2D([coordinate_system["origin_x"], coordinate_system["origin_y"]]), - ) - - -def assign_geographic_coordinate_system_info(geode_object: str, data, input_crs): - info = geographic_coordinate_systems_info(geode_object, input_crs) - assign_crs(geode_object, data, input_crs["name"], info) - - -def convert_geographic_coordinate_system_info(geode_object: str, data, output_crs): - info = geographic_coordinate_systems_info(geode_object, output_crs) - convert_crs(geode_object, data, output_crs["name"], info) - - -def create_coordinate_system( - geode_object: str, data, name, input_coordinate_points, output_coordinate_points -): - input_coordiante_system = coordinate_system(geode_object, input_coordinate_points) - output_coordiante_system = coordinate_system(geode_object, output_coordinate_points) - create_crs( - geode_object, data, name, input_coordiante_system, output_coordiante_system - ) From 583622e5690962d8619d6fc6336a192680d79782 Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Wed, 3 Sep 2025 15:07:18 +0200 Subject: [PATCH 23/29] install_types From 0502230c36ec423a9c25280031039e1254532122 Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Wed, 3 Sep 2025 16:18:59 +0200 Subject: [PATCH 24/29] test --- .vscode/settings.json | 7 ++- src/opengeodeweb_back/geode_functions.py | 4 +- src/opengeodeweb_back/geode_objects.py | 12 ++--- src/opengeodeweb_back/utils_functions.py | 69 +++++++++++++----------- 4 files changed, 52 insertions(+), 40 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 9a4342b6..006e581e 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -4,5 +4,10 @@ ], "python.testing.unittestEnabled": false, "python.testing.pytestEnabled": true, - "mypy-type-checker.args": ["--config-file=mypy.ini"] + "mypy-type-checker.args": [ + "--config-file=mypy.ini" + ], + "mypy-type-checker.interpreter": [ + "${workspaceFolder}/venv/bin/python" + ] } \ No newline at end of file diff --git a/src/opengeodeweb_back/geode_functions.py b/src/opengeodeweb_back/geode_functions.py index 763a4a7e..2019a162 100644 --- a/src/opengeodeweb_back/geode_functions.py +++ b/src/opengeodeweb_back/geode_functions.py @@ -2,8 +2,8 @@ import os # Third party imports -import opengeode_geosciences as og_gs -import opengeode as og +import opengeode_geosciences as og_gs # type: ignore +import opengeode as og # type: ignore import werkzeug import flask diff --git a/src/opengeodeweb_back/geode_objects.py b/src/opengeodeweb_back/geode_objects.py index 7386f24e..d1f25614 100644 --- a/src/opengeodeweb_back/geode_objects.py +++ b/src/opengeodeweb_back/geode_objects.py @@ -1,12 +1,12 @@ # Standard library imports # Third party imports -import opengeode as og -import opengeode_io as og_io -import opengeode_inspector as og_inspector -import opengeode_geosciences as og_gs -import opengeode_geosciencesio as og_gs_io -import geode_viewables as g_v +import opengeode as og # type: ignore +import opengeode_io as og_io # type: ignore +import opengeode_inspector as og_inspector # type: ignore +import opengeode_geosciences as og_gs # type: ignore +import opengeode_geosciencesio as og_gs_io # type: ignore +import geode_viewables as g_v # type: ignore # Local application imports diff --git a/src/opengeodeweb_back/utils_functions.py b/src/opengeodeweb_back/utils_functions.py index fc1aa143..3efd0af9 100644 --- a/src/opengeodeweb_back/utils_functions.py +++ b/src/opengeodeweb_back/utils_functions.py @@ -4,52 +4,55 @@ import time import uuid import zipfile +from collections.abc import Callable +from typing import Any # Third party imports import flask -import fastjsonschema +import fastjsonschema # type: ignore import importlib.metadata as metadata import shutil +from werkzeug.exceptions import HTTPException import werkzeug # Local application imports from . import geode_functions -def increment_request_counter(current_app): +def increment_request_counter(current_app: flask.Flask) -> None: if "REQUEST_COUNTER" in current_app.config: - REQUEST_COUNTER = int(current_app.config.get("REQUEST_COUNTER")) + REQUEST_COUNTER = int(current_app.config.get("REQUEST_COUNTER", 0)) REQUEST_COUNTER += 1 current_app.config.update(REQUEST_COUNTER=REQUEST_COUNTER) -def decrement_request_counter(current_app): +def decrement_request_counter(current_app: flask.Flask) -> None: if "REQUEST_COUNTER" in current_app.config: - REQUEST_COUNTER = int(current_app.config.get("REQUEST_COUNTER")) + REQUEST_COUNTER = int(current_app.config.get("REQUEST_COUNTER", 0)) REQUEST_COUNTER -= 1 current_app.config.update(REQUEST_COUNTER=REQUEST_COUNTER) -def update_last_request_time(current_app): +def update_last_request_time(current_app: flask.Flask) -> None: if "LAST_REQUEST_TIME" in current_app.config: LAST_REQUEST_TIME = time.time() current_app.config.update(LAST_REQUEST_TIME=LAST_REQUEST_TIME) -def before_request(current_app): +def before_request(current_app: flask.Flask) -> None: increment_request_counter(current_app) -def teardown_request(current_app): +def teardown_request(current_app: flask.Flask) -> None: decrement_request_counter(current_app) update_last_request_time(current_app) -def kill_task(current_app): - REQUEST_COUNTER = int(current_app.config.get("REQUEST_COUNTER")) - LAST_PING_TIME = float(current_app.config.get("LAST_PING_TIME")) - LAST_REQUEST_TIME = float(current_app.config.get("LAST_REQUEST_TIME")) - MINUTES_BEFORE_TIMEOUT = float(current_app.config.get("MINUTES_BEFORE_TIMEOUT")) +def kill_task(current_app: flask.Flask) -> None: + REQUEST_COUNTER = int(current_app.config.get("REQUEST_COUNTER", 0)) + LAST_PING_TIME = float(current_app.config.get("LAST_PING_TIME", 0)) + LAST_REQUEST_TIME = float(current_app.config.get("LAST_REQUEST_TIME", 0)) + MINUTES_BEFORE_TIMEOUT = float(current_app.config.get("MINUTES_BEFORE_TIMEOUT", 0)) current_time = time.time() minutes_since_last_request = (current_time - LAST_REQUEST_TIME) / 60 minutes_since_last_ping = (current_time - LAST_PING_TIME) / 60 @@ -64,12 +67,12 @@ def kill_task(current_app): kill_server() -def kill_server(): +def kill_server() -> None: print("Server timed out due to inactivity, shutting down...", flush=True) os._exit(0) -def versions(list_packages: list): +def versions(list_packages: list[str]) -> list[dict[str, str]]: list_with_versions = [] for package in list_packages: list_with_versions.append( @@ -78,7 +81,7 @@ def versions(list_packages: list): return list_with_versions -def validate_request(request, schema): +def validate_request(request: flask.Request, schema: dict[str, str]) -> None: json_data = request.get_json(force=True, silent=True) if json_data is None: @@ -92,22 +95,26 @@ def validate_request(request, schema): flask.abort(400, error_msg) -def set_interval(func, sec, args=None): - def func_wrapper(): - set_interval(func, sec, args) - func(args) +def set_interval( + function: Callable[[Any], None], seconds: float, args: Any +) -> threading.Timer: + def function_wrapper() -> None: + set_interval(function, seconds, args) + function(args) - t = threading.Timer(sec, func_wrapper) - t.daemon = True - t.start() - return t + timer = threading.Timer(seconds, function_wrapper) + timer.daemon = True + timer.start() + return timer -def extension_from_filename(filename): +def extension_from_filename(filename: str) -> str: return os.path.splitext(filename)[1][1:] -def send_file(upload_folder, saved_files, new_file_name): +def send_file( + upload_folder: str, saved_files: str, new_file_name: str +) -> flask.Response: if len(saved_files) == 1: mimetype = "application/octet-binary" else: @@ -132,13 +139,13 @@ def send_file(upload_folder, saved_files, new_file_name): return response -def handle_exception(e): - response = e.get_response() +def handle_exception(exception: HTTPException) -> flask.Response: + response = exception.get_response() response.data = flask.json.dumps( { - "code": e.code, - "name": e.name, - "description": e.description, + "code": exception.code, + "name": exception.name, + "description": exception.description, } ) response.content_type = "application/json" From a1a0666fc5279969dfa1cc7fe51d05d92cfb6af4 Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Wed, 3 Sep 2025 16:21:28 +0200 Subject: [PATCH 25/29] agan From 199887ada18695ea023a7a2b74e4bef10bc80c00 Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Wed, 3 Sep 2025 16:27:21 +0200 Subject: [PATCH 26/29] last From e81c47275114505e6c6929c1383b0b87e672232b Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Wed, 3 Sep 2025 19:02:21 +0200 Subject: [PATCH 27/29] retry From 4880f4281061aec09e81dfad9eb9ce74a9c46d40 Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Wed, 3 Sep 2025 19:13:40 +0200 Subject: [PATCH 28/29] no build From cb8c4fd076542bac8925a81691a0565e2db70c0b Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Thu, 4 Sep 2025 15:17:38 +0200 Subject: [PATCH 29/29] add ignore --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 1a771f5b..01b64dd9 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,5 @@ __pycache__ .vscode uploads node_modules -schemas.json \ No newline at end of file +schemas.json +.mypy_cache \ No newline at end of file