2018-06-14 13:14:23 +00:00
|
|
|
from inspect import isclass
|
|
|
|
from typing import Any, Dict, Iterable, Tuple, Type, Union
|
2018-05-11 16:58:48 +00:00
|
|
|
|
2018-04-27 17:16:43 +00:00
|
|
|
from flask import Response
|
|
|
|
from werkzeug.exceptions import HTTPException
|
|
|
|
|
2018-06-14 13:14:23 +00:00
|
|
|
from ereuse_devicehub.resources import models, schemas
|
2018-06-10 16:47:49 +00:00
|
|
|
from ereuse_utils.test import JSON
|
2018-04-10 15:06:39 +00:00
|
|
|
from teal.client import Client as TealClient
|
2018-05-16 13:23:48 +00:00
|
|
|
from teal.marshmallow import ValidationError
|
2018-04-10 15:06:39 +00:00
|
|
|
|
|
|
|
|
|
|
|
class Client(TealClient):
|
2018-05-16 13:23:48 +00:00
|
|
|
"""A client suited for Devicehub main usage."""
|
|
|
|
|
|
|
|
def __init__(self, application,
|
|
|
|
response_wrapper=None,
|
|
|
|
use_cookies=False,
|
2018-04-27 17:16:43 +00:00
|
|
|
allow_subdomain_redirects=False):
|
|
|
|
super().__init__(application, response_wrapper, use_cookies, allow_subdomain_redirects)
|
|
|
|
|
2018-05-16 13:23:48 +00:00
|
|
|
def open(self,
|
|
|
|
uri: str,
|
2018-06-14 13:14:23 +00:00
|
|
|
res: Union[str, Type[Union[models.Thing, schemas.Thing]]] = None,
|
2018-05-16 13:23:48 +00:00
|
|
|
status: Union[int, Type[HTTPException], Type[ValidationError]] = 200,
|
2018-05-30 10:49:40 +00:00
|
|
|
query: Iterable[Tuple[str, Any]] = tuple(),
|
2018-05-16 13:23:48 +00:00
|
|
|
accept=JSON,
|
|
|
|
content_type=JSON,
|
|
|
|
item=None,
|
|
|
|
headers: dict = None,
|
|
|
|
token: str = None,
|
2018-06-10 16:47:49 +00:00
|
|
|
**kw) -> Tuple[Union[Dict[str, Any], str], Response]:
|
2018-06-14 13:14:23 +00:00
|
|
|
if isclass(res) and issubclass(res, (models.Thing, schemas.Thing)):
|
|
|
|
res = res.t
|
2018-05-11 16:58:48 +00:00
|
|
|
return super().open(uri, res, status, query, accept, content_type, item, headers, token,
|
|
|
|
**kw)
|
|
|
|
|
2018-05-16 13:23:48 +00:00
|
|
|
def get(self,
|
|
|
|
uri: str = '',
|
2018-06-14 13:14:23 +00:00
|
|
|
res: Union[Type[Union[models.Thing, schemas.Thing]], str] = None,
|
2018-05-30 10:49:40 +00:00
|
|
|
query: Iterable[Tuple[str, Any]] = tuple(),
|
2018-05-16 13:23:48 +00:00
|
|
|
status: Union[int, Type[HTTPException], Type[ValidationError]] = 200,
|
|
|
|
item: Union[int, str] = None,
|
|
|
|
accept: str = JSON,
|
|
|
|
headers: dict = None,
|
|
|
|
token: str = None,
|
2018-06-10 16:47:49 +00:00
|
|
|
**kw) -> Tuple[Union[Dict[str, Any], str], Response]:
|
2018-05-11 16:58:48 +00:00
|
|
|
return super().get(uri, res, query, status, item, accept, headers, token, **kw)
|
|
|
|
|
2018-05-16 13:23:48 +00:00
|
|
|
def post(self,
|
|
|
|
data: str or dict,
|
|
|
|
uri: str = '',
|
2018-06-14 13:14:23 +00:00
|
|
|
res: Union[Type[Union[models.Thing, schemas.Thing]], str] = None,
|
2018-05-30 10:49:40 +00:00
|
|
|
query: Iterable[Tuple[str, Any]] = tuple(),
|
2018-05-16 13:23:48 +00:00
|
|
|
status: Union[int, Type[HTTPException], Type[ValidationError]] = 201,
|
|
|
|
content_type: str = JSON,
|
|
|
|
accept: str = JSON,
|
|
|
|
headers: dict = None,
|
|
|
|
token: str = None,
|
2018-06-10 16:47:49 +00:00
|
|
|
**kw) -> Tuple[Union[Dict[str, Any], str], Response]:
|
2018-05-11 16:58:48 +00:00
|
|
|
return super().post(data, uri, res, query, status, content_type, accept, headers, token,
|
|
|
|
**kw)
|
|
|
|
|
2018-04-27 17:16:43 +00:00
|
|
|
def login(self, email: str, password: str):
|
|
|
|
assert isinstance(email, str)
|
|
|
|
assert isinstance(password, str)
|
|
|
|
return self.post({'email': email, 'password': password}, '/users/login', status=200)
|
|
|
|
|
2018-06-10 16:47:49 +00:00
|
|
|
def get_many(self,
|
2018-06-14 13:14:23 +00:00
|
|
|
res: Union[Type[Union[models.Thing, schemas.Thing]], str],
|
2018-06-15 13:31:03 +00:00
|
|
|
resources: Iterable[Union[dict, int]],
|
2018-06-10 16:47:49 +00:00
|
|
|
key: str = None,
|
|
|
|
**kw) -> Iterable[Union[Dict[str, Any], str]]:
|
|
|
|
"""Like :meth:`.get` but with many resources."""
|
|
|
|
return (
|
2018-06-15 13:31:03 +00:00
|
|
|
self.get(res=res, item=r[key] if key else r, **kw)[0]
|
2018-06-10 16:47:49 +00:00
|
|
|
for r in resources
|
|
|
|
)
|
|
|
|
|
2018-04-27 17:16:43 +00:00
|
|
|
|
|
|
|
class UserClient(Client):
|
|
|
|
"""
|
|
|
|
A client that identifies all of its requests with a specific user.
|
|
|
|
|
|
|
|
It will automatically perform login on the first request.
|
|
|
|
"""
|
|
|
|
|
|
|
|
def __init__(self, application,
|
|
|
|
email: str,
|
|
|
|
password: str,
|
|
|
|
response_wrapper=None,
|
|
|
|
use_cookies=False,
|
|
|
|
allow_subdomain_redirects=False):
|
|
|
|
super().__init__(application, response_wrapper, use_cookies, allow_subdomain_redirects)
|
|
|
|
self.email = email # type: str
|
|
|
|
self.password = password # type: str
|
|
|
|
self.user = None # type: dict
|
|
|
|
|
2018-05-16 13:23:48 +00:00
|
|
|
def open(self,
|
|
|
|
uri: str,
|
2018-06-14 13:14:23 +00:00
|
|
|
res: Union[str, Type[Union[models.Thing, schemas.Thing]]] = None,
|
2018-05-16 13:23:48 +00:00
|
|
|
status: int or HTTPException = 200,
|
2018-05-30 10:49:40 +00:00
|
|
|
query: Iterable[Tuple[str, Any]] = tuple(),
|
2018-05-16 13:23:48 +00:00
|
|
|
accept=JSON,
|
|
|
|
content_type=JSON,
|
|
|
|
item=None,
|
|
|
|
headers: dict = None,
|
|
|
|
token: str = None,
|
2018-06-10 16:47:49 +00:00
|
|
|
**kw) -> Tuple[Union[Dict[str, Any], str], Response]:
|
2018-04-27 17:16:43 +00:00
|
|
|
return super().open(uri, res, status, query, accept, content_type, item, headers,
|
|
|
|
self.user['token'] if self.user else token, **kw)
|