Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,10 @@ jobs:
cd server
poetry install --with dev

# - name: Run Ruff check
# run: |
# cd server
# poetry run ruff check --output-format=github .
- name: Run Ruff check
run: |
cd server
poetry run ruff check --output-format=github .

- name: Run Ruff format check
run: |
Expand Down
6 changes: 3 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.16.5
hooks:
# - id: ruff-check
# args: [--fix]
# files: ^server/
- id: ruff-check
args: [--fix]
files: ^server/
- id: ruff-format
files: ^server/
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ pre-commit run --all-files
python3 manage.py migrate
python3 manage.py collectstatic --noinput
python3 manage.py createsuperuser # Unless you will only login with your TACC account
python3 manage.py import-apps # Add set of example apps used in Frontera portal (optional)
python3 manage.py import_apps # Add set of example apps used in Frontera portal (optional)

#### Initialize the CMS in the `core_portal_cms` container:

Expand Down
10 changes: 6 additions & 4 deletions server/conftest.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import pytest
from mock import MagicMock
import json
import os
import tempfile
from portal.apps.auth.models import TapisOAuthToken
from portal.apps.accounts.models import PortalProfile
from unittest.mock import MagicMock

import pytest
from django.conf import settings

from portal.apps.accounts.models import PortalProfile
from portal.apps.auth.models import TapisOAuthToken


@pytest.fixture
def mock_tapis_client(mocker):
Expand Down
121 changes: 68 additions & 53 deletions server/portal/apps/_custom/drp/models.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
from typing import Optional, Literal
from pydantic import ConfigDict, NonNegativeInt, NonNegativeFloat
from typing import Literal

from pydantic import ConfigDict, NonNegativeFloat, NonNegativeInt

from portal.apps.projects.schema_models.base_metadata import (
BaseFileMetadata,
BaseMetadataModel,
BaseProjectMetadata,
BaseFileMetadata,
FileObj,
)

Expand All @@ -20,8 +21,8 @@ class DrpFileMetadata(BaseFileMetadata):
extra="forbid",
)

is_advanced_image_file: Optional[bool] = False
image_type: Optional[
is_advanced_image_file: bool | None = False
image_type: (
Literal[
"8_bit",
"16_bit_signed",
Expand All @@ -38,18 +39,19 @@ class DrpFileMetadata(BaseFileMetadata):
"32_bit_abgr",
"1_bit_bitmap",
]
] = None
height: Optional[NonNegativeInt] = None
width: Optional[NonNegativeInt] = None
number_of_images: Optional[NonNegativeInt] = None
offset_to_first_image: Optional[int] = None
gap_between_images: Optional[int] = None
byte_order: Optional[Literal["big_endian", "little_endian"]] = None
use_binary_correction: Optional[bool] = None
| None
) = None
height: NonNegativeInt | None = None
width: NonNegativeInt | None = None
number_of_images: NonNegativeInt | None = None
offset_to_first_image: int | None = None
gap_between_images: int | None = None
byte_order: Literal["big_endian", "little_endian"] | None = None
use_binary_correction: bool | None = None


class DrpProjectMetadata(BaseProjectMetadata):
license: Optional[str] = "ODC-BY 1.0"
license: str | None = "ODC-BY 1.0"


class DrpDatasetMetadata(BaseMetadataModel):
Expand All @@ -60,8 +62,8 @@ class DrpDatasetMetadata(BaseMetadataModel):
)

name: str
description: Optional[str] = None
uuid: Optional[str] = None
description: str | None = None
uuid: str | None = None
data_type: Literal["sample", "origin_data", "digital_dataset", "analysis_data", "file"]
file_objs: list[FileObj] = []

Expand All @@ -70,66 +72,79 @@ class DrpSampleMetadata(DrpDatasetMetadata):
"""Model for DRP Sample Metadata"""

porous_media_type: Literal[
"sandstone", "soil", "carbonate", "granite", "beads", "fibrous_media", "coal", "energy_storage", "other"
"sandstone",
"soil",
"carbonate",
"granite",
"beads",
"fibrous_media",
"coal",
"energy_storage",
"other",
]

