Skip to content

Commit

Permalink
Added file upload
Browse files Browse the repository at this point in the history
  • Loading branch information
ChristopherSpelt committed Dec 10, 2024
1 parent f19c5df commit 4fa03e5
Show file tree
Hide file tree
Showing 10 changed files with 83 additions and 52 deletions.
2 changes: 1 addition & 1 deletion amt/api/forms/measure.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@


async def get_measure_form(
id: str, current_values: dict[str, str | list[str]], translations: NullTranslations
id: str, current_values: dict[str, str | list[str] | list[tuple[str, str]]], translations: NullTranslations
) -> WebForm:
_ = translations.gettext

Expand Down
8 changes: 4 additions & 4 deletions amt/api/routes/algorithm.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import asyncio
import logging
from io import BytesIO
from collections.abc import Sequence
from typing import Annotated, Any, cast

from fastapi import APIRouter, Depends, File, Form, Request, Response, UploadFile
from fastapi.responses import HTMLResponse, JSONResponse
from fastapi.responses import HTMLResponse
from pydantic import BaseModel, Field
from ulid import ULID

Expand Down Expand Up @@ -526,7 +525,7 @@ async def get_measure(
algorithm = await get_algorithm_or_error(algorithm_id, algorithms_service, request)
measure = await measures_service.fetch_measures([measure_urn])
measure_task = get_measure_task_or_error(algorithm.system_card, measure_urn)
filenames = [object_storage_service.get_file_filename_and_ext(file) for file in measure_task.files]
filenames = [object_storage_service.get_file_info(file) for file in measure_task.files]

measure_form = await get_measure_form(
id="measure_state",
Expand Down Expand Up @@ -776,11 +775,12 @@ async def get_file(
) -> Response:
algorithm = await get_algorithm_or_error(algorithm_id, algorithms_service, request)
file = object_storage_service.get_file(algorithm.organization_id, algorithm_id, ulid)
filename_ext = object_storage_service.get_file_filename_and_ext(algorithm.organization_id, algorithm_id, ulid)

return Response(
content=file.read(decode_content=True),
headers={
"Content-Disposition": f"attachment;filename={ulid}",
"Content-Disposition": f"attachment;filename={filename_ext}",
"Content-Type": "application/octet-stream",
},
)
Expand Down
30 changes: 17 additions & 13 deletions amt/locale/base.pot
Original file line number Diff line number Diff line change
Expand Up @@ -201,29 +201,29 @@ msgstr ""
msgid "Status"
msgstr ""

#: amt/api/forms/measure.py:30
#: amt/api/forms/measure.py:32
msgid "Information on how this measure is implemented"
msgstr ""

#: amt/api/forms/measure.py:31
#: amt/api/forms/measure.py:33
msgid ""
"Describe how the measure has been implemented, including challenges and "
"solutions."
msgstr ""

#: amt/api/forms/measure.py:38
#: amt/api/forms/measure.py:40
msgid "Add files"
msgstr ""

#: amt/api/forms/measure.py:43
#: amt/api/forms/measure.py:45
msgid "Add URI"
msgstr ""

#: amt/api/forms/measure.py:46
#: amt/api/forms/measure.py:48
msgid "Add links to documents"
msgstr ""

#: amt/api/forms/measure.py:47
#: amt/api/forms/measure.py:49
msgid "URI"
msgstr ""

Expand All @@ -238,28 +238,28 @@ msgstr ""
msgid "Name of the organization"
msgstr ""

#: amt/api/forms/organization.py:23
#: amt/api/forms/organization.py:24
msgid "The slug is the web path, like /organizations/my-organization-name"
msgstr ""

#: amt/api/forms/organization.py:24
#: amt/api/forms/organization.py:25
#: amt/site/templates/organizations/home.html.j2:29
msgid "Slug"
msgstr ""

#: amt/api/forms/organization.py:25
#: amt/api/forms/organization.py:26
msgid "The slug for this organization"
msgstr ""

#: amt/api/forms/organization.py:30
#: amt/api/forms/organization.py:32
msgid "Add members"
msgstr ""

#: amt/api/forms/organization.py:31
#: amt/api/forms/organization.py:33
msgid "Search for a person..."
msgstr ""

#: amt/api/forms/organization.py:36
#: amt/api/forms/organization.py:38
msgid "Add organization"
msgstr ""

Expand Down Expand Up @@ -323,6 +323,10 @@ msgid ""
"later."
msgstr ""

#: amt/core/exceptions.py:84
msgid "Something went wrong storing your file. PLease try again later."
msgstr ""

#: amt/site/templates/algorithms/details_base.html.j2:19
msgid "Delete algoritmic system"
msgstr ""
Expand Down Expand Up @@ -494,7 +498,7 @@ msgstr ""
msgid "measures executed"
msgstr ""

#: amt/site/templates/algorithms/details_requirements.html.j2:55
#: amt/site/templates/algorithms/details_requirements.html.j2:59
#: amt/site/templates/macros/editable.html.j2:24
#: amt/site/templates/macros/editable.html.j2:27
msgid "Edit"
Expand Down
Binary file modified amt/locale/en_US/LC_MESSAGES/messages.mo
Binary file not shown.
30 changes: 17 additions & 13 deletions amt/locale/en_US/LC_MESSAGES/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -202,29 +202,29 @@ msgstr ""
msgid "Status"
msgstr ""

#: amt/api/forms/measure.py:30
#: amt/api/forms/measure.py:32
msgid "Information on how this measure is implemented"
msgstr ""

#: amt/api/forms/measure.py:31
#: amt/api/forms/measure.py:33
msgid ""
"Describe how the measure has been implemented, including challenges and "
"solutions."
msgstr ""

#: amt/api/forms/measure.py:38
#: amt/api/forms/measure.py:40
msgid "Add files"
msgstr ""

#: amt/api/forms/measure.py:43
#: amt/api/forms/measure.py:45
msgid "Add URI"
msgstr ""

#: amt/api/forms/measure.py:46
#: amt/api/forms/measure.py:48
msgid "Add links to documents"
msgstr ""

#: amt/api/forms/measure.py:47
#: amt/api/forms/measure.py:49
msgid "URI"
msgstr ""

Expand All @@ -239,28 +239,28 @@ msgstr ""
msgid "Name of the organization"
msgstr ""

#: amt/api/forms/organization.py:23
#: amt/api/forms/organization.py:24
msgid "The slug is the web path, like /organizations/my-organization-name"
msgstr ""

#: amt/api/forms/organization.py:24
#: amt/api/forms/organization.py:25
#: amt/site/templates/organizations/home.html.j2:29
msgid "Slug"
msgstr ""

#: amt/api/forms/organization.py:25
#: amt/api/forms/organization.py:26
msgid "The slug for this organization"
msgstr ""

#: amt/api/forms/organization.py:30
#: amt/api/forms/organization.py:32
msgid "Add members"
msgstr ""

#: amt/api/forms/organization.py:31
#: amt/api/forms/organization.py:33
msgid "Search for a person..."
msgstr ""

#: amt/api/forms/organization.py:36
#: amt/api/forms/organization.py:38
msgid "Add organization"
msgstr ""

Expand Down Expand Up @@ -324,6 +324,10 @@ msgid ""
"later."
msgstr ""

#: amt/core/exceptions.py:84
msgid "Something went wrong storing your file. PLease try again later."
msgstr ""

#: amt/site/templates/algorithms/details_base.html.j2:19
msgid "Delete algoritmic system"
msgstr ""
Expand Down Expand Up @@ -495,7 +499,7 @@ msgstr ""
msgid "measures executed"
msgstr ""

#: amt/site/templates/algorithms/details_requirements.html.j2:55
#: amt/site/templates/algorithms/details_requirements.html.j2:59
#: amt/site/templates/macros/editable.html.j2:24
#: amt/site/templates/macros/editable.html.j2:27
msgid "Edit"
Expand Down
Binary file modified amt/locale/nl_NL/LC_MESSAGES/messages.mo
Binary file not shown.
32 changes: 19 additions & 13 deletions amt/locale/nl_NL/LC_MESSAGES/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -202,31 +202,31 @@ msgstr "Organisatie"
msgid "Status"
msgstr "Status"

#: amt/api/forms/measure.py:30
#: amt/api/forms/measure.py:32
msgid "Information on how this measure is implemented"
msgstr "Informatie over hoe deze maatregel is geïmplementeerd"

#: amt/api/forms/measure.py:31
#: amt/api/forms/measure.py:33
msgid ""
"Describe how the measure has been implemented, including challenges and "
"solutions."
msgstr ""
"Beschrijf hoe de maatregel is geimplementeerd, inclusief uitdagingen "
"enoplossingen."

#: amt/api/forms/measure.py:38
#: amt/api/forms/measure.py:40
msgid "Add files"
msgstr "Bestanden toevoegen"

#: amt/api/forms/measure.py:43
#: amt/api/forms/measure.py:45
msgid "Add URI"
msgstr "Voeg URI toe"

#: amt/api/forms/measure.py:46
#: amt/api/forms/measure.py:48
msgid "Add links to documents"
msgstr "Voeg link naar documenten toe"

#: amt/api/forms/measure.py:47
#: amt/api/forms/measure.py:49
msgid "URI"
msgstr "URI"

Expand All @@ -241,30 +241,30 @@ msgstr "Naam"
msgid "Name of the organization"
msgstr "Naam van de organisatie"

#: amt/api/forms/organization.py:23
#: amt/api/forms/organization.py:24
msgid "The slug is the web path, like /organizations/my-organization-name"
msgstr ""
"Een slug is het pad in het webadres, zoals /organizations/mijn-"
"organisatie-naam"

#: amt/api/forms/organization.py:24
#: amt/api/forms/organization.py:25
#: amt/site/templates/organizations/home.html.j2:29
msgid "Slug"
msgstr "Slug"

#: amt/api/forms/organization.py:25
#: amt/api/forms/organization.py:26
msgid "The slug for this organization"
msgstr "Het web-pad (slug) voor deze organisatie"

#: amt/api/forms/organization.py:30
#: amt/api/forms/organization.py:32
msgid "Add members"
msgstr "Voeg personen toe"

#: amt/api/forms/organization.py:31
#: amt/api/forms/organization.py:33
msgid "Search for a person..."
msgstr "Zoek een persoon..."

#: amt/api/forms/organization.py:36
#: amt/api/forms/organization.py:38
msgid "Add organization"
msgstr "Organisatie toevoegen"

Expand Down Expand Up @@ -336,6 +336,12 @@ msgstr ""
"Er is iets fout gegaan tijdens de autorisatiestroom. Probeer het later "
"opnieuw"

#: amt/core/exceptions.py:84
msgid "Something went wrong storing your file. PLease try again later."
msgstr ""
"Er is iets fout gegaan tijdens het opslaan van uw bestand. Probeer het "
"later opnieuw"

#: amt/site/templates/algorithms/details_base.html.j2:19
msgid "Delete algoritmic system"
msgstr "Verwijder algoritme"
Expand Down Expand Up @@ -509,7 +515,7 @@ msgstr "Annuleren"
msgid "measures executed"
msgstr "maatregelen uitgevoerd"

#: amt/site/templates/algorithms/details_requirements.html.j2:55
#: amt/site/templates/algorithms/details_requirements.html.j2:59
#: amt/site/templates/macros/editable.html.j2:24
#: amt/site/templates/macros/editable.html.j2:27
msgid "Edit"
Expand Down
8 changes: 4 additions & 4 deletions amt/schema/webform.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def __init__(self, type: WebFormFieldType, name: str, label: str, group: str | N

class WebFormField(WebFormBaseField):
placeholder: str | None
default_value: str | list[str] | None
default_value: str | list[str] | list[tuple[str, str]] | None
options: list[WebFormOption] | None
validators: list[Any]
description: str | None
Expand All @@ -53,7 +53,7 @@ def __init__(
name: str,
label: str,
placeholder: str | None = None,
default_value: str | list[str] | None = None,
default_value: str | list[str] | list[tuple[str, str]] | None = None,
options: list[WebFormOption] | None = None,
attributes: dict[str, str] | None = None,
description: str | None = None,
Expand All @@ -80,7 +80,7 @@ def __init__(
name: str,
label: str,
placeholder: str | None = None,
default_value: str | list[str] | None = None,
default_value: str | list[str] | list[tuple[str, str]] | None = None,
options: list[WebFormOption] | None = None,
attributes: dict[str, str] | None = None,
group: str | None = None,
Expand Down Expand Up @@ -110,7 +110,7 @@ def __init__(
name: str,
label: str,
placeholder: str | None = None,
default_value: str | list[str] | None = None,
default_value: str | list[str] | list[tuple[str, str]] | None = None,
options: list[WebFormOption] | None = None,
attributes: dict[str, str] | None = None,
group: str | None = None,
Expand Down
19 changes: 17 additions & 2 deletions amt/services/object_storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

from fastapi import UploadFile
from minio import Minio
from minio.datatypes import Object
from ulid import ULID
from urllib3 import BaseHTTPResponse

Expand Down Expand Up @@ -114,7 +113,7 @@ def get_file(self, organization_id: str | int, algorithm_id: str | int, ulid: UL
raise AMTStorageError() from err
return file

def get_file_filename_and_ext(self, name: str) -> str:
def get_file_info(self, name: str) -> tuple[str, str]:
"""
Gets filename and extension from a file from the object storage without downloading its
contents.
Expand All @@ -124,6 +123,22 @@ def get_file_filename_and_ext(self, name: str) -> str:
except Exception as err:
raise AMTStorageError() from err

object_name = stats.object_name.split("/")[-1] if stats.object_name else ""
name = stats.metadata["X-Amz-Meta-Filename"] if stats.metadata else ""
ext = stats.metadata["X-Amz-Meta-Ext"] if stats.metadata else ""
return object_name, f"{name}{ext}"

def get_file_filename_and_ext(self, organization_id: str | int, algorithm_id: str | int, ulid: ULID) -> str:
"""
Gets filename and extension from a file from the object storage without downloading its
contents.
"""
path = self._generate_destination_path(organization_id, algorithm_id, ulid)
try:
stats = self.client.stat_object(self.bucket_name, path)
except Exception as err:
raise AMTStorageError() from err

name = stats.metadata["X-Amz-Meta-Filename"] if stats.metadata else ""
ext = stats.metadata["X-Amz-Meta-Ext"] if stats.metadata else ""
return f"{name}{ext}"
Loading

0 comments on commit 4fa03e5

Please sign in to comment.