-
Notifications
You must be signed in to change notification settings - Fork 0
[MCC-1498582] - Create layered design #16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,28 +1,17 @@ | ||
| from __future__ import annotations | ||
|
|
||
| from dataclasses import dataclass | ||
|
|
||
|
|
||
| @dataclass(frozen=True) | ||
| class Study: | ||
| id: str | ||
| name: str | ||
| from dataclasses import dataclass, field | ||
| from uuid import UUID | ||
|
|
||
|
|
||
| @dataclass(frozen=True) | ||
| class StudyEnvironment: | ||
| """Environment variables for a study.""" | ||
|
|
||
|
|
||
| @dataclass(frozen=True) | ||
| class Dataset: | ||
| id: str | ||
| study_id: str | ||
| uuid: UUID | ||
| name: str | ||
|
|
||
|
|
||
| @dataclass(frozen=True) | ||
| class DatasetVersion: | ||
| id: str | ||
| dataset_id: str | ||
| class Study: | ||
| uuid: UUID | ||
| name: str | ||
| environments: list[StudyEnvironment] = field(default_factory=list) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| """Service layer — public symbols re-exported for import convenience.""" | ||
|
|
||
| from dataconnect.service.base import DataConnectService | ||
| from dataconnect.service.default import DefaultDataConnectService | ||
|
|
||
| __all__ = [ | ||
| "DataConnectService", | ||
| "DefaultDataConnectService", | ||
| ] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| """Abstract service interface for DataConnect.""" | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| from abc import ABC, abstractmethod | ||
|
|
||
| from dataconnect.models import Study | ||
|
|
||
|
|
||
| class DataConnectService(ABC): | ||
| """Abstract service interface — defines all operations available to the client.""" | ||
|
|
||
| @abstractmethod | ||
| def get_studies(self) -> list[Study]: ... | ||
|
|
||
| @abstractmethod | ||
| def close(self) -> None: ... |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,80 @@ | ||
| """Default service implementation — domain logic, encoding, and error translation.""" | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| from dataconnect.exceptions import ( | ||
| AuthenticationError, | ||
| AuthorizationError, | ||
| ConnectionError, | ||
| DataConnectError, | ||
| NotFoundError, | ||
| QueryError, | ||
| ServerError, | ||
| ValidationError, | ||
| ) | ||
| from dataconnect.models import Study | ||
| from dataconnect.service.base import DataConnectService | ||
| from dataconnect.service.mappers import resource_to_study | ||
| from dataconnect.transport.base import Transport | ||
| from dataconnect.transport.errors import ( | ||
| TransportAuthenticationError, | ||
| TransportAuthorizationError, | ||
| TransportConnectionError, | ||
| TransportError, | ||
| TransportIOError, | ||
| TransportNotFoundError, | ||
| TransportStatusError, | ||
| ) | ||
| from dataconnect.transport.models import ResourceQuery | ||
|
|
||
| # Server action identifiers | ||
| _ACTION_LIST_STUDIES = "studies.list" | ||
|
|
||
|
|
||
| def _translate_error(ex: TransportError) -> DataConnectError: | ||
| """Map a ``TransportError`` to the appropriate public ``DataConnectError``.""" | ||
|
|
||
| if isinstance(ex, TransportAuthenticationError): | ||
| return AuthenticationError(str(ex)) | ||
| if isinstance(ex, TransportAuthorizationError): | ||
| return AuthorizationError(str(ex)) | ||
| if isinstance(ex, TransportNotFoundError): | ||
| return NotFoundError(str(ex)) | ||
| if isinstance(ex, TransportStatusError): | ||
| return ServerError(str(ex), status_code=ex.status_code) | ||
| if isinstance(ex, TransportConnectionError): | ||
| return ConnectionError(str(ex)) | ||
| if isinstance(ex, TransportIOError): | ||
| return QueryError(str(ex)) | ||
|
|
||
| return ServerError(str(ex)) | ||
|
|
||
|
|
||
| class DefaultDataConnectService(DataConnectService): | ||
| """Concrete service injected with an abstract ``Transport``.""" | ||
|
|
||
| def __init__(self, transport: Transport) -> None: | ||
| self._transport = transport | ||
|
|
||
| # DataConnectService | ||
|
|
||
| def get_studies(self) -> list[Study]: | ||
|
|
||
| request = ResourceQuery(action=_ACTION_LIST_STUDIES) | ||
|
|
||
| try: | ||
| resources = self._transport.list_resources(request) | ||
| except TransportError as ex: | ||
| raise _translate_error(ex) from ex | ||
|
|
||
| try: | ||
| return [resource_to_study(r) for r in resources] | ||
| except (KeyError, TypeError, ValueError) as ex: | ||
|
slingampalli-mdsol marked this conversation as resolved.
|
||
| raise ValidationError(f"Unexpected studies response format: {ex}") from ex | ||
|
|
||
| def close(self) -> None: | ||
|
|
||
| try: | ||
| self._transport.close() | ||
| except TransportError as ex: | ||
| raise ConnectionError(str(ex)) from ex | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| """Resource → domain model mappers. | ||
|
|
||
| Each function takes a transport-layer ``ResourceInfo`` and returns a public | ||
| domain model. All wire-format knowledge (JSON encoding, field names, byte | ||
| decoding) is isolated here. | ||
| """ | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| import json | ||
| from uuid import UUID | ||
|
|
||
| from dataconnect.models import Study, StudyEnvironment | ||
| from dataconnect.transport.models import ResourceInfo | ||
|
|
||
|
|
||
| def resource_to_study(resource: ResourceInfo) -> Study: | ||
| """Parse a transport-layer ``ResourceInfo`` into a ``Study`` domain object.""" | ||
|
|
||
|
slingampalli-mdsol marked this conversation as resolved.
|
||
| data = json.loads(resource.endpoints[0].ticket.decode("utf-8")) | ||
|
|
||
| return Study( | ||
| uuid=UUID(data["uuid"]), | ||
| name=data["name"], | ||
| environments=[StudyEnvironment(uuid=UUID(e["uuid"]), name=e["name"]) for e in data.get("environments", [])], | ||
| ) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| """Transport layer — public exports. | ||
|
|
||
| Transport errors (``transport/errors.py``) are intentionally NOT re-exported | ||
| here. They are internal to the transport layer and must not be caught by | ||
| user-facing code. | ||
| """ | ||
|
|
||
| from dataconnect.transport.base import Transport | ||
| from dataconnect.transport.models import DataRef, ResourceInfo, ResourceQuery | ||
|
|
||
| __all__ = [ | ||
| "Transport", | ||
| "ResourceQuery", | ||
| "ResourceInfo", | ||
| "DataRef", | ||
| ] |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.