1

I am developing an application which uses a common Fuseki dataset with other developers. A Javascript function calls AJAX (jQuery $.ajax()) and sends to the Python script three variables via POST request.

Javascript:

$.ajax({
    url: 'py/registerUser.py',
    data: {firstname: registerFirstName, lastname: registerLastName, email: registerEmail},
    dataType: 'json',
    type: 'post',
    success: function(data) {
        if(data["result"] == "ok") {
            validSPARQL = true;
        }
        else {
            validSPARQL = false;
        }
    },
    error: function(data) {
        validSPARQL = false;
    }
});

The Python script retrieves the POST variables and manipulates them to create the query string. Then it sets the method to POST and executes the query on the given address.

Python

#!/usr/bin/python
# -*- coding: utf-8 -*-

import cgi, cgitb, json, re
from SPARQLWrapper import SPARQLWrapper, JSON

arguments = cgi.FieldStorage()
firstname = arguments.getvalue('firstname')
lastname = arguments.getvalue('lastname')
email = arguments.getvalue('email')

queryString = """PREFIX aop:<http://vitali.web.cs.unibo.it/AnnOtaria/person/>
PREFIX rdf:<http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX foaf:<http://xmlns.com/foaf/0.1/>
INSERT DATA {
    aop:""" + firstname + lastname + """ a foaf:Person ;
    foaf:name \"""" + firstname + """ """ + lastname + """\" ;
    foaf:mbox <mailto:""" + email + """> .
}
"""

sparql = SPARQLWrapper("http://linktodataset.com:8181/data/update")
sparql.setQuery(queryString)
sparql.setReturnFormat(JSON)
sparql.setMethod('POST')
sparql.query()

print "Content-type: text/json\n"
print "{ \"result\": \"ok\" }"

My problem: each time I send the query, I get back a Internal Server Error 500. I tried manipulating the code in many ways, I followed the instructions on this page and had a look on this other one, and many others among which the SPARQLWrapper documentation, but nothing happened.

I tried writing the query string in other ways, imported other libraries. Nothing worked.

Note 1: commenting the line sparql.query() the error disappears, obviously it doesn't send any query though.

Note 2: I can send SELECT queries to http://linktodataset.com:8181/data/query, but this doesn't work with INSERT DATA.

Note 3: I tried the query string on the Fuseki Control Panel, in the form dedicated to SPARQL Update and it worked just fine. The same query, in the SPARQL Query form, didn't work.

I am sure I'm doing something wrong, but I can't understand what... Any suggestions? Thank you!

EDIT 1 (09-Feb-2015)

I have edited the query string and I tried printing it, this is the result:

PREFIX aop:<http://mypersonallink.com/person/>
PREFIX rdf:<http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX foaf:<http://xmlns.com/foaf/0.1/>
INSERT DATA {
aop:TestfirstTestlast a foaf:Person ;
foaf:name "Testfirst Testlast" ;
foaf:mbox <mailto:test@mail.com> .
}

EDIT 2 (10-feb-2015)

I installed a local Fuseki and started it with fuseki-server --update --mem /ds. The address is localhost:3030. The Python code has remained almost unchanged (mod_python instead of cgi and, of course, the link to the dataset). Here it is what I get:

MOD_PYTHON ERROR

ProcessId:      13230
Interpreter:    '127.0.1.1'

ServerName:     '127.0.1.1'
DocumentRoot:   '/var/www/personal/html'

URI:            '/py/registerUser.py'
Location:       None
Directory:      '/var/www/personal/html/py/'
Filename:       '/var/www/personal/html/py/registerUser.py'
PathInfo:       ''

Phase:          'PythonHandler'
Handler:        'mod_python.cgihandler'

Traceback (most recent call last):

File "/usr/lib/python2.7/dist-packages/mod_python/importer.py", line 1537, in HandlerDispatch
default=default_handler, arg=req, silent=hlist.silent)

File "/usr/lib/python2.7/dist-packages/mod_python/importer.py", line 1229, in _process_target
result = _execute_target(config, req, object, arg)

File "/usr/lib/python2.7/dist-packages/mod_python/importer.py", line 1128, in _execute_target
result = object(arg)

File "/usr/lib/python2.7/dist-packages/mod_python/cgihandler.py", line 96, in handler
imp.load_module(module_name, fd, path, desc)

File "/var/www/personal/html/py/registerUser.py", line 37, in <module>
sparql.query()

