Skip to content

Commit 409ffe9

Browse files
authored
Merge pull request #223 from Geode-solutions/feat/geode_object_inheritance
feat(geodeObjectInheritance): Blueprint to return a inheritance relaa…
2 parents 357f641 + c9fb3b5 commit 409ffe9

7 files changed

Lines changed: 136 additions & 1 deletion

File tree

opengeodeweb_back_schemas.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,24 @@
294294
],
295295
"additionalProperties": false
296296
},
297+
"geode_object_inheritance": {
298+
"$id": "opengeodeweb_back/geode_object_inheritance",
299+
"route": "/geode_object_inheritance",
300+
"methods": [
301+
"POST"
302+
],
303+
"type": "object",
304+
"properties": {
305+
"geode_object_type": {
306+
"type": "string",
307+
"minLength": 1
308+
}
309+
},
310+
"required": [
311+
"geode_object_type"
312+
],
313+
"additionalProperties": false
314+
},
297315
"export_project": {
298316
"$id": "opengeodeweb_back/export_project",
299317
"route": "/export_project",

requirements.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,3 @@ werkzeug==3.1.2
6060
# flask
6161
# flask-cors
6262

63-
opengeodeweb-microservice==1.*,>=1.0.14

src/opengeodeweb_back/routes/blueprint_routes.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -608,3 +608,48 @@ def import_extension() -> flask.Response:
608608
},
609609
200,
610610
)
611+
612+
613+
@routes.route(
614+
schemas_dict["geode_object_inheritance"]["route"],
615+
methods=schemas_dict["geode_object_inheritance"]["methods"],
616+
)
617+
def geode_object_inheritance() -> flask.Response:
618+
json_data = utils_functions.validate_request(
619+
flask.request, schemas_dict["geode_object_inheritance"]
620+
)
621+
params = schemas.GeodeObjectInheritance.from_dict(json_data)
622+
geode_object_type = params.geode_object_type
623+
target_class = geode_functions.geode_object_from_string(geode_object_type)
624+
625+
def get_all_bases(geode_class: type) -> set[type]:
626+
bases = set()
627+
for base_class in geode_class.__bases__:
628+
if base_class is not object:
629+
bases.add(base_class)
630+
bases.update(get_all_bases(base_class))
631+
return bases
632+
633+
def get_all_subclasses(geode_class: type) -> set[type]:
634+
subclasses = set()
635+
for subclass_class in geode_class.__subclasses__():
636+
subclasses.add(subclass_class)
637+
subclasses.update(get_all_subclasses(subclass_class))
638+
return subclasses
639+
640+
# Extract all related Geode classes (parents and children)
641+
base_classes = get_all_bases(target_class)
642+
subclass_classes = get_all_subclasses(target_class)
643+
644+
# Filter GeodeObjectType to only include registered related objects, excluding target
645+
parents = []
646+
children = []
647+
for geode_object_type_str, geode_class in geode_objects.items():
648+
if geode_class == target_class:
649+
continue
650+
if geode_class in base_classes:
651+
parents.append(geode_object_type_str)
652+
if geode_class in subclass_classes:
653+
children.append(geode_object_type_str)
654+
655+
return flask.make_response({"parents": parents, "children": children}, 200)

src/opengeodeweb_back/routes/schemas/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from .import_extension import *
1313
from .geographic_coordinate_systems import *
1414
from .geode_objects_and_output_extensions import *
15+
from .geode_object_inheritance import *
1516
from .export_project import *
1617
from .edge_attribute_names import *
1718
from .cell_attribute_names import *
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"route": "/geode_object_inheritance",
3+
"methods": [
4+
"POST"
5+
],
6+
"type": "object",
7+
"properties": {
8+
"geode_object_type": {
9+
"type": "string",
10+
"minLength": 1
11+
}
12+
},
13+
"required": [
14+
"geode_object_type"
15+
],
16+
"additionalProperties": false
17+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from dataclasses_json import DataClassJsonMixin
2+
from dataclasses import dataclass
3+
4+
5+
@dataclass
6+
class GeodeObjectInheritance(DataClassJsonMixin):
7+
def __post_init__(self) -> None:
8+
print(self, flush=True)
9+
10+
geode_object_type: str

tests/test_routes.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,3 +379,48 @@ def test_database_uri_path(client: FlaskClient) -> None:
379379
assert app.config["SQLALCHEMY_DATABASE_URI"] == expected_uri
380380

381381
assert os.path.exists(expected_db_path)
382+
383+
384+
def test_geode_object_inheritance(client: FlaskClient) -> None:
385+
route = "/opengeodeweb_back/geode_object_inheritance"
386+
# Test BRep
387+
response = client.post(route, json={"geode_object_type": "BRep"})
388+
assert response.status_code == 200
389+
json_data = response.get_json()
390+
parents = json_data["parents"]
391+
children = json_data["children"]
392+
assert "BRep" not in parents
393+
assert "BRep" not in children
394+
# Descendants
395+
assert "StructuralModel" in children
396+
assert "ImplicitStructuralModel" in children
397+
398+
# Test CrossSection
399+
response = client.post(route, json={"geode_object_type": "CrossSection"})
400+
assert response.status_code == 200
401+
json_data = response.get_json()
402+
parents = json_data["parents"]
403+
children = json_data["children"]
404+
assert "CrossSection" not in parents
405+
assert "CrossSection" not in children
406+
# Parent
407+
assert "Section" in parents
408+
# Descendant
409+
assert "ImplicitCrossSection" in children
410+
411+
# Test PolyhedralSolid3D
412+
response = client.post(route, json={"geode_object_type": "PolyhedralSolid3D"})
413+
assert response.status_code == 200
414+
json_data = response.get_json()
415+
parents = json_data["parents"]
416+
children = json_data["children"]
417+
assert "PolyhedralSolid3D" not in parents
418+
assert "PolyhedralSolid3D" not in children
419+
# Parent
420+
assert "VertexSet" in parents
421+
422+
# Test all params
423+
def get_full_data() -> test_utils.JsonData:
424+
return {"geode_object_type": "BRep"}
425+
426+
test_utils.test_route_wrong_params(client, route, get_full_data)

0 commit comments

Comments
 (0)