porous_media_other_description: Optional[str] = None
porous_media_other_description: str | None = None

source: Literal[
"natural",
"natural_extraterrestrial",
"artificial",
"computer_generated",
]
collection_method: Optional[str] = None
onshore_offshore: Optional[Literal["onshore", "offshore"]] = None
depth: Optional[str] = None
total_vertical_depth: Optional[str] = None
water_depth: Optional[str] = None
geographic_origin: Optional[str] = None
procedure: Optional[str] = None
equipment: Optional[str] = None
algorithm_description: Optional[str] = None
grain_size_min: Optional[NonNegativeFloat] = None
grain_size_max: Optional[NonNegativeFloat] = None
grain_size_avg: Optional[NonNegativeFloat] = None
grain_size_units: Optional[Literal["nanometer", "micrometer", "millimeter", "other"]] = None
porosity: Optional[float] = None
geographical_location: Optional[str] = None
date_of_collection: Optional[str] = None
date_of_creation: Optional[str] = None
identifier: Optional[str] = None
location: Optional[str] = None # TODO_DRP: Remove in new model
collection_method: str | None = None
onshore_offshore: Literal["onshore", "offshore"] | None = None
depth: str | None = None
total_vertical_depth: str | None = None
water_depth: str | None = None
geographic_origin: str | None = None
procedure: str | None = None
equipment: str | None = None
algorithm_description: str | None = None
grain_size_min: NonNegativeFloat | None = None
grain_size_max: NonNegativeFloat | None = None
grain_size_avg: NonNegativeFloat | None = None
grain_size_units: Literal["nanometer", "micrometer", "millimeter", "other"] | None = None
porosity: float | None = None
geographical_location: str | None = None
date_of_collection: str | None = None
date_of_creation: str | None = None
identifier: str | None = None
location: str | None = None # TODO_DRP: Remove in new model


class DrpOriginDatasetMetadata(DrpDatasetMetadata):
"""Model for DRP Origin Dataset Metadata"""

is_segmented: Literal["yes", "no"]
sample: str
imaging_center: Optional[str] = None
imaging_equipment_and_model: Optional[str] = None
image_format: Optional[str] = None
image_dimensions: Optional[str] = None
image_byte_order: Optional[str] = None
voxel_x: Optional[NonNegativeFloat] = None
voxel_y: Optional[NonNegativeFloat] = None
voxel_z: Optional[NonNegativeFloat] = None
voxel_units: Optional[Literal["nanometer", "micrometer", "millimeter", "other"]] = None
dimensionality: Optional[str] = None
digital_dataset: Optional[str] = None
external_uri: Optional[str] = None # TODO_DRP: Remove in new model
imaging_center: str | None = None
imaging_equipment_and_model: str | None = None
image_format: str | None = None
image_dimensions: str | None = None
image_byte_order: str | None = None
voxel_x: NonNegativeFloat | None = None
voxel_y: NonNegativeFloat | None = None
voxel_z: NonNegativeFloat | None = None
voxel_units: Literal["nanometer", "micrometer", "millimeter", "other"] | None = None
dimensionality: str | None = None
digital_dataset: str | None = None
external_uri: str | None = None # TODO_DRP: Remove in new model


class DrpAnalysisDatasetMetadata(DrpDatasetMetadata):
"""Model for DRP Analysis Dataset Metadata"""

is_segmented: Literal["yes", "no"]
dataset_type: Literal[
"machine_learning", "simulation", "geometric_analysis", "experimental", "characterization", "other"
"machine_learning",
"simulation",
"geometric_analysis",
"experimental",
"characterization",
"other",
]
external_uri: Optional[str] = None
external_uri: str | None = None
sample: str
# base_origin_data: Optional[str] = None
digital_dataset: Optional[str] = None
digital_dataset_other_information: Optional[str] = None
digital_dataset: str | None = None
digital_dataset_other_information: str | None = None
8 changes: 4 additions & 4 deletions server/portal/apps/_custom/drp/schema.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
"""DRP schema extension."""

