This repository has been archived by the owner on Sep 18, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 151d613
Showing
12 changed files
with
870 additions
and
0 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# Obelisk Python Client | ||
|
||
Client library for the [Obelisk project](https://obelisk.ilabt.imec.be). | ||
|
||
## Example | ||
|
||
```python | ||
from obelisk import Obelisk, ObeliskPrecisions | ||
|
||
obe = Obelisk(base_url="https://obelisk.ilabt.imec.be", | ||
client_id="CLIENT_ID", | ||
client_secret="CLIENT_SECRET", | ||
scope_id="SCOPE_ID", | ||
precision=ObeliskPrecisions.MILLISECONDS) | ||
|
||
data = [ | ||
[1569369600000, 'temperature', 'aaaaaaaaa', 0] | ||
] | ||
|
||
obe.send_to_obelisk(data) | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# from ObeliskClient import Obelisk, ObeliskError | ||
from obelisk.obeliskclient import Obelisk, ObeliskError, ObeliskPrecisions | ||
|
||
import logging | ||
from logging import NullHandler | ||
|
||
logging.getLogger(__name__).addHandler(NullHandler()) | ||
|
||
__all__ = [ | ||
Obelisk, | ||
ObeliskError, | ||
ObeliskPrecisions | ||
] | ||
|
||
__version__ = '0.0.1' |
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
import logging | ||
from datetime import datetime, timedelta, timezone | ||
from enum import Enum | ||
|
||
import requests | ||
from requests.auth import HTTPBasicAuth | ||
|
||
import backoff | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
class ObeliskError(requests.exceptions.HTTPError): | ||
pass | ||
|
||
|
||
class ObeliskPrecisions(Enum): | ||
MILLISECONDS = 1 | ||
MICROSECONDS = 2 | ||
SECONDS = 3 | ||
|
||
|
||
obelisk_precisions = { | ||
ObeliskPrecisions.MILLISECONDS: 'milliseconds', | ||
ObeliskPrecisions.MICROSECONDS: 'microseconds', | ||
ObeliskPrecisions.SECONDS: 'seconds', | ||
} | ||
|
||
|
||
retry_timeout = backoff.on_exception( | ||
wait_gen=backoff.expo, | ||
exception=( | ||
ObeliskError, | ||
requests.exceptions.Timeout, | ||
requests.exceptions.ConnectionError | ||
), | ||
max_tries=5, | ||
) | ||
|
||
|
||
class Obelisk: | ||
def __init__(self, base_url, client_id, client_secret, scope_id, version='v2', precision=ObeliskPrecisions.MICROSECONDS): | ||
self._base_url = base_url | ||
self._client_id = client_id | ||
self._client_secret = client_secret | ||
self._scope_id = scope_id | ||
self._version = version | ||
self._precision = precision | ||
self._rpt_token = self.__request_rpt_token() | ||
self._rpt_refresh_token = None | ||
self._rpt_refresh_token_expire_date = None | ||
|
||
@retry_timeout | ||
def __request_access_token(self): | ||
headers = {'Content-Type': 'application/x-www-form-urlencoded'} | ||
body = 'grant_type=client_credentials' | ||
r = requests.post("{}/auth/realms/idlab-iot/protocol/openid-connect/token".format(self._base_url), data=body, | ||
auth=HTTPBasicAuth(self._client_id, self._client_secret), headers=headers, timeout=10) | ||
r.raise_for_status() | ||
message = r.json() | ||
return message['access_token'] | ||
|
||
@retry_timeout | ||
def __request_rpt_token(self): | ||
access_token = self.__request_access_token() | ||
headers = { | ||
'Authorization': 'Bearer {}'.format(access_token), | ||
'Content-Type': 'application/x-www-form-urlencoded' | ||
|
||
} | ||
payload = { | ||
'grant_type': 'urn:ietf:params:oauth:grant-type:uma-ticket', | ||
'audience': 'policy-enforcer', | ||
} | ||
r = requests.post("{}/auth/realms/idlab-iot/protocol/openid-connect/token".format(self._base_url), data=payload, | ||
headers=headers, timeout=10) | ||
r.raise_for_status() | ||
message = r.json() | ||
self._rpt_token = message['access_token'] | ||
self._rpt_refresh_token = message['refresh_token'] | ||
self._rpt_refresh_token_expire_date = datetime.utcnow( | ||
) + timedelta(seconds=message['refresh_expires_in']) | ||
|
||
@retry_timeout | ||
def __refresh_rpt_token(self): | ||
headers = {'Content-Type': 'application/x-www-form-urlencoded'} | ||
payload = { | ||
'grant_type': 'refresh_token', | ||
'refresh_token': self._rpt_refresh_token, | ||
'client_id': self._client_id, | ||
'client_secret': self._client_secret, | ||
} | ||
r = requests.post("{}/auth/realms/idlab-iot/protocol/openid-connect/token".format( | ||
self._base_url), headers=headers, data=payload, timeout=10) | ||
r.raise_for_status() | ||
message = r.json() | ||
self._rpt_token = message['access_token'] | ||
self._rpt_refresh_token = message['refresh_token'] | ||
self._rpt_refresh_token_expire_date = datetime.utcnow( | ||
) + timedelta(seconds=message['refresh_expires_in']) | ||
|
||
@retry_timeout | ||
def send_to_obelisk(self, data, refresh_rpt=False): | ||
if refresh_rpt: | ||
if not self._rpt_refresh_token_expire_date or self._rpt_refresh_token_expire_date < datetime.utcnow(): | ||
self.__request_rpt_token() | ||
else: | ||
self.__refresh_rpt_token() | ||
headers = {'Content-Type': 'application/json', | ||
'Authorization': 'Bearer {}'.format(self._rpt_token)} | ||
url = "{}/api/{}/scopes/{}/ingest?precision={}".format( | ||
self._base_url, self._version, self._scope_id, obelisk_precisions[self._precision]) | ||
resp = requests.post(url, json=data, headers=headers, timeout=10) | ||
if resp.status_code == 403 or resp.status_code == 401: | ||
logger.debug("Requesting/renewing RPT token") | ||
self.send_to_obelisk(data, refresh_rpt=True) | ||
else: | ||
resp.raise_for_status() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
Metadata-Version: 2.1 | ||
Name: obelisk-client | ||
Version: 0.0.1 | ||
Summary: Client library for Obelisk. | ||
Home-page: https://github.com/tengu-team/obelisk-client | ||
Author: Sander Borny | ||
Author-email: [email protected] | ||
License: UNKNOWN | ||
Description: # Obelisk Python Client | ||
|
||
Client library for the [Obelisk project](https://obelisk.ilabt.imec.be). | ||
Platform: UNKNOWN | ||
Classifier: Natural Language :: English | ||
Classifier: Programming Language :: Python :: 3 | ||
Classifier: Programming Language :: Python :: 3.5 | ||
Classifier: License :: OSI Approved :: GNU Affero General Public License v3 | ||
Requires-Python: >=3.5 | ||
Description-Content-Type: text/markdown |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
README.md | ||
setup.py | ||
obelisk/__init__.py | ||
obelisk/obeliskclient.py | ||
obelisk_client.egg-info/PKG-INFO | ||
obelisk_client.egg-info/SOURCES.txt | ||
obelisk_client.egg-info/dependency_links.txt | ||
obelisk_client.egg-info/requires.txt | ||
obelisk_client.egg-info/top_level.txt |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
requests | ||
backoff |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
obelisk |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import setuptools | ||
|
||
with open("README.md", "r") as fh: | ||
long_description = fh.read() | ||
|
||
setuptools.setup( | ||
name="obelisk-client", | ||
version="0.0.1", | ||
author="Sander Borny", | ||
author_email="[email protected]", | ||
description="Client library for Obelisk.", | ||
long_description=long_description, | ||
long_description_content_type="text/markdown", | ||
url="https://github.com/IBCNServices/obelisk-python", | ||
packages=setuptools.find_packages(), | ||
classifiers=[ | ||
"Natural Language :: English", | ||
"Programming Language :: Python :: 3", | ||
"Programming Language :: Python :: 3.5", | ||
"License :: OSI Approved :: GNU Affero General Public License v3", | ||
], | ||
install_requires=["requests", "backoff"], | ||
python_requires='>=3.5', | ||
) |