act365 1.0.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- act365/__init__.py +0 -0
- act365/client.py +74 -0
- act365-1.0.2.dist-info/METADATA +15 -0
- act365-1.0.2.dist-info/RECORD +6 -0
- act365-1.0.2.dist-info/WHEEL +4 -0
- act365-1.0.2.dist-info/entry_points.txt +3 -0
act365/__init__.py
ADDED
|
File without changes
|
act365/client.py
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from time import sleep
|
|
3
|
+
|
|
4
|
+
import httpx
|
|
5
|
+
|
|
6
|
+
logging.basicConfig(filename="act365.log", filemode="w", level=logging.INFO)
|
|
7
|
+
LOG = logging.getLogger("act635")
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class Act365Auth(httpx.Auth):
|
|
11
|
+
requires_response_body = True
|
|
12
|
+
|
|
13
|
+
def __init__(
|
|
14
|
+
self,
|
|
15
|
+
username,
|
|
16
|
+
password,
|
|
17
|
+
grant_type="password",
|
|
18
|
+
url="https://userapi.act365.eu/api",
|
|
19
|
+
):
|
|
20
|
+
|
|
21
|
+
if username is None or password is None:
|
|
22
|
+
raise Exception
|
|
23
|
+
self.username = username
|
|
24
|
+
self.password = password
|
|
25
|
+
self.grant_type = grant_type
|
|
26
|
+
self.url = url
|
|
27
|
+
|
|
28
|
+
self.access_token = None
|
|
29
|
+
|
|
30
|
+
def get_token(self):
|
|
31
|
+
data = {
|
|
32
|
+
"grant_type": self.grant_type,
|
|
33
|
+
"username": self.username,
|
|
34
|
+
"password": self.password,
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
while self.access_token is None:
|
|
38
|
+
# Set Content-Type: application/x-www-form-urlencoded via headers
|
|
39
|
+
# as apiary complains about case mismatch
|
|
40
|
+
response = httpx.post(
|
|
41
|
+
self.url + "/account/login",
|
|
42
|
+
data=data,
|
|
43
|
+
timeout=90,
|
|
44
|
+
headers={"Content-Type": "application/x-www-form-urlencoded"},
|
|
45
|
+
)
|
|
46
|
+
LOG.debug(f"Response: {response.status_code} {response.text}")
|
|
47
|
+
LOG.info(f"Response Headers: {response.headers}")
|
|
48
|
+
|
|
49
|
+
if response.status_code == httpx.codes.OK:
|
|
50
|
+
# "token_type":"bearer","expires_in":86399,
|
|
51
|
+
# ".issued":"Wed, 24 Jul 2024 11:37:56 GMT",
|
|
52
|
+
# ".expires":"Thu, 25 Jul 2024 11:37:56 GMT"}'
|
|
53
|
+
self.access_token = response.json().get("access_token", None)
|
|
54
|
+
self.token_type = response.json().get("token_type", None)
|
|
55
|
+
self.expires_in = response.json().get("expires_in", None)
|
|
56
|
+
self.issued = response.json().get(".issued", None)
|
|
57
|
+
self.expires = response.json().get(".expires", None)
|
|
58
|
+
elif response.status_code == httpx.codes.TOO_MANY_REQUESTS:
|
|
59
|
+
sleep(65)
|
|
60
|
+
else:
|
|
61
|
+
raise Exception
|
|
62
|
+
|
|
63
|
+
def auth_flow(self, request):
|
|
64
|
+
if self.access_token is None:
|
|
65
|
+
self.get_token()
|
|
66
|
+
|
|
67
|
+
request.headers["Authorization"] = "Bearer " + self.access_token
|
|
68
|
+
response = yield request
|
|
69
|
+
|
|
70
|
+
if response.status_code == 401:
|
|
71
|
+
self.get_token()
|
|
72
|
+
request.headers["Authorization"] = "Bearer " + self.access_token
|
|
73
|
+
|
|
74
|
+
yield request
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: act365
|
|
3
|
+
Version: 1.0.2
|
|
4
|
+
Summary: Python Client for [ACT365](https://www.act365.eu/)
|
|
5
|
+
Author: Simon McCartney
|
|
6
|
+
Author-email: simon@mccartney.ie
|
|
7
|
+
Requires-Python: >=3.12,<4.0
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
11
|
+
Requires-Dist: httpx (>=0.27.0,<0.28.0)
|
|
12
|
+
Requires-Dist: json5 (==0.9.25)
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
|
|
15
|
+
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
act365/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
act365/client.py,sha256=vH2oSaXJLQWRKNl0oPuWGCvWU54ANcqkKVqEu5fni7Y,2466
|
|
3
|
+
act365-1.0.2.dist-info/METADATA,sha256=ZlnTNFNQf5y0ahCeuW8D1YlUPPurWY0GpAUJHA4Gc_A,460
|
|
4
|
+
act365-1.0.2.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
|
5
|
+
act365-1.0.2.dist-info/entry_points.txt,sha256=6ahC5jfJv-eC9gvbKriGTRZGABm-DSlW6GQY8tLCMMo,47
|
|
6
|
+
act365-1.0.2.dist-info/RECORD,,
|