Skip to content

Commit

Permalink
feat: artifact file schema, controller, and service updates
Browse files Browse the repository at this point in the history
  • Loading branch information
keithmanville committed Oct 21, 2024
1 parent 5872fb7 commit 8884e5e
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 23 deletions.
9 changes: 7 additions & 2 deletions src/dioptra/restapi/v1/artifacts/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@

from .schema import (
ArtifactContentsGetQueryParameters,
ArtifactFileSchema,
ArtifactGetQueryParameters,
ArtifactMutableFieldsSchema,
ArtifactPageSchema,
Expand Down Expand Up @@ -201,6 +202,7 @@ def __init__(

@login_required
@accepts(query_params_schema=ArtifactContentsGetQueryParameters, api=api)
@responds(schema=ArtifactFileSchema(many=True), api=api)
def get(self, id: int):
"""Gets a list of all files associated with an Artifact resource."""
log = LOGGER.new(
Expand All @@ -211,14 +213,17 @@ def get(self, id: int):
path = parsed_query_params["path"]
download = parsed_query_params["download"]

artifact_file = self._artifact_id_contents_service.get(
contents, is_dir = self._artifact_id_contents_service.get(
artifact_id=id,
path=path,
log=log,
)

if path is None and is_dir:
path = f"artifact_{id}.json"

return send_file(
path_or_file=artifact_file,
path_or_file=contents,
as_attachment=download,
download_name=Path(path).name,
)
Expand Down
41 changes: 20 additions & 21 deletions src/dioptra/restapi/v1/artifacts/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,19 +43,33 @@ class ArtifactRefSchema(ArtifactRefBaseSchema): # type: ignore


class ArtifactFileMetadataSchema(Schema):
"""The schema for the files stored in an Artifact resource."""
"""The schema for the artifact file metadata."""

relativePath = fields.String(
attribute="relative_path",
metadata=dict(description="Relative path to the Artifact URI."),
)
fileType = fields.String(
attribute="file_type",
metadata=dict(description="The type of the file."),
dump_only=True,
)
fileSize = fields.Integer(
attribute="file_size",
metadata=dict(description="The size in bytes of the file."),
dump_only=True,
)
fileUrl = fields.Url(
attribute="file_url",
metadata=dict(description="URL for accessing the contents of the file."),
relative=True,
dump_only=True,
)


class ArtifactFileSchema(ArtifactFileMetadataSchema):
"""The schema for an artifact file."""

relativePath = fields.String(
attribute="relative_path",
metadata=dict(description="Relative path to the Artifact URI."),
dump_only=True,
)


Expand All @@ -72,7 +86,7 @@ class ArtifactMutableFieldsSchema(Schema):
ArtifactBaseSchema = generate_base_resource_schema("Artifact", snapshot=True)


class ArtifactSchema(ArtifactMutableFieldsSchema, ArtifactBaseSchema): # type: ignore
class ArtifactSchema(ArtifactFileMetadataSchema, ArtifactMutableFieldsSchema, ArtifactBaseSchema): # type: ignore
"""The schema for the data stored in an Artifact resource."""

jobId = fields.Int(
Expand All @@ -86,21 +100,6 @@ class ArtifactSchema(ArtifactMutableFieldsSchema, ArtifactBaseSchema): # type:
metadata=dict(description="URL pointing to the location of the Artifact."),
required=True,
)
fileType = fields.String(
attribute="file_type",
metadata=dict(description="The type of the file."),
)
fileSize = fields.Integer(
attribute="file_size",
metadata=dict(description="The size in bytes of the file."),
)
files = fields.Nested(
ArtifactFileMetadataSchema,
attribute="files",
metadata=dict(description="The files contained in an artifact."),
many=True,
required=False,
)


class ArtifactPageSchema(BasePageSchema):
Expand Down
23 changes: 23 additions & 0 deletions src/dioptra/restapi/v1/artifacts/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
"""The server-side functions that perform artifact endpoint operations."""
from __future__ import annotations

import io
import json
from typing import Any, Final, cast

import structlog
Expand Down Expand Up @@ -466,3 +468,24 @@ def modify(

class ArtifactIdContentsService(object):
""" """

def get(
self,
artifact_id: str,
path: str,
**kwargs,
) -> (io.BytesIO, bool):

# example:
# If the requested location is a directory, contents is a file with the list of
# file metadata.
is_dir = True
contents = io.BytesIO()
contents.write(
json.dumps(
[{"relativePath": "./", "fileType": "json", "fileSize": 0, "url": ""}]
).encode("utf-8")
)
contents.seek(0)

return contents, is_dir

0 comments on commit 8884e5e

Please sign in to comment.