From f4a475072879af7d0e938ad57e06b745cd8210f4 Mon Sep 17 00:00:00 2001 From: Sigurd Pettersen Date: Thu, 14 Mar 2024 10:05:30 +0100 Subject: [PATCH] Reorganize repo file structure for python code (#592) --- .github/workflows/webviz.yml | 23 +- .gitignore | 6 +- .vscode/launch.json | 4 +- backend.Dockerfile | 15 - backend/src/backend/primary/main.py | 108 ---- .../src/backend/primary/user_session_proxy.py | 149 ----- backend/src/backend/shared_middleware.py | 21 - .../user_session/inactivity_shutdown.py | 28 - backend/src/backend/user_session/main.py | 39 -- .../backend/user_session/routers/general.py | 37 -- .../user_session/routers/grid/router.py | 520 ------------------ .../services/sumo_access/queries/__init__.py | 0 backend/src/services/utils/__init__.py | 0 backend/src/services/utils/mpl_utils.py | 111 ---- backend/src/services/utils/vtk_utils.py | 298 ---------- backend/src/services/vds_access/__init__.py | 0 backend/tests/__init__.py | 0 backend/tests/unit/__init__.py | 0 backend/tests/unit/services/__init__.py | 0 backend_py/libs/core_utils/poetry.lock | 183 ++++++ backend_py/libs/core_utils/pyproject.toml | 15 + .../core_utils/webviz_pkg/core_utils}/b64.py | 0 .../webviz_pkg/core_utils}/perf_timer.py | 0 .../primary}/.vscode/launch.json | 2 +- backend_py/primary/Dockerfile | 27 + {backend => backend_py/primary}/README.md | 0 {backend => backend_py/primary}/poetry.lock | 84 +-- .../primary/primary}/__init__.py | 0 .../primary/primary}/auth/auth_helper.py | 8 +- .../auth/enforce_logged_in_middleware.py | 2 +- .../primary/primary}/config.py | 0 backend_py/primary/primary/main.py | 120 ++++ ...rocess_time_to_server_timing_middleware.py | 0 .../primary/primary/routers}/__init__.py | 0 .../primary/routers/correlations}/__init__.py | 0 .../primary/routers/correlations/router.py | 0 .../primary}/primary/routers/dev/router.py | 18 +- .../primary}/primary/routers/explore.py | 8 +- .../primary}/primary/routers/general.py | 16 +- .../primary/routers/graph}/__init__.py | 0 .../primary}/primary/routers/graph/router.py | 6 +- .../primary}/primary/routers/graph/schemas.py | 0 .../primary/primary/routers/grid}/__init__.py | 0 .../primary}/primary/routers/grid/router.py | 27 +- .../primary}/primary/routers/grid/schemas.py | 3 +- .../routers/inplace_volumetrics}/__init__.py | 0 .../routers/inplace_volumetrics/router.py | 8 +- .../primary/routers/observations/router.py | 7 +- .../primary/routers/observations/schemas.py | 0 .../primary/routers/parameters/__init__,py | 0 .../primary/routers/parameters/router.py | 8 +- .../primary/routers/parameters/schemas.py | 0 .../primary/routers/polygons}/__init__.py | 0 .../primary/routers/polygons/converters.py | 4 +- .../primary/routers/polygons/router.py | 20 +- .../primary/routers/polygons/schemas.py | 0 .../primary/primary/routers/pvt}/__init__.py | 0 .../primary/routers/pvt/converters.py | 0 .../primary}/primary/routers/pvt/router.py | 6 +- .../primary}/primary/routers/pvt/schemas.py | 0 .../primary}/primary/routers/rft/router.py | 15 +- .../primary}/primary/routers/rft/schemas.py | 0 .../primary/routers/seismic}/__init__.py | 0 .../primary/routers/seismic/router.py | 17 +- .../primary/routers/seismic/schemas.py | 3 +- .../primary/routers/surface}/__init__.py | 0 .../primary/routers/surface/converters.py | 10 +- .../primary/routers/surface/router.py | 26 +- .../primary/routers/surface/schemas.py | 4 +- .../primary/routers/timeseries/converters.py | 6 +- .../primary/routers/timeseries/router.py | 14 +- .../primary/routers/timeseries/schemas.py | 0 .../primary/primary/routers/well}/__init__.py | 0 .../primary/routers/well/converters.py | 5 +- .../primary}/primary/routers/well/router.py | 14 +- .../primary}/primary/routers/well/schemas.py | 0 .../routers/well_completions/router.py | 8 +- .../primary/primary/services}/__init__.py | 0 .../services/graph_access/graph_access.py | 0 .../services/parameter_correlations.py | 4 +- .../primary}/services/service_exceptions.py | 0 .../primary/services/smda_access}/__init__.py | 0 .../mocked_drogon_smda_access/__init__.py | 0 .../_generate_testdata.py | 0 .../_mocked_stratigraphy_access.py | 0 .../_mocked_well_access.py | 0 .../_mocked_wellbore_picks.py | 2 +- .../services/smda_access/queries}/__init__.py | 0 .../smda_access/queries/_get_request.py | 4 +- .../get_field_wellbore_trajectories.py | 2 +- .../queries/get_picks_for_wellbore.py | 0 .../queries/get_stratigraphic_units.py | 2 +- .../smda_access/queries/get_well_headers.py | 2 +- .../queries/get_wellbore_picks_for_field.py | 2 +- .../queries/get_wellbore_trajectory.py | 2 +- .../smda_access/stratigraphy_access.py | 0 .../smda_access/stratigraphy_utils.py | 0 .../primary}/services/smda_access/types.py | 0 .../services/smda_access/well_access.py | 0 .../services/summary_vector_statistics.py | 0 .../primary/services/sumo_access}/__init__.py | 0 .../services/sumo_access/_field_metadata.py | 0 .../primary}/services/sumo_access/_helpers.py | 4 +- .../services/sumo_access/_resampling.py | 0 .../dev/dev_summary_access_test_driver.py | 2 +- .../services/sumo_access/generic_types.py | 0 .../services/sumo_access/grid_access.py | 2 +- .../sumo_access/inplace_volumetrics_access.py | 0 .../sumo_access/observation_access.py | 0 .../services/sumo_access/observation_types.py | 0 .../services/sumo_access/parameter_access.py | 2 +- .../services/sumo_access/parameter_types.py | 0 .../services/sumo_access/polygons_access.py | 2 +- .../services/sumo_access/polygons_types.py | 0 .../services/sumo_access/queries}/__init__.py | 0 .../services/sumo_access/queries/case.py | 0 .../services/sumo_access/queries/cpgrid.py | 0 .../services/sumo_access/rft_access.py | 2 +- .../services/sumo_access/rft_types.py | 0 .../services/sumo_access/seismic_access.py | 0 .../services/sumo_access/seismic_types.py | 0 .../services/sumo_access/summary_access.py | 8 +- .../services/sumo_access/summary_types.py | 0 .../services/sumo_access/sumo_explore.py | 0 .../services/sumo_access/surface_access.py | 4 +- .../services/sumo_access/surface_types.py | 0 .../services/sumo_access/table_access.py | 0 .../sumo_access/well_completions_access.py | 0 .../sumo_access/well_completions_types.py | 0 .../surface_query_service.py | 4 +- .../user_session_manager/_background_tasks.py | 0 .../user_session_manager/_radix_helpers.py | 0 .../_user_session_directory.py | 2 +- .../user_session_manager/_util_classes.py | 0 .../user_session_manager.py | 2 +- .../primary/services/utils}/__init__.py | 0 .../primary}/services/utils/arrow_helpers.py | 0 .../services/utils/authenticated_user.py | 2 +- .../services/utils/statistic_function.py | 0 .../services/utils/surface_orientation.py | 0 .../services/utils/surface_to_float32.py | 0 .../primary}/services/utils/surface_to_png.py | 0 .../primary/services/vds_access}/__init__.py | 0 .../services/vds_access/request_types.py | 0 .../services/vds_access/response_types.py | 0 .../services/vds_access/vds_access.py | 2 +- .../primary}/utils/azure_monitor_setup.py | 0 .../primary}/utils/exception_handlers.py | 2 +- .../primary/primary}/utils/logging_setup.py | 0 .../primary/primary}/utils/perf_metrics.py | 2 +- .../primary}/pyproject.toml | 9 +- .../primary/tests}/__init__.py | 0 .../tests/integration/services/conftest.py | 0 .../sumo_access/test_parameter_access.py | 0 .../primary/tests/unit}/__init__.py | 0 .../primary/tests/unit/services}/__init__.py | 0 .../smda_access/test_stratigraphy_utils.py | 8 +- .../services/sumo_access/test_resampling.py | 2 +- .../unit/services/utils/test_arrow_helpers.py | 5 +- docker-compose.yml | 29 +- frontend/src/api/services/DefaultService.ts | 12 - .../private-components/UserSessionState.tsx | 19 +- radixconfig.yml | 72 +-- 163 files changed, 556 insertions(+), 1715 deletions(-) delete mode 100644 backend.Dockerfile delete mode 100644 backend/src/backend/primary/main.py delete mode 100644 backend/src/backend/primary/user_session_proxy.py delete mode 100644 backend/src/backend/shared_middleware.py delete mode 100644 backend/src/backend/user_session/inactivity_shutdown.py delete mode 100644 backend/src/backend/user_session/main.py delete mode 100644 backend/src/backend/user_session/routers/general.py delete mode 100644 backend/src/backend/user_session/routers/grid/router.py delete mode 100644 backend/src/services/sumo_access/queries/__init__.py delete mode 100644 backend/src/services/utils/__init__.py delete mode 100644 backend/src/services/utils/mpl_utils.py delete mode 100644 backend/src/services/utils/vtk_utils.py delete mode 100644 backend/src/services/vds_access/__init__.py delete mode 100644 backend/tests/__init__.py delete mode 100644 backend/tests/unit/__init__.py delete mode 100644 backend/tests/unit/services/__init__.py create mode 100644 backend_py/libs/core_utils/poetry.lock create mode 100644 backend_py/libs/core_utils/pyproject.toml rename {backend/src/services/utils => backend_py/libs/core_utils/webviz_pkg/core_utils}/b64.py (100%) rename {backend/src/services/utils => backend_py/libs/core_utils/webviz_pkg/core_utils}/perf_timer.py (100%) rename {backend => backend_py/primary}/.vscode/launch.json (82%) create mode 100644 backend_py/primary/Dockerfile rename {backend => backend_py/primary}/README.md (100%) rename {backend => backend_py/primary}/poetry.lock (97%) rename {backend/src => backend_py/primary/primary}/__init__.py (100%) rename {backend/src/backend => backend_py/primary/primary}/auth/auth_helper.py (98%) rename {backend/src/backend => backend_py/primary/primary}/auth/enforce_logged_in_middleware.py (98%) rename {backend/src => backend_py/primary/primary}/config.py (100%) create mode 100644 backend_py/primary/primary/main.py rename {backend/src/backend/utils => backend_py/primary/primary/middleware}/add_process_time_to_server_timing_middleware.py (100%) rename {backend/src/backend => backend_py/primary/primary/routers}/__init__.py (100%) rename {backend/src/backend/auth => backend_py/primary/primary/routers/correlations}/__init__.py (100%) rename {backend/src/backend => backend_py/primary}/primary/routers/correlations/router.py (100%) rename {backend/src/backend => backend_py/primary}/primary/routers/dev/router.py (87%) rename {backend/src/backend => backend_py/primary}/primary/routers/explore.py (92%) rename {backend/src/backend => backend_py/primary}/primary/routers/general.py (79%) rename {backend/src/backend/primary => backend_py/primary/primary/routers/graph}/__init__.py (100%) rename {backend/src/backend => backend_py/primary}/primary/routers/graph/router.py (86%) rename {backend/src/backend => backend_py/primary}/primary/routers/graph/schemas.py (100%) rename {backend/src/backend/primary/routers => backend_py/primary/primary/routers/grid}/__init__.py (100%) rename {backend/src/backend => backend_py/primary}/primary/routers/grid/router.py (89%) rename {backend/src/backend => backend_py/primary}/primary/routers/grid/schemas.py (86%) rename {backend/src/backend/primary/routers/correlations => backend_py/primary/primary/routers/inplace_volumetrics}/__init__.py (100%) rename {backend/src/backend => backend_py/primary}/primary/routers/inplace_volumetrics/router.py (93%) rename {backend/src/backend => backend_py/primary}/primary/routers/observations/router.py (75%) rename {backend/src/backend => backend_py/primary}/primary/routers/observations/schemas.py (100%) rename {backend/src/backend => backend_py/primary}/primary/routers/parameters/__init__,py (100%) rename {backend/src/backend => backend_py/primary}/primary/routers/parameters/router.py (93%) rename {backend/src/backend => backend_py/primary}/primary/routers/parameters/schemas.py (100%) rename {backend/src/backend/primary/routers/graph => backend_py/primary/primary/routers/polygons}/__init__.py (100%) rename {backend/src/backend => backend_py/primary}/primary/routers/polygons/converters.py (95%) rename {backend/src/backend => backend_py/primary}/primary/routers/polygons/router.py (80%) rename {backend/src/backend => backend_py/primary}/primary/routers/polygons/schemas.py (100%) rename {backend/src/backend/primary/routers/grid => backend_py/primary/primary/routers/pvt}/__init__.py (100%) rename {backend/src/backend => backend_py/primary}/primary/routers/pvt/converters.py (100%) rename {backend/src/backend => backend_py/primary}/primary/routers/pvt/router.py (92%) rename {backend/src/backend => backend_py/primary}/primary/routers/pvt/schemas.py (100%) rename {backend/src/backend => backend_py/primary}/primary/routers/rft/router.py (76%) rename {backend/src/backend => backend_py/primary}/primary/routers/rft/schemas.py (100%) rename {backend/src/backend/primary/routers/inplace_volumetrics => backend_py/primary/primary/routers/seismic}/__init__.py (100%) rename {backend/src/backend => backend_py/primary}/primary/routers/seismic/router.py (87%) rename {backend/src/backend => backend_py/primary}/primary/routers/seismic/schemas.py (97%) rename {backend/src/backend/primary/routers/polygons => backend_py/primary/primary/routers/surface}/__init__.py (100%) rename {backend/src/backend => backend_py/primary}/primary/routers/surface/converters.py (92%) rename {backend/src/backend => backend_py/primary}/primary/routers/surface/router.py (92%) rename {backend/src/backend => backend_py/primary}/primary/routers/surface/schemas.py (96%) rename {backend/src/backend => backend_py/primary}/primary/routers/timeseries/converters.py (89%) rename {backend/src/backend => backend_py/primary}/primary/routers/timeseries/router.py (96%) rename {backend/src/backend => backend_py/primary}/primary/routers/timeseries/schemas.py (100%) rename {backend/src/backend/primary/routers/pvt => backend_py/primary/primary/routers/well}/__init__.py (100%) rename {backend/src/backend => backend_py/primary}/primary/routers/well/converters.py (91%) rename {backend/src/backend => backend_py/primary}/primary/routers/well/router.py (91%) rename {backend/src/backend => backend_py/primary}/primary/routers/well/schemas.py (100%) rename {backend/src/backend => backend_py/primary}/primary/routers/well_completions/router.py (77%) rename {backend/src/backend/primary/routers/seismic => backend_py/primary/primary/services}/__init__.py (100%) rename {backend/src => backend_py/primary/primary}/services/graph_access/graph_access.py (100%) rename {backend/src => backend_py/primary/primary}/services/parameter_correlations.py (92%) rename {backend/src => backend_py/primary/primary}/services/service_exceptions.py (100%) rename {backend/src/backend/primary/routers/surface => backend_py/primary/primary/services/smda_access}/__init__.py (100%) rename {backend/src => backend_py/primary/primary}/services/smda_access/mocked_drogon_smda_access/__init__.py (100%) rename {backend/src => backend_py/primary/primary}/services/smda_access/mocked_drogon_smda_access/_generate_testdata.py (100%) rename {backend/src => backend_py/primary/primary}/services/smda_access/mocked_drogon_smda_access/_mocked_stratigraphy_access.py (100%) rename {backend/src => backend_py/primary/primary}/services/smda_access/mocked_drogon_smda_access/_mocked_well_access.py (100%) rename {backend/src => backend_py/primary/primary}/services/smda_access/mocked_drogon_smda_access/_mocked_wellbore_picks.py (98%) rename {backend/src/backend/primary/routers/well => backend_py/primary/primary/services/smda_access/queries}/__init__.py (100%) rename {backend/src => backend_py/primary/primary}/services/smda_access/queries/_get_request.py (95%) rename {backend/src => backend_py/primary/primary}/services/smda_access/queries/get_field_wellbore_trajectories.py (96%) rename {backend/src => backend_py/primary/primary}/services/smda_access/queries/get_picks_for_wellbore.py (100%) rename {backend/src => backend_py/primary/primary}/services/smda_access/queries/get_stratigraphic_units.py (93%) rename {backend/src => backend_py/primary/primary}/services/smda_access/queries/get_well_headers.py (93%) rename {backend/src => backend_py/primary/primary}/services/smda_access/queries/get_wellbore_picks_for_field.py (94%) rename {backend/src => backend_py/primary/primary}/services/smda_access/queries/get_wellbore_trajectory.py (96%) rename {backend/src => backend_py/primary/primary}/services/smda_access/stratigraphy_access.py (100%) rename {backend/src => backend_py/primary/primary}/services/smda_access/stratigraphy_utils.py (100%) rename {backend/src => backend_py/primary/primary}/services/smda_access/types.py (100%) rename {backend/src => backend_py/primary/primary}/services/smda_access/well_access.py (100%) rename {backend/src => backend_py/primary/primary}/services/summary_vector_statistics.py (100%) rename {backend/src/backend/user_session => backend_py/primary/primary/services/sumo_access}/__init__.py (100%) rename {backend/src => backend_py/primary/primary}/services/sumo_access/_field_metadata.py (100%) rename {backend/src => backend_py/primary/primary}/services/sumo_access/_helpers.py (96%) rename {backend/src => backend_py/primary/primary}/services/sumo_access/_resampling.py (100%) rename {backend/src => backend_py/primary/primary}/services/sumo_access/dev/dev_summary_access_test_driver.py (97%) rename {backend/src => backend_py/primary/primary}/services/sumo_access/generic_types.py (100%) rename {backend/src => backend_py/primary/primary}/services/sumo_access/grid_access.py (97%) rename {backend/src => backend_py/primary/primary}/services/sumo_access/inplace_volumetrics_access.py (100%) rename {backend/src => backend_py/primary/primary}/services/sumo_access/observation_access.py (100%) rename {backend/src => backend_py/primary/primary}/services/sumo_access/observation_types.py (100%) rename {backend/src => backend_py/primary/primary}/services/sumo_access/parameter_access.py (98%) rename {backend/src => backend_py/primary/primary}/services/sumo_access/parameter_types.py (100%) rename {backend/src => backend_py/primary/primary}/services/sumo_access/polygons_access.py (98%) rename {backend/src => backend_py/primary/primary}/services/sumo_access/polygons_types.py (100%) rename {backend/src/backend/user_session/routers => backend_py/primary/primary/services/sumo_access/queries}/__init__.py (100%) rename {backend/src => backend_py/primary/primary}/services/sumo_access/queries/case.py (100%) rename {backend/src => backend_py/primary/primary}/services/sumo_access/queries/cpgrid.py (100%) rename {backend/src => backend_py/primary/primary}/services/sumo_access/rft_access.py (99%) rename {backend/src => backend_py/primary/primary}/services/sumo_access/rft_types.py (100%) rename {backend/src => backend_py/primary/primary}/services/sumo_access/seismic_access.py (100%) rename {backend/src => backend_py/primary/primary}/services/sumo_access/seismic_types.py (100%) rename {backend/src => backend_py/primary/primary}/services/sumo_access/summary_access.py (98%) rename {backend/src => backend_py/primary/primary}/services/sumo_access/summary_types.py (100%) rename {backend/src => backend_py/primary/primary}/services/sumo_access/sumo_explore.py (100%) rename {backend/src => backend_py/primary/primary}/services/sumo_access/surface_access.py (98%) rename {backend/src => backend_py/primary/primary}/services/sumo_access/surface_types.py (100%) rename {backend/src => backend_py/primary/primary}/services/sumo_access/table_access.py (100%) rename {backend/src => backend_py/primary/primary}/services/sumo_access/well_completions_access.py (100%) rename {backend/src => backend_py/primary/primary}/services/sumo_access/well_completions_types.py (100%) rename {backend/src => backend_py/primary/primary}/services/surface_query_service/surface_query_service.py (97%) rename {backend/src => backend_py/primary/primary}/services/user_session_manager/_background_tasks.py (100%) rename {backend/src => backend_py/primary/primary}/services/user_session_manager/_radix_helpers.py (100%) rename {backend/src => backend_py/primary/primary}/services/user_session_manager/_user_session_directory.py (99%) rename {backend/src => backend_py/primary/primary}/services/user_session_manager/_util_classes.py (100%) rename {backend/src => backend_py/primary/primary}/services/user_session_manager/user_session_manager.py (99%) rename {backend/src/backend/user_session/routers/grid => backend_py/primary/primary/services/utils}/__init__.py (100%) rename {backend/src => backend_py/primary/primary}/services/utils/arrow_helpers.py (100%) rename {backend/src => backend_py/primary/primary}/services/utils/authenticated_user.py (96%) rename {backend/src => backend_py/primary/primary}/services/utils/statistic_function.py (100%) rename {backend/src => backend_py/primary/primary}/services/utils/surface_orientation.py (100%) rename {backend/src => backend_py/primary/primary}/services/utils/surface_to_float32.py (100%) rename {backend/src => backend_py/primary/primary}/services/utils/surface_to_png.py (100%) rename {backend/src/services => backend_py/primary/primary/services/vds_access}/__init__.py (100%) rename {backend/src => backend_py/primary/primary}/services/vds_access/request_types.py (100%) rename {backend/src => backend_py/primary/primary}/services/vds_access/response_types.py (100%) rename {backend/src => backend_py/primary/primary}/services/vds_access/vds_access.py (99%) rename {backend/src/backend => backend_py/primary/primary}/utils/azure_monitor_setup.py (100%) rename {backend/src/backend => backend_py/primary/primary}/utils/exception_handlers.py (98%) rename {backend/src/backend => backend_py/primary/primary}/utils/logging_setup.py (100%) rename {backend/src/backend => backend_py/primary/primary}/utils/perf_metrics.py (97%) rename {backend => backend_py/primary}/pyproject.toml (93%) rename {backend/src/services/smda_access => backend_py/primary/tests}/__init__.py (100%) rename {backend => backend_py/primary}/tests/integration/services/conftest.py (100%) rename {backend => backend_py/primary}/tests/integration/services/sumo_access/test_parameter_access.py (100%) rename {backend/src/services/smda_access/queries => backend_py/primary/tests/unit}/__init__.py (100%) rename {backend/src/services/sumo_access => backend_py/primary/tests/unit/services}/__init__.py (100%) rename {backend => backend_py/primary}/tests/unit/services/smda_access/test_stratigraphy_utils.py (89%) rename {backend => backend_py/primary}/tests/unit/services/sumo_access/test_resampling.py (99%) rename {backend => backend_py/primary}/tests/unit/services/utils/test_arrow_helpers.py (88%) diff --git a/.github/workflows/webviz.yml b/.github/workflows/webviz.yml index fdb3e3159..c6ffdbb21 100644 --- a/.github/workflows/webviz.yml +++ b/.github/workflows/webviz.yml @@ -70,9 +70,9 @@ jobs: - name: 🕵️ Check auto-generated frontend code is in sync with backend run: | - docker build -f backend.Dockerfile -t backend:latest . - CONTAINER_ID=$(docker run --detach -p 5000:5000 --env UVICORN_PORT=5000 --env UVICORN_ENTRYPOINT=src.backend.primary.main:app --env WEBVIZ_CLIENT_SECRET=0 --env WEBVIZ_SMDA_SUBSCRIPTION_KEY=0 --env WEBVIZ_SMDA_RESOURCE_SCOPE=0 --env WEBVIZ_VDS_HOST_ADDRESS=0 backend:latest) - sleep 5 # Ensure the backend server is up and running exposing /openapi.json + docker build -f ./backend_py/primary/Dockerfile -t backend:latest . + CONTAINER_ID=$(docker run --detach -p 5000:5000 --env UVICORN_PORT=5000 --env WEBVIZ_CLIENT_SECRET=0 --env WEBVIZ_SMDA_SUBSCRIPTION_KEY=0 --env WEBVIZ_SMDA_RESOURCE_SCOPE=0 --env WEBVIZ_VDS_HOST_ADDRESS=0 backend:latest) + sleep 10 # Ensure the backend server is up and running exposing /openapi.json npm run generate-api --prefix ./frontend docker stop $CONTAINER_ID git diff --exit-code ./frontend/src/api || exit 1 @@ -91,7 +91,7 @@ jobs: cache: pip - name: 📦 Install poetry and dependencies - working-directory: ./backend + working-directory: ./backend_py/primary run: | pip install --upgrade pip pip install poetry @@ -100,15 +100,16 @@ jobs: poetry install --with dev - name: 🕵️ Check code style & linting - working-directory: ./backend + working-directory: ./backend_py/primary run: | - black --check src/ tests/ - pylint src/ tests/ - bandit --recursive src/ - mypy src/ tests/ + set -x + black --check primary/ tests/ + pylint primary/ tests/ + bandit --recursive primary/ + mypy primary/ tests/ - name: 🤖 Run tests - working-directory: ./backend + working-directory: ./backend_py/primary env: WEBVIZ_CLIENT_SECRET: 0 WEBVIZ_SMDA_SUBSCRIPTION_KEY: 0 @@ -148,4 +149,4 @@ jobs: - name: 🐳 Verify Docker images build run: | docker build -f frontend-prod.Dockerfile . - docker build -f backend.Dockerfile . + docker build -f ./backend_py/primary/Dockerfile . diff --git a/.gitignore b/.gitignore index f7f274172..d1aa4f4e5 100644 --- a/.gitignore +++ b/.gitignore @@ -108,9 +108,10 @@ dist .tern-port # .vscode -.vscode/ +**/.vscode/* !.vscode/tasks.json !.vscode/launch.json +!backend_py/primary/.vscode/launch.json # playwright results playwright-report/ @@ -122,3 +123,6 @@ playwright-report/ # Ignore Jupyter Notebook checkpoints (hidden directories) .ipynb_checkpoints/ + +# Python virtual environments +.venv diff --git a/.vscode/launch.json b/.vscode/launch.json index 116c58dcb..d5196d4dc 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -7,8 +7,8 @@ "connect": { "host": "localhost", "port": 5678 }, "pathMappings": [ { - "localRoot": "${workspaceFolder}/backend", - "remoteRoot": "/home/appuser/backend" + "localRoot": "${workspaceFolder}/backend_py/primary", + "remoteRoot": "/home/appuser/backend_py/primary" } ] }, diff --git a/backend.Dockerfile b/backend.Dockerfile deleted file mode 100644 index ca192388a..000000000 --- a/backend.Dockerfile +++ /dev/null @@ -1,15 +0,0 @@ -FROM python:3.11-slim@sha256:ad2c4e5884418404c5289acad4a471dde8500e24ba57ad574cdcae46523e507a - -RUN useradd --create-home --uid 1234 appuser # Changing to non-root user early - -USER 1234 - -COPY --chown=appuser ./backend /home/appuser/backend -WORKDIR /home/appuser/backend - -ENV PATH="${PATH}:/home/appuser/.local/bin" -RUN pip install poetry \ - && poetry export -f requirements.txt -o requirements.txt \ - && pip install -r requirements.txt - -CMD exec uvicorn --proxy-headers --host=0.0.0.0 $UVICORN_ENTRYPOINT diff --git a/backend/src/backend/primary/main.py b/backend/src/backend/primary/main.py deleted file mode 100644 index 4e5f9bcb3..000000000 --- a/backend/src/backend/primary/main.py +++ /dev/null @@ -1,108 +0,0 @@ -import datetime -import logging -import os - -from fastapi import FastAPI -from fastapi.routing import APIRoute -from fastapi.responses import ORJSONResponse -from uvicorn.middleware.proxy_headers import ProxyHeadersMiddleware - -from src.backend.utils.add_process_time_to_server_timing_middleware import AddProcessTimeToServerTimingMiddleware -from src.backend.utils.azure_monitor_setup import setup_azure_monitor_telemetry -from src.backend.utils.exception_handlers import override_default_fastapi_exception_handlers -from src.backend.utils.exception_handlers import configure_service_level_exception_handlers -from src.backend.utils.logging_setup import ensure_console_log_handler_is_configured, setup_normal_log_levels -from src.backend.shared_middleware import add_shared_middlewares -from src.backend.auth.auth_helper import AuthHelper -from .routers.explore import router as explore_router -from .routers.general import router as general_router -from .routers.inplace_volumetrics.router import router as inplace_volumetrics_router -from .routers.surface.router import router as surface_router -from .routers.timeseries.router import router as timeseries_router -from .routers.parameters.router import router as parameters_router -from .routers.correlations.router import router as correlations_router -from .routers.grid.router import router as grid_router -from .routers.pvt.router import router as pvt_router -from .routers.well_completions.router import router as well_completions_router -from .routers.well.router import router as well_router -from .routers.seismic.router import router as seismic_router -from .routers.polygons.router import router as polygons_router -from .routers.graph.router import router as graph_router -from .routers.observations.router import router as observations_router -from .routers.rft.router import router as rft_router -from .routers.dev.router import router as dev_router - - -ensure_console_log_handler_is_configured() -setup_normal_log_levels() - -# temporarily set some loggers to DEBUG -# logging.getLogger().setLevel(logging.DEBUG) -logging.getLogger("src.services.sumo_access").setLevel(logging.DEBUG) -logging.getLogger("src.services.user_session_manager").setLevel(logging.DEBUG) -logging.getLogger("src.backend.primary.routers.dev").setLevel(logging.DEBUG) - -LOGGER = logging.getLogger(__name__) - - -def custom_generate_unique_id(route: APIRoute) -> str: - return f"{route.name}" - - -app = FastAPI( - generate_unique_id_function=custom_generate_unique_id, - root_path="/api", - default_response_class=ORJSONResponse, -) - -if os.environ.get("APPLICATIONINSIGHTS_CONNECTION_STRING"): - LOGGER.info("Configuring Azure Monitor telemetry for primary backend") - setup_azure_monitor_telemetry(app) -else: - LOGGER.warning("Skipping telemetry configuration, APPLICATIONINSIGHTS_CONNECTION_STRING env variable not set.") - - -# The tags we add here will determine the name of the frontend api service for our endpoints as well as -# providing some grouping when viewing the openapi documentation. -app.include_router(explore_router, tags=["explore"]) -app.include_router(timeseries_router, prefix="/timeseries", tags=["timeseries"]) -app.include_router( - inplace_volumetrics_router, - prefix="/inplace_volumetrics", - tags=["inplace_volumetrics"], -) -app.include_router(surface_router, prefix="/surface", tags=["surface"]) -app.include_router(parameters_router, prefix="/parameters", tags=["parameters"]) -app.include_router(correlations_router, prefix="/correlations", tags=["correlations"]) -app.include_router(grid_router, prefix="/grid", tags=["grid"]) -app.include_router(pvt_router, prefix="/pvt", tags=["pvt"]) -app.include_router(well_completions_router, prefix="/well_completions", tags=["well_completions"]) -app.include_router(well_router, prefix="/well", tags=["well"]) -app.include_router(seismic_router, prefix="/seismic", tags=["seismic"]) -app.include_router(polygons_router, prefix="/polygons", tags=["polygons"]) -app.include_router(graph_router, prefix="/graph", tags=["graph"]) -app.include_router(observations_router, prefix="/observations", tags=["observations"]) -app.include_router(rft_router, prefix="/rft", tags=["rft"]) -app.include_router(dev_router, prefix="/dev", tags=["dev"], include_in_schema=False) - -authHelper = AuthHelper() -app.include_router(authHelper.router) -app.include_router(general_router) - -configure_service_level_exception_handlers(app) -override_default_fastapi_exception_handlers(app) - -# This middleware instance approximately measures execution time of the route handler itself -app.add_middleware(AddProcessTimeToServerTimingMiddleware, metric_name="total-exec-route") - -add_shared_middlewares(app) - -app.add_middleware(ProxyHeadersMiddleware, trusted_hosts="*") - -# This middleware instance measures execution time of the endpoints, including the cost of other middleware -app.add_middleware(AddProcessTimeToServerTimingMiddleware, metric_name="total") - - -@app.get("/") -async def root() -> str: - return f"Backend is alive at this time: {datetime.datetime.now()}" diff --git a/backend/src/backend/primary/user_session_proxy.py b/backend/src/backend/primary/user_session_proxy.py deleted file mode 100644 index e7b8d5786..000000000 --- a/backend/src/backend/primary/user_session_proxy.py +++ /dev/null @@ -1,149 +0,0 @@ -import os -import asyncio -from typing import Any, Optional - -import httpx -import redis -from starlette.requests import Request -from starlette.responses import StreamingResponse -from starlette.background import BackgroundTask - -from src import config -from src.services.utils.authenticated_user import AuthenticatedUser - -LOCALHOST_DEVELOPMENT = os.environ.get("UVICORN_RELOAD") == "true" - - -class _RedisUserJobs: - def __init__(self) -> None: - # redis.Redis does not yet have namespace support - https://github.com/redis/redis-py/issues/12 - need to prefix manually. - self._redis_client = redis.Redis.from_url(config.REDIS_USER_SESSION_URL, decode_responses=True) - - def get_job_name(self, user_id: str) -> Optional[str]: - return self._redis_client.get("user-job-name:" + user_id) - - def set_job_name(self, user_id: str, job_name: str) -> None: - self._redis_client.set("user-job-name:" + user_id, job_name) - - -class RadixJobScheduler: - """Utility class to help with spawning Radix jobs on demand, - and provide correct URL to communicate with running Radix jobs""" - - def __init__(self, name: str, port: int) -> None: - self._name = name - self._port = port - self._redis_user_jobs = _RedisUserJobs() - - def _get_job_name(self, user_id: str) -> Optional[str]: - return self._redis_user_jobs.get_job_name(user_id) - - def _set_job_name(self, user_id: str, job_name: str) -> None: - self._redis_user_jobs.set_job_name(user_id, job_name) - - async def _active_running_job(self, user_id: str) -> bool: - """Returns true if there already is a running job for logged in user.""" - - existing_job_name = self._get_job_name(user_id) - if not existing_job_name: - return False - if LOCALHOST_DEVELOPMENT: - return True - - async with httpx.AsyncClient() as client: - res = await client.get(f"http://{self._name}:{self._port}/api/v1/jobs/{existing_job_name}") - - job = res.json() - - if job.get("status") != "Running" or not job.get("started"): - return False - - try: - httpx.get(f"http://{existing_job_name}:{self._port}/") - except (ConnectionRefusedError, httpx.ConnectError, httpx.ConnectTimeout): - print(f"User session container for user {user_id} not yet up.") - return False - - return True - - async def _create_new_job(self, user_id: str) -> None: - """Create a new Radix job by sending request to Radix job scheduler. - If localhost development, simply return already running container with - same name.""" - - if LOCALHOST_DEVELOPMENT: - self._set_job_name(user_id, self._name) - else: - print(f"Requesting new user session container for user {user_id}.") - async with httpx.AsyncClient() as client: - res = await client.post( - f"http://{self._name}:{self._port}/api/v1/jobs", - # Maximum limits in "resources" for a Radix job is as of May 2023 - # the specs of a single Standard_E16as_v4 node, i.e.: - # * vCPU: 16 - # * memory: 128 GiB - # * temp storage (SSD): 256 GiB - # - # As of now our CPU/memory requests are hardcoded below, but in the future maybe - # these could be dynamic based on e.g. the selected ensemble sizess by the user. - json={ - "resources": { - "limits": {"memory": "32GiB", "cpu": "2"}, - "requests": {"memory": "32GiB", "cpu": "1"}, - } - }, - ) - self._set_job_name(user_id, res.json()["name"]) - - while not await self._active_running_job(user_id): - # It takes a couple of seconds before Radix job uvicorn process has - # started and begins to listen at the end point. - await asyncio.sleep(1) - - async def get_base_url(self, user_id: str) -> str: - """Input is ID of logged in user. Returned value is base URL towards the correct - Radix job""" - if not await self._active_running_job(user_id): - await self._create_new_job(user_id) - - job_name = self._get_job_name(user_id) - - return f"http://{job_name}:{self._port}" - - -# For now we only have one type of job: -RADIX_JOB_SCHEDULER_INSTANCE = RadixJobScheduler("backend-user-session", 8000) - - -async def proxy_to_user_session(request: Request, authenticated_user: AuthenticatedUser) -> Any: - # Ideally this function should probably be a starlette/FastAPI middleware, but it appears that - # it is not yet possible to put middleware on single routes through decorator like in express.js. - - base_url = await RADIX_JOB_SCHEDULER_INSTANCE.get_base_url( - authenticated_user._user_id # pylint: disable=protected-access - ) - - # See https://github.com/tiangolo/fastapi/discussions/7382: - - client = httpx.AsyncClient(base_url=base_url) - - url = httpx.URL( - path=request.url.path.removeprefix("/api").rstrip("/"), - query=request.url.query.encode("utf-8"), - ) - - job_req = client.build_request( - request.method, - url, - headers=request.headers.raw, - content=request.stream(), - timeout=600, - ) - job_resp = await client.send(job_req, stream=True) - - return StreamingResponse( - job_resp.aiter_raw(), - status_code=job_resp.status_code, - headers=job_resp.headers, - background=BackgroundTask(job_resp.aclose), - ) diff --git a/backend/src/backend/shared_middleware.py b/backend/src/backend/shared_middleware.py deleted file mode 100644 index 60c48c1b6..000000000 --- a/backend/src/backend/shared_middleware.py +++ /dev/null @@ -1,21 +0,0 @@ -from fastapi import FastAPI -from starsessions import SessionMiddleware -from starsessions.stores.redis import RedisStore - -from src import config -from src.backend.auth.enforce_logged_in_middleware import EnforceLoggedInMiddleware - - -def add_shared_middlewares(app: FastAPI) -> None: - # Add out custom middleware to enforce that user is logged in - # Also redirects to /login endpoint for some select paths - unprotected_paths = ["/logged_in_user", "/alive", "/openapi.json"] - paths_redirected_to_login = ["/", "/alive_protected"] - app.add_middleware( - EnforceLoggedInMiddleware, - unprotected_paths=unprotected_paths, - paths_redirected_to_login=paths_redirected_to_login, - ) - - session_store = RedisStore(config.REDIS_USER_SESSION_URL, prefix="user-auth:") - app.add_middleware(SessionMiddleware, store=session_store) diff --git a/backend/src/backend/user_session/inactivity_shutdown.py b/backend/src/backend/user_session/inactivity_shutdown.py deleted file mode 100644 index a86f49a64..000000000 --- a/backend/src/backend/user_session/inactivity_shutdown.py +++ /dev/null @@ -1,28 +0,0 @@ -import os -import time -from threading import Timer -from typing import Callable, Any - -from fastapi import Request, FastAPI - -LOCALHOST_DEVELOPMENT = os.environ.get("UVICORN_RELOAD") == "true" - - -class InactivityShutdown: - def __init__(self, app: FastAPI, inactivity_limit_minutes: int) -> None: - self._time_last_request: float = time.time() - self._inactivity_limit_seconds: int = inactivity_limit_minutes * 60 - - @app.middleware("http") - async def _update_time_last_request(request: Request, call_next: Callable) -> Any: - self._time_last_request = time.time() - return await call_next(request) - - if not LOCALHOST_DEVELOPMENT: - Timer(60.0, self.check_inactivity_threshold).start() - - def check_inactivity_threshold(self) -> None: - if time.time() > self._time_last_request + self._inactivity_limit_seconds: - os._exit(0) - else: - Timer(60.0, self.check_inactivity_threshold).start() diff --git a/backend/src/backend/user_session/main.py b/backend/src/backend/user_session/main.py deleted file mode 100644 index 223ff6596..000000000 --- a/backend/src/backend/user_session/main.py +++ /dev/null @@ -1,39 +0,0 @@ -import logging -import os - -from fastapi import FastAPI -from fastapi.responses import ORJSONResponse - -from src.backend.utils.azure_monitor_setup import setup_azure_monitor_telemetry -from src.backend.utils.logging_setup import ensure_console_log_handler_is_configured, setup_normal_log_levels -from src.backend.shared_middleware import add_shared_middlewares -from .inactivity_shutdown import InactivityShutdown -from .routers.general import router as general_router - -# mypy: disable-error-code="attr-defined" -from .routers.grid.router import router as grid_router - - -ensure_console_log_handler_is_configured() -setup_normal_log_levels() - -LOGGER = logging.getLogger(__name__) - - -app = FastAPI(default_response_class=ORJSONResponse) - -if os.environ.get("APPLICATIONINSIGHTS_CONNECTION_STRING"): - LOGGER.info("Configuring Azure Monitor telemetry for user session server") - setup_azure_monitor_telemetry(app) -else: - LOGGER.warning("Skipping telemetry configuration, APPLICATIONINSIGHTS_CONNECTION_STRING env variable not set.") - -app.include_router(general_router) -app.include_router(grid_router, prefix="/grid") -add_shared_middlewares(app) - -# We shut down the user session container after some -# minutes without receiving any new requests: -InactivityShutdown(app, inactivity_limit_minutes=30) - -LOGGER.info("Successfully completed user session server initialization.") diff --git a/backend/src/backend/user_session/routers/general.py b/backend/src/backend/user_session/routers/general.py deleted file mode 100644 index 3d1fd4566..000000000 --- a/backend/src/backend/user_session/routers/general.py +++ /dev/null @@ -1,37 +0,0 @@ -import datetime -from typing import Dict, Union, NamedTuple - -import psutil -from fastapi import APIRouter, Depends -from src.backend.auth.auth_helper import AuthHelper, AuthenticatedUser - -router = APIRouter() - -START_TIME_CONTAINER = datetime.datetime.now() - - -def _convert_psutil_object_to_dict(psutil_object: NamedTuple) -> Dict[str, Union[str, Dict[str, str]]]: - return {key: getattr(psutil_object, key) for key in psutil_object._fields} - - -@router.get("/user_session_container") -async def user_session_container( - authenticated_user: AuthenticatedUser = Depends(AuthHelper.get_authenticated_user), -) -> dict: - """Get information about user session container, like when it was started - together with memory and disk usage. NB! Note that a session container is started - if one is not already running when accessing this endpoint. - - For explanation of the different memory metrics, see e.g. psutil documentation like - * https://psutil.readthedocs.io/en/latest/index.html?highlight=Process()#psutil.virtual_memory - * https://psutil.readthedocs.io/en/latest/index.html?highlight=Process()#psutil.Process - """ - - return { - "username": authenticated_user.get_username(), - "startTimeContainer": START_TIME_CONTAINER, - "rootDiskSystem": _convert_psutil_object_to_dict(psutil.disk_usage("/")), - "memorySystem": _convert_psutil_object_to_dict(psutil.virtual_memory()), - "memoryPythonProcess": _convert_psutil_object_to_dict(psutil.Process().memory_info()), - "cpuPercent": psutil.cpu_percent(), - } diff --git a/backend/src/backend/user_session/routers/grid/router.py b/backend/src/backend/user_session/routers/grid/router.py deleted file mode 100644 index fd55d354d..000000000 --- a/backend/src/backend/user_session/routers/grid/router.py +++ /dev/null @@ -1,520 +0,0 @@ -# type: ignore -# for now -from functools import cache -from typing import List, Tuple -import logging -import os -from concurrent.futures import ThreadPoolExecutor - -import psutil -import numpy as np -import orjson -import xtgeo -from vtkmodules.util.numpy_support import vtk_to_numpy -from fastapi import APIRouter, Depends, Request -from fastapi.responses import ORJSONResponse - -from src.backend.auth.auth_helper import AuthenticatedUser, AuthHelper -from src.backend.primary.routers.grid.schemas import ( - GridSurface, - GridIntersection, -) -from src.services.sumo_access.grid_access import GridAccess -from src.services.utils.b64 import b64_encode_float_array_as_float32, b64_encode_uint_array_as_smallest_size -from src.services.utils.vtk_utils import ( - VtkGridSurface, - get_scalar_values, - get_surface, - cut_along_polyline, - flatten_sliced_grid, - xtgeo_grid_to_vtk_explicit_structured_grid, - create_polyline, - grid_to_numpy, - get_triangles, -) -from src.services.utils.mpl_utils import visualize_triangles_with_scalars -from src.services.utils.perf_timer import PerfTimer - -router = APIRouter() -LOGGER = logging.getLogger(__name__) - - -@router.get("/grid_surface", response_model=GridSurface) -async def grid_surface( - request: Request, - authenticated_user: AuthenticatedUser = Depends(AuthHelper.get_authenticated_user), -): - case_uuid = request.query_params.get("case_uuid") - ensemble_name = request.query_params.get("ensemble_name") - grid_name = request.query_params.get("grid_name") - realization = request.query_params.get("realization") - - # Get Xtgeo grid - xtgeo_grid = await get_grid_geometry( - authenticated_user=authenticated_user, - case_uuid=case_uuid, - ensemble_name=ensemble_name, - grid_name=grid_name, - realization=realization, - ) - - # Get grid information from xtgeo (xmin, ymin, etc...) - grid_geometrics = xtgeo_grid.get_geometrics(allcells=True, return_dict=True) - - # Get grid surface (visible cells) - grid_surface_instance = get_grid_surface(grid_geometry=xtgeo_grid) - - # Extract points and polygons from surface - points_np = vtk_to_numpy(grid_surface_instance.polydata.GetPoints().GetData()).ravel().astype(np.float32) - polys_np = vtk_to_numpy(grid_surface_instance.polydata.GetPolys().GetData()).astype(np.int64) - - # Reduce precision of points to 2 decimals - points_np = np.around(points_np, decimals=2) - - grid_surface_payload = GridSurface( - points_b64arr=b64_encode_float_array_as_float32(points_np), - polys_b64arr=b64_encode_uint_array_as_smallest_size(polys_np), - **grid_geometrics, - ) - return ORJSONResponse(grid_surface_payload.dict()) - - -@router.get( - "/grid_parameter", response_model=List[float] -) # stating response_model here instead of return type apparently disables pydantic validation of the response (https://stackoverflow.com/a/65715205) -# type: ignore -async def grid_parameter( - request: Request, - authenticated_user: AuthenticatedUser = Depends(AuthHelper.get_authenticated_user), -): - case_uuid = request.query_params.get("case_uuid") - ensemble_name = request.query_params.get("ensemble_name") - grid_name = request.query_params.get("grid_name") - parameter_name = request.query_params.get("parameter_name") - realization = request.query_params.get("realization") - - # Get Xtgeo grid - xtgeo_grid = await get_grid_geometry( - authenticated_user=authenticated_user, - case_uuid=case_uuid, - ensemble_name=ensemble_name, - grid_name=grid_name, - realization=realization, - ) - # Get grid surface (visible cells) - grid_polydata = get_grid_surface(grid_geometry=xtgeo_grid) - - # Get Xtgeo parameter - xtgeo_parameter = await get_grid_parameter( - authenticated_user=authenticated_user, - case_uuid=case_uuid, - ensemble_name=ensemble_name, - grid_name=grid_name, - parameter_name=parameter_name, - realization=realization, - ) - - # Get scalar values from parameter - scalar_values = get_scalar_values(xtgeo_parameter, cell_ids=grid_polydata.original_cell_ids) - - # Handle xtgeo undefined values and truncate - scalar_values[scalar_values == -999.0] = np.nan - scalar_values[scalar_values < np.nanmin(scalar_values)] = np.nanmin(scalar_values) - scalar_values[scalar_values > np.nanmax(scalar_values)] = np.nanmax(scalar_values) - - return ORJSONResponse(scalar_values.tolist()) - - -@router.get( - "/grid_parameter_intersection", response_model=List[float] -) # stating response_model here instead of return type apparently disables pydantic validation of the response (https://stackoverflow.com/a/65715205) -# type: ignore -async def grid_parameter_intersection( # pylint: disable=too-many-locals - request: Request, - authenticated_user: AuthenticatedUser = Depends(AuthHelper.get_authenticated_user), -): - case_uuid = request.query_params.get("case_uuid") - ensemble_name = request.query_params.get("ensemble_name") - grid_name = request.query_params.get("grid_name") - parameter_name = request.query_params.get("parameter_name") - realization = request.query_params.get("realization") - - timer = PerfTimer() - # Get Xtgeo grid - xtgeo_grid = await get_grid_geometry( - authenticated_user=authenticated_user, - case_uuid=case_uuid, - ensemble_name=ensemble_name, - grid_name=grid_name, - realization=realization, - ) - # Activate all cells. Should we do this? - xtgeo_grid.activate_all() - print( - f"DOWNLOADED/READ CACHE: grid_geometry for {grid_name}, realization: {realization}: {round(timer.lap_s(),2)}s", - flush=True, - ) - # Get xtgeo parameter - xtgeo_parameter = await get_grid_parameter( - authenticated_user=authenticated_user, - case_uuid=case_uuid, - ensemble_name=ensemble_name, - grid_name=grid_name, - parameter_name=parameter_name, - realization=realization, - ) - print( - f"DOWNLOADED/READ CACHE: grid_parameter for {parameter_name}, realization: {realization}: {round(timer.lap_s(),2)}s", - flush=True, - ) - - # HARDCODED POLYLINE FOR TESTING - xyz_arr = tuple( - tuple(point) - for point in [ - [463156.911, 5929542.294, -49.0], - [463564.402, 5931057.803, -1293.4185], - [463637.925, 5931184.235, -1536.9384], - [463690.658, 5931278.837, -1616.4998], - [463910.452, 5931688.122, -1630.5153], - [464465.876, 5932767.761, -1656.9874], - [464765.876, 5934767.761, -1656.9874], - ] - ) - - # Generate intersection data - coords, triangles, original_cell_indices_np, polyline = generate_grid_intersection(xtgeo_grid, xyz_arr) - print( - f"CALCULATED INTERSECTION: realization: {realization}: {round(timer.lap_s(),2)}s", - flush=True, - ) - - # Get scalar values from parameter and select only the cells that intersect with the polyline - values = get_scalar_values(xtgeo_parameter, cell_ids=original_cell_indices_np) - print( - f"READ SCALAR VALUES: realization: {realization}: {round(timer.lap_s(),2)}s", - flush=True, - ) - - # Handle undefined values and truncate - values[values < np.nanmin(values)] = np.nanmin(values) - values[values > np.nanmax(values)] = np.nanmax(values) - # values[values > 0.4] = 0.4 - # values = values[original_cell_indices_np] - # scalar_values[scalar_values == -999.0] = 0 - - # Get polyline coordinates - polyline_coords = np.array([polyline.GetPoint(i)[:3] for i in range(polyline.GetNumberOfPoints())]) - - # Calculate the cumulative distance along the polyline - polyline_distances = np.zeros(polyline_coords.shape[0]) - for i in range(1, polyline_coords.shape[0]): - polyline_distances[i] = polyline_distances[i - 1] + np.linalg.norm( - polyline_coords[i, :2] - polyline_coords[i - 1, :2] - ) - - polyline_x = polyline_distances - polyline_y = polyline_coords[:, 2] - - # Visualize the intersection using matplotlib as a base64 encoded image - image_data = visualize_triangles_with_scalars(coords, triangles, values, polyline, "55/33-A-4") - print( - f"MATPLOTLIB IMAGE: realization: {realization}: {round(timer.lap_s(),2)}s", - flush=True, - ) - - # Get the bounding box of the intersection - x_min, x_max = np.min(coords[:, 0]), np.max(coords[:, 0]) - y_min, y_max = np.min(coords[:, 1]), np.max(coords[:, 1]) - - # Create the intersection data object - intersection_data = GridIntersection( - image=f"data:image/png;base64,{image_data}", - polyline_x=polyline_x.tolist(), - polyline_y=polyline_y.tolist(), - x_min=float(x_min), - x_max=float(x_max), - y_min=float(y_min), - y_max=float(y_max), - ) - return ORJSONResponse(intersection_data.__dict__) - - -@router.get( - "/statistical_grid_parameter_intersection", response_model=List[float] -) # stating response_model here instead of return type apparently disables pydantic validation of the response (https://stackoverflow.com/a/65715205) -# type: ignore -async def statistical_grid_parameter_intersection( # pylint: disable=too-many-locals - request: Request, - authenticated_user: AuthenticatedUser = Depends(AuthHelper.get_authenticated_user), -): - timer = PerfTimer() - print("#" * 80, flush=True) - print("ENTERING STATISTICAL GRID PARAMETER INTERSECTION", flush=True) - print( - f"Memory usage: {psutil.Process(os.getpid()).memory_info().rss / 1024 ** 2} MB", - flush=True, - ) - print("-" * 80, flush=True) - - case_uuid = request.query_params.get("case_uuid") - ensemble_name = request.query_params.get("ensemble_name") - grid_name = request.query_params.get("grid_name") - parameter_name = request.query_params.get("parameter_name") - # convert json string of realizations into list - realizations = orjson.loads(request.query_params.get("realizations")) # pylint: disable=maybe-no-member - - grid_access = await GridAccess.from_case_uuid(authenticated_user.get_sumo_access_token(), case_uuid, ensemble_name) - - # Check that all grids have equal nx, ny, nz - # Should raise a http exception instead of a value error - if not await grid_access.grids_have_equal_nxnynz(grid_name=grid_name): - raise ValueError("Grids must have equal nx, ny, nz") - - # Get Xtgeo grid - xtgeo_grid = await get_grid_geometry( - authenticated_user=authenticated_user, - case_uuid=case_uuid, - ensemble_name=ensemble_name, - grid_name=grid_name, - realization=0, - ) - - # Activate all cells. Should we do this? - xtgeo_grid.activate_all() - print( - f"DOWNLOADED/READ CACHE: grid_geometry for {grid_name}, realization: {0}: {round(timer.lap_s(),2)}s", - flush=True, - ) - - print("-" * 80, flush=True) - print("GETTING GRID PARAMETERS", flush=True) - - ### Using ThreadPoolExecutor to parallelize the download of the grid parameters - async def worker(real): - return await get_grid_parameter( - authenticated_user=authenticated_user, - case_uuid=case_uuid, - ensemble_name=ensemble_name, - grid_name=grid_name, - parameter_name=parameter_name, - realization=real, - ) - - with ThreadPoolExecutor() as executor: - xtgeo_parameters = list(executor.map(worker, realizations)) - print( - f"DOWNLOADED/READ CACHE: grid_parameters for {parameter_name}, realizations: {realizations}: {round(timer.lap_s(),2)}s", - flush=True, - ) - - # HARDCODED POLYLINE FOR TESTING - xyz_arr = tuple( - tuple(point) - for point in [ - [463156.911, 5929542.294, -49.0], - [463564.402, 5931057.803, -1293.4185], - [463637.925, 5931184.235, -1536.9384], - [463690.658, 5931278.837, -1616.4998], - [463910.452, 5931688.122, -1630.5153], - [464465.876, 5932767.761, -1656.9874], - [464765.876, 5934767.761, -1656.9874], - ] - ) - print("-" * 80, flush=True) - print("GENERATING GRID INTERSECTION", flush=True) - - # Generate intersection data - coords, triangles, original_cell_indices_np, polyline = generate_grid_intersection(xtgeo_grid, xyz_arr) - print( - f"CALCULATED INTERSECTION: realization: {0}: {round(timer.lap_s(),2)}s", - flush=True, - ) - print("-" * 80, flush=True) - - # Get scalar values for each realization - all_scalar_values = [ - get_scalar_values(xtgeo_parameter, cell_ids=original_cell_indices_np) for xtgeo_parameter in xtgeo_parameters - ] - - # Calculate the mean scalar value for each cell - values = np.nanmean(all_scalar_values, axis=0) - - # Handle xtgeo undefined values and truncate - values[values < np.nanmin(values)] = np.nanmin(values) - values[values > np.nanmax(values)] = np.nanmax(values) - values[values == -999.0] = np.nan - print( - f"DOWNLOADED/READ CACHE: scalar_values for {parameter_name}, realizations: {realizations}: {round(timer.lap_s(),2)}s", - flush=True, - ) - - # Get polyline coordinates - polyline_coords = np.array([polyline.GetPoint(i)[:3] for i in range(polyline.GetNumberOfPoints())]) - - # Calculate the cumulative distance along the polyline - polyline_distances = np.zeros(polyline_coords.shape[0]) - for i in range(1, polyline_coords.shape[0]): - polyline_distances[i] = polyline_distances[i - 1] + np.linalg.norm( - polyline_coords[i, :2] - polyline_coords[i - 1, :2] - ) - - polyline_x = polyline_distances - polyline_y = polyline_coords[:, 2] - print("-" * 80, flush=True) - - print("GENERATE MATPLOTLIB IMAGE", flush=True) - - # Visualize the intersection using matplotlib as a base64 encoded image - image_data = visualize_triangles_with_scalars(coords, triangles, values, polyline, "55/33-A-4") - print( - f"GENERATED MATPLOTLIB IMAGE: {parameter_name}, realization: {0}: {round(timer.lap_s(),2)}s", - flush=True, - ) - - # Get the bounding box of the intersection - x_min, x_max = np.min(coords[:, 0]), np.max(coords[:, 0]) - y_min, y_max = np.min(coords[:, 1]), np.max(coords[:, 1]) - - # Create the intersection data object - intersection_data = GridIntersection( - image=f"data:image/png;base64,{image_data}", - polyline_x=polyline_x.tolist(), - polyline_y=polyline_y.tolist(), - x_min=float(x_min), - x_max=float(x_max), - y_min=float(y_min), - y_max=float(y_max), - ) - - print("-" * 80, flush=True) - print("EXITING STATISTICAL GRID PARAMETER INTERSECTION", flush=True) - print( - f"Memory usage: {psutil.Process(os.getpid()).memory_info().rss / 1024 ** 2} MB", - flush=True, - ) - print("#" * 80, flush=True) - - return ORJSONResponse(intersection_data.__dict__) - - -@router.get( - "/statistical_grid_parameter", response_model=List[float] -) # stating response_model here instead of return type apparently disables pydantic validation of the response (https://stackoverflow.com/a/65715205) -# type: ignore -async def statistical_grid_parameter( - request: Request, - authenticated_user: AuthenticatedUser = Depends(AuthHelper.get_authenticated_user), -): - case_uuid = request.query_params.get("case_uuid") - ensemble_name = request.query_params.get("ensemble_name") - grid_name = request.query_params.get("grid_name") - parameter_name = request.query_params.get("parameter_name") - # convert json string of realizations into list - realizations = orjson.loads(request.query_params.get("realizations")) # pylint: disable=maybe-no-member - - grid_access = await GridAccess.from_case_uuid(authenticated_user.get_sumo_access_token(), case_uuid, ensemble_name) - - # Check that all grids have equal nx, ny, nz - # Should riase a http exception instead of a value error - if not grid_access.grids_have_equal_nxnynz(grid_name=grid_name): - raise ValueError("Grids must have equal nx, ny, nz") - - xtgeo_grid = await get_grid_geometry( - authenticated_user=authenticated_user, - case_uuid=case_uuid, - ensemble_name=ensemble_name, - grid_name=grid_name, - realization=realizations[0], - ) - - # Get grid surface (visible cells) - grid_polydata = get_grid_surface(grid_geometry=xtgeo_grid) - - # Get the xtgeo grid parameters for each realization - xtgeo_parameters = [ - await get_grid_parameter( - authenticated_user=authenticated_user, - case_uuid=case_uuid, - ensemble_name=ensemble_name, - grid_name=grid_name, - parameter_name=parameter_name, - realization=real, - ) - for real in realizations - ] - - # Get the scalar values for each parameter - all_scalar_values = [ - get_scalar_values(xtgeo_parameter, cell_ids=grid_polydata.original_cell_ids) - for xtgeo_parameter in xtgeo_parameters - ] - - # Calculate the mean scalar values for each cell - mean_scalar_values = np.nanmean(all_scalar_values, axis=0) - - # Handle xtgeo undefined values and truncate - mean_scalar_values[mean_scalar_values == -999.0] = np.nan - mean_scalar_values[mean_scalar_values < np.nanmin(mean_scalar_values)] = np.nanmin(mean_scalar_values) - mean_scalar_values[mean_scalar_values > np.nanmax(mean_scalar_values)] = np.nanmax(mean_scalar_values) - - return ORJSONResponse(mean_scalar_values.tolist()) - - -# @cache -async def get_grid_geometry( - authenticated_user: AuthenticatedUser, - case_uuid: str, - ensemble_name: str, - grid_name: str, - realization: int, -) -> xtgeo.Grid: - """Get the xtgeo grid geometry for a given realization""" - token = authenticated_user.get_sumo_access_token() - grid_access = await GridAccess.from_case_uuid(token, case_uuid, ensemble_name) - grid_geometry = await grid_access.get_grid_geometry(grid_name, int(realization)) - - return grid_geometry - - -@cache -def get_grid_surface(grid_geometry: xtgeo.Grid) -> VtkGridSurface: - return get_surface(grid_geometry) - - -# @cache -async def get_grid_parameter( - authenticated_user: AuthenticatedUser, - case_uuid: str, - ensemble_name: str, - grid_name: str, - parameter_name: str, - realization: int, -) -> xtgeo.GridProperty: - token = authenticated_user.get_sumo_access_token() - grid_access = await GridAccess.from_case_uuid(token, case_uuid, ensemble_name) - - return await grid_access.get_grid_parameter(grid_name, parameter_name, int(realization)) - - -@cache -def generate_grid_intersection(grid_geometry: xtgeo.Grid, xyz_arr: Tuple[List[float]]): - polyline = create_polyline(xyz_arr) - poly_xy = [] - for xy in xyz_arr: - poly_xy.extend([xy[0], xy[1]]) - - esgrid = xtgeo_grid_to_vtk_explicit_structured_grid(grid_geometry) - sliced_grid = cut_along_polyline(esgrid, poly_xy) - original_cell_indices_np = [ - int(c) for c in vtk_to_numpy(sliced_grid.GetCellData().GetAbstractArray("vtkOriginalCellIds")) - ] - - flattened_grid = flatten_sliced_grid(sliced_grid, polyline, original_cell_ids=original_cell_indices_np) - coords = grid_to_numpy(flattened_grid) - triangles = get_triangles(flattened_grid) - original_cell_indices_np = [ - int(c) for c in vtk_to_numpy(flattened_grid.GetCellData().GetAbstractArray("vtkOriginalCellIds")) - ] - - return (coords, triangles, original_cell_indices_np, polyline) diff --git a/backend/src/services/sumo_access/queries/__init__.py b/backend/src/services/sumo_access/queries/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/backend/src/services/utils/__init__.py b/backend/src/services/utils/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/backend/src/services/utils/mpl_utils.py b/backend/src/services/utils/mpl_utils.py deleted file mode 100644 index 855365b70..000000000 --- a/backend/src/services/utils/mpl_utils.py +++ /dev/null @@ -1,111 +0,0 @@ -# pylint: skip-file -import base64 -from io import BytesIO - -import numpy as np -import matplotlib.pyplot as plt -import matplotlib.tri as tri -import matplotlib.cm as cm -from mpl_toolkits.axes_grid1 import make_axes_locatable -from vtkmodules.vtkCommonDataModel import vtkPolyData - - -def visualize_triangles_with_scalars( - coords: np.ndarray, - triangles: list, - scalars: np.ma.core.MaskedArray, - polyline: vtkPolyData, - well_name: str = "Well", - y_scale_factor: int = 20, -) -> str: - x = coords[:, 0] - y = coords[:, 1] * y_scale_factor - - # Create triangulation - triang = tri.Triangulation(x, y, triangles) - - # Create the figure - fig, ax = plt.subplots(figsize=(8, 6), dpi=600) - - # Plot the triangulation with scalar values - tpc = ax.tripcolor(triang, scalars, shading="flat", cmap=plt.cm.viridis) - # Get the polyline coordinates - polyline_coords = np.array([polyline.GetPoint(i)[:3] for i in range(polyline.GetNumberOfPoints())]) - - # Calculate the cumulative distance along the polyline - polyline_distances = np.zeros(polyline_coords.shape[0]) - for i in range(1, polyline_coords.shape[0]): - polyline_distances[i] = polyline_distances[i - 1] + np.linalg.norm( - polyline_coords[i, :2] - polyline_coords[i - 1, :2] - ) - - polyline_x = polyline_distances - polyline_y = polyline_coords[:, 2] * y_scale_factor - - # Plot the polyline as a black line - ax.plot(polyline_x, polyline_y, color="black", linewidth=3) - # # Add text near the polyline - # mid_index = len(polyline_x) // 2 - # ax.text(polyline_x[mid_index], polyline_y[mid_index], well_name, color="black") - - # Set aspect ratio - ax.set_aspect("equal") - - # Remove axis - ax.axis("off") - - # Set axis limits - ax.set_xlim(x.min(), x.max()) - ax.set_ylim(y.min(), y.max()) - - # Adjust the margins - plt.tight_layout() - - # Save the plot to a file - buf = BytesIO() - plt.savefig(buf, bbox_inches="tight", pad_inches=0) - buf.seek(0) - im_base64 = base64.b64encode(buf.read()).decode("utf-8") - plt.close(fig) - # Show the plot - return im_base64 - - -# def plot_cells_with_scalar(triangulation: tri.Triangulation, scalar, polyline): -# fig, ax = plt.subplots(figsize=(8, 6), dpi=600) -# divider = make_axes_locatable(ax) - -# cmap = cm.get_cmap("viridis") -# tpc = ax.tripcolor(triangulation, facecolors=scalar, cmap=cmap) - -# # Adjust the margins -# plt.tight_layout() - -# # Remove axis -# ax.axis("off") - -# # Plot the polyline directly using x-axis as length and z-values from the polyline -# x_poly = [0] -# z_poly = [polyline[0][2]] - -# for i in range(1, len(polyline)): -# x0, y0, z0 = polyline[i - 1] -# x1, y1, z1 = polyline[i] -# segment_length = np.sqrt((x1 - x0) ** 2 + (y1 - y0) ** 2) -# x_poly.append(x_poly[-1] + segment_length) -# z_poly.append(-z1) - -# ax.plot(x_poly, z_poly, c="k", linewidth=2) - -# # Set the y-axis (z-axis in our case) limits -# min_z = np.min(triangulation.y) - 100 -# max_z = np.max(triangulation.y) + 100 -# ax.set_ylim(min_z, max_z) - -# buf = BytesIO() -# plt.savefig(buf, bbox_inches="tight", pad_inches=0) -# buf.seek(0) -# im_base64 = base64.b64encode(buf.read()).decode("utf-8") -# plt.close(fig) - -# return im_base64 diff --git a/backend/src/services/utils/vtk_utils.py b/backend/src/services/utils/vtk_utils.py deleted file mode 100644 index 340f6cf28..000000000 --- a/backend/src/services/utils/vtk_utils.py +++ /dev/null @@ -1,298 +0,0 @@ -# pylint: skip-file -# type: ignore -# for now -from typing import Optional, List -from dataclasses import dataclass -import numpy as np -import xtgeo - -# pylint: disable=no-name-in-module, -from vtkmodules.util.numpy_support import ( - numpy_to_vtk, - numpy_to_vtkIdTypeArray, - vtk_to_numpy, -) - -# pylint: disable=no-name-in-module, -from vtkmodules.vtkCommonCore import vtkPoints - -# pylint: disable=no-name-in-module, -from vtkmodules.vtkCommonDataModel import ( - vtkCellArray, - vtkDataSetAttributes, - vtkExplicitStructuredGrid, - vtkUnstructuredGrid, - vtkPolyData, - vtkPlane, -) - -# pylint: disable=no-name-in-module, -from vtkmodules.vtkFiltersCore import ( - vtkAppendPolyData, - vtkClipPolyData, - vtkExplicitStructuredGridCrop, - vtkExplicitStructuredGridToUnstructuredGrid, - vtkExtractCellsAlongPolyLine, - vtkPlaneCutter, - vtkUnstructuredGridToExplicitStructuredGrid, -) - -# pylint: disable=no-name-in-module, -from vtkmodules.vtkFiltersGeometry import vtkExplicitStructuredGridSurfaceFilter - -# pylint: disable=no-name-in-module, -from vtkmodules.vtkFiltersSources import vtkPolyLineSource - - -@dataclass -class VtkGridSurface: - polydata: vtkPolyData - original_cell_ids: np.ndarray - - -def _create_vtk_esgrid_from_verts_and_conn( - point_dims: np.ndarray, vertex_arr_np: np.ndarray, conn_arr_np: np.ndarray -) -> vtkExplicitStructuredGrid: - vertex_arr_np = vertex_arr_np.reshape(-1, 3) - points_vtkarr = numpy_to_vtk(vertex_arr_np, deep=1) - vtk_points = vtkPoints() - vtk_points.SetData(points_vtkarr) - - conn_idarr = numpy_to_vtkIdTypeArray(conn_arr_np, deep=1) - vtk_cell_array = vtkCellArray() - vtk_cell_array.SetData(8, conn_idarr) - - vtk_esgrid = vtkExplicitStructuredGrid() - vtk_esgrid.SetDimensions(point_dims) - vtk_esgrid.SetPoints(vtk_points) - vtk_esgrid.SetCells(vtk_cell_array) - - vtk_esgrid.ComputeFacesConnectivityFlagsArray() - - return vtk_esgrid - - -def xtgeo_grid_to_vtk_explicit_structured_grid( - xtg_grid: xtgeo.Grid, -) -> vtkExplicitStructuredGrid: - # Create geometry data suitable for use with VTK's explicit structured grid - # based on the specified xtgeo 3d grid - pt_dims, vertex_arr, conn_arr, inactive_arr = xtg_grid.get_vtk_esg_geometry_data() - vertex_arr[:, 2] *= -1 - - vtk_esgrid = _create_vtk_esgrid_from_verts_and_conn(pt_dims, vertex_arr, conn_arr) - - # Make sure we hide the inactive cells. - # First we let VTK allocate cell ghost array, then we obtain a numpy view - # on the array and write to that (we're actually modifying the native VTK array) - ghost_arr_vtk = vtk_esgrid.AllocateCellGhostArray() - ghost_arr_np = vtk_to_numpy(ghost_arr_vtk) - ghost_arr_np[inactive_arr] = vtkDataSetAttributes.HIDDENCELL - - return vtk_esgrid - - -def _calc_grid_surface(esgrid: vtkExplicitStructuredGrid) -> vtkPolyData: - surf_filter = vtkExplicitStructuredGridSurfaceFilter() - surf_filter.SetInputData(esgrid) - surf_filter.PassThroughCellIdsOn() - surf_filter.Update() - - polydata: vtkPolyData = surf_filter.GetOutput() - return polydata - - -def get_surface( - xtgeo_grid: xtgeo.Grid, -) -> VtkGridSurface: - es_grid = xtgeo_grid_to_vtk_explicit_structured_grid(xtgeo_grid) - polydata = _calc_grid_surface(es_grid) - - original_cell_indices_np = vtk_to_numpy(polydata.GetCellData().GetAbstractArray("vtkOriginalCellIds")) - return VtkGridSurface(polydata=polydata, original_cell_ids=original_cell_indices_np) - - -def get_scalar_values(xtgeo_grid_property: xtgeo.GridProperty, cell_ids: Optional[np.ndarray] = None) -> np.ndarray: - fill_value = 0.0 if not xtgeo_grid_property.isdiscrete else -1 - raw_scalar_np = xtgeo_grid_property.values.ravel(order="F") - raw_scalar_np.filled(fill_value) - - if cell_ids is not None: - return raw_scalar_np[cell_ids].astype(np.float32) - return raw_scalar_np.astype(np.float32) - - -def _vtk_esg_to_ug(vtk_esgrid: vtkExplicitStructuredGrid) -> vtkUnstructuredGrid: - convert_filter = vtkExplicitStructuredGridToUnstructuredGrid() - convert_filter.SetInputData(vtk_esgrid) - convert_filter.Update() - vtk_ugrid = convert_filter.GetOutput() - - return vtk_ugrid - - -def cut_along_polyline( - esgrid: vtkExplicitStructuredGrid, - polyline_xy: List[float], -) -> vtkPolyData: - num_points_in_polyline = int(len(polyline_xy) / 2) - - ugrid = _vtk_esg_to_ug(esgrid) - - # !!!!!!!!!!!!!! - # Requires VTK 9.2-ish - # ugrid = _extract_intersected_ugrid(ugrid, polyline_xy, 10.0) - - cutter_alg = vtkPlaneCutter() - cutter_alg.SetInputDataObject(ugrid) - - # cell_locator = vtkStaticCellLocator() - # cell_locator.SetDataSet(esgrid) - # cell_locator.BuildLocator() - - # box_clip_alg = vtkBoxClipDataSet() - # box_clip_alg.SetInputDataObject(ugrid) - - append_alg = vtkAppendPolyData() - - et_cut_s = 0.0 - et_clip_s = 0.0 - - for i in range(0, num_points_in_polyline - 1): - x_0 = polyline_xy[2 * i] - y_0 = polyline_xy[2 * i + 1] - x_1 = polyline_xy[2 * (i + 1)] - y_1 = polyline_xy[2 * (i + 1) + 1] - fwd_vec = np.array([x_1 - x_0, y_1 - y_0, 0.0]) - fwd_vec /= np.linalg.norm(fwd_vec) - right_vec = np.array([fwd_vec[1], -fwd_vec[0], 0]) - - # box_clip_alg.SetBoxClip(x_0, x_1, y_0, y_1, min_z, max_z) - # box_clip_alg.Update() - # clipped_ugrid = box_clip_alg.GetOutputDataObject(0) - - # polyline_bounds = _calc_polyline_bounds([x_0, y_0, x_1, y_1]) - # polyline_bounds.extend([min_z, max_z]) - # cell_ids = vtkIdList() - # cell_locator.FindCellsWithinBounds(polyline_bounds, cell_ids) - # print(f"{cell_ids.GetNumberOfIds()} {polyline_bounds=}") - - plane = vtkPlane() - plane.SetOrigin([x_0, y_0, 0]) - plane.SetNormal(right_vec) - - plane_0 = vtkPlane() - plane_0.SetOrigin([x_0, y_0, 0]) - plane_0.SetNormal(fwd_vec) - - plane_1 = vtkPlane() - plane_1.SetOrigin([x_1, y_1, 0]) - plane_1.SetNormal(-fwd_vec) - - cutter_alg.SetPlane(plane) - cutter_alg.Update() - - cut_surface_polydata = cutter_alg.GetOutput() - # print(f"{type(cut_surface_polydata)=}") - - # Used vtkPolyDataPlaneClipper earlier, but it seems that it doesn't - # maintain the original cell IDs that we need for the result mapping. - # May want to check up on any performance degradation! - clipper_0 = vtkClipPolyData() - clipper_0.SetInputDataObject(cut_surface_polydata) - clipper_0.SetClipFunction(plane_0) - clipper_0.Update() - clipped_polydata = clipper_0.GetOutput() - - clipper_1 = vtkClipPolyData() - clipper_1.SetInputDataObject(clipped_polydata) - clipper_1.SetClipFunction(plane_1) - clipper_1.Update() - clipped_polydata = clipper_1.GetOutput() - - append_alg.AddInputData(clipped_polydata) - - append_alg.Update() - comb_polydata = append_alg.GetOutput() - return comb_polydata - - -def flatten_sliced_grid(sliced_grid: vtkPolyData, polyline, original_cell_ids) -> vtkPolyData: - """Flatten the sliced grid to a 2D grid.""" - points = sliced_grid.GetPoints() - num_points = points.GetNumberOfPoints() - flattened_points = vtkPoints() - - for i in range(num_points): - point = np.array(points.GetPoint(i)) - min_dist = float("inf") - closest_point = np.array(polyline.GetPoint(0))[:2] - for j in range(polyline.GetNumberOfPoints() - 1): - p1 = np.array(polyline.GetPoint(j))[:2] - p2 = np.array(polyline.GetPoint(j + 1))[:2] - segment = p2 - p1 - segment_length = np.linalg.norm(segment) - segment_normalized = segment / segment_length - projection = np.dot(point[:2] - p1, segment_normalized) - if 0 <= projection <= segment_length: - projected_point = p1 + projection * segment_normalized - dist = np.linalg.norm(point[:2] - projected_point) - if dist < min_dist: - min_dist = dist - closest_point = projected_point - - flattened_points.InsertNextPoint( - ( - np.linalg.norm(closest_point - np.array(polyline.GetPoint(0))[:2]), - point[2], - 0, - ) - ) - - flattened_grid = vtkPolyData() - flattened_grid.SetPoints(flattened_points) - flattened_grid.SetPolys(sliced_grid.GetPolys()) - - # Transfer original cell IDs to the flattened grid - original_cell_ids_array = numpy_to_vtk(np.array(original_cell_ids)) - flattened_grid.GetCellData().AddArray(original_cell_ids_array) - flattened_grid.GetCellData().GetAbstractArray(0).SetName("vtkOriginalCellIds") - - return flattened_grid - - -def get_triangles(poly_data) -> List[List[int]]: - triangles = [] - num_cells = poly_data.GetNumberOfCells() - for i in range(num_cells): - cell = poly_data.GetCell(i) - if cell.GetNumberOfPoints() == 3: - triangles.append([cell.GetPointId(0), cell.GetPointId(1), cell.GetPointId(2)]) - return triangles - - -def create_polyline(polyline: List[List[float]]): - points = vtkPoints() - for point in polyline: - points.InsertNextPoint(point) - points.InsertNextPoint(point) - points.InsertNextPoint(point) - points.InsertNextPoint(point) - points.InsertNextPoint(point) - - polyline = vtkPolyLineSource() - polyline.SetPoints(points) - - polyline.Update() - return polyline.GetOutput() - - -def grid_to_numpy(flattened_grid): - points = flattened_grid.GetPoints() - num_points = points.GetNumberOfPoints() - coords = np.zeros((num_points, 2)) - - for i in range(num_points): - coords[i, 0], coords[i, 1], _ = points.GetPoint(i) - - return coords diff --git a/backend/src/services/vds_access/__init__.py b/backend/src/services/vds_access/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/backend/tests/__init__.py b/backend/tests/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/backend/tests/unit/__init__.py b/backend/tests/unit/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/backend/tests/unit/services/__init__.py b/backend/tests/unit/services/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/backend_py/libs/core_utils/poetry.lock b/backend_py/libs/core_utils/poetry.lock new file mode 100644 index 000000000..f03c465b8 --- /dev/null +++ b/backend_py/libs/core_utils/poetry.lock @@ -0,0 +1,183 @@ +# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. + +[[package]] +name = "annotated-types" +version = "0.6.0" +description = "Reusable constraint types to use with typing.Annotated" +optional = false +python-versions = ">=3.8" +files = [ + {file = "annotated_types-0.6.0-py3-none-any.whl", hash = "sha256:0641064de18ba7a25dee8f96403ebc39113d0cb953a01429249d5c7564666a43"}, + {file = "annotated_types-0.6.0.tar.gz", hash = "sha256:563339e807e53ffd9c267e99fc6d9ea23eb8443c08f112651963e24e22f84a5d"}, +] + +[[package]] +name = "numpy" +version = "1.26.4" +description = "Fundamental package for array computing in Python" +optional = false +python-versions = ">=3.9" +files = [ + {file = "numpy-1.26.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9ff0f4f29c51e2803569d7a51c2304de5554655a60c5d776e35b4a41413830d0"}, + {file = "numpy-1.26.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e4ee3380d6de9c9ec04745830fd9e2eccb3e6cf790d39d7b98ffd19b0dd754a"}, + {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d209d8969599b27ad20994c8e41936ee0964e6da07478d6c35016bc386b66ad4"}, + {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffa75af20b44f8dba823498024771d5ac50620e6915abac414251bd971b4529f"}, + {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:62b8e4b1e28009ef2846b4c7852046736bab361f7aeadeb6a5b89ebec3c7055a"}, + {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a4abb4f9001ad2858e7ac189089c42178fcce737e4169dc61321660f1a96c7d2"}, + {file = "numpy-1.26.4-cp310-cp310-win32.whl", hash = "sha256:bfe25acf8b437eb2a8b2d49d443800a5f18508cd811fea3181723922a8a82b07"}, + {file = "numpy-1.26.4-cp310-cp310-win_amd64.whl", hash = "sha256:b97fe8060236edf3662adfc2c633f56a08ae30560c56310562cb4f95500022d5"}, + {file = "numpy-1.26.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c66707fabe114439db9068ee468c26bbdf909cac0fb58686a42a24de1760c71"}, + {file = "numpy-1.26.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:edd8b5fe47dab091176d21bb6de568acdd906d1887a4584a15a9a96a1dca06ef"}, + {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab55401287bfec946ced39700c053796e7cc0e3acbef09993a9ad2adba6ca6e"}, + {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:666dbfb6ec68962c033a450943ded891bed2d54e6755e35e5835d63f4f6931d5"}, + {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:96ff0b2ad353d8f990b63294c8986f1ec3cb19d749234014f4e7eb0112ceba5a"}, + {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:60dedbb91afcbfdc9bc0b1f3f402804070deed7392c23eb7a7f07fa857868e8a"}, + {file = "numpy-1.26.4-cp311-cp311-win32.whl", hash = "sha256:1af303d6b2210eb850fcf03064d364652b7120803a0b872f5211f5234b399f20"}, + {file = "numpy-1.26.4-cp311-cp311-win_amd64.whl", hash = "sha256:cd25bcecc4974d09257ffcd1f098ee778f7834c3ad767fe5db785be9a4aa9cb2"}, + {file = "numpy-1.26.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218"}, + {file = "numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b"}, + {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b"}, + {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed"}, + {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a"}, + {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0"}, + {file = "numpy-1.26.4-cp312-cp312-win32.whl", hash = "sha256:50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110"}, + {file = "numpy-1.26.4-cp312-cp312-win_amd64.whl", hash = "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818"}, + {file = "numpy-1.26.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7349ab0fa0c429c82442a27a9673fc802ffdb7c7775fad780226cb234965e53c"}, + {file = "numpy-1.26.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:52b8b60467cd7dd1e9ed082188b4e6bb35aa5cdd01777621a1658910745b90be"}, + {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5241e0a80d808d70546c697135da2c613f30e28251ff8307eb72ba696945764"}, + {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f870204a840a60da0b12273ef34f7051e98c3b5961b61b0c2c1be6dfd64fbcd3"}, + {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:679b0076f67ecc0138fd2ede3a8fd196dddc2ad3254069bcb9faf9a79b1cebcd"}, + {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:47711010ad8555514b434df65f7d7b076bb8261df1ca9bb78f53d3b2db02e95c"}, + {file = "numpy-1.26.4-cp39-cp39-win32.whl", hash = "sha256:a354325ee03388678242a4d7ebcd08b5c727033fcff3b2f536aea978e15ee9e6"}, + {file = "numpy-1.26.4-cp39-cp39-win_amd64.whl", hash = "sha256:3373d5d70a5fe74a2c1bb6d2cfd9609ecf686d47a2d7b1d37a8f3b6bf6003aea"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:afedb719a9dcfc7eaf2287b839d8198e06dcd4cb5d276a3df279231138e83d30"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95a7476c59002f2f6c590b9b7b998306fba6a5aa646b1e22ddfeaf8f78c3a29c"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7e50d0a0cc3189f9cb0aeb3a6a6af18c16f59f004b866cd2be1c14b36134a4a0"}, + {file = "numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010"}, +] + +[[package]] +name = "pydantic" +version = "2.6.3" +description = "Data validation using Python type hints" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pydantic-2.6.3-py3-none-any.whl", hash = "sha256:72c6034df47f46ccdf81869fddb81aade68056003900a8724a4f160700016a2a"}, + {file = "pydantic-2.6.3.tar.gz", hash = "sha256:e07805c4c7f5c6826e33a1d4c9d47950d7eaf34868e2690f8594d2e30241f11f"}, +] + +[package.dependencies] +annotated-types = ">=0.4.0" +pydantic-core = "2.16.3" +typing-extensions = ">=4.6.1" + +[package.extras] +email = ["email-validator (>=2.0.0)"] + +[[package]] +name = "pydantic-core" +version = "2.16.3" +description = "" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pydantic_core-2.16.3-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:75b81e678d1c1ede0785c7f46690621e4c6e63ccd9192af1f0bd9d504bbb6bf4"}, + {file = "pydantic_core-2.16.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9c865a7ee6f93783bd5d781af5a4c43dadc37053a5b42f7d18dc019f8c9d2bd1"}, + {file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:162e498303d2b1c036b957a1278fa0899d02b2842f1ff901b6395104c5554a45"}, + {file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2f583bd01bbfbff4eaee0868e6fc607efdfcc2b03c1c766b06a707abbc856187"}, + {file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b926dd38db1519ed3043a4de50214e0d600d404099c3392f098a7f9d75029ff8"}, + {file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:716b542728d4c742353448765aa7cdaa519a7b82f9564130e2b3f6766018c9ec"}, + {file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc4ad7f7ee1a13d9cb49d8198cd7d7e3aa93e425f371a68235f784e99741561f"}, + {file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bd87f48924f360e5d1c5f770d6155ce0e7d83f7b4e10c2f9ec001c73cf475c99"}, + {file = "pydantic_core-2.16.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0df446663464884297c793874573549229f9eca73b59360878f382a0fc085979"}, + {file = "pydantic_core-2.16.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4df8a199d9f6afc5ae9a65f8f95ee52cae389a8c6b20163762bde0426275b7db"}, + {file = "pydantic_core-2.16.3-cp310-none-win32.whl", hash = "sha256:456855f57b413f077dff513a5a28ed838dbbb15082ba00f80750377eed23d132"}, + {file = "pydantic_core-2.16.3-cp310-none-win_amd64.whl", hash = "sha256:732da3243e1b8d3eab8c6ae23ae6a58548849d2e4a4e03a1924c8ddf71a387cb"}, + {file = "pydantic_core-2.16.3-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:519ae0312616026bf4cedc0fe459e982734f3ca82ee8c7246c19b650b60a5ee4"}, + {file = "pydantic_core-2.16.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b3992a322a5617ded0a9f23fd06dbc1e4bd7cf39bc4ccf344b10f80af58beacd"}, + {file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d62da299c6ecb04df729e4b5c52dc0d53f4f8430b4492b93aa8de1f541c4aac"}, + {file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2acca2be4bb2f2147ada8cac612f8a98fc09f41c89f87add7256ad27332c2fda"}, + {file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1b662180108c55dfbf1280d865b2d116633d436cfc0bba82323554873967b340"}, + {file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e7c6ed0dc9d8e65f24f5824291550139fe6f37fac03788d4580da0d33bc00c97"}, + {file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a6b1bb0827f56654b4437955555dc3aeeebeddc47c2d7ed575477f082622c49e"}, + {file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e56f8186d6210ac7ece503193ec84104da7ceb98f68ce18c07282fcc2452e76f"}, + {file = "pydantic_core-2.16.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:936e5db01dd49476fa8f4383c259b8b1303d5dd5fb34c97de194560698cc2c5e"}, + {file = "pydantic_core-2.16.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:33809aebac276089b78db106ee692bdc9044710e26f24a9a2eaa35a0f9fa70ba"}, + {file = "pydantic_core-2.16.3-cp311-none-win32.whl", hash = "sha256:ded1c35f15c9dea16ead9bffcde9bb5c7c031bff076355dc58dcb1cb436c4721"}, + {file = "pydantic_core-2.16.3-cp311-none-win_amd64.whl", hash = "sha256:d89ca19cdd0dd5f31606a9329e309d4fcbb3df860960acec32630297d61820df"}, + {file = "pydantic_core-2.16.3-cp311-none-win_arm64.whl", hash = "sha256:6162f8d2dc27ba21027f261e4fa26f8bcb3cf9784b7f9499466a311ac284b5b9"}, + {file = "pydantic_core-2.16.3-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:0f56ae86b60ea987ae8bcd6654a887238fd53d1384f9b222ac457070b7ac4cff"}, + {file = "pydantic_core-2.16.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c9bd22a2a639e26171068f8ebb5400ce2c1bc7d17959f60a3b753ae13c632975"}, + {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4204e773b4b408062960e65468d5346bdfe139247ee5f1ca2a378983e11388a2"}, + {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f651dd19363c632f4abe3480a7c87a9773be27cfe1341aef06e8759599454120"}, + {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaf09e615a0bf98d406657e0008e4a8701b11481840be7d31755dc9f97c44053"}, + {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8e47755d8152c1ab5b55928ab422a76e2e7b22b5ed8e90a7d584268dd49e9c6b"}, + {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:500960cb3a0543a724a81ba859da816e8cf01b0e6aaeedf2c3775d12ee49cade"}, + {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cf6204fe865da605285c34cf1172879d0314ff267b1c35ff59de7154f35fdc2e"}, + {file = "pydantic_core-2.16.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d33dd21f572545649f90c38c227cc8631268ba25c460b5569abebdd0ec5974ca"}, + {file = "pydantic_core-2.16.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:49d5d58abd4b83fb8ce763be7794d09b2f50f10aa65c0f0c1696c677edeb7cbf"}, + {file = "pydantic_core-2.16.3-cp312-none-win32.whl", hash = "sha256:f53aace168a2a10582e570b7736cc5bef12cae9cf21775e3eafac597e8551fbe"}, + {file = "pydantic_core-2.16.3-cp312-none-win_amd64.whl", hash = "sha256:0d32576b1de5a30d9a97f300cc6a3f4694c428d956adbc7e6e2f9cad279e45ed"}, + {file = "pydantic_core-2.16.3-cp312-none-win_arm64.whl", hash = "sha256:ec08be75bb268473677edb83ba71e7e74b43c008e4a7b1907c6d57e940bf34b6"}, + {file = "pydantic_core-2.16.3-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:b1f6f5938d63c6139860f044e2538baeee6f0b251a1816e7adb6cbce106a1f01"}, + {file = "pydantic_core-2.16.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2a1ef6a36fdbf71538142ed604ad19b82f67b05749512e47f247a6ddd06afdc7"}, + {file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:704d35ecc7e9c31d48926150afada60401c55efa3b46cd1ded5a01bdffaf1d48"}, + {file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d937653a696465677ed583124b94a4b2d79f5e30b2c46115a68e482c6a591c8a"}, + {file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c9803edf8e29bd825f43481f19c37f50d2b01899448273b3a7758441b512acf8"}, + {file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:72282ad4892a9fb2da25defeac8c2e84352c108705c972db82ab121d15f14e6d"}, + {file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f752826b5b8361193df55afcdf8ca6a57d0232653494ba473630a83ba50d8c9"}, + {file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4384a8f68ddb31a0b0c3deae88765f5868a1b9148939c3f4121233314ad5532c"}, + {file = "pydantic_core-2.16.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a4b2bf78342c40b3dc830880106f54328928ff03e357935ad26c7128bbd66ce8"}, + {file = "pydantic_core-2.16.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:13dcc4802961b5f843a9385fc821a0b0135e8c07fc3d9949fd49627c1a5e6ae5"}, + {file = "pydantic_core-2.16.3-cp38-none-win32.whl", hash = "sha256:e3e70c94a0c3841e6aa831edab1619ad5c511199be94d0c11ba75fe06efe107a"}, + {file = "pydantic_core-2.16.3-cp38-none-win_amd64.whl", hash = "sha256:ecdf6bf5f578615f2e985a5e1f6572e23aa632c4bd1dc67f8f406d445ac115ed"}, + {file = "pydantic_core-2.16.3-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:bda1ee3e08252b8d41fa5537413ffdddd58fa73107171a126d3b9ff001b9b820"}, + {file = "pydantic_core-2.16.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:21b888c973e4f26b7a96491c0965a8a312e13be108022ee510248fe379a5fa23"}, + {file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be0ec334369316fa73448cc8c982c01e5d2a81c95969d58b8f6e272884df0074"}, + {file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b5b6079cc452a7c53dd378c6f881ac528246b3ac9aae0f8eef98498a75657805"}, + {file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ee8d5f878dccb6d499ba4d30d757111847b6849ae07acdd1205fffa1fc1253c"}, + {file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7233d65d9d651242a68801159763d09e9ec96e8a158dbf118dc090cd77a104c9"}, + {file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c6119dc90483a5cb50a1306adb8d52c66e447da88ea44f323e0ae1a5fcb14256"}, + {file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:578114bc803a4c1ff9946d977c221e4376620a46cf78da267d946397dc9514a8"}, + {file = "pydantic_core-2.16.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d8f99b147ff3fcf6b3cc60cb0c39ea443884d5559a30b1481e92495f2310ff2b"}, + {file = "pydantic_core-2.16.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4ac6b4ce1e7283d715c4b729d8f9dab9627586dafce81d9eaa009dd7f25dd972"}, + {file = "pydantic_core-2.16.3-cp39-none-win32.whl", hash = "sha256:e7774b570e61cb998490c5235740d475413a1f6de823169b4cf94e2fe9e9f6b2"}, + {file = "pydantic_core-2.16.3-cp39-none-win_amd64.whl", hash = "sha256:9091632a25b8b87b9a605ec0e61f241c456e9248bfdcf7abdf344fdb169c81cf"}, + {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:36fa178aacbc277bc6b62a2c3da95226520da4f4e9e206fdf076484363895d2c"}, + {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:dcca5d2bf65c6fb591fff92da03f94cd4f315972f97c21975398bd4bd046854a"}, + {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2a72fb9963cba4cd5793854fd12f4cfee731e86df140f59ff52a49b3552db241"}, + {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b60cc1a081f80a2105a59385b92d82278b15d80ebb3adb200542ae165cd7d183"}, + {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cbcc558401de90a746d02ef330c528f2e668c83350f045833543cd57ecead1ad"}, + {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:fee427241c2d9fb7192b658190f9f5fd6dfe41e02f3c1489d2ec1e6a5ab1e04a"}, + {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f4cb85f693044e0f71f394ff76c98ddc1bc0953e48c061725e540396d5c8a2e1"}, + {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:b29eeb887aa931c2fcef5aa515d9d176d25006794610c264ddc114c053bf96fe"}, + {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a425479ee40ff021f8216c9d07a6a3b54b31c8267c6e17aa88b70d7ebd0e5e5b"}, + {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:5c5cbc703168d1b7a838668998308018a2718c2130595e8e190220238addc96f"}, + {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99b6add4c0b39a513d323d3b93bc173dac663c27b99860dd5bf491b240d26137"}, + {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75f76ee558751746d6a38f89d60b6228fa174e5172d143886af0f85aa306fd89"}, + {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:00ee1c97b5364b84cb0bd82e9bbf645d5e2871fb8c58059d158412fee2d33d8a"}, + {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:287073c66748f624be4cef893ef9174e3eb88fe0b8a78dc22e88eca4bc357ca6"}, + {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ed25e1835c00a332cb10c683cd39da96a719ab1dfc08427d476bce41b92531fc"}, + {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:86b3d0033580bd6bbe07590152007275bd7af95f98eaa5bd36f3da219dcd93da"}, + {file = "pydantic_core-2.16.3.tar.gz", hash = "sha256:1cac689f80a3abab2d3c0048b29eea5751114054f032a941a32de4c852c59cad"}, +] + +[package.dependencies] +typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" + +[[package]] +name = "typing-extensions" +version = "4.10.0" +description = "Backported and Experimental Type Hints for Python 3.8+" +optional = false +python-versions = ">=3.8" +files = [ + {file = "typing_extensions-4.10.0-py3-none-any.whl", hash = "sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475"}, + {file = "typing_extensions-4.10.0.tar.gz", hash = "sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb"}, +] + +[metadata] +lock-version = "2.0" +python-versions = "^3.11" +content-hash = "94e824aa93b25684a6ae3f9bbff99c166a956ec1cbc59a6214133d9212d42d40" diff --git a/backend_py/libs/core_utils/pyproject.toml b/backend_py/libs/core_utils/pyproject.toml new file mode 100644 index 000000000..6045696ff --- /dev/null +++ b/backend_py/libs/core_utils/pyproject.toml @@ -0,0 +1,15 @@ +[tool.poetry] +name = "core-utils" +version = "0.0.1" +description = "Package with general Webviz utilities" +authors = ["R&T Equinor", "Ceetron Solutions AS"] +packages = [ { include = "webviz_pkg" } ] + +[tool.poetry.dependencies] +python = "^3.11" +numpy = "^1.24.1" +pydantic = "^2.3.0" + +[build-system] +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api" \ No newline at end of file diff --git a/backend/src/services/utils/b64.py b/backend_py/libs/core_utils/webviz_pkg/core_utils/b64.py similarity index 100% rename from backend/src/services/utils/b64.py rename to backend_py/libs/core_utils/webviz_pkg/core_utils/b64.py diff --git a/backend/src/services/utils/perf_timer.py b/backend_py/libs/core_utils/webviz_pkg/core_utils/perf_timer.py similarity index 100% rename from backend/src/services/utils/perf_timer.py rename to backend_py/libs/core_utils/webviz_pkg/core_utils/perf_timer.py diff --git a/backend/.vscode/launch.json b/backend_py/primary/.vscode/launch.json similarity index 82% rename from backend/.vscode/launch.json rename to backend_py/primary/.vscode/launch.json index 6f7bb14f7..695c19216 100644 --- a/backend/.vscode/launch.json +++ b/backend_py/primary/.vscode/launch.json @@ -8,7 +8,7 @@ "pathMappings": [ { "localRoot": "${workspaceFolder}", - "remoteRoot": "/home/appuser/backend" + "remoteRoot": "/home/appuser/backend_py/primary" } ] } diff --git a/backend_py/primary/Dockerfile b/backend_py/primary/Dockerfile new file mode 100644 index 000000000..c41b46a93 --- /dev/null +++ b/backend_py/primary/Dockerfile @@ -0,0 +1,27 @@ +FROM python:3.11-slim@sha256:ad2c4e5884418404c5289acad4a471dde8500e24ba57ad574cdcae46523e507a + +RUN useradd --create-home --uid 1234 appuser # Changing to non-root user early + +USER 1234 + +ENV PATH="${PATH}:/home/appuser/.local/bin" + +RUN python3 -m pip install --user pipx +RUN python3 -m pipx ensurepath +RUN pipx install poetry==1.8.2 + +ENV VIRTUAL_ENV=/home/appuser/venv +RUN python3 -m venv $VIRTUAL_ENV +ENV PATH="$VIRTUAL_ENV/bin:$PATH" + +WORKDIR /home/appuser/backend_py/primary + +COPY --chown=appuser ./backend_py/primary/pyproject.toml /home/appuser/backend_py/primary/ +COPY --chown=appuser ./backend_py/primary/poetry.lock /home/appuser/backend_py/primary/ +RUN poetry install --only main --no-root --no-directory + +COPY --chown=appuser ./backend_py/libs /home/appuser/backend_py/libs +COPY --chown=appuser ./backend_py/primary /home/appuser/backend_py/primary +RUN poetry install --only main + +CMD exec uvicorn --proxy-headers --host=0.0.0.0 primary.main:app diff --git a/backend/README.md b/backend_py/primary/README.md similarity index 100% rename from backend/README.md rename to backend_py/primary/README.md diff --git a/backend/poetry.lock b/backend_py/primary/poetry.lock similarity index 97% rename from backend/poetry.lock rename to backend_py/primary/poetry.lock index e3cef9c06..1f65263f7 100644 --- a/backend/poetry.lock +++ b/backend_py/primary/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. [[package]] name = "annotated-types" @@ -594,6 +594,23 @@ mypy = ["contourpy[bokeh]", "docutils-stubs", "mypy (==0.991)", "types-Pillow"] test = ["Pillow", "matplotlib", "pytest"] test-no-images = ["pytest"] +[[package]] +name = "core-utils" +version = "0.0.1" +description = "Package with general Webviz utilities" +optional = false +python-versions = "^3.11" +files = [] +develop = true + +[package.dependencies] +numpy = "^1.24.1" +pydantic = "^2.3.0" + +[package.source] +type = "directory" +url = "../libs/core_utils" + [[package]] name = "cryptography" version = "39.0.0" @@ -2343,32 +2360,6 @@ mmh3 = "*" redis = ">=4,<5" typing-extensions = "*" -[[package]] -name = "psutil" -version = "5.9.5" -description = "Cross-platform lib for process and system monitoring in Python." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "psutil-5.9.5-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:be8929ce4313f9f8146caad4272f6abb8bf99fc6cf59344a3167ecd74f4f203f"}, - {file = "psutil-5.9.5-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:ab8ed1a1d77c95453db1ae00a3f9c50227ebd955437bcf2a574ba8adbf6a74d5"}, - {file = "psutil-5.9.5-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:4aef137f3345082a3d3232187aeb4ac4ef959ba3d7c10c33dd73763fbc063da4"}, - {file = "psutil-5.9.5-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:ea8518d152174e1249c4f2a1c89e3e6065941df2fa13a1ab45327716a23c2b48"}, - {file = "psutil-5.9.5-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:acf2aef9391710afded549ff602b5887d7a2349831ae4c26be7c807c0a39fac4"}, - {file = "psutil-5.9.5-cp27-none-win32.whl", hash = "sha256:5b9b8cb93f507e8dbaf22af6a2fd0ccbe8244bf30b1baad6b3954e935157ae3f"}, - {file = "psutil-5.9.5-cp27-none-win_amd64.whl", hash = "sha256:8c5f7c5a052d1d567db4ddd231a9d27a74e8e4a9c3f44b1032762bd7b9fdcd42"}, - {file = "psutil-5.9.5-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:3c6f686f4225553615612f6d9bc21f1c0e305f75d7d8454f9b46e901778e7217"}, - {file = "psutil-5.9.5-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7a7dd9997128a0d928ed4fb2c2d57e5102bb6089027939f3b722f3a210f9a8da"}, - {file = "psutil-5.9.5-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89518112647f1276b03ca97b65cc7f64ca587b1eb0278383017c2a0dcc26cbe4"}, - {file = "psutil-5.9.5-cp36-abi3-win32.whl", hash = "sha256:104a5cc0e31baa2bcf67900be36acde157756b9c44017b86b2c049f11957887d"}, - {file = "psutil-5.9.5-cp36-abi3-win_amd64.whl", hash = "sha256:b258c0c1c9d145a1d5ceffab1134441c4c5113b2417fafff7315a917a026c3c9"}, - {file = "psutil-5.9.5-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:c607bb3b57dc779d55e1554846352b4e358c10fff3abf3514a7a6601beebdb30"}, - {file = "psutil-5.9.5.tar.gz", hash = "sha256:5410638e4df39c54d957fc51ce03048acd8e6d60abc0f5107af51e5fb566eb3c"}, -] - -[package.extras] -test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"] - [[package]] name = "py-cpuinfo" version = "9.0.0" @@ -3316,43 +3307,6 @@ h11 = ">=0.8" [package.extras] standard = ["colorama (>=0.4)", "httptools (>=0.5.0)", "python-dotenv (>=0.13)", "pyyaml (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "watchfiles (>=0.13)", "websockets (>=10.4)"] -[[package]] -name = "vtk" -version = "9.2.6" -description = "VTK is an open-source toolkit for 3D computer graphics, image processing, and visualization" -optional = false -python-versions = "*" -files = [ - {file = "vtk-9.2.6-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:acf8b0e0a2b51b8aa36cee1ea1ba0b73c565871efaa14cf2606d9bef36feba3a"}, - {file = "vtk-9.2.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8ec9827287f1743c736ea9b51572d20dcd15a065170808f97408eebd404275b4"}, - {file = "vtk-9.2.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3473f3b3dc919d3e2ef0cc9927654731941fd7b79d3dcaa343cdaff3e4e40838"}, - {file = "vtk-9.2.6-cp310-cp310-win_amd64.whl", hash = "sha256:37561b19b4b70c7034d9e689238560d7afec49ff89704b9bb3c9bb89a90ee54e"}, - {file = "vtk-9.2.6-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:9289f6ee5432f0a00aeb7b674d7ca03054bc50fa6c74126751f8b19f931f52fc"}, - {file = "vtk-9.2.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0b947a33a7c5562ac4d9c8dce389f4ed720cc2559389048993ae45cbed3bbeb1"}, - {file = "vtk-9.2.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87930115c8067a2d482beebc48a50fcacdc0154d8d7c763471a9be8b5eb76cc3"}, - {file = "vtk-9.2.6-cp311-cp311-win_amd64.whl", hash = "sha256:6c3ca0663f251fbd6e26d93294801ceee6c3cc329f6070dccde3b68046ab9ee7"}, - {file = "vtk-9.2.6-cp36-cp36m-macosx_10_10_x86_64.whl", hash = "sha256:86c548da22a0bd9ce9e060364925e8fa0a551064f9660ae1d486ac3118ffb770"}, - {file = "vtk-9.2.6-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f7622e98b3590bf909f056a1bad55575760727fd673c3e8e224134d52b11d00d"}, - {file = "vtk-9.2.6-cp36-cp36m-win_amd64.whl", hash = "sha256:bb28432277136774e91eb1084a8f5f1c4c952d4e74f74626a16ac6e199eba5c5"}, - {file = "vtk-9.2.6-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:feb9d211583d7b1dd45ca6616bf2f9622d0eadf9e3084f53d20de819e5808d42"}, - {file = "vtk-9.2.6-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3bc1123b6f2f3746d35325cf1a48630c8f49a3516c9970a5bdea15823909bbca"}, - {file = "vtk-9.2.6-cp37-cp37m-win_amd64.whl", hash = "sha256:78103568e97d947026cd39a70e6719277d7341f984c06abaec64d3429e200a6f"}, - {file = "vtk-9.2.6-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:8236e00d0ad24730f4b783bbc038108426e6a78c892fd6ae9a8e8eb846f3e8e3"}, - {file = "vtk-9.2.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:affbb15762bcb6d9632a668ec53c6a3102d4f6c14c4178f01489c0b711114521"}, - {file = "vtk-9.2.6-cp38-cp38-win_amd64.whl", hash = "sha256:f9d3450c00ced28f942a0a7dc5f27a667cf6b171d9ef5a090cb7c8e21dd1a121"}, - {file = "vtk-9.2.6-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:9b396909a4372d3be4a01fde4a0af4f3e410742d73d185982c6f48a61090ebfe"}, - {file = "vtk-9.2.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9d41a18bbd6fac18a814bbaeeb615044da036afc2bd98cdf7ea52853fd1ef950"}, - {file = "vtk-9.2.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:79991dccbc483a8e5d23e5d3ae1e358fee0526fe8f710d07868ecae58c6b9535"}, - {file = "vtk-9.2.6-cp39-cp39-win_amd64.whl", hash = "sha256:2d905a686ee1b28dd2ac3c3595a3fbcbd171e4b1f9aabac3c8019c6f3a4f8157"}, -] - -[package.dependencies] -matplotlib = ">=2.0.0" - -[package.extras] -numpy = ["numpy (>=1.9)"] -web = ["wslink (>=1.0.4)"] - [[package]] name = "wrapt" version = "1.15.0" @@ -3498,4 +3452,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "0035b8a2a08108ddc7391118ac9ab700bf061c56b785c0f6c1a41d6b65ab2f0e" +content-hash = "0138b0a8902575704f558577c37e40fc9128819a11bde186e407ce839da40cf3" diff --git a/backend/src/__init__.py b/backend_py/primary/primary/__init__.py similarity index 100% rename from backend/src/__init__.py rename to backend_py/primary/primary/__init__.py diff --git a/backend/src/backend/auth/auth_helper.py b/backend_py/primary/primary/auth/auth_helper.py similarity index 98% rename from backend/src/backend/auth/auth_helper.py rename to backend_py/primary/primary/auth/auth_helper.py index 9d5678df6..58846258f 100644 --- a/backend/src/backend/auth/auth_helper.py +++ b/backend_py/primary/primary/auth/auth_helper.py @@ -1,5 +1,5 @@ -import os import base64 +import os import time from typing import List, Optional @@ -8,10 +8,10 @@ import starsessions from fastapi import APIRouter, Request, Response from fastapi.responses import RedirectResponse +from webviz_pkg.core_utils.perf_timer import PerfTimer -from src.services.utils.authenticated_user import AuthenticatedUser -from src.services.utils.perf_timer import PerfTimer -from src import config +from primary import config +from primary.services.utils.authenticated_user import AuthenticatedUser class AuthHelper: diff --git a/backend/src/backend/auth/enforce_logged_in_middleware.py b/backend_py/primary/primary/auth/enforce_logged_in_middleware.py similarity index 98% rename from backend/src/backend/auth/enforce_logged_in_middleware.py rename to backend_py/primary/primary/auth/enforce_logged_in_middleware.py index 255fe5649..57a6e27e2 100644 --- a/backend/src/backend/auth/enforce_logged_in_middleware.py +++ b/backend_py/primary/primary/auth/enforce_logged_in_middleware.py @@ -6,7 +6,7 @@ from fastapi.responses import PlainTextResponse, RedirectResponse from starlette.middleware.base import BaseHTTPMiddleware, RequestResponseEndpoint -from src.backend.auth.auth_helper import AuthHelper +from .auth_helper import AuthHelper class EnforceLoggedInMiddleware(BaseHTTPMiddleware): diff --git a/backend/src/config.py b/backend_py/primary/primary/config.py similarity index 100% rename from backend/src/config.py rename to backend_py/primary/primary/config.py diff --git a/backend_py/primary/primary/main.py b/backend_py/primary/primary/main.py new file mode 100644 index 000000000..2bebc5cc9 --- /dev/null +++ b/backend_py/primary/primary/main.py @@ -0,0 +1,120 @@ +import datetime +import logging +import os + +from fastapi import FastAPI +from fastapi.responses import ORJSONResponse +from fastapi.routing import APIRoute +from starsessions import SessionMiddleware +from starsessions.stores.redis import RedisStore +from uvicorn.middleware.proxy_headers import ProxyHeadersMiddleware + +from primary.auth.auth_helper import AuthHelper +from primary.auth.enforce_logged_in_middleware import EnforceLoggedInMiddleware +from primary.middleware.add_process_time_to_server_timing_middleware import AddProcessTimeToServerTimingMiddleware +from primary.routers.correlations.router import router as correlations_router +from primary.routers.dev.router import router as dev_router +from primary.routers.explore import router as explore_router +from primary.routers.general import router as general_router +from primary.routers.graph.router import router as graph_router +from primary.routers.grid.router import router as grid_router +from primary.routers.inplace_volumetrics.router import router as inplace_volumetrics_router +from primary.routers.observations.router import router as observations_router +from primary.routers.parameters.router import router as parameters_router +from primary.routers.polygons.router import router as polygons_router +from primary.routers.pvt.router import router as pvt_router +from primary.routers.rft.router import router as rft_router +from primary.routers.seismic.router import router as seismic_router +from primary.routers.surface.router import router as surface_router +from primary.routers.timeseries.router import router as timeseries_router +from primary.routers.well.router import router as well_router +from primary.routers.well_completions.router import router as well_completions_router +from primary.utils.azure_monitor_setup import setup_azure_monitor_telemetry +from primary.utils.exception_handlers import configure_service_level_exception_handlers +from primary.utils.exception_handlers import override_default_fastapi_exception_handlers +from primary.utils.logging_setup import ensure_console_log_handler_is_configured, setup_normal_log_levels + +from . import config + + +ensure_console_log_handler_is_configured() +setup_normal_log_levels() + +# temporarily set some loggers to DEBUG +# logging.getLogger().setLevel(logging.DEBUG) +logging.getLogger("primary.services.sumo_access").setLevel(logging.DEBUG) +logging.getLogger("primary.services.user_session_manager").setLevel(logging.DEBUG) +logging.getLogger("primary.routers.dev").setLevel(logging.DEBUG) + +LOGGER = logging.getLogger(__name__) + + +def custom_generate_unique_id(route: APIRoute) -> str: + return f"{route.name}" + + +app = FastAPI( + generate_unique_id_function=custom_generate_unique_id, + root_path="/api", + default_response_class=ORJSONResponse, +) + +if os.environ.get("APPLICATIONINSIGHTS_CONNECTION_STRING"): + LOGGER.info("Configuring Azure Monitor telemetry for primary backend") + setup_azure_monitor_telemetry(app) +else: + LOGGER.warning("Skipping telemetry configuration, APPLICATIONINSIGHTS_CONNECTION_STRING env variable not set.") + + +# The tags we add here will determine the name of the frontend api service for our endpoints as well as +# providing some grouping when viewing the openapi documentation. +app.include_router(explore_router, tags=["explore"]) +app.include_router(timeseries_router, prefix="/timeseries", tags=["timeseries"]) +app.include_router(inplace_volumetrics_router, prefix="/inplace_volumetrics", tags=["inplace_volumetrics"]) +app.include_router(surface_router, prefix="/surface", tags=["surface"]) +app.include_router(parameters_router, prefix="/parameters", tags=["parameters"]) +app.include_router(correlations_router, prefix="/correlations", tags=["correlations"]) +app.include_router(grid_router, prefix="/grid", tags=["grid"]) +app.include_router(pvt_router, prefix="/pvt", tags=["pvt"]) +app.include_router(well_completions_router, prefix="/well_completions", tags=["well_completions"]) +app.include_router(well_router, prefix="/well", tags=["well"]) +app.include_router(seismic_router, prefix="/seismic", tags=["seismic"]) +app.include_router(polygons_router, prefix="/polygons", tags=["polygons"]) +app.include_router(graph_router, prefix="/graph", tags=["graph"]) +app.include_router(observations_router, prefix="/observations", tags=["observations"]) +app.include_router(rft_router, prefix="/rft", tags=["rft"]) +app.include_router(dev_router, prefix="/dev", tags=["dev"], include_in_schema=False) + +auth_helper = AuthHelper() +app.include_router(auth_helper.router) +app.include_router(general_router) + +configure_service_level_exception_handlers(app) +override_default_fastapi_exception_handlers(app) + + +# This middleware instance approximately measures execution time of the route handler itself +app.add_middleware(AddProcessTimeToServerTimingMiddleware, metric_name="total-exec-route") + +# Add out custom middleware to enforce that user is logged in +# Also redirects to /login endpoint for some select paths +unprotected_paths = ["/logged_in_user", "/alive", "/openapi.json"] +paths_redirected_to_login = ["/", "/alive_protected"] +app.add_middleware( + EnforceLoggedInMiddleware, + unprotected_paths=unprotected_paths, + paths_redirected_to_login=paths_redirected_to_login, +) + +session_store = RedisStore(config.REDIS_USER_SESSION_URL, prefix="user-auth:") +app.add_middleware(SessionMiddleware, store=session_store) + +app.add_middleware(ProxyHeadersMiddleware, trusted_hosts="*") + +# This middleware instance measures execution time of the endpoints, including the cost of other middleware +app.add_middleware(AddProcessTimeToServerTimingMiddleware, metric_name="total") + + +@app.get("/") +async def root() -> str: + return f"Primary backend is alive at this time: {datetime.datetime.now()}" diff --git a/backend/src/backend/utils/add_process_time_to_server_timing_middleware.py b/backend_py/primary/primary/middleware/add_process_time_to_server_timing_middleware.py similarity index 100% rename from backend/src/backend/utils/add_process_time_to_server_timing_middleware.py rename to backend_py/primary/primary/middleware/add_process_time_to_server_timing_middleware.py diff --git a/backend/src/backend/__init__.py b/backend_py/primary/primary/routers/__init__.py similarity index 100% rename from backend/src/backend/__init__.py rename to backend_py/primary/primary/routers/__init__.py diff --git a/backend/src/backend/auth/__init__.py b/backend_py/primary/primary/routers/correlations/__init__.py similarity index 100% rename from backend/src/backend/auth/__init__.py rename to backend_py/primary/primary/routers/correlations/__init__.py diff --git a/backend/src/backend/primary/routers/correlations/router.py b/backend_py/primary/primary/routers/correlations/router.py similarity index 100% rename from backend/src/backend/primary/routers/correlations/router.py rename to backend_py/primary/primary/routers/correlations/router.py diff --git a/backend/src/backend/primary/routers/dev/router.py b/backend_py/primary/primary/routers/dev/router.py similarity index 87% rename from backend/src/backend/primary/routers/dev/router.py rename to backend_py/primary/primary/routers/dev/router.py index e7d0b6a6c..5b859b3a3 100644 --- a/backend/src/backend/primary/routers/dev/router.py +++ b/backend_py/primary/primary/routers/dev/router.py @@ -5,15 +5,15 @@ import httpx from fastapi import APIRouter, Depends, HTTPException, Query, Path -from src.backend.auth.auth_helper import AuthenticatedUser, AuthHelper -from src.services.user_session_manager.user_session_manager import UserSessionManager -from src.services.user_session_manager.user_session_manager import UserComponent -from src.services.user_session_manager.user_session_manager import _USER_SESSION_DEFS -from src.services.user_session_manager._radix_helpers import create_new_radix_job, RadixResourceRequests -from src.services.user_session_manager._radix_helpers import get_all_radix_jobs, get_radix_job_state -from src.services.user_session_manager._radix_helpers import delete_all_radix_jobs -from src.services.user_session_manager._user_session_directory import UserSessionDirectory -from src.services.user_session_manager._background_tasks import run_in_background_task +from primary.auth.auth_helper import AuthenticatedUser, AuthHelper +from primary.services.user_session_manager.user_session_manager import UserSessionManager +from primary.services.user_session_manager.user_session_manager import UserComponent +from primary.services.user_session_manager.user_session_manager import _USER_SESSION_DEFS +from primary.services.user_session_manager._radix_helpers import create_new_radix_job, RadixResourceRequests +from primary.services.user_session_manager._radix_helpers import get_all_radix_jobs, get_radix_job_state +from primary.services.user_session_manager._radix_helpers import delete_all_radix_jobs +from primary.services.user_session_manager._user_session_directory import UserSessionDirectory +from primary.services.user_session_manager._background_tasks import run_in_background_task LOGGER = logging.getLogger(__name__) diff --git a/backend/src/backend/primary/routers/explore.py b/backend_py/primary/primary/routers/explore.py similarity index 92% rename from backend/src/backend/primary/routers/explore.py rename to backend_py/primary/primary/routers/explore.py index 831768e76..b2ba82811 100644 --- a/backend/src/backend/primary/routers/explore.py +++ b/backend_py/primary/primary/routers/explore.py @@ -3,10 +3,10 @@ from fastapi import APIRouter, Depends, Path, Query from pydantic import BaseModel -from src.backend.auth.auth_helper import AuthHelper -from src.services.sumo_access.sumo_explore import SumoExplore -from src.services.utils.authenticated_user import AuthenticatedUser -from src.services.sumo_access._helpers import SumoEnsemble +from primary.auth.auth_helper import AuthHelper +from primary.services.sumo_access.sumo_explore import SumoExplore +from primary.services.utils.authenticated_user import AuthenticatedUser +from primary.services.sumo_access._helpers import SumoEnsemble router = APIRouter() diff --git a/backend/src/backend/primary/routers/general.py b/backend_py/primary/primary/routers/general.py similarity index 79% rename from backend/src/backend/primary/routers/general.py rename to backend_py/primary/primary/routers/general.py index bcb6b6b45..58ede3f30 100644 --- a/backend/src/backend/primary/routers/general.py +++ b/backend_py/primary/primary/routers/general.py @@ -4,13 +4,11 @@ import httpx import starsessions -from starlette.responses import StreamingResponse -from fastapi import APIRouter, HTTPException, Request, status, Depends, Query +from fastapi import APIRouter, HTTPException, Request, status, Query from pydantic import BaseModel -from src.backend.auth.auth_helper import AuthHelper, AuthenticatedUser -from src.backend.primary.user_session_proxy import proxy_to_user_session -from src.services.graph_access.graph_access import GraphApiAccess +from primary.auth.auth_helper import AuthHelper +from primary.services.graph_access.graph_access import GraphApiAccess LOGGER = logging.getLogger(__name__) @@ -81,11 +79,3 @@ async def logged_in_user( print("Error while fetching user avatar and info from Microsoft Graph API (Invalid URL):\n", exc) return user_info - - -@router.get("/user_session_container") -async def user_session_container( - request: Request, authenticated_user: AuthenticatedUser = Depends(AuthHelper.get_authenticated_user) -) -> StreamingResponse: - """Get information about user session container (note that one is started if not already running).""" - return await proxy_to_user_session(request, authenticated_user) diff --git a/backend/src/backend/primary/__init__.py b/backend_py/primary/primary/routers/graph/__init__.py similarity index 100% rename from backend/src/backend/primary/__init__.py rename to backend_py/primary/primary/routers/graph/__init__.py diff --git a/backend/src/backend/primary/routers/graph/router.py b/backend_py/primary/primary/routers/graph/router.py similarity index 86% rename from backend/src/backend/primary/routers/graph/router.py rename to backend_py/primary/primary/routers/graph/router.py index 0deb3fb2a..9d913a09b 100644 --- a/backend/src/backend/primary/routers/graph/router.py +++ b/backend_py/primary/primary/routers/graph/router.py @@ -3,9 +3,9 @@ import httpx from fastapi import APIRouter, Depends, Query -from src.backend.auth.auth_helper import AuthHelper -from src.services.utils.authenticated_user import AuthenticatedUser -from src.services.graph_access.graph_access import GraphApiAccess +from primary.auth.auth_helper import AuthHelper +from primary.services.utils.authenticated_user import AuthenticatedUser +from primary.services.graph_access.graph_access import GraphApiAccess from .schemas import GraphUserPhoto diff --git a/backend/src/backend/primary/routers/graph/schemas.py b/backend_py/primary/primary/routers/graph/schemas.py similarity index 100% rename from backend/src/backend/primary/routers/graph/schemas.py rename to backend_py/primary/primary/routers/graph/schemas.py diff --git a/backend/src/backend/primary/routers/__init__.py b/backend_py/primary/primary/routers/grid/__init__.py similarity index 100% rename from backend/src/backend/primary/routers/__init__.py rename to backend_py/primary/primary/routers/grid/__init__.py diff --git a/backend/src/backend/primary/routers/grid/router.py b/backend_py/primary/primary/routers/grid/router.py similarity index 89% rename from backend/src/backend/primary/routers/grid/router.py rename to backend_py/primary/primary/routers/grid/router.py index fc064fec3..6c1a5cff4 100644 --- a/backend/src/backend/primary/routers/grid/router.py +++ b/backend_py/primary/primary/routers/grid/router.py @@ -1,17 +1,19 @@ from typing import List -from fastapi import APIRouter, Depends, Query +from fastapi import APIRouter, Depends, Query, HTTPException, status from starlette.requests import Request -from src.services.utils.authenticated_user import AuthenticatedUser -from src.backend.auth.auth_helper import AuthHelper -from src.backend.primary.user_session_proxy import proxy_to_user_session +from primary.services.utils.authenticated_user import AuthenticatedUser +from primary.auth.auth_helper import AuthHelper -from src.services.sumo_access.grid_access import GridAccess +from primary.services.sumo_access.grid_access import GridAccess from .schemas import GridSurface, GridIntersection router = APIRouter() +# pylint: disable=unused-argument +# pylint: disable=unused-variable + @router.get("/grid_model_names/") async def get_grid_model_names( @@ -71,8 +73,7 @@ async def grid_surface( receive=request._receive, # pylint: disable=protected-access ) - response = await proxy_to_user_session(updated_request, authenticated_user) - return response + raise HTTPException(status.HTTP_501_NOT_IMPLEMENTED) @router.get("/grid_parameter") @@ -107,8 +108,7 @@ async def grid_parameter( receive=request._receive, # pylint: disable=protected-access ) - response = await proxy_to_user_session(updated_request, authenticated_user) - return response + raise HTTPException(status.HTTP_501_NOT_IMPLEMENTED) @router.get("/grid_parameter_intersection") @@ -143,8 +143,7 @@ async def grid_parameter_intersection( receive=request._receive, # pylint: disable=protected-access ) - response = await proxy_to_user_session(updated_request, authenticated_user) - return response + raise HTTPException(status.HTTP_501_NOT_IMPLEMENTED) @router.get("/statistical_grid_parameter_intersection") @@ -179,8 +178,7 @@ async def statistical_grid_parameter_intersection( receive=request._receive, # pylint: disable=protected-access ) - response = await proxy_to_user_session(updated_request, authenticated_user) - return response + raise HTTPException(status.HTTP_501_NOT_IMPLEMENTED) @router.get("/statistical_grid_parameter") @@ -214,5 +212,4 @@ async def statistical_grid_parameter( receive=request._receive, # pylint: disable=protected-access ) - response = await proxy_to_user_session(updated_request, authenticated_user) - return response + raise HTTPException(status.HTTP_501_NOT_IMPLEMENTED) diff --git a/backend/src/backend/primary/routers/grid/schemas.py b/backend_py/primary/primary/routers/grid/schemas.py similarity index 86% rename from backend/src/backend/primary/routers/grid/schemas.py rename to backend_py/primary/primary/routers/grid/schemas.py index c8a3abe03..27230eb0b 100644 --- a/backend/src/backend/primary/routers/grid/schemas.py +++ b/backend_py/primary/primary/routers/grid/schemas.py @@ -1,8 +1,7 @@ from typing import List from pydantic import BaseModel - -from src.services.utils.b64 import B64FloatArray, B64UintArray +from webviz_pkg.core_utils.b64 import B64FloatArray, B64UintArray class GridSurface(BaseModel): diff --git a/backend/src/backend/primary/routers/correlations/__init__.py b/backend_py/primary/primary/routers/inplace_volumetrics/__init__.py similarity index 100% rename from backend/src/backend/primary/routers/correlations/__init__.py rename to backend_py/primary/primary/routers/inplace_volumetrics/__init__.py diff --git a/backend/src/backend/primary/routers/inplace_volumetrics/router.py b/backend_py/primary/primary/routers/inplace_volumetrics/router.py similarity index 93% rename from backend/src/backend/primary/routers/inplace_volumetrics/router.py rename to backend_py/primary/primary/routers/inplace_volumetrics/router.py index 7e2df6b0e..828a53bf7 100644 --- a/backend/src/backend/primary/routers/inplace_volumetrics/router.py +++ b/backend_py/primary/primary/routers/inplace_volumetrics/router.py @@ -1,16 +1,16 @@ from typing import List, Optional, Sequence from fastapi import APIRouter, Depends, Query -from src.services.sumo_access.inplace_volumetrics_access import ( +from primary.services.sumo_access.inplace_volumetrics_access import ( InplaceVolumetricsAccess, InplaceVolumetricsTableMetaData, InplaceVolumetricsCategoricalMetaData, ) -from src.services.sumo_access.generic_types import EnsembleScalarResponse -from src.services.utils.authenticated_user import AuthenticatedUser +from primary.services.sumo_access.generic_types import EnsembleScalarResponse +from primary.services.utils.authenticated_user import AuthenticatedUser -from src.backend.auth.auth_helper import AuthHelper +from primary.auth.auth_helper import AuthHelper router = APIRouter() diff --git a/backend/src/backend/primary/routers/observations/router.py b/backend_py/primary/primary/routers/observations/router.py similarity index 75% rename from backend/src/backend/primary/routers/observations/router.py rename to backend_py/primary/primary/routers/observations/router.py index c22f9f020..33578c4cd 100644 --- a/backend/src/backend/primary/routers/observations/router.py +++ b/backend_py/primary/primary/routers/observations/router.py @@ -1,11 +1,10 @@ import logging -from typing import List, Optional, Literal from fastapi import APIRouter, Depends, Query -from src.backend.auth.auth_helper import AuthHelper -from src.services.sumo_access.observation_access import ObservationAccess -from src.services.utils.authenticated_user import AuthenticatedUser +from primary.auth.auth_helper import AuthHelper +from primary.services.sumo_access.observation_access import ObservationAccess +from primary.services.utils.authenticated_user import AuthenticatedUser from . import schemas diff --git a/backend/src/backend/primary/routers/observations/schemas.py b/backend_py/primary/primary/routers/observations/schemas.py similarity index 100% rename from backend/src/backend/primary/routers/observations/schemas.py rename to backend_py/primary/primary/routers/observations/schemas.py diff --git a/backend/src/backend/primary/routers/parameters/__init__,py b/backend_py/primary/primary/routers/parameters/__init__,py similarity index 100% rename from backend/src/backend/primary/routers/parameters/__init__,py rename to backend_py/primary/primary/routers/parameters/__init__,py diff --git a/backend/src/backend/primary/routers/parameters/router.py b/backend_py/primary/primary/routers/parameters/router.py similarity index 93% rename from backend/src/backend/primary/routers/parameters/router.py rename to backend_py/primary/primary/routers/parameters/router.py index d670d31d1..983b88d6a 100644 --- a/backend/src/backend/primary/routers/parameters/router.py +++ b/backend_py/primary/primary/routers/parameters/router.py @@ -3,10 +3,10 @@ from fastapi import APIRouter, Depends, Query -from src.backend.auth.auth_helper import AuthHelper -from src.services.sumo_access.parameter_access import ParameterAccess -from src.services.sumo_access.parameter_types import EnsembleParameter, EnsembleSensitivity -from src.services.utils.authenticated_user import AuthenticatedUser +from primary.auth.auth_helper import AuthHelper +from primary.services.sumo_access.parameter_access import ParameterAccess +from primary.services.sumo_access.parameter_types import EnsembleParameter, EnsembleSensitivity +from primary.services.utils.authenticated_user import AuthenticatedUser from . import schemas diff --git a/backend/src/backend/primary/routers/parameters/schemas.py b/backend_py/primary/primary/routers/parameters/schemas.py similarity index 100% rename from backend/src/backend/primary/routers/parameters/schemas.py rename to backend_py/primary/primary/routers/parameters/schemas.py diff --git a/backend/src/backend/primary/routers/graph/__init__.py b/backend_py/primary/primary/routers/polygons/__init__.py similarity index 100% rename from backend/src/backend/primary/routers/graph/__init__.py rename to backend_py/primary/primary/routers/polygons/__init__.py diff --git a/backend/src/backend/primary/routers/polygons/converters.py b/backend_py/primary/primary/routers/polygons/converters.py similarity index 95% rename from backend/src/backend/primary/routers/polygons/converters.py rename to backend_py/primary/primary/routers/polygons/converters.py index fbcf8b1f6..6aef1f0d3 100644 --- a/backend/src/backend/primary/routers/polygons/converters.py +++ b/backend_py/primary/primary/routers/polygons/converters.py @@ -1,8 +1,8 @@ from typing import List import xtgeo -from src.services.smda_access.types import StratigraphicSurface -from src.services.sumo_access.polygons_types import PolygonsMeta as SumoPolygonsMeta +from primary.services.smda_access.types import StratigraphicSurface +from primary.services.sumo_access.polygons_types import PolygonsMeta as SumoPolygonsMeta from . import schemas diff --git a/backend/src/backend/primary/routers/polygons/router.py b/backend_py/primary/primary/routers/polygons/router.py similarity index 80% rename from backend/src/backend/primary/routers/polygons/router.py rename to backend_py/primary/primary/routers/polygons/router.py index cc0b683c1..d3f4a79c9 100644 --- a/backend/src/backend/primary/routers/polygons/router.py +++ b/backend_py/primary/primary/routers/polygons/router.py @@ -2,19 +2,17 @@ from typing import List, Union from fastapi import APIRouter, Depends, HTTPException, Query +from webviz_pkg.core_utils.perf_timer import PerfTimer -from src.services.sumo_access._helpers import SumoCase -from src.services.smda_access.stratigraphy_access import StratigraphyAccess -from src.services.sumo_access.polygons_access import PolygonsAccess -from src.services.smda_access.stratigraphy_utils import sort_stratigraphic_names_by_hierarchy -from src.services.smda_access.mocked_drogon_smda_access import _mocked_stratigraphy_access -from src.services.utils.authenticated_user import AuthenticatedUser -from src.services.utils.perf_timer import PerfTimer -from src.backend.auth.auth_helper import AuthHelper +from primary.auth.auth_helper import AuthHelper +from primary.services.smda_access.mocked_drogon_smda_access import _mocked_stratigraphy_access +from primary.services.smda_access.stratigraphy_access import StratigraphyAccess +from primary.services.smda_access.stratigraphy_utils import sort_stratigraphic_names_by_hierarchy +from primary.services.sumo_access._helpers import SumoCase +from primary.services.sumo_access.polygons_access import PolygonsAccess +from primary.services.utils.authenticated_user import AuthenticatedUser - -from . import schemas -from . import converters +from . import converters, schemas LOGGER = logging.getLogger(__name__) diff --git a/backend/src/backend/primary/routers/polygons/schemas.py b/backend_py/primary/primary/routers/polygons/schemas.py similarity index 100% rename from backend/src/backend/primary/routers/polygons/schemas.py rename to backend_py/primary/primary/routers/polygons/schemas.py diff --git a/backend/src/backend/primary/routers/grid/__init__.py b/backend_py/primary/primary/routers/pvt/__init__.py similarity index 100% rename from backend/src/backend/primary/routers/grid/__init__.py rename to backend_py/primary/primary/routers/pvt/__init__.py diff --git a/backend/src/backend/primary/routers/pvt/converters.py b/backend_py/primary/primary/routers/pvt/converters.py similarity index 100% rename from backend/src/backend/primary/routers/pvt/converters.py rename to backend_py/primary/primary/routers/pvt/converters.py diff --git a/backend/src/backend/primary/routers/pvt/router.py b/backend_py/primary/primary/routers/pvt/router.py similarity index 92% rename from backend/src/backend/primary/routers/pvt/router.py rename to backend_py/primary/primary/routers/pvt/router.py index 6aeb694ff..a50e1175a 100644 --- a/backend/src/backend/primary/routers/pvt/router.py +++ b/backend_py/primary/primary/routers/pvt/router.py @@ -3,9 +3,9 @@ from fastapi import APIRouter, Depends, HTTPException, Query -from src.backend.auth.auth_helper import AuthHelper -from src.services.sumo_access.table_access import TableAccess -from src.services.utils.authenticated_user import AuthenticatedUser +from primary.auth.auth_helper import AuthHelper +from primary.services.sumo_access.table_access import TableAccess +from primary.services.utils.authenticated_user import AuthenticatedUser from .converters import pvt_dataframe_to_api_data from .schemas import PvtData diff --git a/backend/src/backend/primary/routers/pvt/schemas.py b/backend_py/primary/primary/routers/pvt/schemas.py similarity index 100% rename from backend/src/backend/primary/routers/pvt/schemas.py rename to backend_py/primary/primary/routers/pvt/schemas.py diff --git a/backend/src/backend/primary/routers/rft/router.py b/backend_py/primary/primary/routers/rft/router.py similarity index 76% rename from backend/src/backend/primary/routers/rft/router.py rename to backend_py/primary/primary/routers/rft/router.py index 178313a1d..7de32ceee 100644 --- a/backend/src/backend/primary/routers/rft/router.py +++ b/backend_py/primary/primary/routers/rft/router.py @@ -1,16 +1,11 @@ import logging from typing import Annotated -import pyarrow as pa -import pyarrow.compute as pc -from fastapi import APIRouter, Depends, HTTPException, Query - -from src.backend.auth.auth_helper import AuthHelper -from src.services.summary_vector_statistics import compute_vector_statistics -from src.services.sumo_access.generic_types import EnsembleScalarResponse -from src.services.sumo_access.parameter_access import ParameterAccess -from src.services.sumo_access.rft_access import RftAccess -from src.services.utils.authenticated_user import AuthenticatedUser +from fastapi import APIRouter, Depends, Query + +from primary.auth.auth_helper import AuthHelper +from primary.services.sumo_access.rft_access import RftAccess +from primary.services.utils.authenticated_user import AuthenticatedUser from . import schemas diff --git a/backend/src/backend/primary/routers/rft/schemas.py b/backend_py/primary/primary/routers/rft/schemas.py similarity index 100% rename from backend/src/backend/primary/routers/rft/schemas.py rename to backend_py/primary/primary/routers/rft/schemas.py diff --git a/backend/src/backend/primary/routers/inplace_volumetrics/__init__.py b/backend_py/primary/primary/routers/seismic/__init__.py similarity index 100% rename from backend/src/backend/primary/routers/inplace_volumetrics/__init__.py rename to backend_py/primary/primary/routers/seismic/__init__.py diff --git a/backend/src/backend/primary/routers/seismic/router.py b/backend_py/primary/primary/routers/seismic/router.py similarity index 87% rename from backend/src/backend/primary/routers/seismic/router.py rename to backend_py/primary/primary/routers/seismic/router.py index 90b037e50..781a548f3 100644 --- a/backend/src/backend/primary/routers/seismic/router.py +++ b/backend_py/primary/primary/routers/seismic/router.py @@ -1,19 +1,18 @@ import logging from typing import List, Optional -from fastapi import APIRouter, Depends, HTTPException, Query, Body +from fastapi import APIRouter, Body, Depends, HTTPException, Query +from webviz_pkg.core_utils.b64 import b64_encode_float_array_as_float32 -from src.services.sumo_access.seismic_access import SeismicAccess, VdsHandle -from src.services.vds_access.vds_access import VdsAccess -from src.services.utils.authenticated_user import AuthenticatedUser -from src.backend.auth.auth_helper import AuthHelper -from src.services.utils.b64 import b64_encode_float_array_as_float32 -from src.services.vds_access.response_types import VdsMetadata -from src.services.vds_access.request_types import VdsCoordinateSystem, VdsCoordinates +from primary.auth.auth_helper import AuthHelper +from primary.services.sumo_access.seismic_access import SeismicAccess, VdsHandle +from primary.services.utils.authenticated_user import AuthenticatedUser +from primary.services.vds_access.request_types import VdsCoordinates, VdsCoordinateSystem +from primary.services.vds_access.response_types import VdsMetadata +from primary.services.vds_access.vds_access import VdsAccess from . import schemas - LOGGER = logging.getLogger(__name__) router = APIRouter() diff --git a/backend/src/backend/primary/routers/seismic/schemas.py b/backend_py/primary/primary/routers/seismic/schemas.py similarity index 97% rename from backend/src/backend/primary/routers/seismic/schemas.py rename to backend_py/primary/primary/routers/seismic/schemas.py index 3e2c4b087..dbcf7430c 100644 --- a/backend/src/backend/primary/routers/seismic/schemas.py +++ b/backend_py/primary/primary/routers/seismic/schemas.py @@ -1,8 +1,7 @@ from typing import List from pydantic import BaseModel - -from src.services.utils.b64 import B64FloatArray +from webviz_pkg.core_utils.b64 import B64FloatArray class SeismicCubeMeta(BaseModel): diff --git a/backend/src/backend/primary/routers/polygons/__init__.py b/backend_py/primary/primary/routers/surface/__init__.py similarity index 100% rename from backend/src/backend/primary/routers/polygons/__init__.py rename to backend_py/primary/primary/routers/surface/__init__.py diff --git a/backend/src/backend/primary/routers/surface/converters.py b/backend_py/primary/primary/routers/surface/converters.py similarity index 92% rename from backend/src/backend/primary/routers/surface/converters.py rename to backend_py/primary/primary/routers/surface/converters.py index 5b6a48f3f..26568174b 100644 --- a/backend/src/backend/primary/routers/surface/converters.py +++ b/backend_py/primary/primary/routers/surface/converters.py @@ -3,12 +3,12 @@ import numpy as np import xtgeo from numpy.typing import NDArray +from webviz_pkg.core_utils.b64 import b64_encode_float_array_as_float32 -from src.services.smda_access.types import StratigraphicSurface -from src.services.sumo_access.surface_types import SurfaceMeta as SumoSurfaceMeta -from src.services.sumo_access.surface_types import XtgeoSurfaceIntersectionPolyline, XtgeoSurfaceIntersectionResult -from src.services.utils.b64 import b64_encode_float_array_as_float32 -from src.services.utils.surface_to_float32 import surface_to_float32_numpy_array +from primary.services.smda_access.types import StratigraphicSurface +from primary.services.sumo_access.surface_types import SurfaceMeta as SumoSurfaceMeta +from primary.services.sumo_access.surface_types import XtgeoSurfaceIntersectionPolyline, XtgeoSurfaceIntersectionResult +from primary.services.utils.surface_to_float32 import surface_to_float32_numpy_array from . import schemas diff --git a/backend/src/backend/primary/routers/surface/router.py b/backend_py/primary/primary/routers/surface/router.py similarity index 92% rename from backend/src/backend/primary/routers/surface/router.py rename to backend_py/primary/primary/routers/surface/router.py index 4ac930c5a..8fcf3e863 100644 --- a/backend/src/backend/primary/routers/surface/router.py +++ b/backend_py/primary/primary/routers/surface/router.py @@ -2,19 +2,19 @@ from typing import List, Union, Optional from fastapi import APIRouter, Depends, HTTPException, Query, Response, Body - -from src.services.sumo_access.surface_access import SurfaceAccess -from src.services.smda_access.stratigraphy_access import StratigraphyAccess -from src.services.smda_access.stratigraphy_utils import sort_stratigraphic_names_by_hierarchy -from src.services.smda_access.mocked_drogon_smda_access import _mocked_stratigraphy_access -from src.services.utils.statistic_function import StatisticFunction -from src.services.utils.authenticated_user import AuthenticatedUser -from src.services.utils.perf_timer import PerfTimer -from src.backend.auth.auth_helper import AuthHelper -from src.backend.utils.perf_metrics import PerfMetrics -from src.services.sumo_access._helpers import SumoCase -from src.services.surface_query_service.surface_query_service import batch_sample_surface_in_points_async -from src.services.surface_query_service.surface_query_service import RealizationSampleResult +from webviz_pkg.core_utils.perf_timer import PerfTimer + +from primary.services.sumo_access.surface_access import SurfaceAccess +from primary.services.smda_access.stratigraphy_access import StratigraphyAccess +from primary.services.smda_access.stratigraphy_utils import sort_stratigraphic_names_by_hierarchy +from primary.services.smda_access.mocked_drogon_smda_access import _mocked_stratigraphy_access +from primary.services.utils.statistic_function import StatisticFunction +from primary.services.utils.authenticated_user import AuthenticatedUser +from primary.auth.auth_helper import AuthHelper +from primary.utils.perf_metrics import PerfMetrics +from primary.services.sumo_access._helpers import SumoCase +from primary.services.surface_query_service.surface_query_service import batch_sample_surface_in_points_async +from primary.services.surface_query_service.surface_query_service import RealizationSampleResult from . import converters from . import schemas diff --git a/backend/src/backend/primary/routers/surface/schemas.py b/backend_py/primary/primary/routers/surface/schemas.py similarity index 96% rename from backend/src/backend/primary/routers/surface/schemas.py rename to backend_py/primary/primary/routers/surface/schemas.py index 2a2b7338c..43a807c8e 100644 --- a/backend/src/backend/primary/routers/surface/schemas.py +++ b/backend_py/primary/primary/routers/surface/schemas.py @@ -2,9 +2,9 @@ from typing import List, Optional from pydantic import BaseModel +from webviz_pkg.core_utils.b64 import B64FloatArray -from src.services.smda_access.types import StratigraphicFeature -from src.services.utils.b64 import B64FloatArray +from primary.services.smda_access.types import StratigraphicFeature class SurfaceStatisticFunction(str, Enum): diff --git a/backend/src/backend/primary/routers/timeseries/converters.py b/backend_py/primary/primary/routers/timeseries/converters.py similarity index 89% rename from backend/src/backend/primary/routers/timeseries/converters.py rename to backend_py/primary/primary/routers/timeseries/converters.py index da715f8e2..e449e6e8d 100644 --- a/backend/src/backend/primary/routers/timeseries/converters.py +++ b/backend_py/primary/primary/routers/timeseries/converters.py @@ -1,8 +1,8 @@ from typing import List, Optional, Sequence -from src.services.summary_vector_statistics import VectorStatistics -from src.services.sumo_access.summary_access import VectorMetadata -from src.services.utils.statistic_function import StatisticFunction +from primary.services.summary_vector_statistics import VectorStatistics +from primary.services.sumo_access.summary_access import VectorMetadata +from primary.services.utils.statistic_function import StatisticFunction from . import schemas diff --git a/backend/src/backend/primary/routers/timeseries/router.py b/backend_py/primary/primary/routers/timeseries/router.py similarity index 96% rename from backend/src/backend/primary/routers/timeseries/router.py rename to backend_py/primary/primary/routers/timeseries/router.py index 45882129b..9e494a642 100644 --- a/backend/src/backend/primary/routers/timeseries/router.py +++ b/backend_py/primary/primary/routers/timeseries/router.py @@ -5,13 +5,13 @@ import pyarrow.compute as pc from fastapi import APIRouter, Depends, HTTPException, Query, Response -from src.backend.auth.auth_helper import AuthHelper -from src.backend.utils.perf_metrics import PerfMetrics -from src.services.summary_vector_statistics import compute_vector_statistics -from src.services.sumo_access.generic_types import EnsembleScalarResponse -from src.services.sumo_access.parameter_access import ParameterAccess -from src.services.sumo_access.summary_access import Frequency, SummaryAccess -from src.services.utils.authenticated_user import AuthenticatedUser +from primary.auth.auth_helper import AuthHelper +from primary.utils.perf_metrics import PerfMetrics +from primary.services.summary_vector_statistics import compute_vector_statistics +from primary.services.sumo_access.generic_types import EnsembleScalarResponse +from primary.services.sumo_access.parameter_access import ParameterAccess +from primary.services.sumo_access.summary_access import Frequency, SummaryAccess +from primary.services.utils.authenticated_user import AuthenticatedUser from . import converters, schemas diff --git a/backend/src/backend/primary/routers/timeseries/schemas.py b/backend_py/primary/primary/routers/timeseries/schemas.py similarity index 100% rename from backend/src/backend/primary/routers/timeseries/schemas.py rename to backend_py/primary/primary/routers/timeseries/schemas.py diff --git a/backend/src/backend/primary/routers/pvt/__init__.py b/backend_py/primary/primary/routers/well/__init__.py similarity index 100% rename from backend/src/backend/primary/routers/pvt/__init__.py rename to backend_py/primary/primary/routers/well/__init__.py diff --git a/backend/src/backend/primary/routers/well/converters.py b/backend_py/primary/primary/routers/well/converters.py similarity index 91% rename from backend/src/backend/primary/routers/well/converters.py rename to backend_py/primary/primary/routers/well/converters.py index d52be1ce3..21e8569d8 100644 --- a/backend/src/backend/primary/routers/well/converters.py +++ b/backend_py/primary/primary/routers/well/converters.py @@ -1,7 +1,8 @@ from typing import List -from src.backend.primary.routers.well import schemas -from src.services.smda_access.types import WellBorePick, StratigraphicUnit +from primary.services.smda_access.types import WellBorePick, StratigraphicUnit + +from . import schemas def convert_wellbore_picks_to_schema(wellbore_picks: List[WellBorePick]) -> List[schemas.WellBorePick]: diff --git a/backend/src/backend/primary/routers/well/router.py b/backend_py/primary/primary/routers/well/router.py similarity index 91% rename from backend/src/backend/primary/routers/well/router.py rename to backend_py/primary/primary/routers/well/router.py index f3583cf9e..605f6694c 100644 --- a/backend/src/backend/primary/routers/well/router.py +++ b/backend_py/primary/primary/routers/well/router.py @@ -3,13 +3,13 @@ from fastapi import APIRouter, Depends, Query -from src.services.smda_access import mocked_drogon_smda_access -from src.services.smda_access.well_access import WellAccess -from src.services.smda_access.stratigraphy_access import StratigraphyAccess -from src.services.utils.authenticated_user import AuthenticatedUser -from src.backend.auth.auth_helper import AuthHelper -from src.services.sumo_access._helpers import SumoCase -from src.services.smda_access.types import WellBoreHeader, WellBoreTrajectory +from primary.services.smda_access import mocked_drogon_smda_access +from primary.services.smda_access.well_access import WellAccess +from primary.services.smda_access.stratigraphy_access import StratigraphyAccess +from primary.services.utils.authenticated_user import AuthenticatedUser +from primary.auth.auth_helper import AuthHelper +from primary.services.sumo_access._helpers import SumoCase +from primary.services.smda_access.types import WellBoreHeader, WellBoreTrajectory from . import schemas from . import converters diff --git a/backend/src/backend/primary/routers/well/schemas.py b/backend_py/primary/primary/routers/well/schemas.py similarity index 100% rename from backend/src/backend/primary/routers/well/schemas.py rename to backend_py/primary/primary/routers/well/schemas.py diff --git a/backend/src/backend/primary/routers/well_completions/router.py b/backend_py/primary/primary/routers/well_completions/router.py similarity index 77% rename from backend/src/backend/primary/routers/well_completions/router.py rename to backend_py/primary/primary/routers/well_completions/router.py index 8e7dc5eaa..acce7fec6 100644 --- a/backend/src/backend/primary/routers/well_completions/router.py +++ b/backend_py/primary/primary/routers/well_completions/router.py @@ -2,11 +2,11 @@ from fastapi import APIRouter, Depends, HTTPException, Query -from src.backend.auth.auth_helper import AuthHelper -from src.services.utils.authenticated_user import AuthenticatedUser +from primary.auth.auth_helper import AuthHelper +from primary.services.utils.authenticated_user import AuthenticatedUser -from src.services.sumo_access.well_completions_access import WellCompletionsAccess -from src.services.sumo_access.well_completions_types import WellCompletionsData +from primary.services.sumo_access.well_completions_access import WellCompletionsAccess +from primary.services.sumo_access.well_completions_types import WellCompletionsData router = APIRouter() diff --git a/backend/src/backend/primary/routers/seismic/__init__.py b/backend_py/primary/primary/services/__init__.py similarity index 100% rename from backend/src/backend/primary/routers/seismic/__init__.py rename to backend_py/primary/primary/services/__init__.py diff --git a/backend/src/services/graph_access/graph_access.py b/backend_py/primary/primary/services/graph_access/graph_access.py similarity index 100% rename from backend/src/services/graph_access/graph_access.py rename to backend_py/primary/primary/services/graph_access/graph_access.py diff --git a/backend/src/services/parameter_correlations.py b/backend_py/primary/primary/services/parameter_correlations.py similarity index 92% rename from backend/src/services/parameter_correlations.py rename to backend_py/primary/primary/services/parameter_correlations.py index 227204f69..ba5894e73 100644 --- a/backend/src/services/parameter_correlations.py +++ b/backend_py/primary/primary/services/parameter_correlations.py @@ -2,8 +2,8 @@ import pandas as pd -from src.services.sumo_access.parameter_access import EnsembleParameter -from src.services.sumo_access.generic_types import EnsembleScalarResponse, EnsembleCorrelations +from primary.services.sumo_access.parameter_access import EnsembleParameter +from primary.services.sumo_access.generic_types import EnsembleScalarResponse, EnsembleCorrelations def correlate_parameters_with_response( diff --git a/backend/src/services/service_exceptions.py b/backend_py/primary/primary/services/service_exceptions.py similarity index 100% rename from backend/src/services/service_exceptions.py rename to backend_py/primary/primary/services/service_exceptions.py diff --git a/backend/src/backend/primary/routers/surface/__init__.py b/backend_py/primary/primary/services/smda_access/__init__.py similarity index 100% rename from backend/src/backend/primary/routers/surface/__init__.py rename to backend_py/primary/primary/services/smda_access/__init__.py diff --git a/backend/src/services/smda_access/mocked_drogon_smda_access/__init__.py b/backend_py/primary/primary/services/smda_access/mocked_drogon_smda_access/__init__.py similarity index 100% rename from backend/src/services/smda_access/mocked_drogon_smda_access/__init__.py rename to backend_py/primary/primary/services/smda_access/mocked_drogon_smda_access/__init__.py diff --git a/backend/src/services/smda_access/mocked_drogon_smda_access/_generate_testdata.py b/backend_py/primary/primary/services/smda_access/mocked_drogon_smda_access/_generate_testdata.py similarity index 100% rename from backend/src/services/smda_access/mocked_drogon_smda_access/_generate_testdata.py rename to backend_py/primary/primary/services/smda_access/mocked_drogon_smda_access/_generate_testdata.py diff --git a/backend/src/services/smda_access/mocked_drogon_smda_access/_mocked_stratigraphy_access.py b/backend_py/primary/primary/services/smda_access/mocked_drogon_smda_access/_mocked_stratigraphy_access.py similarity index 100% rename from backend/src/services/smda_access/mocked_drogon_smda_access/_mocked_stratigraphy_access.py rename to backend_py/primary/primary/services/smda_access/mocked_drogon_smda_access/_mocked_stratigraphy_access.py diff --git a/backend/src/services/smda_access/mocked_drogon_smda_access/_mocked_well_access.py b/backend_py/primary/primary/services/smda_access/mocked_drogon_smda_access/_mocked_well_access.py similarity index 100% rename from backend/src/services/smda_access/mocked_drogon_smda_access/_mocked_well_access.py rename to backend_py/primary/primary/services/smda_access/mocked_drogon_smda_access/_mocked_well_access.py diff --git a/backend/src/services/smda_access/mocked_drogon_smda_access/_mocked_wellbore_picks.py b/backend_py/primary/primary/services/smda_access/mocked_drogon_smda_access/_mocked_wellbore_picks.py similarity index 98% rename from backend/src/services/smda_access/mocked_drogon_smda_access/_mocked_wellbore_picks.py rename to backend_py/primary/primary/services/smda_access/mocked_drogon_smda_access/_mocked_wellbore_picks.py index 39ef35785..efd6f282a 100644 --- a/backend/src/services/smda_access/mocked_drogon_smda_access/_mocked_wellbore_picks.py +++ b/backend_py/primary/primary/services/smda_access/mocked_drogon_smda_access/_mocked_wellbore_picks.py @@ -1,6 +1,6 @@ from typing import List -from src.services.smda_access.types import WellBorePick +from primary.services.smda_access.types import WellBorePick mocked_wellbore_picks: List[WellBorePick] = [ WellBorePick( diff --git a/backend/src/backend/primary/routers/well/__init__.py b/backend_py/primary/primary/services/smda_access/queries/__init__.py similarity index 100% rename from backend/src/backend/primary/routers/well/__init__.py rename to backend_py/primary/primary/services/smda_access/queries/__init__.py diff --git a/backend/src/services/smda_access/queries/_get_request.py b/backend_py/primary/primary/services/smda_access/queries/_get_request.py similarity index 95% rename from backend/src/services/smda_access/queries/_get_request.py rename to backend_py/primary/primary/services/smda_access/queries/_get_request.py index b03ed4abd..52c14d3fe 100644 --- a/backend/src/services/smda_access/queries/_get_request.py +++ b/backend_py/primary/primary/services/smda_access/queries/_get_request.py @@ -2,9 +2,9 @@ import httpx from dotenv import load_dotenv +from webviz_pkg.core_utils.perf_timer import PerfTimer -from src import config -from src.services.utils.perf_timer import PerfTimer +from primary import config load_dotenv() diff --git a/backend/src/services/smda_access/queries/get_field_wellbore_trajectories.py b/backend_py/primary/primary/services/smda_access/queries/get_field_wellbore_trajectories.py similarity index 96% rename from backend/src/services/smda_access/queries/get_field_wellbore_trajectories.py rename to backend_py/primary/primary/services/smda_access/queries/get_field_wellbore_trajectories.py index 4fc498163..f8cf57d69 100644 --- a/backend/src/services/smda_access/queries/get_field_wellbore_trajectories.py +++ b/backend_py/primary/primary/services/smda_access/queries/get_field_wellbore_trajectories.py @@ -2,7 +2,7 @@ import pandas as pd -from src.services.utils.perf_timer import PerfTimer +from webviz_pkg.core_utils.perf_timer import PerfTimer from ..types import WellBoreTrajectory from ._get_request import get diff --git a/backend/src/services/smda_access/queries/get_picks_for_wellbore.py b/backend_py/primary/primary/services/smda_access/queries/get_picks_for_wellbore.py similarity index 100% rename from backend/src/services/smda_access/queries/get_picks_for_wellbore.py rename to backend_py/primary/primary/services/smda_access/queries/get_picks_for_wellbore.py diff --git a/backend/src/services/smda_access/queries/get_stratigraphic_units.py b/backend_py/primary/primary/services/smda_access/queries/get_stratigraphic_units.py similarity index 93% rename from backend/src/services/smda_access/queries/get_stratigraphic_units.py rename to backend_py/primary/primary/services/smda_access/queries/get_stratigraphic_units.py index 2828affdf..6d5ac97c7 100644 --- a/backend/src/services/smda_access/queries/get_stratigraphic_units.py +++ b/backend_py/primary/primary/services/smda_access/queries/get_stratigraphic_units.py @@ -1,6 +1,6 @@ from typing import List -from src.services.utils.perf_timer import PerfTimer +from webviz_pkg.core_utils.perf_timer import PerfTimer from ..types import StratigraphicUnit from ._get_request import get diff --git a/backend/src/services/smda_access/queries/get_well_headers.py b/backend_py/primary/primary/services/smda_access/queries/get_well_headers.py similarity index 93% rename from backend/src/services/smda_access/queries/get_well_headers.py rename to backend_py/primary/primary/services/smda_access/queries/get_well_headers.py index 978035344..746e97236 100644 --- a/backend/src/services/smda_access/queries/get_well_headers.py +++ b/backend_py/primary/primary/services/smda_access/queries/get_well_headers.py @@ -1,7 +1,7 @@ from typing import List -from src.services.utils.perf_timer import PerfTimer +from webviz_pkg.core_utils.perf_timer import PerfTimer from ..types import WellBoreHeader from ._get_request import get diff --git a/backend/src/services/smda_access/queries/get_wellbore_picks_for_field.py b/backend_py/primary/primary/services/smda_access/queries/get_wellbore_picks_for_field.py similarity index 94% rename from backend/src/services/smda_access/queries/get_wellbore_picks_for_field.py rename to backend_py/primary/primary/services/smda_access/queries/get_wellbore_picks_for_field.py index 2f6537558..4cf513703 100644 --- a/backend/src/services/smda_access/queries/get_wellbore_picks_for_field.py +++ b/backend_py/primary/primary/services/smda_access/queries/get_wellbore_picks_for_field.py @@ -1,6 +1,6 @@ from typing import List, Optional -from src.services.utils.perf_timer import PerfTimer +from webviz_pkg.core_utils.perf_timer import PerfTimer from ..types import WellBorePick from ._get_request import get diff --git a/backend/src/services/smda_access/queries/get_wellbore_trajectory.py b/backend_py/primary/primary/services/smda_access/queries/get_wellbore_trajectory.py similarity index 96% rename from backend/src/services/smda_access/queries/get_wellbore_trajectory.py rename to backend_py/primary/primary/services/smda_access/queries/get_wellbore_trajectory.py index 698fb0278..2f8c8da5c 100644 --- a/backend/src/services/smda_access/queries/get_wellbore_trajectory.py +++ b/backend_py/primary/primary/services/smda_access/queries/get_wellbore_trajectory.py @@ -2,7 +2,7 @@ import pandas as pd -from src.services.utils.perf_timer import PerfTimer +from webviz_pkg.core_utils.perf_timer import PerfTimer from ..types import WellBoreTrajectory from ._get_request import get diff --git a/backend/src/services/smda_access/stratigraphy_access.py b/backend_py/primary/primary/services/smda_access/stratigraphy_access.py similarity index 100% rename from backend/src/services/smda_access/stratigraphy_access.py rename to backend_py/primary/primary/services/smda_access/stratigraphy_access.py diff --git a/backend/src/services/smda_access/stratigraphy_utils.py b/backend_py/primary/primary/services/smda_access/stratigraphy_utils.py similarity index 100% rename from backend/src/services/smda_access/stratigraphy_utils.py rename to backend_py/primary/primary/services/smda_access/stratigraphy_utils.py diff --git a/backend/src/services/smda_access/types.py b/backend_py/primary/primary/services/smda_access/types.py similarity index 100% rename from backend/src/services/smda_access/types.py rename to backend_py/primary/primary/services/smda_access/types.py diff --git a/backend/src/services/smda_access/well_access.py b/backend_py/primary/primary/services/smda_access/well_access.py similarity index 100% rename from backend/src/services/smda_access/well_access.py rename to backend_py/primary/primary/services/smda_access/well_access.py diff --git a/backend/src/services/summary_vector_statistics.py b/backend_py/primary/primary/services/summary_vector_statistics.py similarity index 100% rename from backend/src/services/summary_vector_statistics.py rename to backend_py/primary/primary/services/summary_vector_statistics.py diff --git a/backend/src/backend/user_session/__init__.py b/backend_py/primary/primary/services/sumo_access/__init__.py similarity index 100% rename from backend/src/backend/user_session/__init__.py rename to backend_py/primary/primary/services/sumo_access/__init__.py diff --git a/backend/src/services/sumo_access/_field_metadata.py b/backend_py/primary/primary/services/sumo_access/_field_metadata.py similarity index 100% rename from backend/src/services/sumo_access/_field_metadata.py rename to backend_py/primary/primary/services/sumo_access/_field_metadata.py diff --git a/backend/src/services/sumo_access/_helpers.py b/backend_py/primary/primary/services/sumo_access/_helpers.py similarity index 96% rename from backend/src/services/sumo_access/_helpers.py rename to backend_py/primary/primary/services/sumo_access/_helpers.py index 620273658..e6167c1b0 100644 --- a/backend/src/services/sumo_access/_helpers.py +++ b/backend_py/primary/primary/services/sumo_access/_helpers.py @@ -4,8 +4,8 @@ from fmu.sumo.explorer.objects import CaseCollection, Case from fmu.sumo.explorer.explorer import Pit -from src import config -from src.services.service_exceptions import Service, NoDataError, MultipleDataMatchesError +from primary import config +from primary.services.service_exceptions import Service, NoDataError, MultipleDataMatchesError from .queries.case import get_stratigraphic_column_identifier, get_field_identifiers diff --git a/backend/src/services/sumo_access/_resampling.py b/backend_py/primary/primary/services/sumo_access/_resampling.py similarity index 100% rename from backend/src/services/sumo_access/_resampling.py rename to backend_py/primary/primary/services/sumo_access/_resampling.py diff --git a/backend/src/services/sumo_access/dev/dev_summary_access_test_driver.py b/backend_py/primary/primary/services/sumo_access/dev/dev_summary_access_test_driver.py similarity index 97% rename from backend/src/services/sumo_access/dev/dev_summary_access_test_driver.py rename to backend_py/primary/primary/services/sumo_access/dev/dev_summary_access_test_driver.py index 0f7ac2ef5..bf84280d4 100644 --- a/backend/src/services/sumo_access/dev/dev_summary_access_test_driver.py +++ b/backend_py/primary/primary/services/sumo_access/dev/dev_summary_access_test_driver.py @@ -7,7 +7,7 @@ from fmu.sumo.explorer.explorer import SumoClient -from src.services.summary_vector_statistics import compute_vector_statistics_table, compute_vector_statistics +from primary.services.summary_vector_statistics import compute_vector_statistics_table, compute_vector_statistics from ..summary_access import SummaryAccess, RealizationVector, Frequency from ..sumo_explore import SumoExplore diff --git a/backend/src/services/sumo_access/generic_types.py b/backend_py/primary/primary/services/sumo_access/generic_types.py similarity index 100% rename from backend/src/services/sumo_access/generic_types.py rename to backend_py/primary/primary/services/sumo_access/generic_types.py diff --git a/backend/src/services/sumo_access/grid_access.py b/backend_py/primary/primary/services/sumo_access/grid_access.py similarity index 97% rename from backend/src/services/sumo_access/grid_access.py rename to backend_py/primary/primary/services/sumo_access/grid_access.py index a59b9229e..fa9b5b9b6 100644 --- a/backend/src/services/sumo_access/grid_access.py +++ b/backend_py/primary/primary/services/sumo_access/grid_access.py @@ -4,7 +4,7 @@ import xtgeo -from src.services.utils.perf_timer import PerfTimer +from webviz_pkg.core_utils.perf_timer import PerfTimer from ._helpers import SumoEnsemble from .queries.cpgrid import ( diff --git a/backend/src/services/sumo_access/inplace_volumetrics_access.py b/backend_py/primary/primary/services/sumo_access/inplace_volumetrics_access.py similarity index 100% rename from backend/src/services/sumo_access/inplace_volumetrics_access.py rename to backend_py/primary/primary/services/sumo_access/inplace_volumetrics_access.py diff --git a/backend/src/services/sumo_access/observation_access.py b/backend_py/primary/primary/services/sumo_access/observation_access.py similarity index 100% rename from backend/src/services/sumo_access/observation_access.py rename to backend_py/primary/primary/services/sumo_access/observation_access.py diff --git a/backend/src/services/sumo_access/observation_types.py b/backend_py/primary/primary/services/sumo_access/observation_types.py similarity index 100% rename from backend/src/services/sumo_access/observation_types.py rename to backend_py/primary/primary/services/sumo_access/observation_types.py diff --git a/backend/src/services/sumo_access/parameter_access.py b/backend_py/primary/primary/services/sumo_access/parameter_access.py similarity index 98% rename from backend/src/services/sumo_access/parameter_access.py rename to backend_py/primary/primary/services/sumo_access/parameter_access.py index 119c4a869..ac4dafd3b 100644 --- a/backend/src/services/sumo_access/parameter_access.py +++ b/backend_py/primary/primary/services/sumo_access/parameter_access.py @@ -6,7 +6,7 @@ import pyarrow as pa import pyarrow.parquet as pq -from ..utils.perf_timer import PerfTimer +from webviz_pkg.core_utils.perf_timer import PerfTimer from ._helpers import SumoEnsemble from .parameter_types import ( EnsembleParameter, diff --git a/backend/src/services/sumo_access/parameter_types.py b/backend_py/primary/primary/services/sumo_access/parameter_types.py similarity index 100% rename from backend/src/services/sumo_access/parameter_types.py rename to backend_py/primary/primary/services/sumo_access/parameter_types.py diff --git a/backend/src/services/sumo_access/polygons_access.py b/backend_py/primary/primary/services/sumo_access/polygons_access.py similarity index 98% rename from backend/src/services/sumo_access/polygons_access.py rename to backend_py/primary/primary/services/sumo_access/polygons_access.py index cb65a225c..81bc44018 100644 --- a/backend/src/services/sumo_access/polygons_access.py +++ b/backend_py/primary/primary/services/sumo_access/polygons_access.py @@ -6,7 +6,7 @@ import xtgeo from fmu.sumo.explorer.objects import PolygonsCollection -from src.services.utils.perf_timer import PerfTimer +from webviz_pkg.core_utils.perf_timer import PerfTimer from ._helpers import SumoEnsemble from .polygons_types import PolygonsMeta diff --git a/backend/src/services/sumo_access/polygons_types.py b/backend_py/primary/primary/services/sumo_access/polygons_types.py similarity index 100% rename from backend/src/services/sumo_access/polygons_types.py rename to backend_py/primary/primary/services/sumo_access/polygons_types.py diff --git a/backend/src/backend/user_session/routers/__init__.py b/backend_py/primary/primary/services/sumo_access/queries/__init__.py similarity index 100% rename from backend/src/backend/user_session/routers/__init__.py rename to backend_py/primary/primary/services/sumo_access/queries/__init__.py diff --git a/backend/src/services/sumo_access/queries/case.py b/backend_py/primary/primary/services/sumo_access/queries/case.py similarity index 100% rename from backend/src/services/sumo_access/queries/case.py rename to backend_py/primary/primary/services/sumo_access/queries/case.py diff --git a/backend/src/services/sumo_access/queries/cpgrid.py b/backend_py/primary/primary/services/sumo_access/queries/cpgrid.py similarity index 100% rename from backend/src/services/sumo_access/queries/cpgrid.py rename to backend_py/primary/primary/services/sumo_access/queries/cpgrid.py diff --git a/backend/src/services/sumo_access/rft_access.py b/backend_py/primary/primary/services/sumo_access/rft_access.py similarity index 99% rename from backend/src/services/sumo_access/rft_access.py rename to backend_py/primary/primary/services/sumo_access/rft_access.py index be5b49d4c..602383947 100644 --- a/backend/src/services/sumo_access/rft_access.py +++ b/backend_py/primary/primary/services/sumo_access/rft_access.py @@ -7,9 +7,9 @@ import pyarrow.compute as pc import pyarrow.parquet as pq from fmu.sumo.explorer.objects import Case, TableCollection +from webviz_pkg.core_utils.perf_timer import PerfTimer from ._helpers import SumoEnsemble -from ..utils.perf_timer import PerfTimer from .rft_types import RftInfo, RftRealizationData LOGGER = logging.getLogger(__name__) diff --git a/backend/src/services/sumo_access/rft_types.py b/backend_py/primary/primary/services/sumo_access/rft_types.py similarity index 100% rename from backend/src/services/sumo_access/rft_types.py rename to backend_py/primary/primary/services/sumo_access/rft_types.py diff --git a/backend/src/services/sumo_access/seismic_access.py b/backend_py/primary/primary/services/sumo_access/seismic_access.py similarity index 100% rename from backend/src/services/sumo_access/seismic_access.py rename to backend_py/primary/primary/services/sumo_access/seismic_access.py diff --git a/backend/src/services/sumo_access/seismic_types.py b/backend_py/primary/primary/services/sumo_access/seismic_types.py similarity index 100% rename from backend/src/services/sumo_access/seismic_types.py rename to backend_py/primary/primary/services/sumo_access/seismic_types.py diff --git a/backend/src/services/sumo_access/summary_access.py b/backend_py/primary/primary/services/sumo_access/summary_access.py similarity index 98% rename from backend/src/services/sumo_access/summary_access.py rename to backend_py/primary/primary/services/sumo_access/summary_access.py index 225c8529b..cb1077028 100644 --- a/backend/src/services/sumo_access/summary_access.py +++ b/backend_py/primary/primary/services/sumo_access/summary_access.py @@ -6,11 +6,11 @@ import pyarrow as pa import pyarrow.compute as pc from fmu.sumo.explorer.objects import Case, TableCollection, Table +from webviz_pkg.core_utils.perf_timer import PerfTimer -from src.services.utils.arrow_helpers import sort_table_on_real_then_date, is_date_column_monotonically_increasing -from src.services.utils.arrow_helpers import find_first_non_increasing_date_pair -from src.services.utils.perf_timer import PerfTimer -from src.services.service_exceptions import ( +from primary.services.utils.arrow_helpers import sort_table_on_real_then_date, is_date_column_monotonically_increasing +from primary.services.utils.arrow_helpers import find_first_non_increasing_date_pair +from primary.services.service_exceptions import ( Service, NoDataError, InvalidDataError, diff --git a/backend/src/services/sumo_access/summary_types.py b/backend_py/primary/primary/services/sumo_access/summary_types.py similarity index 100% rename from backend/src/services/sumo_access/summary_types.py rename to backend_py/primary/primary/services/sumo_access/summary_types.py diff --git a/backend/src/services/sumo_access/sumo_explore.py b/backend_py/primary/primary/services/sumo_access/sumo_explore.py similarity index 100% rename from backend/src/services/sumo_access/sumo_explore.py rename to backend_py/primary/primary/services/sumo_access/sumo_explore.py diff --git a/backend/src/services/sumo_access/surface_access.py b/backend_py/primary/primary/services/sumo_access/surface_access.py similarity index 98% rename from backend/src/services/sumo_access/surface_access.py rename to backend_py/primary/primary/services/sumo_access/surface_access.py index 90f7a8ab3..d0353be1b 100644 --- a/backend/src/services/sumo_access/surface_access.py +++ b/backend_py/primary/primary/services/sumo_access/surface_access.py @@ -8,8 +8,8 @@ from fmu.sumo.explorer import TimeFilter, TimeType from fmu.sumo.explorer.objects import SurfaceCollection, Surface -from src.services.utils.perf_timer import PerfTimer -from src.services.utils.statistic_function import StatisticFunction +from webviz_pkg.core_utils.perf_timer import PerfTimer +from primary.services.utils.statistic_function import StatisticFunction from ._helpers import SumoEnsemble from .surface_types import SurfaceMeta, XtgeoSurfaceIntersectionResult, XtgeoSurfaceIntersectionPolyline diff --git a/backend/src/services/sumo_access/surface_types.py b/backend_py/primary/primary/services/sumo_access/surface_types.py similarity index 100% rename from backend/src/services/sumo_access/surface_types.py rename to backend_py/primary/primary/services/sumo_access/surface_types.py diff --git a/backend/src/services/sumo_access/table_access.py b/backend_py/primary/primary/services/sumo_access/table_access.py similarity index 100% rename from backend/src/services/sumo_access/table_access.py rename to backend_py/primary/primary/services/sumo_access/table_access.py diff --git a/backend/src/services/sumo_access/well_completions_access.py b/backend_py/primary/primary/services/sumo_access/well_completions_access.py similarity index 100% rename from backend/src/services/sumo_access/well_completions_access.py rename to backend_py/primary/primary/services/sumo_access/well_completions_access.py diff --git a/backend/src/services/sumo_access/well_completions_types.py b/backend_py/primary/primary/services/sumo_access/well_completions_types.py similarity index 100% rename from backend/src/services/sumo_access/well_completions_types.py rename to backend_py/primary/primary/services/sumo_access/well_completions_types.py diff --git a/backend/src/services/surface_query_service/surface_query_service.py b/backend_py/primary/primary/services/surface_query_service/surface_query_service.py similarity index 97% rename from backend/src/services/surface_query_service/surface_query_service.py rename to backend_py/primary/primary/services/surface_query_service/surface_query_service.py index ffefda94c..c6ba807ff 100644 --- a/backend/src/services/surface_query_service/surface_query_service.py +++ b/backend_py/primary/primary/services/surface_query_service/surface_query_service.py @@ -9,8 +9,8 @@ from pydantic import BaseModel from sumo.wrapper import SumoClient -from src import config -from src.services.service_exceptions import AuthorizationError, Service +from primary import config +from primary.services.service_exceptions import AuthorizationError, Service LOGGER = logging.getLogger(__name__) diff --git a/backend/src/services/user_session_manager/_background_tasks.py b/backend_py/primary/primary/services/user_session_manager/_background_tasks.py similarity index 100% rename from backend/src/services/user_session_manager/_background_tasks.py rename to backend_py/primary/primary/services/user_session_manager/_background_tasks.py diff --git a/backend/src/services/user_session_manager/_radix_helpers.py b/backend_py/primary/primary/services/user_session_manager/_radix_helpers.py similarity index 100% rename from backend/src/services/user_session_manager/_radix_helpers.py rename to backend_py/primary/primary/services/user_session_manager/_radix_helpers.py diff --git a/backend/src/services/user_session_manager/_user_session_directory.py b/backend_py/primary/primary/services/user_session_manager/_user_session_directory.py similarity index 99% rename from backend/src/services/user_session_manager/_user_session_directory.py rename to backend_py/primary/primary/services/user_session_manager/_user_session_directory.py index f0b385a64..328a6d330 100644 --- a/backend/src/services/user_session_manager/_user_session_directory.py +++ b/backend_py/primary/primary/services/user_session_manager/_user_session_directory.py @@ -4,7 +4,7 @@ import redis -from src import config +from primary import config LOGGER = logging.getLogger(__name__) diff --git a/backend/src/services/user_session_manager/_util_classes.py b/backend_py/primary/primary/services/user_session_manager/_util_classes.py similarity index 100% rename from backend/src/services/user_session_manager/_util_classes.py rename to backend_py/primary/primary/services/user_session_manager/_util_classes.py diff --git a/backend/src/services/user_session_manager/user_session_manager.py b/backend_py/primary/primary/services/user_session_manager/user_session_manager.py similarity index 99% rename from backend/src/services/user_session_manager/user_session_manager.py rename to backend_py/primary/primary/services/user_session_manager/user_session_manager.py index d9198ad53..ec28b7c3b 100644 --- a/backend/src/services/user_session_manager/user_session_manager.py +++ b/backend_py/primary/primary/services/user_session_manager/user_session_manager.py @@ -7,7 +7,7 @@ import httpx from pottery import Redlock -from src.services.utils.perf_timer import PerfTimer +from webviz_pkg.core_utils.perf_timer import PerfTimer from ._radix_helpers import IS_ON_RADIX_PLATFORM from ._radix_helpers import create_new_radix_job, RadixResourceRequests diff --git a/backend/src/backend/user_session/routers/grid/__init__.py b/backend_py/primary/primary/services/utils/__init__.py similarity index 100% rename from backend/src/backend/user_session/routers/grid/__init__.py rename to backend_py/primary/primary/services/utils/__init__.py diff --git a/backend/src/services/utils/arrow_helpers.py b/backend_py/primary/primary/services/utils/arrow_helpers.py similarity index 100% rename from backend/src/services/utils/arrow_helpers.py rename to backend_py/primary/primary/services/utils/arrow_helpers.py diff --git a/backend/src/services/utils/authenticated_user.py b/backend_py/primary/primary/services/utils/authenticated_user.py similarity index 96% rename from backend/src/services/utils/authenticated_user.py rename to backend_py/primary/primary/services/utils/authenticated_user.py index 8a61eeb3a..4e38d3ba7 100644 --- a/backend/src/services/utils/authenticated_user.py +++ b/backend_py/primary/primary/services/utils/authenticated_user.py @@ -2,7 +2,7 @@ from typing import Any, Optional, TypedDict -from src.services.service_exceptions import Service, AuthorizationError +from primary.services.service_exceptions import Service, AuthorizationError class AccessTokens(TypedDict): diff --git a/backend/src/services/utils/statistic_function.py b/backend_py/primary/primary/services/utils/statistic_function.py similarity index 100% rename from backend/src/services/utils/statistic_function.py rename to backend_py/primary/primary/services/utils/statistic_function.py diff --git a/backend/src/services/utils/surface_orientation.py b/backend_py/primary/primary/services/utils/surface_orientation.py similarity index 100% rename from backend/src/services/utils/surface_orientation.py rename to backend_py/primary/primary/services/utils/surface_orientation.py diff --git a/backend/src/services/utils/surface_to_float32.py b/backend_py/primary/primary/services/utils/surface_to_float32.py similarity index 100% rename from backend/src/services/utils/surface_to_float32.py rename to backend_py/primary/primary/services/utils/surface_to_float32.py diff --git a/backend/src/services/utils/surface_to_png.py b/backend_py/primary/primary/services/utils/surface_to_png.py similarity index 100% rename from backend/src/services/utils/surface_to_png.py rename to backend_py/primary/primary/services/utils/surface_to_png.py diff --git a/backend/src/services/__init__.py b/backend_py/primary/primary/services/vds_access/__init__.py similarity index 100% rename from backend/src/services/__init__.py rename to backend_py/primary/primary/services/vds_access/__init__.py diff --git a/backend/src/services/vds_access/request_types.py b/backend_py/primary/primary/services/vds_access/request_types.py similarity index 100% rename from backend/src/services/vds_access/request_types.py rename to backend_py/primary/primary/services/vds_access/request_types.py diff --git a/backend/src/services/vds_access/response_types.py b/backend_py/primary/primary/services/vds_access/response_types.py similarity index 100% rename from backend/src/services/vds_access/response_types.py rename to backend_py/primary/primary/services/vds_access/response_types.py diff --git a/backend/src/services/vds_access/vds_access.py b/backend_py/primary/primary/services/vds_access/vds_access.py similarity index 99% rename from backend/src/services/vds_access/vds_access.py rename to backend_py/primary/primary/services/vds_access/vds_access.py index af79d88ba..acc99de4c 100644 --- a/backend/src/services/vds_access/vds_access.py +++ b/backend_py/primary/primary/services/vds_access/vds_access.py @@ -7,7 +7,7 @@ from requests_toolbelt.multipart.decoder import MultipartDecoder, BodyPart import httpx -from src import config +from primary import config from .response_types import VdsMetadata, VdsFenceMetadata from .request_types import ( diff --git a/backend/src/backend/utils/azure_monitor_setup.py b/backend_py/primary/primary/utils/azure_monitor_setup.py similarity index 100% rename from backend/src/backend/utils/azure_monitor_setup.py rename to backend_py/primary/primary/utils/azure_monitor_setup.py diff --git a/backend/src/backend/utils/exception_handlers.py b/backend_py/primary/primary/utils/exception_handlers.py similarity index 98% rename from backend/src/backend/utils/exception_handlers.py rename to backend_py/primary/primary/utils/exception_handlers.py index 0030cf9d4..988921077 100644 --- a/backend/src/backend/utils/exception_handlers.py +++ b/backend_py/primary/primary/utils/exception_handlers.py @@ -10,7 +10,7 @@ from starlette.responses import JSONResponse, Response from starlette.status import HTTP_422_UNPROCESSABLE_ENTITY, HTTP_500_INTERNAL_SERVER_ERROR -from src.services.service_exceptions import ServiceLayerException +from primary.services.service_exceptions import ServiceLayerException def my_http_exception_handler(request: Request, exc: StarletteHTTPException) -> Response | JSONResponse: diff --git a/backend/src/backend/utils/logging_setup.py b/backend_py/primary/primary/utils/logging_setup.py similarity index 100% rename from backend/src/backend/utils/logging_setup.py rename to backend_py/primary/primary/utils/logging_setup.py diff --git a/backend/src/backend/utils/perf_metrics.py b/backend_py/primary/primary/utils/perf_metrics.py similarity index 97% rename from backend/src/backend/utils/perf_metrics.py rename to backend_py/primary/primary/utils/perf_metrics.py index 6c7ee71ad..24540a9c4 100644 --- a/backend/src/backend/utils/perf_metrics.py +++ b/backend_py/primary/primary/utils/perf_metrics.py @@ -1,6 +1,6 @@ from starlette.responses import MutableHeaders, Response -from src.services.utils.perf_timer import PerfTimer +from webviz_pkg.core_utils.perf_timer import PerfTimer class PerfMetrics: diff --git a/backend/pyproject.toml b/backend_py/primary/pyproject.toml similarity index 93% rename from backend/pyproject.toml rename to backend_py/primary/pyproject.toml index 9944e5e4b..da59054f1 100644 --- a/backend/pyproject.toml +++ b/backend_py/primary/pyproject.toml @@ -1,7 +1,6 @@ [tool.poetry] -name = "backend" -version = "0.1.0" -description = "" +package-mode = false +name = "primary" authors = ["R&T Equinor", "Ceetron Solutions AS"] readme = "README.md" @@ -21,14 +20,12 @@ numpy = "^1.24.1" orjson = "^3.8.10" pandas = {version = "2.0.1", extras = ["performance"]} httpx = "^0.24.0" -psutil = "^5.9.5" -vtk = "^9.2.6" fmu-sumo = "1.0.3" sumo-wrapper-python = "1.0.6" azure-monitor-opentelemetry = "^1.1.0" requests-toolbelt = "^1.0.0" pottery = "^3.0.0" - +core_utils = {path = "../libs/core_utils", develop = true} [tool.poetry.group.dev.dependencies] black = "^22.12.0" diff --git a/backend/src/services/smda_access/__init__.py b/backend_py/primary/tests/__init__.py similarity index 100% rename from backend/src/services/smda_access/__init__.py rename to backend_py/primary/tests/__init__.py diff --git a/backend/tests/integration/services/conftest.py b/backend_py/primary/tests/integration/services/conftest.py similarity index 100% rename from backend/tests/integration/services/conftest.py rename to backend_py/primary/tests/integration/services/conftest.py diff --git a/backend/tests/integration/services/sumo_access/test_parameter_access.py b/backend_py/primary/tests/integration/services/sumo_access/test_parameter_access.py similarity index 100% rename from backend/tests/integration/services/sumo_access/test_parameter_access.py rename to backend_py/primary/tests/integration/services/sumo_access/test_parameter_access.py diff --git a/backend/src/services/smda_access/queries/__init__.py b/backend_py/primary/tests/unit/__init__.py similarity index 100% rename from backend/src/services/smda_access/queries/__init__.py rename to backend_py/primary/tests/unit/__init__.py diff --git a/backend/src/services/sumo_access/__init__.py b/backend_py/primary/tests/unit/services/__init__.py similarity index 100% rename from backend/src/services/sumo_access/__init__.py rename to backend_py/primary/tests/unit/services/__init__.py diff --git a/backend/tests/unit/services/smda_access/test_stratigraphy_utils.py b/backend_py/primary/tests/unit/services/smda_access/test_stratigraphy_utils.py similarity index 89% rename from backend/tests/unit/services/smda_access/test_stratigraphy_utils.py rename to backend_py/primary/tests/unit/services/smda_access/test_stratigraphy_utils.py index 13eab9066..913f50bf9 100644 --- a/backend/tests/unit/services/smda_access/test_stratigraphy_utils.py +++ b/backend_py/primary/tests/unit/services/smda_access/test_stratigraphy_utils.py @@ -1,12 +1,12 @@ from typing import List import pytest -from services.smda_access.stratigraphy_utils import ( +from primary.services.smda_access.stratigraphy_utils import ( sort_stratigraphic_names_by_hierarchy, sort_stratigraphic_units_by_hierarchy, ) -from services.smda_access.types import StratigraphicUnit, StratigraphicSurface, StratigraphicFeature -from services.smda_access.mocked_drogon_smda_access._mocked_stratigraphy_access import DROGON_STRAT_UNITS +from primary.services.smda_access.types import StratigraphicUnit, StratigraphicSurface, StratigraphicFeature +from primary.services.smda_access.mocked_drogon_smda_access._mocked_stratigraphy_access import DROGON_STRAT_UNITS @pytest.mark.parametrize( @@ -48,7 +48,7 @@ def test_sort_stratigraphic_units_by_hierarchy( ], ) def test_sort_stratigraphic_names_by_hierarchy( - strat_units: List[StratigraphicUnit], expected_output: List[StratigraphicUnit] + strat_units: List[StratigraphicUnit], expected_output: List[StratigraphicSurface] ) -> None: sorted_surfaces = sort_stratigraphic_names_by_hierarchy(strat_units) sorted_surface_names = [surf.name for surf in sorted_surfaces] diff --git a/backend/tests/unit/services/sumo_access/test_resampling.py b/backend_py/primary/tests/unit/services/sumo_access/test_resampling.py similarity index 99% rename from backend/tests/unit/services/sumo_access/test_resampling.py rename to backend_py/primary/tests/unit/services/sumo_access/test_resampling.py index 7f59d3031..b5475711c 100644 --- a/backend/tests/unit/services/sumo_access/test_resampling.py +++ b/backend_py/primary/tests/unit/services/sumo_access/test_resampling.py @@ -2,7 +2,7 @@ import pyarrow as pa import pyarrow.compute as pc -from services.sumo_access._resampling import ( +from primary.services.sumo_access._resampling import ( Frequency, generate_normalized_sample_dates, interpolate_backfill, diff --git a/backend/tests/unit/services/utils/test_arrow_helpers.py b/backend_py/primary/tests/unit/services/utils/test_arrow_helpers.py similarity index 88% rename from backend/tests/unit/services/utils/test_arrow_helpers.py rename to backend_py/primary/tests/unit/services/utils/test_arrow_helpers.py index 40108f117..a7feb2acd 100644 --- a/backend/tests/unit/services/utils/test_arrow_helpers.py +++ b/backend_py/primary/tests/unit/services/utils/test_arrow_helpers.py @@ -1,5 +1,6 @@ -from services.utils.arrow_helpers import is_date_column_monotonically_increasing, find_first_non_increasing_date_pair -from services.utils.arrow_helpers import detect_missing_realizations +from primary.services.utils.arrow_helpers import is_date_column_monotonically_increasing +from primary.services.utils.arrow_helpers import find_first_non_increasing_date_pair +from primary.services.utils.arrow_helpers import detect_missing_realizations import pyarrow as pa import numpy as np diff --git a/docker-compose.yml b/docker-compose.yml index ec1e28898..8006f7808 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -19,14 +19,13 @@ services: backend-primary: build: context: . - dockerfile: backend.Dockerfile + dockerfile: ./backend_py/primary/Dockerfile ports: - 5000:5000 - 5678:5678 environment: - UVICORN_PORT=5000 - UVICORN_RELOAD=true - - UVICORN_ENTRYPOINT=src.backend.primary.main:app - WEBVIZ_CLIENT_SECRET - WEBVIZ_SMDA_RESOURCE_SCOPE - WEBVIZ_SMDA_SUBSCRIPTION_KEY @@ -37,12 +36,13 @@ services: - OTEL_RESOURCE_ATTRIBUTES=service.namespace=local, service.version=dummy0.1.2 - CODESPACE_NAME # Automatically set env. variable by GitHub codespace volumes: - - ./backend/src:/home/appuser/backend/src + - ./backend_py/primary/primary:/home/appuser/backend_py/primary/primary + - ./backend_py/libs:/home/appuser/backend_py/libs command: [ "sh", "-c", - "pip install debugpy && python -m debugpy --listen 0.0.0.0:5678 -m uvicorn --proxy-headers --host=0.0.0.0 $${UVICORN_ENTRYPOINT}", + "pip install debugpy && python -m debugpy --listen 0.0.0.0:5678 -m uvicorn --proxy-headers --host=0.0.0.0 primary.main:app", ] surface-query: @@ -78,27 +78,6 @@ services: volumes: - ./backend_py/user_grid3d_ri:/home/appuser/backend_py/user_grid3d_ri - backend-user-session: - build: - context: . - dockerfile: backend.Dockerfile - ports: - - 8000:8000 - environment: - - UVICORN_PORT=8000 - - UVICORN_RELOAD=true - - UVICORN_ENTRYPOINT=src.backend.user_session.main:app - - WEBVIZ_CLIENT_SECRET - - WEBVIZ_SMDA_RESOURCE_SCOPE - - WEBVIZ_SMDA_SUBSCRIPTION_KEY - - WEBVIZ_SUMO_ENV - - WEBVIZ_VDS_HOST_ADDRESS - - APPLICATIONINSIGHTS_CONNECTION_STRING - - OTEL_SERVICE_NAME=user-session - - OTEL_RESOURCE_ATTRIBUTES=service.namespace=local, service.version=dummy0.1.2 - volumes: - - ./backend/src:/home/appuser/backend/src - redis-user-session: image: bitnami/redis:6.2.10@sha256:bd42fcdab5959ce2b21b6ea8410d4b3ee87ecb2e320260326ec731ecfcffbd0e expose: diff --git a/frontend/src/api/services/DefaultService.ts b/frontend/src/api/services/DefaultService.ts index 926930b66..a314d8e9f 100644 --- a/frontend/src/api/services/DefaultService.ts +++ b/frontend/src/api/services/DefaultService.ts @@ -80,18 +80,6 @@ export class DefaultService { }, }); } - /** - * User Session Container - * Get information about user session container (note that one is started if not already running). - * @returns any Successful Response - * @throws ApiError - */ - public userSessionContainer(): CancelablePromise { - return this.httpRequest.request({ - method: 'GET', - url: '/user_session_container', - }); - } /** * Root * @returns string Successful Response diff --git a/frontend/src/framework/internal/components/NavBar/private-components/UserSessionState.tsx b/frontend/src/framework/internal/components/NavBar/private-components/UserSessionState.tsx index 54b07a4d6..04c652166 100644 --- a/frontend/src/framework/internal/components/NavBar/private-components/UserSessionState.tsx +++ b/frontend/src/framework/internal/components/NavBar/private-components/UserSessionState.tsx @@ -1,20 +1,11 @@ import { Memory } from "@mui/icons-material"; -import { useQuery } from "@tanstack/react-query"; - -import { apiService } from "@framework/ApiService"; - -const useUserSessionState = () => useQuery({ - queryKey: ["default.userSessionContainer"], - queryFn: () => apiService.default.userSessionContainer(), - refetchInterval: 200000 -}); export const UserSessionState = ({expanded}: {expanded: boolean}) => { - - const sessionState = useUserSessionState(); - - const memoryPercent = Math.round(sessionState.data?.memorySystem?.percent) || "-" - const cpuPercent = Math.round(sessionState.data?.cpuPercent) || "-" + // const sessionState = useUserSessionState(); + // const memoryPercent = Math.round(sessionState.data?.memorySystem?.percent) || "-" + // const cpuPercent = Math.round(sessionState.data?.cpuPercent) || "-" + const memoryPercent = "-" + const cpuPercent = "-" return
{expanded ? "Memory:" : "M"} {memoryPercent} %
diff --git a/radixconfig.yml b/radixconfig.yml index bac031ed2..405153ecf 100644 --- a/radixconfig.yml +++ b/radixconfig.yml @@ -23,7 +23,7 @@ spec: port: 8080 - name: backend-primary - dockerFileName: backend.Dockerfile + dockerFileName: ./backend_py/primary/Dockerfile ports: - name: http port: 5000 @@ -41,7 +41,6 @@ spec: envVar: WEBVIZ_VDS_HOST_ADDRESS variables: UVICORN_PORT: 5000 - UVICORN_ENTRYPOINT: src.backend.primary.main:app environmentConfig: - environment: prod secretRefs: @@ -182,75 +181,6 @@ spec: variables: UVICORN_PORT: 8002 - - name: backend-user-session - dockerFileName: backend.Dockerfile - schedulerPort: 8000 - ports: - - name: http - port: 8000 - secretRefs: - azureKeyVaults: - - name: webviz - items: - - name: WEBVIZ-CLIENT-SECRET - envVar: WEBVIZ_CLIENT_SECRET - - name: WEBVIZ-SMDA-RESOURCE-SCOPE - envVar: WEBVIZ_SMDA_RESOURCE_SCOPE - - name: WEBVIZ-SMDA-SUBSCRIPTION-KEY - envVar: WEBVIZ_SMDA_SUBSCRIPTION_KEY - - name: WEBVIZ-VDS-HOST-ADDRESS - envVar: WEBVIZ_VDS_HOST_ADDRESS - variables: - UVICORN_PORT: 8000 - UVICORN_ENTRYPOINT: src.backend.user_session.main:app - environmentConfig: - # As of October 2023 in radix, these settings need to be duplicated for both environments. - - environment: prod - secretRefs: - azureKeyVaults: - - name: webviz - items: - - name: WEBVIZ-INSIGHTS-CONNECTIONSTRING-PROD - envVar: APPLICATIONINSIGHTS_CONNECTION_STRING - variables: - OTEL_RESOURCE_ATTRIBUTES: service.name=user-session, service.namespace=prod, service.version=tbd0.1.2 - volumeMounts: - - name: webvizcache - path: /tmp/webvizcache/ - blobfuse2: - container: cache - uid: 1234 - - environment: review - secretRefs: - azureKeyVaults: - - name: webviz - items: - - name: WEBVIZ-INSIGHTS-CONNECTIONSTRING-REVIEW - envVar: APPLICATIONINSIGHTS_CONNECTION_STRING - variables: - OTEL_RESOURCE_ATTRIBUTES: service.name=user-session, service.namespace=review, service.version=tbd0.1.2 - volumeMounts: - - name: webvizcache - path: /tmp/webvizcache/ - blobfuse2: - container: cache - uid: 1234 - - environment: dev - secretRefs: - azureKeyVaults: - - name: webviz - items: - - name: WEBVIZ-INSIGHTS-CONNECTIONSTRING-DEV - envVar: APPLICATIONINSIGHTS_CONNECTION_STRING - variables: - OTEL_RESOURCE_ATTRIBUTES: service.name=user-session, service.namespace=dev, service.version=tbd0.1.2 - volumeMounts: - - name: webvizcache - path: /tmp/webvizcache/ - blobfuse2: - container: cache - uid: 1234 - dnsAppAlias: environment: prod component: frontend