from portal.apps.projects.schema_models import constants
from portal.apps._custom.drp.models import (
DrpProjectMetadata,
DrpSampleMetadata,
DrpOriginDatasetMetadata,
DrpAnalysisDatasetMetadata,
DrpFileMetadata,
DrpOriginDatasetMetadata,
DrpProjectMetadata,
DrpSampleMetadata,
)
from portal.apps.projects.schema_models import constants

SCHEMA_MAPPING = {
constants.PROJECT: DrpProjectMetadata,
Expand Down
1 change: 1 addition & 0 deletions server/portal/apps/_custom/drp/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"""

from django.urls import re_path

from portal.apps._custom.drp.views import DigitalRocksSampleView, GenerateImagesView

app_name = "custom"
Expand Down
12 changes: 7 additions & 5 deletions server/portal/apps/_custom/drp/views.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import json
from portal.views.base import BaseApiView
import logging

import networkx as nx
from django.conf import settings
from django.http import HttpRequest, JsonResponse
from portal.exceptions.api import ApiException

from portal.apps.projects.models.project_metadata import ProjectMetadata
from portal.apps.projects.schema_models import constants
import networkx as nx
from portal.apps.projects.workspace_operations.project_meta_operations import patch_file_obj_entity
from portal.apps.projects.tasks import process_file
from portal.apps.projects.views import get_project_client
import logging
from portal.apps.projects.workspace_operations.project_meta_operations import patch_file_obj_entity
from portal.exceptions.api import ApiException
from portal.views.base import BaseApiView

logger = logging.getLogger(__name__)

Expand Down
1 change: 1 addition & 0 deletions server/portal/apps/accounts/api/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"""

from django.urls import re_path

from portal.apps.accounts.api.views.systems import SystemKeysView

app_name = "portal_accounts_api"
Expand Down
14 changes: 8 additions & 6 deletions server/portal/apps/accounts/api/views/systems.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,23 @@
:synopsis: Account's systems views
"""

import logging
import json
from django.http import JsonResponse
import logging

from django.contrib.auth.decorators import login_required
from django.http import JsonResponse
from django.utils.decorators import method_decorator
from portal.views.base import BaseApiView
from portal.apps.accounts.managers import accounts as AccountsManager
from tapipy.errors import BaseTapyException

from portal.apps.accounts.managers import accounts as AccountsManager
from portal.apps.datafiles.utils import evaluate_datafiles_storage_system
from portal.apps.onboarding.steps.system_access_v3 import (
create_system_credentials_with_keys,
create_system_credentials_with_tms,
create_system_credentials_with_password,
create_system_credentials_with_tms,
)
from portal.utils.encryption import createKeyPair
from portal.apps.datafiles.utils import evaluate_datafiles_storage_system
from portal.views.base import BaseApiView

logger = logging.getLogger(__name__)

Expand Down
12 changes: 4 additions & 8 deletions server/portal/apps/accounts/integrations.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from importlib import import_module
from django.conf import settings
import logging
from importlib import import_module

from django.conf import settings

logger = logging.getLogger(__name__)
INTEGRATION_APPS = [s["integration"] for s in settings.PORTAL_DATAFILES_STORAGE_SYSTEMS if "integration" in s]
Expand All @@ -12,14 +12,10 @@ def get_integrations(request):

for app in INTEGRATION_APPS:
try:
mod = import_module("{}.integrations".format(app))
mod = import_module(f"{app}.integrations")
app_integrations += mod.provide_integrations(request)

except Exception as exc:
logger.warning(
"Call to module.provide_integrations fail for module: {app_name}. {exc}".format(
app_name=app, exc=str(exc)
)
)
logger.warning(f"Call to module.provide_integrations fail for module: {app}. {str(exc)}")

return app_integrations
1 change: 1 addition & 0 deletions server/portal/apps/accounts/managers/abstract.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"""

from abc import ABCMeta, abstractmethod

from six import add_metaclass


Expand Down
2 changes: 2 additions & 0 deletions server/portal/apps/accounts/managers/accounts.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@

import logging
from importlib import import_module

from django.conf import settings
from paramiko.ssh_exception import AuthenticationException, ChannelException, SSHException

from portal.apps.accounts.managers.ssh_keys import KeyCannotBeAdded

logger = logging.getLogger(__name__)
Expand Down
Loading
Loading