Skip to content

Commit

Permalink
Merge pull request #62 from klavinslab/sample-property-fixes
Browse files Browse the repository at this point in the history
Sample property fixes
  • Loading branch information
jvrana authored Sep 14, 2018
2 parents 1207c24 + 392269d commit d83deea
Show file tree
Hide file tree
Showing 11 changed files with 312 additions and 158 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -163,3 +163,4 @@ doctest

/.tox/

/tests/archived/temp/**/*
79 changes: 28 additions & 51 deletions pydent/aqhttp.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,14 @@
"""

import json
import re

import requests

from pydent.exceptions import (TridentRequestError, TridentLoginError,
from pydent.exceptions import (TridentRequestError, TridentLoginError, AquariumError,
TridentTimeoutError, TridentJSONDataIncomplete)
from pydent.utils import url_build


# TODO: Replace request history with save_attr in models?
class AqHTTP(object):
"""
Defines a session/connection to Aquarium.
Expand All @@ -46,25 +44,22 @@ def __init__(self, login, password, aquarium_url):
"""
self.login = login
self.aquarium_url = aquarium_url
self._requests_session = None
self.timeout = self.__class__.TIMEOUT
self._login(login, password)
self.request_history = {}

@staticmethod
def create_session_json(login, password):
"""Formats login information for aquarium"""
return {
"session": {
"login": login,
"password": password
}
}

@property
def url(self):
"""An alias of aquarium_url"""
return self.aquarium_url

@staticmethod
def create_session_json(login, password):
return {"session": {
"login": login,
"password": password
}}

def _login(self, login, password):
"""
Login to aquarium and saves header as a requests.Session()
Expand All @@ -75,7 +70,9 @@ def _login(self, login, password):
json=session_data, timeout=self.timeout)

cookies = dict(res.cookies)
if not any(["remember_token" in k for k in cookies]):

