Skip to content
Snippets Groups Projects
Commit 33ff27f9 authored by Henrik tom Wörden's avatar Henrik tom Wörden
Browse files

MAINT: cosmetics and comments

parent ac261ec1
Branches
Tags
No related merge requests found
...@@ -24,26 +24,30 @@ ...@@ -24,26 +24,30 @@
# #
"""Connection to a CaosDB server.""" """Connection to a CaosDB server."""
from __future__ import absolute_import, print_function, unicode_literals from __future__ import absolute_import, print_function, unicode_literals
import logging
import ssl
import sys import sys
from builtins import str # pylint: disable=redefined-builtin from builtins import str # pylint: disable=redefined-builtin
from errno import EPIPE as BrokenPipe
from socket import error as SocketError
from caosdb.configuration import get_config
from caosdb.exceptions import (AuthorizationException, CaosDBException,
ClientErrorException, ConfigurationException,
ConnectionException, EntityDoesNotExistError,
LoginFailedException, ServerErrorException,
URITooLongException)
from .interface import CaosDBHTTPResponse, CaosDBServerConnection
from .streaminghttp import StreamingHTTPSConnection
from .utils import make_uri_path, parse_url, urlencode
try: try:
from urllib.parse import quote, urlparse from urllib.parse import quote, urlparse
except ImportError: except ImportError:
from urllib import quote from urllib import quote
from urlparse import urlparse from urlparse import urlparse
from errno import EPIPE as BrokenPipe
from socket import error as SocketError
import ssl
import logging
from caosdb.exceptions import (CaosDBException, LoginFailedException,
AuthorizationException, URITooLongException,
ConnectionException, ServerErrorException,
EntityDoesNotExistError, ClientErrorException,
ConfigurationException)
from caosdb.configuration import get_config
from .utils import urlencode, make_uri_path, parse_url
from .interface import CaosDBServerConnection, CaosDBHTTPResponse
from .streaminghttp import StreamingHTTPSConnection
# pylint: disable=missing-docstring # pylint: disable=missing-docstring
...@@ -106,14 +110,19 @@ class _DefaultCaosDBServerConnection(CaosDBServerConnection): ...@@ -106,14 +110,19 @@ class _DefaultCaosDBServerConnection(CaosDBServerConnection):
string. string.
**kwargs : **kwargs :
Any keyword arguments will be ignored. Any keyword arguments will be ignored.
TODO: Why are they allowed then?
Returns Returns
------- -------
TODO: What?
""" """
if headers is None: if headers is None:
headers = {} headers = {}
try: try:
self._http_con = StreamingHTTPSConnection( self._http_con = StreamingHTTPSConnection(
# TODO looks as if configure needs to be done first.
# That is however not assured.
host=self.setup_fields["host"], host=self.setup_fields["host"],
timeout=self.setup_fields["timeout"], timeout=self.setup_fields["timeout"],
context=self.setup_fields["context"], context=self.setup_fields["context"],
...@@ -124,6 +133,7 @@ class _DefaultCaosDBServerConnection(CaosDBServerConnection): ...@@ -124,6 +133,7 @@ class _DefaultCaosDBServerConnection(CaosDBServerConnection):
raise ConnectionException( raise ConnectionException(
"Connection failed. Network or server down? " + str(socket_err) "Connection failed. Network or server down? " + str(socket_err)
) )
return _WrappedHTTPResponse(self._http_con.getresponse()) return _WrappedHTTPResponse(self._http_con.getresponse())
def configure(self, **config): def configure(self, **config):
...@@ -148,18 +158,22 @@ class _DefaultCaosDBServerConnection(CaosDBServerConnection): ...@@ -148,18 +158,22 @@ class _DefaultCaosDBServerConnection(CaosDBServerConnection):
If no url has been specified, or if the CA certificate cannot be If no url has been specified, or if the CA certificate cannot be
loaded. loaded.
""" """
if "ssl_version" in config and config["cacert"] is not None: if "ssl_version" in config and config["cacert"] is not None:
ssl_version = getattr(ssl, config["ssl_version"]) ssl_version = getattr(ssl, config["ssl_version"])
else: else:
ssl_version = ssl.PROTOCOL_TLSv1 ssl_version = ssl.PROTOCOL_TLSv1
context = ssl.SSLContext(ssl_version) context = ssl.SSLContext(ssl_version)
context.verify_mode = ssl.CERT_REQUIRED context.verify_mode = ssl.CERT_REQUIRED
if config.get("ssl_insecure"): if config.get("ssl_insecure"):
print("Relaxed SSL mode.") print("Relaxed SSL mode.")
context.verify_mode = ssl.CERT_NONE context.verify_mode = ssl.CERT_NONE
if (not context.verify_mode == ssl.CERT_NONE and if (not context.verify_mode == ssl.CERT_NONE and
hasattr(context, "check_hostname")): hasattr(context, "check_hostname")):
context.check_hostname = True context.check_hostname = True
if ("cacert" in config and config["cacert"] is not None and if ("cacert" in config and config["cacert"] is not None and
config["cacert"]): config["cacert"]):
try: try:
...@@ -168,6 +182,7 @@ class _DefaultCaosDBServerConnection(CaosDBServerConnection): ...@@ -168,6 +182,7 @@ class _DefaultCaosDBServerConnection(CaosDBServerConnection):
raise ConnectionException("Could not load the cacert in" raise ConnectionException("Could not load the cacert in"
"`{}`: {}".format(config["cacert"], "`{}`: {}".format(config["cacert"],
exc)) exc))
if "url" in config: if "url" in config:
parsed_url = parse_url(config["url"]) parsed_url = parse_url(config["url"])
host = parsed_url.netloc host = parsed_url.netloc
...@@ -179,6 +194,7 @@ class _DefaultCaosDBServerConnection(CaosDBServerConnection): ...@@ -179,6 +194,7 @@ class _DefaultCaosDBServerConnection(CaosDBServerConnection):
"file.") "file.")
socket_proxy = None socket_proxy = None
if "socket_proxy" in config: if "socket_proxy" in config:
socket_proxy = config["socket_proxy"] socket_proxy = config["socket_proxy"]
...@@ -206,14 +222,16 @@ def _make_conf(*conf): ...@@ -206,14 +222,16 @@ def _make_conf(*conf):
A merged config dict. A merged config dict.
""" """
result = {} result = {}
for conf_dict in conf: for conf_dict in conf:
result.update(conf_dict) result.update(conf_dict)
return result return result
_DEFAULT_CONF = { _DEFAULT_CONF = {
"password_method": "plain", "password_method": "plain",
"implementation": _DefaultCaosDBServerConnection, "implementation": _DefaultCaosDBServerConnection,
"timeout": 210 "timeout": 210
} }
...@@ -253,6 +271,7 @@ def _get_authenticator(**config): ...@@ -253,6 +271,7 @@ def _get_authenticator(**config):
auth_provider = sys.modules[auth_module].get_authentication_provider() auth_provider = sys.modules[auth_module].get_authentication_provider()
auth_provider.configure(**config) auth_provider.configure(**config)
return auth_provider return auth_provider
except ImportError: except ImportError:
...@@ -294,6 +313,7 @@ def configure_connection(**kwargs): ...@@ -294,6 +313,7 @@ def configure_connection(**kwargs):
connection = _Connection.get_instance() connection = _Connection.get_instance()
connection.configure(**local_conf) connection.configure(**local_conf)
return connection return connection
...@@ -304,14 +324,17 @@ def get_connection(): ...@@ -304,14 +324,17 @@ def get_connection():
be called inside this function without arguments. be called inside this function without arguments.
""" """
connection = _Connection.get_instance() connection = _Connection.get_instance()
if connection.is_configured: if connection.is_configured:
return connection return connection
return configure_connection() return configure_connection()
def _handle_response_status(http_response): def _handle_response_status(http_response):
status = http_response.status status = http_response.status
if status == 200: if status == 200:
return return
...@@ -367,16 +390,19 @@ class _Connection(object): # pylint: disable=useless-object-inheritance ...@@ -367,16 +390,19 @@ class _Connection(object): # pylint: disable=useless-object-inheritance
def get_instance(cls): def get_instance(cls):
if cls.__instance is None: if cls.__instance is None:
cls.__instance = _Connection() cls.__instance = _Connection()
return cls.__instance return cls.__instance
def configure(self, **config): def configure(self, **config):
self.is_configured = True self.is_configured = True
if "implementation" not in config: if "implementation" not in config:
raise ConfigurationException( raise ConfigurationException(
"Missing CaosDBServerConnection implementation. You did not " "Missing CaosDBServerConnection implementation. You did not "
"specify an `implementation` for the connection.") "specify an `implementation` for the connection.")
try: try:
self._delegate_connection = config["implementation"]() self._delegate_connection = config["implementation"]()
if not isinstance(self._delegate_connection, if not isinstance(self._delegate_connection,
CaosDBServerConnection): CaosDBServerConnection):
raise TypeError("The `implementation` callable did not return " raise TypeError("The `implementation` callable did not return "
...@@ -388,12 +414,14 @@ class _Connection(object): # pylint: disable=useless-object-inheritance ...@@ -388,12 +414,14 @@ class _Connection(object): # pylint: disable=useless-object-inheritance
"instance of `CaosDBServerConnection` (e.g. a constructor " "instance of `CaosDBServerConnection` (e.g. a constructor "
"or a factory).", type_err) "or a factory).", type_err)
self._delegate_connection.configure(**config) self._delegate_connection.configure(**config)
if "password_method" not in config: if "password_method" not in config:
raise ConfigurationException("Missing password_method. You did " raise ConfigurationException("Missing password_method. You did "
"not specify a `password_method` for" "not specify a `password_method` for"
"the connection.") "the connection.")
self._authenticator = _get_authenticator( self._authenticator = _get_authenticator(
connection=self._delegate_connection, **config) connection=self._delegate_connection, **config)
if "auth_token" in config: if "auth_token" in config:
self._authenticator.auth_token = config["auth_token"] self._authenticator.auth_token = config["auth_token"]
...@@ -403,6 +431,7 @@ class _Connection(object): # pylint: disable=useless-object-inheritance ...@@ -403,6 +431,7 @@ class _Connection(object): # pylint: disable=useless-object-inheritance
path = make_uri_path(entity_uri_segments, query_dict) path = make_uri_path(entity_uri_segments, query_dict)
http_response = self._http_request(method="GET", path=path, **kwargs) http_response = self._http_request(method="GET", path=path, **kwargs)
return http_response return http_response
def delete(self, entity_uri_segments=None, query_dict=None, **kwargs): def delete(self, entity_uri_segments=None, query_dict=None, **kwargs):
...@@ -410,12 +439,14 @@ class _Connection(object): # pylint: disable=useless-object-inheritance ...@@ -410,12 +439,14 @@ class _Connection(object): # pylint: disable=useless-object-inheritance
http_response = self._http_request( http_response = self._http_request(
method="DELETE", path=path, **kwargs) method="DELETE", path=path, **kwargs)
return http_response return http_response
def update(self, entity_uri_segment, query_dict=None, **kwargs): def update(self, entity_uri_segment, query_dict=None, **kwargs):
path = make_uri_path(entity_uri_segment, query_dict) path = make_uri_path(entity_uri_segment, query_dict)
http_response = self._http_request(method="PUT", path=path, **kwargs) http_response = self._http_request(method="PUT", path=path, **kwargs)
return http_response return http_response
def activate_user(self, link): def activate_user(self, link):
...@@ -425,6 +456,7 @@ class _Connection(object): # pylint: disable=useless-object-inheritance ...@@ -425,6 +456,7 @@ class _Connection(object): # pylint: disable=useless-object-inheritance
query = fullurl.query query = fullurl.query
http_response = self._http_request( http_response = self._http_request(
method="GET", path=path + "?" + query) method="GET", path=path + "?" + query)
return http_response return http_response
def put_form_data(self, entity_uri_segment, params): def put_form_data(self, entity_uri_segment, params):
...@@ -446,6 +478,7 @@ class _Connection(object): # pylint: disable=useless-object-inheritance ...@@ -446,6 +478,7 @@ class _Connection(object): # pylint: disable=useless-object-inheritance
path=quote(path), path=quote(path),
body=body, body=body,
headers=headers) headers=headers)
return response return response
def insert(self, entity_uri_segment, query_dict=None, body=None, **kwargs): def insert(self, entity_uri_segment, query_dict=None, body=None, **kwargs):
...@@ -453,6 +486,7 @@ class _Connection(object): # pylint: disable=useless-object-inheritance ...@@ -453,6 +486,7 @@ class _Connection(object): # pylint: disable=useless-object-inheritance
http_response = self._http_request( http_response = self._http_request(
method="POST", path=path, body=body, **kwargs) method="POST", path=path, body=body, **kwargs)
return http_response return http_response
def download_file(self, path): def download_file(self, path):
...@@ -461,6 +495,7 @@ class _Connection(object): # pylint: disable=useless-object-inheritance ...@@ -461,6 +495,7 @@ class _Connection(object): # pylint: disable=useless-object-inheritance
try: try:
uri_segments = ["FileSystem"] uri_segments = ["FileSystem"]
uri_segments.extend(path.split("/")) uri_segments.extend(path.split("/"))
return self.retrieve(entity_uri_segments=uri_segments) return self.retrieve(entity_uri_segments=uri_segments)
except EntityDoesNotExistError: except EntityDoesNotExistError:
raise EntityDoesNotExistError("This file does not exist.") raise EntityDoesNotExistError("This file does not exist.")
...@@ -479,6 +514,7 @@ class _Connection(object): # pylint: disable=useless-object-inheritance ...@@ -479,6 +514,7 @@ class _Connection(object): # pylint: disable=useless-object-inheritance
except SocketError as e: except SocketError as e:
if e.errno != BrokenPipe: if e.errno != BrokenPipe:
raise raise
return self._retry_http_request(method=method, path=path, return self._retry_http_request(method=method, path=path,
headers=headers, body=body, headers=headers, body=body,
reconnect=False, reconnect=False,
...@@ -486,6 +522,7 @@ class _Connection(object): # pylint: disable=useless-object-inheritance ...@@ -486,6 +522,7 @@ class _Connection(object): # pylint: disable=useless-object-inheritance
except LoginFailedException: except LoginFailedException:
if kwargs.get("reconnect", True) is True: if kwargs.get("reconnect", True) is True:
self._login() self._login()
return self._retry_http_request(method=method, path=path, return self._retry_http_request(method=method, path=path,
headers=headers, body=body, headers=headers, body=body,
reconnect=False, reconnect=False,
...@@ -497,6 +534,7 @@ class _Connection(object): # pylint: disable=useless-object-inheritance ...@@ -497,6 +534,7 @@ class _Connection(object): # pylint: disable=useless-object-inheritance
if hasattr(body, "encode"): if hasattr(body, "encode"):
# python3 # python3
body = body.encode("utf-8") body = body.encode("utf-8")
if headers is None: if headers is None:
headers = {} headers = {}
self._authenticator.on_request(method=method, path=path, self._authenticator.on_request(method=method, path=path,
...@@ -511,4 +549,5 @@ class _Connection(object): # pylint: disable=useless-object-inheritance ...@@ -511,4 +549,5 @@ class _Connection(object): # pylint: disable=useless-object-inheritance
str(http_response.getheaders())) str(http_response.getheaders()))
_handle_response_status(http_response) _handle_response_status(http_response)
self._authenticator.on_response(http_response) self._authenticator.on_response(http_response)
return http_response return http_response
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment