Skip to content

Commit

Permalink
added ontology and prefix facades
Browse files Browse the repository at this point in the history
  • Loading branch information
ensaremirerol committed Dec 6, 2024
1 parent e344d84 commit c5fe128
Show file tree
Hide file tree
Showing 34 changed files with 1,398 additions and 243 deletions.
21 changes: 10 additions & 11 deletions bootstrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
from dotenv import load_dotenv
from kink import di

from server.services.core.config_service import (
ConfigServiceProtocol,
)
from server.services.core.sqlite_db_service import (
DBService,
)
Expand Down Expand Up @@ -47,21 +50,17 @@ async def bootstrap():
logger.info(f"System: {di['SYSTEM']}")
logger.info(f"Architecture: {di['ARCH']}")

logger.info("Starting core services...")
logger.info("Initializing services")

import server.services # noqa: F401 Reason: For DI to register services, they need to be imported

# This is a hack to ensure that the DBService is initialized
di[DBService].get_engine()

from server.services.core.config_service import (
ConfigService,
)

di[ConfigService].set("system", di["SYSTEM"])
di[ConfigService].set("arch", di["ARCH"])
di[ConfigService].set("app_dir", str(di["APP_DIR"]))

from server.services.core.workspace_metadata_service import (
WorkspaceMetadataService, # noqa
di[ConfigServiceProtocol].set("system", di["SYSTEM"])
di[ConfigServiceProtocol].set("arch", di["ARCH"])
di[ConfigServiceProtocol].set(
"app_dir", str(di["APP_DIR"])
)

logger.info("Environment variables loaded")
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description = "A Python project for RDF crafting"
authors = [
{ name = "Ensar Emir EROL", email = "ensar.erol@maastrichtuniversity.nl" }
]
requires-python = "==3.11.10"
requires-python = "==3.11.*"

dependencies = [
"annotated-types==0.7.0",
Expand Down
9 changes: 9 additions & 0 deletions server/const/err_enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class ErrCodes(Enum):
# FS Service
FILE_NOT_FOUND = 0
FILE_CORRUPTED = 1
FILE_EXISTS = 2

# Workspace Metadata Service
WORKSPACE_METADATA_NOT_FOUND = 20
Expand All @@ -16,3 +17,11 @@ class ErrCodes(Enum):

# Ontology Service
ONTOLOGY_NOT_FOUND = 40

# Workspace Service
WORKSPACE_NOT_FOUND = 60
PREFIX_NOT_FOUND = 61
PREFIX_EXISTS = 62

# DB Service
DB_ERROR = 80
75 changes: 75 additions & 0 deletions server/facades/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import logging
from abc import ABC, abstractmethod
from dataclasses import dataclass
from typing import Any

from server.exceptions import ErrCodes, ServerException


@dataclass
class FacadeResponse:
status: int
message: str
data: Any | None = None
err_code: ErrCodes | None = None

def to_dict(self):
return {
"status": self.status,
"message": self.message,
"data": self.data,
"err_code": self.err_code.value
if self.err_code
else None,
}


class BaseFacade(ABC):
def __init__(self):
self.logger = logging.getLogger(
self.__class__.__name__
)

@abstractmethod
def execute(self, *args, **kwargs) -> FacadeResponse:
pass

@staticmethod
def error_wrapper(
func,
):
def wrapper(*args, **kwargs):
try:
return func(*args, **kwargs)
except Exception as e:
return BaseFacade._error_response(e)

return wrapper

@staticmethod
def _error_response(
e: Exception,
):
if isinstance(e, ServerException):
return FacadeResponse(
message=e.message,
status=400,
err_code=e.code,
)
return FacadeResponse(
message=str(e),
status=500,
err_code=ErrCodes.UNKNOWN_ERROR,
)

@staticmethod
def _success_response(
data: Any,
message: str,
status: int = 200,
) -> FacadeResponse:
return FacadeResponse(
message=message,
status=status,
data=data,
)
File renamed without changes.
63 changes: 63 additions & 0 deletions server/facades/workspace/create_workspace_facade.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
from kink import inject

from server.facades import BaseFacade, FacadeResponse
from server.models.workspace import (
WorkspaceModel,
WorkspaceType,
)
from server.services.core.workspace_metadata_service import (
WorkspaceMetadataServiceProtocol,
)
from server.services.local.local_workspace_service import (
WorkspaceServiceProtocol,
)


@inject
class CreateWorkspaceFacade(BaseFacade):
def __init__(
self,
workspace_metadata_service: WorkspaceMetadataServiceProtocol,
workspace_service: WorkspaceServiceProtocol,
):
super().__init__()
self.workspace_metadata_service = (
workspace_metadata_service
)
self.workspace_service = workspace_service

@BaseFacade.error_wrapper
def execute(
self,
name: str,
description: str,
type: WorkspaceType,
location: str,
) -> FacadeResponse:
self.logger.info("Creating workspace metadata")

workspace_metadata = self.workspace_metadata_service.create_workspace_metadata(
name=name,
description=description,
type=type,
location=location,
)

self.logger.info("Creating workspace")
model: WorkspaceModel = (
WorkspaceModel.create_with_defaults(
uuid=workspace_metadata.uuid,
name=name,
description=description,
type=type,
location=location,
)
)
self.workspace_service.create_workspace(
workspace=model
)

return self._success_response(
data=workspace_metadata,
message="Workspace created",
)
57 changes: 57 additions & 0 deletions server/facades/workspace/delete_workspace_facade.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
from kink import inject

from server.exceptions import ErrCodes
from server.facades import (
BaseFacade,
FacadeResponse,
ServerException,
)
from server.services.core.workspace_metadata_service import (
WorkspaceMetadataServiceProtocol,
)
from server.services.local.local_workspace_service import (
WorkspaceServiceProtocol,
)


@inject
class DeleteWorkspaceFacade(BaseFacade):
def __init__(
self,
workspace_metadata_service: WorkspaceMetadataServiceProtocol,
workspace_service: WorkspaceServiceProtocol,
):
super().__init__()
self.workspace_metadata_service = (
workspace_metadata_service
)
self.workspace_service = workspace_service

@BaseFacade.error_wrapper
def execute(
self,
uuid: str,
) -> FacadeResponse:
self.logger.info("Retrieving workspace metadata")
workspace_metadata = self.workspace_metadata_service.get_workspace_metadata(
uuid=uuid,
)
self.logger.info("Deleting workspace")
try:
self.workspace_service.delete_workspace(
location=workspace_metadata.location,
)

except ServerException as e:
# Ignore workspace not found error
if e.code != ErrCodes.WORKSPACE_NOT_FOUND:
raise e

self.logger.info("Deleting workspace metadata")
self.workspace_metadata_service.delete_workspace_metadata(
uuid=uuid,
)
return FacadeResponse(
status=204,
message="Workspace deleted",
)
50 changes: 50 additions & 0 deletions server/facades/workspace/get_workspaces_facade.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
from kink import inject

from server.facades import (
BaseFacade,
FacadeResponse,
)
from server.services.core.workspace_metadata_service import (
WorkspaceMetadataServiceProtocol,
)
from server.services.local.local_workspace_service import (
WorkspaceServiceProtocol,
)


@inject
class GetWorkspacesFacade(BaseFacade):
def __init__(
self,
workspace_metadata_service: WorkspaceMetadataServiceProtocol,
workspace_service: WorkspaceServiceProtocol,
):
super().__init__()
self.workspace_metadata_service = (
workspace_metadata_service
)
self.workspace_service = workspace_service

@BaseFacade.error_wrapper
def execute(
self,
) -> FacadeResponse:
self.logger.info(
"Retrieving all workspace metadata"
)
all_workspace_metadata = (
self.workspace_metadata_service.get_workspaces()
)

all_workspaces = [
self.workspace_service.get_workspace(
metadata.location,
)
for metadata in all_workspace_metadata
]

return FacadeResponse(
status=200,
message="All workspaces retrieved",
data=all_workspaces,
)
79 changes: 79 additions & 0 deletions server/facades/workspace/ontology/create_ontology_in_workspace.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
from kink import inject

from server.const.err_enums import ErrCodes

Check failure on line 3 in server/facades/workspace/ontology/create_ontology_in_workspace.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (F401)

server/facades/workspace/ontology/create_ontology_in_workspace.py:3:36: F401 `server.const.err_enums.ErrCodes` imported but unused
from server.facades import (
BaseFacade,
FacadeResponse,
)
from server.models.ontology import Ontology
from server.service_protocols.ontology_service_protocol import (
OntologyServiceProtocol,
)
from server.services.core.workspace_metadata_service import (
WorkspaceMetadataServiceProtocol,
)
from server.services.local.local_workspace_service import (
WorkspaceServiceProtocol,
)


@inject
class CreateOntologyInWorkspaceFacade(BaseFacade):
def __init__(
self,
workspace_metadata_service: WorkspaceMetadataServiceProtocol,
workspace_service: WorkspaceServiceProtocol,
ontology_service: OntologyServiceProtocol,
):
super().__init__()
self.workspace_metadata_service = (
workspace_metadata_service
)
self.workspace_service = workspace_service
self.ontology_service = ontology_service

@BaseFacade.error_wrapper
def execute(
self,
workspace_id: str,
name: str,
description: str,
base_uri: str,
content: bytes,
) -> FacadeResponse:
self.logger.info("Retrieving workspace metadata")
workspace_metadata = self.workspace_metadata_service.get_workspace_metadata(
workspace_id,
)

self.logger.info("Retrieving workspace")
workspace = self.workspace_service.get_workspace(
workspace_metadata.location,
)

self.logger.info("Creating ontology")
ontology: Ontology = (
self.ontology_service.create_ontology(
name,
description,
base_uri,
content,
)
)

self.logger.info("Adding ontology to workspace")

new_model = workspace.copy_with(
ontologies=workspace.ontologies
+ [ontology.uuid],
)

self.workspace_service.update_workspace(
new_model,
)

return FacadeResponse(
status=200,
message="Ontology created",
data=ontology,
)
Loading

0 comments on commit c5fe128

Please sign in to comment.