trivialapi 0.0.1__tar.gz

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.
@@ -0,0 +1,37 @@
1
+ Metadata-Version: 2.1
2
+ Name: trivialapi
3
+ Version: 0.0.1
4
+ Summary: A trivial set of API bindings for the TODA payment API
5
+ Author-email: inaimathi <leo.zovic@gmail.com>
6
+ Project-URL: Homepage, https://github.com/inaimathi/pytoda
7
+ Project-URL: Issues, https://github.com/inaimathi/pytoda/issues
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.10
12
+ Description-Content-Type: text/markdown
13
+ Requires-Dist: requests
14
+
15
+ # TODA Micro
16
+
17
+ - A basic port of [this](https://github.com/TODAQmicro/payment-node) that doesn't suck too much.
18
+
19
+ ## Basic usage
20
+
21
+ ```
22
+ >>> from src.trivialapi.toda import core
23
+ <module 'src.trivialapi.toda.core'>
24
+ >>> tw = core.Twin.from_file("~/path/to/your/twin.json")
25
+ <src.trivialapi.toda.core.Twin object at 0x74622b7ed150>
26
+ >>> tw.hostname
27
+ '41a9cbc977c39bd3eb5a52a5924f8ef5.micro-staging.biz.todaq.net'
28
+ >>> tw.key
29
+ 'redacted'
30
+ >>> tw.mint(1000, minting_info="Precision 0 minting test")
31
+ {'result': 'success', 'files': ['419bfe67b7fafe0842813f13044d637775349d2b4df347639eccc6ec82093a8ecb'], 'root': '41a2099e84dd4690ea55774506d58ee6cf6ac9fe0c9806239ef6e251a6bc597641'}
32
+ >>> tw.balance()
33
+ [{'balance': 1000, 'quantity': 1000, 'files': ['419bfe67b7fafe0842813f13044d637775349d2b4df347639eccc6ec82093a8ecb'], 'fileValue': {'419bfe67b7fafe0842813f13044d637775349d2b4df347639eccc6ec82093a8ecb': 1000}, 'poptop': '419ccac82bcf1216a70929664cdeaa97bcc01deb87d190a0c7ce90e62d7b89a6bf', 'displayPrecision': 0, 'type': '41a2099e84dd4690ea55774506d58ee6cf6ac9fe0c9806239ef6e251a6bc597641'}]
34
+ ```
35
+
36
+
37
+
@@ -0,0 +1,23 @@
1
+ # TODA Micro
2
+
3
+ - A basic port of [this](https://github.com/TODAQmicro/payment-node) that doesn't suck too much.
4
+
5
+ ## Basic usage
6
+
7
+ ```
8
+ >>> from src.trivialapi.toda import core
9
+ <module 'src.trivialapi.toda.core'>
10
+ >>> tw = core.Twin.from_file("~/path/to/your/twin.json")
11
+ <src.trivialapi.toda.core.Twin object at 0x74622b7ed150>
12
+ >>> tw.hostname
13
+ '41a9cbc977c39bd3eb5a52a5924f8ef5.micro-staging.biz.todaq.net'
14
+ >>> tw.key
15
+ 'redacted'
16
+ >>> tw.mint(1000, minting_info="Precision 0 minting test")
17
+ {'result': 'success', 'files': ['419bfe67b7fafe0842813f13044d637775349d2b4df347639eccc6ec82093a8ecb'], 'root': '41a2099e84dd4690ea55774506d58ee6cf6ac9fe0c9806239ef6e251a6bc597641'}
18
+ >>> tw.balance()
19
+ [{'balance': 1000, 'quantity': 1000, 'files': ['419bfe67b7fafe0842813f13044d637775349d2b4df347639eccc6ec82093a8ecb'], 'fileValue': {'419bfe67b7fafe0842813f13044d637775349d2b4df347639eccc6ec82093a8ecb': 1000}, 'poptop': '419ccac82bcf1216a70929664cdeaa97bcc01deb87d190a0c7ce90e62d7b89a6bf', 'displayPrecision': 0, 'type': '41a2099e84dd4690ea55774506d58ee6cf6ac9fe0c9806239ef6e251a6bc597641'}]
20
+ ```
21
+
22
+
23
+
@@ -0,0 +1,23 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "trivialapi"
7
+ version = "0.0.1"
8
+ authors = [
9
+ { name="inaimathi", email="leo.zovic@gmail.com" },
10
+ ]
11
+ description = "A trivial set of API bindings for the TODA payment API"
12
+ readme = "README.md"
13
+ requires-python = ">=3.10"
14
+ classifiers = [
15
+ "Programming Language :: Python :: 3",
16
+ "License :: OSI Approved :: MIT License",
17
+ "Operating System :: OS Independent",
18
+ ]
19
+ dependencies = ["requests"]
20
+
21
+ [project.urls]
22
+ Homepage = "https://github.com/inaimathi/pytoda"
23
+ Issues = "https://github.com/inaimathi/pytoda/issues"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,9 @@
1
+ from . import util
2
+
3
+
4
+ def create(accessToken, twinId, cost, descriptor, dq):
5
+ return util.apiPost(
6
+ "v2/commodity",
7
+ accessToken,
8
+ {"cost": cost, "descriptor": descriptor, "dq": dq, "twin_id": twinId},
9
+ )
@@ -0,0 +1,78 @@
1
+ import json
2
+ import os
3
+
4
+ from . import token, twin, util
5
+
6
+
7
+ class TODA:
8
+ def __init__(self, id, created_at, updated_at, secrets):
9
+ self.id = id
10
+ self.created_at = created_at
11
+ self.updated_at = updated_at
12
+ self.secrets = secrets
13
+ client = [s for s in secrets if "client_id" in s and "client_secret" in s][0]
14
+ self.client_id = client["client_id"]
15
+ self.client_secret = client["client_secret"]
16
+ self.token = token.get(self.client_id, self.client_secret)[0]["access_token"]
17
+
18
+ @classmethod
19
+ def from_dict(cls, dct):
20
+ res = cls(**dct)
21
+ return res
22
+
23
+ @classmethod
24
+ def from_file(cls, path):
25
+ with open(os.path.expanduser(path), "r") as f:
26
+ return cls.from_dict(json.loads(f.read()))
27
+
28
+ def createTwin(self, dq=None):
29
+ if dq is None:
30
+ dq = util.STAGING_DQ
31
+ res = twin.create(self.token, dq)[0]
32
+ if res is not None:
33
+ with open(f"twin-{res['id']}.json", "w") as f:
34
+ f.write(json.dumps(res))
35
+ return Twin.from_dict(res)
36
+
37
+ def getTwin(self):
38
+ pass
39
+
40
+
41
+ class Twin:
42
+ def __init__(self, id, hostname, key, balances):
43
+ self.id = id
44
+ self.hostname = hostname
45
+ self.key = key
46
+ self.balances = balances
47
+ pass
48
+
49
+ @classmethod
50
+ def from_dict(cls, dct):
51
+ res = cls(**dct)
52
+ return res
53
+
54
+ @classmethod
55
+ def from_file(cls, path):
56
+ with open(os.path.expanduser(path), "r") as f:
57
+ return cls.from_dict(json.loads(f.read()))
58
+
59
+ def mint(self, quantity, display_precision=0, minting_info=None):
60
+ return util.apiPost(
61
+ f"https://{self.hostname}/dq?apiKey={self.key}",
62
+ None,
63
+ {
64
+ "quantity": quantity,
65
+ "displayPrecision": display_precision,
66
+ "mintingInfo": minting_info,
67
+ },
68
+ )[0]
69
+
70
+ def transfer(self, root, amount, destination_hostname):
71
+ return util.apiPost(
72
+ f"https://{self.hostname}/dq/{root}/transfer?apiKey={self.key}",
73
+ None,
74
+ {"amount": amount, "destination": destination_hostname},
75
+ )[0]
76
+
77
+ def balance(self):
78
+ return util.apiGet(f"https://{self.hostname}/dq?apiKey={self.key}", None)[0]
@@ -0,0 +1,7 @@
1
+ from . import util
2
+
3
+
4
+ def valid(accessToken, hash, nonce, timestamp):
5
+ return util.apiPost(
6
+ f"v2/payment/{hash}/validate", {"nonce": nonce, "timestamp": timestamp}
7
+ )
@@ -0,0 +1,10 @@
1
+ import base64
2
+
3
+ from . import util
4
+
5
+
6
+ def get(clientId, clientSecret):
7
+ token = base64.b64encode(f"{clientId}:{clientSecret}".encode("utf-8")).decode(
8
+ "utf-8"
9
+ )
10
+ return util.apiPost("v2/account/oauth/token", f"Basic {token}")
@@ -0,0 +1,13 @@
1
+ from . import util
2
+
3
+
4
+ def create(accessToken, dq):
5
+ return util.apiPost("v2/twin", accessToken, {"dq": dq})
6
+
7
+
8
+ def get(accessToken, twinId):
9
+ return util.apiGet(f"v2/twin/{twinId}", accessToken)
10
+
11
+
12
+ def getTwins(accessToken):
13
+ return util.apiGet("v2/twins", accessToken)
@@ -0,0 +1,46 @@
1
+ from os import environ as ENV
2
+
3
+ import requests
4
+
5
+ STAGING_DQ = "410ddbac7c8a259da8dfcc5f55bcb28b77d29be9c540a2c23444b416d584801c30"
6
+ BASE_URL = ENV.get("API_BASE_URL", "https://pay.stage.m.todaq.net").rstrip("/")
7
+
8
+
9
+ def url(path, base=None):
10
+ if path.startswith("http"):
11
+ return path
12
+
13
+ if base is None:
14
+ base = BASE_URL
15
+
16
+ return f"{base.rstrip('/')}/{path.lstrip('/')}"
17
+
18
+
19
+ def headers(accessToken):
20
+ hdrs = {
21
+ "Content-Type": "application/json",
22
+ "Accept": "application/json",
23
+ }
24
+ if accessToken is None:
25
+ return hdrs
26
+ elif accessToken.startswith("Basic") or accessToken.startswith("Bearer"):
27
+ auth = accessToken
28
+ else:
29
+ auth = f"Bearer {accessToken}"
30
+
31
+ hdrs["Authorization"] = auth
32
+ return hdrs
33
+
34
+
35
+ def apiGet(path, accessToken):
36
+ resp = requests.get(url(path), headers=headers(accessToken))
37
+ if 299 >= resp.status_code >= 200:
38
+ return resp.json(), None
39
+ return None, resp
40
+
41
+
42
+ def apiPost(path, accessToken, data=None):
43
+ resp = requests.post(url(path), headers=headers(accessToken), json=data)
44
+ if 299 >= resp.status_code >= 200:
45
+ return resp.json(), None
46
+ return None, resp
@@ -0,0 +1,37 @@
1
+ Metadata-Version: 2.1
2
+ Name: trivialapi
3
+ Version: 0.0.1
4
+ Summary: A trivial set of API bindings for the TODA payment API
5
+ Author-email: inaimathi <leo.zovic@gmail.com>
6
+ Project-URL: Homepage, https://github.com/inaimathi/pytoda
7
+ Project-URL: Issues, https://github.com/inaimathi/pytoda/issues
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.10
12
+ Description-Content-Type: text/markdown
13
+ Requires-Dist: requests
14
+
15
+ # TODA Micro
16
+
17
+ - A basic port of [this](https://github.com/TODAQmicro/payment-node) that doesn't suck too much.
18
+
19
+ ## Basic usage
20
+
21
+ ```
22
+ >>> from src.trivialapi.toda import core
23
+ <module 'src.trivialapi.toda.core'>
24
+ >>> tw = core.Twin.from_file("~/path/to/your/twin.json")
25
+ <src.trivialapi.toda.core.Twin object at 0x74622b7ed150>
26
+ >>> tw.hostname
27
+ '41a9cbc977c39bd3eb5a52a5924f8ef5.micro-staging.biz.todaq.net'
28
+ >>> tw.key
29
+ 'redacted'
30
+ >>> tw.mint(1000, minting_info="Precision 0 minting test")
31
+ {'result': 'success', 'files': ['419bfe67b7fafe0842813f13044d637775349d2b4df347639eccc6ec82093a8ecb'], 'root': '41a2099e84dd4690ea55774506d58ee6cf6ac9fe0c9806239ef6e251a6bc597641'}
32
+ >>> tw.balance()
33
+ [{'balance': 1000, 'quantity': 1000, 'files': ['419bfe67b7fafe0842813f13044d637775349d2b4df347639eccc6ec82093a8ecb'], 'fileValue': {'419bfe67b7fafe0842813f13044d637775349d2b4df347639eccc6ec82093a8ecb': 1000}, 'poptop': '419ccac82bcf1216a70929664cdeaa97bcc01deb87d190a0c7ce90e62d7b89a6bf', 'displayPrecision': 0, 'type': '41a2099e84dd4690ea55774506d58ee6cf6ac9fe0c9806239ef6e251a6bc597641'}]
34
+ ```
35
+
36
+
37
+
@@ -0,0 +1,14 @@
1
+ README.md
2
+ pyproject.toml
3
+ src/trivialapi.egg-info/PKG-INFO
4
+ src/trivialapi.egg-info/SOURCES.txt
5
+ src/trivialapi.egg-info/dependency_links.txt
6
+ src/trivialapi.egg-info/requires.txt
7
+ src/trivialapi.egg-info/top_level.txt
8
+ src/trivialapi/toda/commodity.py
9
+ src/trivialapi/toda/core.py
10
+ src/trivialapi/toda/payment.py
11
+ src/trivialapi/toda/token.py
12
+ src/trivialapi/toda/twin.py
13
+ src/trivialapi/toda/util.py
14
+ tests/test_basics.py
@@ -0,0 +1 @@
1
+ requests
@@ -0,0 +1 @@
1
+ trivialapi
@@ -0,0 +1,11 @@
1
+ import unittest
2
+
3
+ from src.trivialapi.toda import core
4
+
5
+
6
+ class TestBasics(unittest.TestCase):
7
+ def test_basics(self):
8
+ core.Twin
9
+ self.assertTrue(True)
10
+ self.assertIsNone(None)
11
+ self.assertEqual("a", "a")