added snippet interface and httpclient

This commit is contained in:
2021-05-31 21:18:25 +02:00
parent 6d207c1db9
commit a1856a68e5
8 changed files with 257 additions and 50 deletions

84
scilog/httpclient.py Normal file
View File

@ -0,0 +1,84 @@
import requests
import functools
import json
from abc import ABC, abstractmethod
from .authclient import AuthMixin, AuthError, HEADER_JSON
def authenticated(func):
@functools.wraps(func)
def authenticated_call(*args, **kwargs):
if not issubclass(type(args[0]), HttpClient):
raise AttributeError("First argument must be an instance of HttpClient")
if "headers" in kwargs:
kwargs["headers"]["Authorization"] = args[0].token
else:
kwargs["headers"] = {}
kwargs["headers"]["Authorization"] = args[0].token
return func(*args, **kwargs)
return authenticated_call
class HttpClient(AuthMixin):
def __init__(self, address):
self.address = address
self._verify_certificate = True
super().__init__(address)
def authenticate(self, username, password):
auth_payload = {
"principal": username,
"password": password
}
res = self._login(auth_payload, HEADER_JSON)
try:
token = "Bearer " + res["token"]
except KeyError as e:
raise AuthError(res) from e
else:
return token
@authenticated
def get_request(self, url, params=None, headers=None, timeout=10):
response = requests.get(url, params=params, headers=headers, timeout=timeout, verify=self._verify_certificate)
if response.ok:
return response.json()
else:
if response.reason == "Unauthorized":
self.config.delete()
self._retrieve_token()
raise response.raise_for_status()
else:
raise response.raise_for_status()
@authenticated
def post_request(self, url, payload=None, headers=None, timeout=10):
response = requests.post(url, json=payload, headers=headers, timeout=timeout, verify=self._verify_certificate).json()
return response
def _login(self, payload=None, headers=None, timeout=10):
return requests.post(self.address + "/users/login", json=payload, headers=headers, timeout=timeout, verify=self._verify_certificate).json()
def typename(self, obj):
return type(obj).__name__
@staticmethod
def make_filter(where:dict=None, limit:int=0, skip:int=0, fields:dict=None, include:dict=None, order:list=None):
filt = dict()
if where is not None:
items = [{k: v} for k, v in where.items()]
filt["where"] = {"and": items}
if limit > 0:
filt["limit"] = limit
if skip > 0:
filt["skip"] = skip
if fields is not None:
filt["fields"] = include
if order is not None:
filt["order"] = order
filt = json.dumps(filt)
return {"filter": filt}