# Check for remember token
if not any(["remember_token" in k for k in dict(res.cookies)]):
raise TridentLoginError(
"Authentication error. Remember token not found in login request."
" Contact developers."
Expand All @@ -85,21 +82,19 @@ def _login(self, login, password):
for c in dict(cookies):
if "remember_token" in c:
cookies["remember_token"] = cookies[c]
self.cookies = cookies
# TODO: do we remove the session cookie to handle asynchrounous requests?
self.cookies = dict(cookies)
except requests.exceptions.MissingSchema as error:
raise TridentLoginError(
"Aquairum URL {0} incorrectly formatted. {1}".format(
self.aquarium_url, error.args[0]))
except requests.exceptions.ConnectTimeout:
raise TridentTimeoutError(
"Aquarium took too long to respond during login. Make sure "
"the url {} is correct. Alternatively, use Session.set_timeout"
"Either Aquarium took too long to respond during login or you internet"
" connection is slow. Make sure the url {} is correct. Alternatively,"
" use Session.set_timeout"
" to increase the request timeout.".format(self.aquarium_url))

def clear_history(self):
"""Clears the request history."""
self.request_history = {}

@staticmethod
def _serialize_request(url, method, body):
return json.dumps({
Expand All @@ -108,8 +103,7 @@ def _serialize_request(url, method, body):
"body": body
}, sort_keys=True)

def request(self, method, path, timeout=None,
get_from_history_ok=False, allow_none=True, **kwargs):
def request(self, method, path, timeout=None, allow_none=True, **kwargs):
"""
Performs a http request.
Expand All @@ -120,9 +114,6 @@ def request(self, method, path, timeout=None,
:param timeout: time in seconds to process request before raising
exception
:type timeout: int
:param get_from_history_ok: whether its ok to return previously found
request from history (default=False)
:type get_from_history_ok: boolean
:param allow_none: if False will raise error when json_data
contains a None or null value (default: True)
:type allow_none: boolean
Expand All @@ -142,12 +133,9 @@ def request(self, method, path, timeout=None,
if 'json' in kwargs:
body = kwargs['json']

# get result from history (if ok) otherwise, make a http request;
# save result to history
key = self._serialize_request(url, method, body)
result = None
if get_from_history_ok:
result = self.request_history.get(key, None)

if result is None:
result = requests.request(
method,
Expand All @@ -156,18 +144,20 @@ def request(self, method, path, timeout=None,
timeout=timeout,
cookies=self.cookies,
**kwargs)
self.request_history[key] = result

return self._response_to_json(result)

def _response_to_json(self, result):
"""
Turns :class:`requests.Request` instance into a json.
Raises TridentRequestError if an error occurs.
"""

if result.url == url_build(self.aquarium_url, "signin"):
msg = "There was an error with authenticating the request. Aquarium " + \
"re-routed to the sign-in page."
raise TridentRequestError(msg, result)

try:
result_json = result.json()
except json.JSONDecodeError:
Expand All @@ -176,7 +166,9 @@ def _response_to_json(self, result):
raise TridentRequestError(msg, result)
if result_json and 'errors' in result_json:
errors = result_json['errors']
msg = "Error response:\n{}".format("\n".join(errors))
if isinstance(errors, list):
errors = "\n".join(errors)
msg = "Error response:\n{}".format(errors)
raise TridentRequestError(msg, result)
return result_json

Expand All @@ -190,8 +182,7 @@ def _disallow_null_in_json(json_data):
raise TridentJSONDataIncomplete(
"JSON data {} contains a null value.".format(json_data))

def post(self, path, json_data=None, timeout=None,
get_from_history_ok=False, allow_none=True, **kwargs):
def post(self, path, json_data=None, timeout=None, allow_none=True, **kwargs):
"""
Make a post request to the session
Expand All @@ -202,9 +193,6 @@ def post(self, path, json_data=None, timeout=None,
:param timeout: time in seconds to process request before raising
exception
:type timeout: int
:param get_from_history_ok: whether its ok to return previously found
request from history (default=False)
:type get_from_history_ok: boolean
:param allow_none: if False throw error if json_data contains a null
or None value (default True)
:type allow_none: boolean
Expand All @@ -214,11 +202,9 @@ def post(self, path, json_data=None, timeout=None,
:rtype: dict
"""
return self.request("post", path, json=json_data, timeout=timeout,
get_from_history_ok=get_from_history_ok,
allow_none=allow_none, **kwargs)

def put(self, path, json_data=None, timeout=None,
get_from_history_ok=False, allow_none=True, **kwargs):
def put(self, path, json_data=None, timeout=None, allow_none=True, **kwargs):
"""
Make a put request to the session
Expand All @@ -229,9 +215,6 @@ def put(self, path, json_data=None, timeout=None,
:param timeout: time in seconds to process request before raising
exception
:type timeout: int
:param get_from_history_ok: whether its ok to return previously found
request from history (default=False)
:type get_from_history_ok: boolean
:param allow_none: if False throw error when json_data contains a null
or None value (default True)
:type allow_none: boolean
Expand All @@ -241,11 +224,9 @@ def put(self, path, json_data=None, timeout=None,
:rtype: dict
"""
return self.request("put", path, json=json_data, timeout=timeout,
get_from_history_ok=get_from_history_ok,
allow_none=allow_none, **kwargs)

def get(self, path, timeout=None,
get_from_history_ok=False, allow_none=True, **kwargs):
def get(self, path, timeout=None, allow_none=True, **kwargs):
"""
Make a get request to the session
Expand All @@ -254,9 +235,6 @@ def get(self, path, timeout=None,
:param timeout: time in seconds to process request before raising
exception
:type timeout: int
:param get_from_history_ok: whether its ok to return previously found
request from history (default=False)
:type get_from_history_ok: boolean
:param allow_none: if False throw error when json_data contains a null
or None value (default: True)
:type allow_none: boolean
Expand All @@ -266,7 +244,6 @@ def get(self, path, timeout=None,
:rtype: dict
"""
return self.request("get", path, timeout=timeout,
get_from_history_ok=get_from_history_ok,
allow_none=allow_none, **kwargs)

def delete(self, path, timeout=None, **kwargs):
Expand Down
13 changes: 11 additions & 2 deletions pydent/aqsession.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,17 @@ def __init__(self, login, password, aquarium_url, name=None):

# initialize model interfaces
for model_name in allmodels:
setattr(self, model_name,
ModelInterface(model_name, self.__aqhttp, self))
self._register_interface(model_name)

def _register_interface(self, model_name):
# get model class f(e.g. "Sample")
model = ModelRegistry.get_model(model_name)

# get model interface from model class
model_interface = model.interface(self)

# set interface to session attribute (e.g. session.Sample calls Sample model interface)
setattr(self, model_name, model_interface)

def set_timeout(self, timeout_in_seconds):
"""Sets the request timeout."""
Expand Down
7 changes: 3 additions & 4 deletions pydent/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,11 @@
from requests.exceptions import RequestException, ConnectTimeout


class TridentRequestError(RequestException):
class TridentRequestError(IOError):
"""There was an ambiguous exception that occured handling your request."""
def __init__(self, message, response):
self.message = message
self.response = response

class AquariumError(IOError):
"""Aquarium raised an error"""

class TridentJSONDataIncomplete(RequestException):
"""JSON data contains a null value and may be incomplete."""
Expand Down
Loading

0 comments on commit d83deea

Please sign in to comment.