<commit_before>"""Provide an interface to SPARQL query endpoints."""

from cStringIO import StringIO
import datetime
import urllib
import urlparse

import httplib2
from lxml import objectify
import pytz
import rdflib
import simplejson

import logging

log = logging.getLogger(__name__)

class SPARQLQueryException(Exception):
    """Raised when the SPARQL store returns an HTTP status code other than 200 OK."""
    pass

class UnknownSPARQLReturnTypeException(Exception):
    """Raised when the SPARQL store provides a response with an unrecognized content-type."""
    pass

class SPARQLServer(object):
    """A server that can run SPARQL queries."""

    def __init__(self, query_url, post_queries = True):
        self.query_url = query_url
        self.post_queries = post_queries

    acceptable_sparql_responses = [
        'application/sparql-results+json',
        'application/rdf+xml',
        'application/sparql-results+xml',
    ]

    def query(self, sparql, output='json'):
        """Executes a SPARQL query. The return type varies based on what the
        SPARQL store responds with:

        * application/rdf+xml: an rdflib.ConjunctiveGraph
        * application/sparql-results+json: A dictionary from simplejson
        * application/sparql-results+xml: An lxml.objectify structure

        :param sparql: The SPARQL to execute.
        :returns: The results of the query from the SPARQL store."""
        http = httplib2.Http()

        log.debug("Querying: %s with: %r", self.query_url, sparql)
        if self.post_queries:
            response, content = http.request(
                uri=self.query_url, method='POST',
                body=urllib.urlencode({'query': sparql, 'output':output }),
                headers={
                    "Content-Type": "application/x-www-form-urlencoded",
                    "Accept": ','.join(self.acceptable_sparql_responses),
                })
        else:
            params = urllib.urlencode({'query': sparql, 'output':output })
            response, content = http.request(
                uri=self.query_url + '?' + params, method='GET',
                headers={
                    "Accept": ','.join(self.acceptable_sparql_responses),
            })
        if response['status'] == '204':
            return True
        if response['status'] != '200':
            raise SPARQLQueryException('%s: %s' % (response, content))
        if response['content-type'].startswith('application/rdf+xml'):
            graph = rdflib.ConjunctiveGraph()
            graph.parse(StringIO(content), self.query_url)
            return graph
        elif response['content-type'].startswith('application/sparql-results+json'):
            return simplejson.loads(content)
        elif response['content-type'].startswith('application/sparql-results+xml'):
            return objectify.parse(StringIO(content))
        else:<commit_msg>Support for named-graph-uri and default-graph-uri parameters<commit_after>"""Provide an interface to SPARQL query endpoints."""

from cStringIO import StringIO
import datetime
import urllib
import urlparse

import httplib2
from lxml import objectify
import pytz
import rdflib
import simplejson

import logging

log = logging.getLogger(__name__)

class SPARQLQueryException(Exception):
    """Raised when the SPARQL store returns an HTTP status code other than 200 OK."""
    pass

class UnknownSPARQLReturnTypeException(Exception):
    """Raised when the SPARQL store provides a response with an unrecognized content-type."""
    pass

class SPARQLServer(object):
    """A server that can run SPARQL queries."""

    def __init__(self, query_url, post_queries = True):
        self.query_url = query_url
        self.post_queries = post_queries

    acceptable_sparql_responses = [
        'application/sparql-results+json',
        'application/rdf+xml',
        'application/sparql-results+xml',
    ]

    def query(self, sparql, output='json', default_graph=[], named_graph=[]):
        """Executes a SPARQL query. The return type varies based on what the
        SPARQL store responds with:

        * application/rdf+xml: an rdflib.ConjunctiveGraph
        * application/sparql-results+json: A dictionary from simplejson
        * application/sparql-results+xml: An lxml.objectify structure

        :param sparql: The SPARQL to execute.
        :returns: The results of the query from the SPARQL store."""
        http = httplib2.Http()

        log.debug("Querying: %s with: %r", self.query_url, sparql)
        params_dict = {'query': sparql, 'output': output}
        if default_graph:
            for g in default_graph:
                print g
                print str(g)
            params_dict['default-graph-uri'] = default_graph
        if named_graph:
            params_dict['named-graph-uri'] = named_graph
        if self.post_queries:
            response, content = http.request(
                uri=self.query_url, method='POST',
                body=urllib.urlencode(params_dict, doseq=True),
                headers={
                    "Content-Type": "application/x-www-form-urlencoded",
                    "Accept": ','.join(self.acceptable_sparql_responses),
                })
        else:
            params = urllib.urlencode(params_dict, doseq=True)
            print params
            response, content = http.request(
                uri=self.query_url + '?' + params, method='GET',
                headers={
                    "Accept": ','.join(self.acceptable_sparql_responses),
            })
        if response['status'] == '204':
            return True
        if response['status'] != '200':
            raise SPARQLQueryException('%s: %s' % (response, content))
        if response['content-type'].startswith('application/rdf+xml'):
            graph = rdflib.ConjunctiveGraph()
            graph.parse(StringIO(content), self.query_url)
            return graph
        elif response['content-type'].startswith('application/sparql-results+json'):
            return simplejson.loads(content)
        elif response['content-type'].startswith('application/sparql-results+xml'):
            return objectify.parse(StringIO(content))
        else:
{'fraction_non_alphanumeric': 0.10673340868722751, 'fraction_numerical': 0.003552397868561279, 'mean_word_length': 2.5679723502304146, 'pattern_counts': {'":': 6, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 16}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5856823', 'n_tokens_mistral': 1789, 'n_tokens_neox': 1719, 'n_words': 431}