Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support of sessions by requests, removed dependency of urllib's authentications #229

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion SPARQLWrapper/KeyCaseInsensitiveDict.py
Original file line number Diff line number Diff line change
@@ -18,15 +18,19 @@

_V = TypeVar("_V")


class KeyCaseInsensitiveDict(Dict[str, _V]):
"""
A simple implementation of a key case-insensitive dictionary
"""

def __init__(self, d: Mapping[str, _V]={}) -> None:
def __init__(self, d=None) -> None:
"""
:param dict d: The source dictionary.
"""
super().__init__()
if d is None:
d = {}
for k, v in d.items():
self[k] = v

8 changes: 2 additions & 6 deletions SPARQLWrapper/SPARQLExceptions.py
Original file line number Diff line number Diff line change
@@ -35,13 +35,9 @@ def __init__(self, response: Optional[bytes] = None):
:param string response: The server response
"""
if response:
formatted_msg = "%s: %s. \n\nResponse:\n%r" % (
self.__class__.__name__,
self.msg,
response,
)
formatted_msg = f"{self.__class__.__name__}: {self.msg}. \n\nResponse:\n{response}"
else:
formatted_msg = "%s: %s." % (self.__class__.__name__, self.msg)
formatted_msg = f"{self.__class__.__name__}: {self.msg}."

super(SPARQLWrapperException, self).__init__(formatted_msg)

69 changes: 22 additions & 47 deletions SPARQLWrapper/SmartWrapper.py
Original file line number Diff line number Diff line change
@@ -20,11 +20,13 @@
"""


import contextlib
from typing import Any, Dict, List, Optional, Tuple, Union

from SPARQLWrapper.Wrapper import JSON, SELECT, QueryResult
from SPARQLWrapper.Wrapper import SPARQLWrapper as SW


######################################################################################


@@ -66,15 +68,10 @@ def __init__(self, variable: str, binding: Dict[str, str]) -> None:
self.type = binding["type"]
self.lang = None
self.datatype = None
try:
with contextlib.suppress(Exception):
self.lang = binding["xml:lang"]
except:
# no lang is set
pass
try:
with contextlib.suppress(Exception):
self.datatype = binding["datatype"]
except:
pass

def __repr__(self) -> str:
cls = self.__class__.__name__
@@ -119,31 +116,16 @@ def __init__(self, retval: QueryResult):
self.fullResult = retval._convertJSON()
self.head = self.fullResult["head"]
self.variables: Optional[List[str]] = None
try:
with contextlib.suppress(Exception):
self.variables = self.fullResult["head"]["vars"]
except:
pass

self.bindings: List[Dict[str, Value]] = []
try:
with contextlib.suppress(Exception):
for b in self.fullResult["results"]["bindings"]:
# This is a single binding. It is a dictionary per variable; each value is a dictionary again
# that has to be converted into a Value instance
newBind = {}
# type error: Item "None" of "Union[List[str], Any, None]" has no attribute "__iter__" (not iterable)
for key in self.variables: # type: ignore [union-attr]
if key in b:
# there is a real binding for this key
newBind[key] = Value(key, b[key])
newBind = {key: Value(key, b[key]) for key in self.variables if key in b}
self.bindings.append(newBind)
except:
pass

self.askResult = False
try:
with contextlib.suppress(Exception):
self.askResult = self.fullResult["boolean"]
except:
pass

def getValues(self, key: str) -> Optional[List[Value]]:
"""A shorthand for the retrieval of all bindings for a single key. It is
@@ -156,7 +138,7 @@ def getValues(self, key: str) -> Optional[List[Value]]:
"""
try:
return [b[key] for b in self[key]]
except:
except Exception:
return []

def __contains__(self, key: Union[str, List[str], Tuple[str]]) -> bool:
@@ -180,21 +162,17 @@ def __contains__(self, key: Union[str, List[str], Tuple[str]]) -> bool:
return False
for b in self.bindings:
# try to find a binding where all key elements are present
if False in [k in b for k in key]:
# this is not a binding for the key combination, move on...
continue
else:
if False not in [k in b for k in key]:
# yep, this one is good!
return True
return False
else:
# type error: Unsupported right operand type for in ("Optional[List[str]]")
if key not in self.variables: # type: ignore [operator]
return False
for b in self.bindings:
if key in b:
return True
return False
return False

