Skip to content

Commit

Permalink
[#38] merge branch 'develop' of https://github.com/I-GUIDE/catalogapi
Browse files Browse the repository at this point in the history
…into 38-update-to-pydantic-v2
  • Loading branch information
pkdash committed Sep 12, 2023
2 parents 00be384 + e2daeca commit d997914
Show file tree
Hide file tree
Showing 31 changed files with 8,339 additions and 343 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/deploy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,9 @@ jobs:
VUE_APP_URL: ${{ secrets.VUE_APP_URL }}
VUE_APP_LOGIN_URL: ${{ secrets.VUE_APP_LOGIN_URL }}
VUE_APP_CLIENT_ID: ${{ secrets.VUE_APP_CLIENT_ID }}
VUE_APP_GOOGLE_MAPS_API_KEY: ${{ secrets.VUE_APP_GOOGLE_MAPS_API_KEY }}
run: |
variables=("VUE_APP_NAME" "VUE_APP_API_URL" "VUE_APP_SUPPORT_EMAIL" "VUE_APP_URL" "VUE_APP_LOGIN_URL" "VUE_APP_CLIENT_ID")
variables=("VUE_APP_NAME" "VUE_APP_API_URL" "VUE_APP_SUPPORT_EMAIL" "VUE_APP_URL" "VUE_APP_LOGIN_URL" "VUE_APP_CLIENT_ID" "VUE_APP_GOOGLE_MAPS_API_KEY")
# Empty the .env file
> frontend/.env
Expand Down
2 changes: 2 additions & 0 deletions api/adapters/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# import all adapters here to get them registered
from api.adapters import hydroshare
12 changes: 8 additions & 4 deletions api/adapters/hydroshare.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import requests
from starlette import status
# from starlette import status
from datetime import datetime
from typing import List, Optional, Union
from pydantic import BaseModel, EmailStr, HttpUrl

from api.adapters.base import AbstractRepositoryMetadataAdapter, AbstractRepositoryRequestHandler
from api.adapters.utils import RepositoryType
from api.adapters.utils import RepositoryType, register_adapter
from api.exceptions import RepositoryException
from api.models import schema
from api.models.catalog import DatasetMetadataDOC
Expand Down Expand Up @@ -169,7 +170,7 @@ def get_metadata(self, record_id: str):

def make_request(url, file_list=False) -> Union[dict, List[dict]]:
response = requests.get(url)
if response.status_code != status.HTTP_200_OK:
if response.status_code != 200:
raise RepositoryException(status_code=response.status_code, detail=response.text)
if not file_list:
return response.json()
Expand All @@ -179,7 +180,7 @@ def make_request(url, file_list=False) -> Union[dict, List[dict]]:
# check if there are more results to fetch - by default, 100 files are returned from HydroShare
while response.json()["next"]:
response = requests.get(response.json()["next"])
if response.status_code != status.HTTP_200_OK:
if response.status_code != 200:
raise RepositoryException(status_code=response.status_code, detail=response.text)
content_files.extend(response.json()["results"])
return content_files
Expand Down Expand Up @@ -213,6 +214,9 @@ def update_submission(submission: Submission, repo_record_id: str) -> Submission
return submission


register_adapter(RepositoryType.HYDROSHARE, HydroshareMetadataAdapter)


class _HydroshareResourceMetadata(BaseModel):
title: str
abstract: str
Expand Down
17 changes: 17 additions & 0 deletions api/adapters/utils.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
from enum import Enum
from typing import Type, Union

from api.adapters.base import AbstractRepositoryMetadataAdapter


class RepositoryType(str, Enum):
HYDROSHARE = 'HYDROSHARE'


_adapter_registry = {}


def register_adapter(repository_type: RepositoryType, adapter_class: Type[AbstractRepositoryMetadataAdapter]) -> None:
_adapter_registry[repository_type] = adapter_class


def get_adapter_by_type(repository_type: RepositoryType) -> Union[AbstractRepositoryMetadataAdapter, None]:
adapter_cls = _adapter_registry.get(repository_type, None)
if adapter_cls:
return adapter_cls()
return None
5 changes: 1 addition & 4 deletions api/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
from fastapi import HTTPException


class RepositoryException(HTTPException):
class RepositoryException(Exception):
def __init__(self, status_code: int, detail: str):
self._status_code = status_code
self._detail = detail
Expand Down
3 changes: 2 additions & 1 deletion api/models/catalog.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import datetime
from typing import Optional

from beanie import Document

Expand Down Expand Up @@ -37,4 +38,4 @@ def delete_revision_id(self):


class DatasetMetadataDOC(CoreMetadataDOC):
repository_identifier: str = None
repository_identifier: Optional[str] = None
20 changes: 20 additions & 0 deletions api/models/management/change_streams_pre_and_post.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import asyncio
from api.config import get_settings
from api.models.catalog import DatasetMetadataDOC

from beanie import init_beanie
from motor.motor_asyncio import AsyncIOMotorClient


async def main():
db = AsyncIOMotorClient(get_settings().db_connection_string)
await init_beanie(database=db[get_settings().database_name], document_models=[DatasetMetadataDOC])
# https://www.mongodb.com/docs/manual/reference/command/collMod/#change-streams-with-document-pre--and-post-images
# This enables us to get the record id of a deleted submission within a trigger. We need this for removing
# discovery records when a submission is deleted
await db[get_settings().database_name].command(
({'collMod': DatasetMetadataDOC.get_collection_name(), "changeStreamPreAndPostImages": {'enabled': True}}))
db.close()

if __name__ == "__main__":
asyncio.run(main())
21 changes: 9 additions & 12 deletions api/models/schemas/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@
"title": "@Type"
},
"name": {
"description": "Name of the organization.",
"description": "Name of the provider organization or repository.",
"title": "Name",
"type": "string"
},
Expand Down Expand Up @@ -219,7 +219,7 @@
"name"
],
"title": "Funding Organization",
"type": "string"
"type": "object"
},
"GeoCoordinates": {
"properties": {
Expand Down Expand Up @@ -314,7 +314,7 @@
"title": "@Type"
},
"name": {
"description": "Name of the organization.",
"description": "Name of the provider organization or repository.",
"title": "Name",
"type": "string"
},
Expand Down Expand Up @@ -350,7 +350,7 @@
"name"
],
"title": "Funding Organization",
"type": "string"
"type": "object"
},
{
"type": "null"
Expand Down Expand Up @@ -483,6 +483,7 @@
"type": "object"
},
"LanguageEnum": {
"description": "",
"enum": [
"eng",
"esp"
Expand Down Expand Up @@ -970,9 +971,6 @@
}
],
"description": "A date/time object containing the instant corresponding to the termination of the time interval (ISO8601 formatted date - YYYY-MM-DDTHH:MM). If the ending date is left off, that means the temporal coverage is ongoing.",
"formatMinimum": {
"$data": "1/startDate"
},
"title": "End date"
}
},
Expand Down Expand Up @@ -1032,6 +1030,7 @@
"anyOf": [
{
"items": {
"title": "Identifier",
"type": "string"
},
"type": "array"
Expand Down Expand Up @@ -1567,6 +1566,7 @@
"inLanguage": {
"anyOf": [
{
"description": "",
"enum": [
"eng",
"esp"
Expand Down Expand Up @@ -1750,7 +1750,7 @@
"title": "@Type"
},
"name": {
"description": "Name of the organization.",
"description": "Name of the provider organization or repository.",
"title": "Name",
"type": "string"
},
Expand Down Expand Up @@ -1786,7 +1786,7 @@
"name"
],
"title": "Funding Organization",
"type": "string"
"type": "object"
},
{
"type": "null"
Expand Down Expand Up @@ -1831,9 +1831,6 @@
}
],
"description": "A date/time object containing the instant corresponding to the termination of the time interval (ISO8601 formatted date - YYYY-MM-DDTHH:MM). If the ending date is left off, that means the temporal coverage is ongoing.",
"formatMinimum": {
"$data": "1/startDate"
},
"title": "End date"
}
},
Expand Down
108 changes: 35 additions & 73 deletions api/models/schemas/ui-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -449,28 +449,22 @@
"options": {
"map": {
"type": "box",
"northlimit": "northlimit",
"eastlimit": "eastlimit",
"southlimit": "southlimit",
"westlimit": "westlimit"
"format": "GeoShape",
"box": "box"
}
},
"elements": [
{
"type": "Control",
"scope": "#/properties/northlimit"
},
{
"type": "Control",
"scope": "#/properties/eastlimit"
},
{
"type": "Control",
"scope": "#/properties/southlimit"
"scope": "#/properties/@type",
"rule": {
"effect": "HIDE",
"condition": {}
}
},
{
"type": "Control",
"scope": "#/properties/westlimit"
"scope": "#/properties/box"
}
]
}
Expand Down Expand Up @@ -792,67 +786,35 @@
"scope": "#/properties/funder",
"options": {
"detail": {
"0": {
"type": "VerticalLayout",
"elements": [
{
"type": "Control",
"scope": "#/properties/@type",
"rule": {
"effect": "HIDE",
"condition": {}
}
},
{
"type": "Control",
"scope": "#/properties/name"
},
{
"type": "HorizontalLayout",
"elements": [
{
"type": "Control",
"scope": "#/properties/email"
},
{
"type": "Control",
"scope": "#/properties/identifier"
}
]
"label": "Organization",
"type": "VerticalLayout",
"elements": [
{
"type": "Control",
"scope": "#/properties/@type",
"rule": {
"effect": "HIDE",
"condition": {}
}
]
},
"1": {
"label": "Organization",
"type": "VerticalLayout",
"elements": [
{
"type": "Control",
"scope": "#/properties/@type",
"rule": {
"effect": "HIDE",
"condition": {}
},
{
"type": "HorizontalLayout",
"elements": [
{
"type": "Control",
"scope": "#/properties/name"
},
{
"type": "Control",
"scope": "#/properties/url"
}
},
{
"type": "HorizontalLayout",
"elements": [
{
"type": "Control",
"scope": "#/properties/name"
},
{
"type": "Control",
"scope": "#/properties/url"
}
]
},
{
"type": "Control",
"scope": "#/properties/address"
}
]
}
]
},
{
"type": "Control",
"scope": "#/properties/address"
}
]
}
}
}
Expand Down
8 changes: 5 additions & 3 deletions api/models/user.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
from datetime import datetime
from typing import List, Optional
from typing import List, Optional, TYPE_CHECKING

from beanie import Document, Link, PydanticObjectId
from pydantic import HttpUrl, model_validator

from api.adapters.utils import RepositoryType
if TYPE_CHECKING:
# this avoids circular imports
from api.adapters.utils import RepositoryType


class Submission(Document):
Expand All @@ -31,7 +33,7 @@ class User(Document):
def submission(self, identifier: PydanticObjectId) -> Submission:
return next(filter(lambda submission: submission.identifier == identifier, self.submissions), None)

def submission_by_repository(self, repo_type: RepositoryType, identifier: str) -> Submission:
def submission_by_repository(self, repo_type: 'RepositoryType', identifier: str) -> Submission:
return next(
filter(
lambda submission: submission.repository_identifier == identifier
Expand Down
Loading

0 comments on commit d997914

Please sign in to comment.