Skip to content

Commit 9a70e2e

Browse files
authored
Centralize encoding of binary blob, do not return binary for /resources (#642)
* Always use a base64 representation for images * Clean up encoding of images since it is now centralized * Do not show the binary blobs for the user resources endpoint
1 parent 668d60c commit 9a70e2e

File tree

4 files changed

+18
-29
lines changed

4 files changed

+18
-29
lines changed

src/database/model/ai_asset/distribution.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
import base64
12
from datetime import datetime
23
from typing import Type
34

5+
from fastapi.encoders import jsonable_encoder
46
from pydantic import create_model
5-
from sqlalchemy import Column, Integer, ForeignKey, String, LargeBinary
7+
from sqlalchemy import Column, ForeignKey, String, LargeBinary
68
from sqlmodel import Field
79

810
from database.model.concept.concept import AIoDConceptBase
@@ -62,6 +64,14 @@ class DistributionBase(AIoDConceptBase):
6264
sa_column=Column(LargeBinary),
6365
)
6466

67+
def dict(self, *args, **kwargs):
68+
# Defining it as a `Config` does not work for some reason.
69+
item_dict = super().dict(*args, **kwargs)
70+
item = jsonable_encoder(
71+
item_dict, custom_encoder={bytes: lambda v: base64.b64encode(v).decode("utf-8")}
72+
)
73+
return item
74+
6575

6676
def distribution_factory(table_from: str, distribution_name="distribution") -> Type:
6777
name = f"{distribution_name}_{table_from}"

src/routers/resource_router.py

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -230,14 +230,10 @@ def get_resources(
230230
session, pagination, resource_filters, user, platform
231231
)
232232
for resource in resources:
233-
if not get_image and hasattr(resource, "media") and resource.media:
233+
if not get_image and hasattr(resource, "media"):
234234
for media_obj in resource.media:
235235
media_obj.binary_blob = None
236236

237-
# Add image blobs if requested
238-
if get_image:
239-
self._add_binary_bytes_to_resource(session, resource)
240-
241237
return [convert_schema(resource) for resource in resources]
242238
except Exception as e:
243239
raise as_http_exception(e)
@@ -266,9 +262,6 @@ def get_resource(
266262
for media_obj in resource.media:
267263
media_obj.binary_blob = None
268264

269-
if get_image:
270-
resource = self._add_binary_bytes_to_resource(session, resource)
271-
272265
if resource.aiod_entry.status != EntryStatus.PUBLISHED:
273266
if user is None:
274267
raise HTTPException(
@@ -389,18 +382,6 @@ def get_resources(
389382

390383
return get_resources
391384

392-
def _add_binary_bytes_to_resource(self, session: Session, resource: AIoDConcept):
393-
"""
394-
Attach binary_blob bytes as base64 encoded image from the resource's media.
395-
"""
396-
if hasattr(resource, "media") and resource.media:
397-
for media_obj in resource.media:
398-
if media_obj.binary_blob:
399-
media_obj.binary_blob = base64.b64encode(media_obj.binary_blob).decode("utf-8")
400-
else:
401-
media_obj.binary_blob = None
402-
return resource
403-
404385
def get_resource_func(self):
405386
"""
406387
Return a function that can be used to retrieve a single resource.

src/routers/resource_routers/organisation_router.py

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
from sqlmodel import select, Session
66
from database.model.agent.organisation import Organisation
77
from database.session import get_session
8-
import base64
98
from authentication import KeycloakUser, get_user_or_none, get_user_or_raise
109
from dependencies.filtering import ResourceFiltersParams
1110
from dependencies.pagination import PaginationParams
@@ -190,13 +189,7 @@ async def organisation_image(
190189
status_code=HTTPStatus.NOT_FOUND, detail=f"Organisation {identifier} not found."
191190
)
192191

193-
org_image_media = []
194-
for media in org.media:
195-
if media.binary_blob:
196-
media.binary_blob = base64.b64encode(media.binary_blob).decode("utf-8")
197-
org_image_media.append(media)
198-
199-
return org_image_media
192+
return [media for media in org.media if media.binary_blob]
200193

201194
@router.delete( # type: ignore[no-redef]
202195
path, tags=[self.resource_name_plural]

src/routers/user_router.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,11 @@ def get_versioned_resources_for_user(
6161
offset=pagination.offset,
6262
limit=limit,
6363
)
64+
all_assets = [asset for assets in resources.values() for asset in assets]
65+
for resource in [a for a in all_assets if hasattr(a, "media")]:
66+
for media in resource.media:
67+
media.binary_blob = None
68+
6469
orm_to_read = {
6570
r.resource_class.__tablename__: r.orm_to_read
6671
for r in versioned_routers.get(version, [])

0 commit comments

Comments
 (0)