def __getitem__(self, key: Union[slice, str, List[str]]) -> List[Dict[str, Value]]:
"""Emulation of the ``obj[key]`` operator. Slice notation is also available.
@@ -222,18 +200,18 @@ def _checkKeys(keys: Union[List[Any], Tuple[Any, ...]]) -> bool:
for k in keys:
# type error: Unsupported right operand type for in ("Optional[List[str]]")
if (
not isinstance(k, str)
or k not in self.variables # type: ignore [operator]
not isinstance(k, str)
or k not in self.variables # type: ignore [operator]
):
return False
return True

def _nonSliceCase(
key: Union[
str,
List[Any],
Tuple[Any],
]
key: Union[
str,
List[Any],
Tuple[Any],
]
) -> Union[List[Any], bool, Tuple[Any]]:
# type error: Unsupported right operand type for in ("Optional[List[str]]")
if isinstance(key, str) and key != "" and key in self.variables: # type: ignore[operator]
@@ -273,7 +251,7 @@ def _nonSliceCase(
# if we got that far, we should be all right!
retval.append(b)
# if retval is of zero length, no hit; an exception should be raised to stay within the python style
if len(retval) == 0:
if not retval:
raise IndexError
return retval

@@ -330,7 +308,7 @@ def setReturnFormat(self, format: Optional[str]) -> None:
"""
pass

def query(self) -> Union[Bindings, QueryResult]: # type: ignore[override]
def query(self) -> Union[Bindings, QueryResult]: # type: ignore[override]
"""
Execute the query and do an automatic conversion.

@@ -345,13 +323,10 @@ def query(self) -> Union[Bindings, QueryResult]: # type: ignore[override]
"""
res = super(SPARQLWrapper2, self).query()

if self.queryType == SELECT:
return Bindings(res)
else:
return res
return Bindings(res) if self.queryType == SELECT else res

def queryAndConvert( # type: ignore[override]
self,
self,
) -> Union[Union[Bindings, QueryResult], QueryResult.ConvertResult]:
"""This is here to override the inherited method; it is equivalent to :class:`query`.

436 changes: 216 additions & 220 deletions SPARQLWrapper/Wrapper.py

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions SPARQLWrapper/__init__.py
Original file line number Diff line number Diff line change
@@ -3,8 +3,8 @@
"""
**SPARQLWrapper** is a simple Python wrapper around a `SPARQL <https://www.w3.org/TR/sparql11-overview/>`_ service to
remotelly execute your queries. It helps in creating the query
invokation and, possibly, convert the result into a more manageable
remotely execute your queries. It helps in creating the query
invocation and, possibly, convert the result into a more manageable
format.
"""
17 changes: 9 additions & 8 deletions SPARQLWrapper/sparql_dataframe.py
Original file line number Diff line number Diff line change
@@ -16,7 +16,7 @@ class QueryException(Exception):


def get_sparql_dataframe_orig(
endpoint: str, query: Union[str, bytes]
endpoint: str, query: Union[str, bytes]
) -> "pd.DataFrame":
"""copy paste from: https://github.com/lawlesst/sparql-dataframe"""
# pandas inside to avoid requiring it
@@ -28,15 +28,17 @@ def get_sparql_dataframe_orig(
raise QueryException("Only SPARQL SELECT queries are supported.")
sparql.setReturnFormat(CSV)
results = sparql.query().convert()
if isinstance(results, bytes):
_csv = io.StringIO(results.decode("utf-8"))
return pd.read_csv(_csv, sep=",")
else:

if not isinstance(results, bytes):
raise TypeError(type(results))

_csv = io.StringIO(results.decode("utf-8"))

return pd.read_csv(_csv, sep=",")


def get_sparql_typed_dict(
endpoint: str, query: Union[str, bytes]
endpoint: str, query: Union[str, bytes]
) -> List[Dict[str, Value]]:
"""modified from: https://github.com/lawlesst/sparql-dataframe"""
# pandas inside to avoid requiring it
@@ -70,5 +72,4 @@ def get_sparql_dataframe(endpoint: str, query: Union[str, bytes]) -> "pd.DataFra

d = get_sparql_typed_dict(endpoint, query)
# TODO: will nan fill somehow, make more strict if there is way of getting the nan types from rdflib
df = pd.DataFrame(d)
return df
return pd.DataFrame(d)