Skip to content

Commit

Permalink
compute better filenames for returned rdf
Browse files Browse the repository at this point in the history
As per issue idn-au/catalogue-data#35 The
returned RDF files did not have appropriate filenames.
  • Loading branch information
lalewis1 committed Jul 29, 2024
1 parent 715ec4b commit ffc6ba4
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 43 deletions.
52 changes: 23 additions & 29 deletions prez/renderers/renderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,18 @@
from fastapi import status
from fastapi.exceptions import HTTPException
from fastapi.responses import StreamingResponse
from rdflib import Graph, URIRef, Namespace, RDF
from rdflib import RDF, Graph, Namespace, URIRef
from starlette.requests import Request
from starlette.responses import Response

from prez.models.profiles_and_mediatypes import ProfilesMediatypesInfo
from prez.models.profiles_item import ProfileItem
from prez.renderers.csv_renderer import render_csv_dropdown
from prez.renderers.json_renderer import render_json_dropdown, NotFoundError
from prez.renderers.json_renderer import NotFoundError, render_json_dropdown
from prez.services.curie_functions import get_curie_id_for_uri
from prez.sparql.methods import Repo
from prez.sparql.objects_listings import (
generate_item_construct,
get_annotation_properties,
)
from prez.sparql.objects_listings import (generate_item_construct,
get_annotation_properties)

log = logging.getLogger(__name__)

Expand All @@ -33,52 +31,49 @@ async def return_from_graph(
selected_class: URIRef,
repo: Repo,
):
profile_headers["Content-Disposition"] = "inline"
# set content-disposition
profile_headers["Content-Disposition"] = (
"attachment;" if str(mediatype) == "text/csv" else "inline;"
)
iri = graph.value(None, RDF.type, selected_class)
if iri:
profile_headers[
"Content-Disposition"
] += f" filename={get_curie_id_for_uri(URIRef(str(iri)))}"
elif selected_class:
profile_headers[
"Content-Disposition"
] += f" filename={selected_class.split('#')[-1].split('/')[-1]}"

if str(mediatype) in RDF_MEDIATYPES:
return await return_rdf(graph, mediatype, profile_headers)

elif profile == URIRef("https://w3id.org/profile/dd"):
graph = await return_annotated_rdf(graph, profile, repo)

try:
# TODO: Currently, data is generated in memory, instead of in a streaming manner.
# Not possible to do a streaming response yet since we are reading the RDF
# data into an in-memory graph.
jsonld_data = await render_json_dropdown(graph, profile, selected_class)

if str(mediatype) == "text/csv":
iri = graph.value(None, RDF.type, selected_class)
if iri:
filename = get_curie_id_for_uri(URIRef(str(iri)))
else:
filename = selected_class.split("#")[-1].split("/")[-1]
stream = render_csv_dropdown(jsonld_data["@graph"])
response = StreamingResponse(stream, media_type=mediatype)
response.headers[
"Content-Disposition"
] = f"attachment;filename={filename}.csv"
return response

# application/json
stream = io.StringIO(json.dumps(jsonld_data))
return StreamingResponse(stream, media_type=mediatype)

else:
stream = io.StringIO(json.dumps(jsonld_data))
return StreamingResponse(
stream, media_type=mediatype, headers=profile_headers
)
except NotFoundError as err:
raise HTTPException(status.HTTP_404_NOT_FOUND, str(err))

else:
if "anot+" in mediatype:
non_anot_mediatype = mediatype.replace("anot+", "")
profile_headers['Content-Type'] = non_anot_mediatype
profile_headers["Content-Type"] = non_anot_mediatype
graph = await return_annotated_rdf(graph, profile, repo)
content = io.BytesIO(
graph.serialize(format=non_anot_mediatype, encoding="utf-8")
)
return StreamingResponse(
content=content, media_type=non_anot_mediatype, headers=profile_headers
)

raise HTTPException(
status.HTTP_400_BAD_REQUEST, f"Unsupported mediatype: {mediatype}."
)
Expand All @@ -91,7 +86,6 @@ async def return_rdf(graph, mediatype, profile_headers):
format=RDF_SERIALIZER_TYPES_MAP[str(mediatype)], encoding="utf-8"
)
)
profile_headers["Content-Disposition"] = "inline"
return StreamingResponse(content=obj, media_type=mediatype, headers=profile_headers)


Expand Down
23 changes: 9 additions & 14 deletions prez/routers/vocprez.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,23 @@
import logging

from fastapi import APIRouter, Request
from fastapi import Depends
from fastapi import APIRouter, Depends, Request
from fastapi.responses import RedirectResponse
from rdflib import URIRef, SKOS
from rdflib import SKOS, URIRef
from starlette.responses import PlainTextResponse

from prez.bnode import get_bnode_depth
from prez.dependencies import get_repo, get_system_repo
from prez.models.profiles_and_mediatypes import ProfilesMediatypesInfo
from prez.queries.vocprez import (
get_concept_scheme_query,
get_concept_scheme_top_concepts_query,
get_concept_narrowers_query,
)
from prez.renderers.renderer import (
return_from_graph,
)
from prez.queries.vocprez import (get_concept_narrowers_query,
get_concept_scheme_query,
get_concept_scheme_top_concepts_query)
from prez.renderers.renderer import return_from_graph
from prez.response import StreamingTurtleAnnotatedResponse
from prez.routers.identifier import get_iri_route
from prez.services.objects import object_function
from prez.services.listings import listing_function
from prez.services.link_generation import _add_prez_links
from prez.services.curie_functions import get_curie_id_for_uri
from prez.services.link_generation import _add_prez_links
from prez.services.listings import listing_function
from prez.services.objects import object_function
from prez.sparql.methods import Repo
from prez.sparql.resource import get_resource

Expand Down

0 comments on commit ffc6ba4

Please sign in to comment.