File "/usr/lib/pymodules/python2.7/SPARQLWrapper/Wrapper.py", line 355, in query
return QueryResult(self._query())

File "/usr/lib/pymodules/python2.7/SPARQLWrapper/Wrapper.py", line 330, in _query
raise QueryBadFormed

QueryBadFormed: QueryBadFormed: a bad request has been sent to the endpoint, probably the sparql query is bad formed

Note the last line:

QueryBadFormed: QueryBadFormed: a bad request has been sent to the endpoint, probably the sparql query is bad formed

Well, I commented sparql.query() and printed the queryString, copied it and put it into the SPARQL Update box reachable at http://localhost:3030/sparql.tpl and it worked just fine.

Community
  • 1
  • 1
TheOldMe
  • 21
  • 1
  • 6
  • Could you print the request after you've constructed it, and add it to the question. Your query string could very easily be invalid, depending on the values of firstname and lastname, but *we* don't know what those values are. String concatenation like this (as well as unprotected interpolation) can easily lead to syntax errors (at best) and SPARQL injection (at worst). – Joshua Taylor Feb 05 '15 at 13:27
  • @JoshuaTaylor, sorry for my delay. I have added what you requested. The string seems to be ok to me, doesn't it? – TheOldMe Feb 09 '15 at 13:38
  • Also, I have changed the Javascript because I need to send a POST request (and no more GET) with three variables (and not two). – TheOldMe Feb 09 '15 at 13:46
  • I've added an answer. – Joshua Taylor Feb 09 '15 at 17:30
  • Just to be clear, does SPARQLWrapper claim to support SPARQL 1.1 Update? Browsing the docs, I see things about SPARQL Query, but not SPARQL 1.1 Update. If the SPARQLWrapper is trying to parse the update or the results, it might not work if it doesn't support SPARQL 1.1 Update. – Joshua Taylor Feb 10 '15 at 18:37
  • An [update from May 2014](https://github.com/RDFLib/sparqlwrapper/releases/tag/1.6.0) says that there is SPARQL 1.1 Update support (that release fixed some issues). What version of SPARQL Wrapper are you using? – Joshua Taylor Feb 10 '15 at 18:38
  • Well, I checked this and I found out that the version is 1.4.1 both on local and remote servers. Despite it is not important for the local server, it is for the remote one. I wonder how to insert new triples, then. Thank you, Joshua, you have been very helpful, anyway! I will update my post in case of success. – TheOldMe Feb 10 '15 at 22:52
  • I'm not sure what you mean by "the version is 1.4.1 both on local and remote servers". You'd be running the SPARQLWrapper *client* locally, and a Fuseki *server* remotely, no? – Joshua Taylor Feb 11 '15 at 14:00
  • I have tried both locally *and* remotely. Anyway it seems to work *locally* with WSGI, but it doesn't remotely. I'll keep this post updated. – TheOldMe Feb 16 '15 at 21:16

2 Answers2

1

Does the Fuseki endpoint actually have "update" enabled? Note that in the documentation, Fuseki: serving RDF data over HTTP, there is an --update option:

  • --update
    Allow update. Otherwise only read requests are served (ignored if a configuration file is given).

Then, you also mentioned:

Note 2: I can send SELECT queries to http://linktodataset.com:8181/data/query, but this doesn't work with INSERT DATA.

You should not expect that to work. In the same documentation that I linked to above, we see this example (note the URLs where queries and updates should be sent):

fuseki-server --update --mem /ds

runs the server on port 3030 with an in-memory dataset. It can be accessed via the appropriate protocol at the following URLs:

  • SPARQL query: http://localhost:3030/ds/query
  • SPARQL update: http://localhost:3030/ds/update
  • SPARQL HTTP update: http://localhost:3030/ds/data

Your INSERT DATA is an update query, and would need to be sent to something like http://linktodataset.com:8181/data/update.

Joshua Taylor
  • 84,998
  • 9
  • 154
  • 353
1

this is a simple code works on Fuseki (./fuseki-server --update)

sparql = SPARQLWrapper("http://127.0.0.1:3030/gptest/update")


sparql.setQuery("""
INSERT DATA {
<http://kook.com/a> <http://kook.com/b> <http://kook.com/c>.
}
""")
sparql.method
sparql.setReturnFormat(JSON)
results = sparql.query().convert()


print(results)
Khaledvic
  • 534
  • 4
  • 16