Skip to content

Commit

Permalink
Serialize query results early and stream out.
Browse files Browse the repository at this point in the history
  • Loading branch information
Stefano Cossu committed Mar 9, 2018
1 parent f569606 commit d756458
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 23 deletions.
17 changes: 14 additions & 3 deletions lakesuperior/api/query.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,32 @@
import logging

from io import BytesIO

from lakesuperior.dictionaries.namespaces import ns_collection as nsc
from lakesuperior.dictionaries.namespaces import ns_mgr as nsm
from lakesuperior.env import env
from lakesuperior.store.ldp_rs.lmdb_store import LmdbStore, TxnManager


logger = logging.getLogger(__name__)
rdfly = env.app_globals.rdfly
rdf_store = env.app_globals.rdf_store


def sparql_query(qry_str):
def sparql_query(qry_str, fmt):
'''
Send a SPARQL query to the triplestore.
@param qry_str (str) SPARQL query string. SPARQL 1.1 Query Language
(https://www.w3.org/TR/sparql11-query/) is supported.
@param fmt(string) Serialization format. This varies depending on the
query type (SELECT, ASK, CONSTRUCT, etc.). [@TODO Add reference to RDFLib
serialization formats]
@return rdflib.query.QueryResult
@return BytesIO
'''
return rdfly.raw_query(qry_str)
with TxnManager(rdf_store) as txn:
qres = rdfly.raw_query(qry_str)
out_stream = BytesIO(qres.serialize(format=fmt))

return out_stream
34 changes: 14 additions & 20 deletions lakesuperior/endpoints/query.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
import logging

from flask import Blueprint, current_app, request, render_template
from flask import Blueprint, current_app, request, render_template, send_file
from rdflib.plugin import PluginException

from lakesuperior.env import env
from lakesuperior.dictionaries.namespaces import ns_mgr as nsm
from lakesuperior.api import query as query_api
from lakesuperior.store.ldp_rs.lmdb_store import LmdbStore, TxnManager

# Query endpoint. raw SPARQL queries exposing the underlying layout can be made
# available. Also convenience methods that allow simple lookups based on simple
# binary comparisons should be added. Binary lookups—maybe?
# N.B All data sources are read-only for this endpoint.

logger = logging.getLogger(__name__)
rdf_store = env.app_globals.rdf_store
rdfly = env.app_globals.rdfly

query = Blueprint('query', __name__)
Expand Down Expand Up @@ -55,25 +53,21 @@ def sparql():
if request.method == 'GET':
return render_template('sparql_query.html', nsm=nsm)
else:
if request.mimetype == 'multipart/form-data':
qstr = request.form['query']
if request.mimetype == 'application/sparql-query':
qstr = request.stream.read()
else:
qstr = stream.read()
qstr = request.form['query']
logger.debug('Query: {}'.format(qstr))
with TxnManager(rdf_store) as txn:
qres = query_api.sparql_query(qstr)

match = request.accept_mimetypes.best_match(accept_mimetypes.keys())
if match:
enc = accept_mimetypes[match]
else:
enc = request.accept_mimetypes.best
match = request.accept_mimetypes.best_match(accept_mimetypes.keys())
fmt = (
accept_mimetypes[match] if match
else request.accept_mimetypes.best)

try:
out = qres.serialize(format=enc)
except PluginException:
return (
'Unable to serialize results into format {}'.format(enc),
406)
try:
out_stream = query_api.sparql_query(qstr, fmt)
except PluginException:
return (
'Unable to serialize results into format {}'.format(fmt), 406)

return out, 200
return send_file(out_stream, mimetype=fmt), 200

0 comments on commit d756458

Please sign in to comment.