getquantumrand 1.0.0__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.
- getquantumrand-1.0.0/PKG-INFO +79 -0
- getquantumrand-1.0.0/README.md +61 -0
- getquantumrand-1.0.0/getquantumrand/__init__.py +6 -0
- getquantumrand-1.0.0/getquantumrand/client.py +297 -0
- getquantumrand-1.0.0/getquantumrand.egg-info/PKG-INFO +79 -0
- getquantumrand-1.0.0/getquantumrand.egg-info/SOURCES.txt +9 -0
- getquantumrand-1.0.0/getquantumrand.egg-info/dependency_links.txt +1 -0
- getquantumrand-1.0.0/getquantumrand.egg-info/requires.txt +1 -0
- getquantumrand-1.0.0/getquantumrand.egg-info/top_level.txt +1 -0
- getquantumrand-1.0.0/pyproject.toml +28 -0
- getquantumrand-1.0.0/setup.cfg +4 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: getquantumrand
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Python SDK for the QuantumRand API — true quantum randomness as a service
|
|
5
|
+
License: MIT
|
|
6
|
+
Project-URL: Homepage, https://quantumrand.dev
|
|
7
|
+
Project-URL: Repository, https://github.com/getquantumrand/quantumrand-
|
|
8
|
+
Project-URL: Documentation, https://quantumrand.dev/docs
|
|
9
|
+
Keywords: quantum,random,qrng,cryptography,api
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Topic :: Security :: Cryptography
|
|
15
|
+
Requires-Python: >=3.9
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
Requires-Dist: httpx>=0.24
|
|
18
|
+
|
|
19
|
+
# getquantumrand — Python SDK
|
|
20
|
+
|
|
21
|
+
True quantum randomness as a service.
|
|
22
|
+
|
|
23
|
+
## Install
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
pip install getquantumrand
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Quick Start
|
|
30
|
+
|
|
31
|
+
```python
|
|
32
|
+
from getquantumrand import QuantumRandClient
|
|
33
|
+
|
|
34
|
+
qr = QuantumRandClient("qr_your_api_key")
|
|
35
|
+
|
|
36
|
+
# Generate 256 quantum random bits
|
|
37
|
+
bits = qr.bits(256)
|
|
38
|
+
|
|
39
|
+
# Random hex string
|
|
40
|
+
hex_str = qr.hex(128)
|
|
41
|
+
|
|
42
|
+
# Random integer in range
|
|
43
|
+
number = qr.integer(1, 100)
|
|
44
|
+
|
|
45
|
+
# Cryptographic key (AES-256)
|
|
46
|
+
key = qr.key(256)
|
|
47
|
+
|
|
48
|
+
# Batch: multiple values in one call
|
|
49
|
+
results = qr.batch([
|
|
50
|
+
{"type": "bits", "params": {"n": 64}},
|
|
51
|
+
{"type": "integer", "params": {"min": 1, "max": 6}},
|
|
52
|
+
{"type": "integer", "params": {"min": 1, "max": 6}},
|
|
53
|
+
])
|
|
54
|
+
|
|
55
|
+
# Async webhook delivery
|
|
56
|
+
qr.webhook("https://your-app.com/webhook", type="key", params={"bits": 256})
|
|
57
|
+
|
|
58
|
+
# Usage stats
|
|
59
|
+
print(qr.stats())
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Configuration
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
qr = QuantumRandClient(
|
|
66
|
+
api_key="qr_your_key",
|
|
67
|
+
base_url="https://quantumrand.dev", # default
|
|
68
|
+
backend="origin_cloud", # or "aer_simulator", "origin_wuyuan"
|
|
69
|
+
timeout=30.0,
|
|
70
|
+
)
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Get a Free API Key
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
curl -X POST https://quantumrand.dev/keys/create \
|
|
77
|
+
-H "Content-Type: application/json" \
|
|
78
|
+
-d '{"name": "Your Name", "email": "you@example.com"}'
|
|
79
|
+
```
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# getquantumrand — Python SDK
|
|
2
|
+
|
|
3
|
+
True quantum randomness as a service.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install getquantumrand
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
from getquantumrand import QuantumRandClient
|
|
15
|
+
|
|
16
|
+
qr = QuantumRandClient("qr_your_api_key")
|
|
17
|
+
|
|
18
|
+
# Generate 256 quantum random bits
|
|
19
|
+
bits = qr.bits(256)
|
|
20
|
+
|
|
21
|
+
# Random hex string
|
|
22
|
+
hex_str = qr.hex(128)
|
|
23
|
+
|
|
24
|
+
# Random integer in range
|
|
25
|
+
number = qr.integer(1, 100)
|
|
26
|
+
|
|
27
|
+
# Cryptographic key (AES-256)
|
|
28
|
+
key = qr.key(256)
|
|
29
|
+
|
|
30
|
+
# Batch: multiple values in one call
|
|
31
|
+
results = qr.batch([
|
|
32
|
+
{"type": "bits", "params": {"n": 64}},
|
|
33
|
+
{"type": "integer", "params": {"min": 1, "max": 6}},
|
|
34
|
+
{"type": "integer", "params": {"min": 1, "max": 6}},
|
|
35
|
+
])
|
|
36
|
+
|
|
37
|
+
# Async webhook delivery
|
|
38
|
+
qr.webhook("https://your-app.com/webhook", type="key", params={"bits": 256})
|
|
39
|
+
|
|
40
|
+
# Usage stats
|
|
41
|
+
print(qr.stats())
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Configuration
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
qr = QuantumRandClient(
|
|
48
|
+
api_key="qr_your_key",
|
|
49
|
+
base_url="https://quantumrand.dev", # default
|
|
50
|
+
backend="origin_cloud", # or "aer_simulator", "origin_wuyuan"
|
|
51
|
+
timeout=30.0,
|
|
52
|
+
)
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Get a Free API Key
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
curl -X POST https://quantumrand.dev/keys/create \
|
|
59
|
+
-H "Content-Type: application/json" \
|
|
60
|
+
-d '{"name": "Your Name", "email": "you@example.com"}'
|
|
61
|
+
```
|
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
"""QuantumRand API client."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import hashlib
|
|
6
|
+
import hmac as hmac_mod
|
|
7
|
+
import time
|
|
8
|
+
import uuid
|
|
9
|
+
|
|
10
|
+
import httpx
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class QuantumRandError(Exception):
|
|
14
|
+
"""Raised when the QuantumRand API returns an error."""
|
|
15
|
+
|
|
16
|
+
def __init__(self, message: str, status_code: int = 0, request_id: str = ""):
|
|
17
|
+
super().__init__(message)
|
|
18
|
+
self.status_code = status_code
|
|
19
|
+
self.request_id = request_id
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class QuantumRandClient:
|
|
23
|
+
"""
|
|
24
|
+
Client for the QuantumRand API.
|
|
25
|
+
|
|
26
|
+
Usage::
|
|
27
|
+
|
|
28
|
+
from quantumrand import QuantumRandClient
|
|
29
|
+
|
|
30
|
+
qr = QuantumRandClient("qr_your_api_key")
|
|
31
|
+
bits = qr.bits(256)
|
|
32
|
+
print(bits) # "10110010..."
|
|
33
|
+
|
|
34
|
+
hex_str = qr.hex(128)
|
|
35
|
+
number = qr.integer(1, 100)
|
|
36
|
+
key = qr.key(256)
|
|
37
|
+
|
|
38
|
+
# Batch requests
|
|
39
|
+
results = qr.batch([
|
|
40
|
+
{"type": "bits", "params": {"n": 64}},
|
|
41
|
+
{"type": "integer", "params": {"min": 1, "max": 6}},
|
|
42
|
+
{"type": "integer", "params": {"min": 1, "max": 6}},
|
|
43
|
+
])
|
|
44
|
+
|
|
45
|
+
# With HMAC request signing
|
|
46
|
+
qr = QuantumRandClient("qr_key", hmac_secret="your_secret")
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
DEFAULT_BASE_URL = "https://quantumrand.dev"
|
|
50
|
+
|
|
51
|
+
def __init__(
|
|
52
|
+
self,
|
|
53
|
+
api_key: str,
|
|
54
|
+
base_url: str | None = None,
|
|
55
|
+
backend: str = "origin_cloud",
|
|
56
|
+
timeout: float = 30.0,
|
|
57
|
+
hmac_secret: str | None = None,
|
|
58
|
+
):
|
|
59
|
+
self.api_key = api_key
|
|
60
|
+
self.base_url = (base_url or self.DEFAULT_BASE_URL).rstrip("/")
|
|
61
|
+
self.backend = backend
|
|
62
|
+
self.hmac_secret = hmac_secret
|
|
63
|
+
self._client = httpx.Client(
|
|
64
|
+
base_url=self.base_url,
|
|
65
|
+
headers={"X-API-Key": self.api_key},
|
|
66
|
+
timeout=timeout,
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
def _sign_request(self, method: str, path: str, query: str = "") -> dict:
|
|
70
|
+
"""Generate HMAC-SHA256 signature headers."""
|
|
71
|
+
if not self.hmac_secret:
|
|
72
|
+
return {}
|
|
73
|
+
ts = str(int(time.time()))
|
|
74
|
+
payload = f"{ts}{method.upper()}{path}{query}"
|
|
75
|
+
sig = hmac_mod.new(self.hmac_secret.encode(), payload.encode(), hashlib.sha256).hexdigest()
|
|
76
|
+
return {"X-Signature": sig, "X-Timestamp": ts}
|
|
77
|
+
|
|
78
|
+
def _request(self, method: str, path: str, **kwargs) -> dict:
|
|
79
|
+
# Prepend /v1 to all API paths
|
|
80
|
+
v1_path = f"/v1{path}"
|
|
81
|
+
|
|
82
|
+
# Build query string for signing
|
|
83
|
+
params = kwargs.get("params", {})
|
|
84
|
+
query = "&".join(f"{k}={v}" for k, v in sorted(params.items())) if params else ""
|
|
85
|
+
|
|
86
|
+
# Add signing + request ID headers
|
|
87
|
+
headers = {"X-Request-ID": uuid.uuid4().hex}
|
|
88
|
+
headers.update(self._sign_request(method, v1_path, query))
|
|
89
|
+
kwargs.setdefault("headers", {}).update(headers)
|
|
90
|
+
|
|
91
|
+
resp = self._client.request(method, v1_path, **kwargs)
|
|
92
|
+
request_id = resp.headers.get("x-request-id", "")
|
|
93
|
+
data = resp.json()
|
|
94
|
+
if resp.status_code >= 400:
|
|
95
|
+
detail = data.get("detail") or data.get("error") or resp.text
|
|
96
|
+
raise QuantumRandError(str(detail), resp.status_code, request_id)
|
|
97
|
+
if not data.get("success"):
|
|
98
|
+
raise QuantumRandError(data.get("error", "Unknown error"), request_id=request_id)
|
|
99
|
+
return data["data"]
|
|
100
|
+
|
|
101
|
+
def bits(self, n: int = 256) -> str:
|
|
102
|
+
"""Generate `n` quantum random bits. Returns a string of 0s and 1s."""
|
|
103
|
+
data = self._request("GET", "/generate/bits", params={"n": n, "backend": self.backend})
|
|
104
|
+
return data["raw_bits"]
|
|
105
|
+
|
|
106
|
+
def hex(self, n: int = 256) -> str:
|
|
107
|
+
"""Generate a quantum random hex string from `n` bits."""
|
|
108
|
+
data = self._request("GET", "/generate/hex", params={"n": n, "backend": self.backend})
|
|
109
|
+
return data["hex"]
|
|
110
|
+
|
|
111
|
+
def integer(self, min_val: int = 0, max_val: int = 100) -> int:
|
|
112
|
+
"""Generate a quantum random integer in [min_val, max_val]."""
|
|
113
|
+
data = self._request("GET", "/generate/integer", params={"min": min_val, "max": max_val, "backend": self.backend})
|
|
114
|
+
return data["value"]
|
|
115
|
+
|
|
116
|
+
def key(self, bits: int = 256) -> str:
|
|
117
|
+
"""Generate a quantum random cryptographic key (hex). Supports 128, 192, 256, 512 bits."""
|
|
118
|
+
data = self._request("POST", "/generate/key", params={"bits": bits, "backend": self.backend})
|
|
119
|
+
return data["key_hex"]
|
|
120
|
+
|
|
121
|
+
def batch(self, requests: list[dict]) -> list[dict]:
|
|
122
|
+
"""
|
|
123
|
+
Generate multiple random values in one API call.
|
|
124
|
+
|
|
125
|
+
Each request should be a dict with 'type' and 'params'::
|
|
126
|
+
|
|
127
|
+
[
|
|
128
|
+
{"type": "bits", "params": {"n": 64}},
|
|
129
|
+
{"type": "integer", "params": {"min": 1, "max": 100}},
|
|
130
|
+
]
|
|
131
|
+
"""
|
|
132
|
+
data = self._request("POST", "/generate/batch", params={"backend": self.backend}, json={"requests": requests})
|
|
133
|
+
return data["results"]
|
|
134
|
+
|
|
135
|
+
def webhook(self, callback_url: str, type: str = "bits", params: dict | None = None) -> dict:
|
|
136
|
+
"""Trigger async generation with results delivered to a callback URL."""
|
|
137
|
+
data = self._request(
|
|
138
|
+
"POST", "/generate/webhook",
|
|
139
|
+
params={"backend": self.backend},
|
|
140
|
+
json={"callback_url": callback_url, "type": type, "params": params or {}},
|
|
141
|
+
)
|
|
142
|
+
return data
|
|
143
|
+
|
|
144
|
+
def stats(self) -> dict:
|
|
145
|
+
"""Get your usage statistics."""
|
|
146
|
+
return self._request("GET", "/keys/stats")
|
|
147
|
+
|
|
148
|
+
def me(self) -> dict:
|
|
149
|
+
"""Get your API key info."""
|
|
150
|
+
return self._request("GET", "/keys/me")
|
|
151
|
+
|
|
152
|
+
def health(self) -> dict:
|
|
153
|
+
"""Check API health status."""
|
|
154
|
+
resp = self._client.get("/health")
|
|
155
|
+
return resp.json().get("data", {})
|
|
156
|
+
|
|
157
|
+
# ── Gaming ────────────────────────────────────────────────────────
|
|
158
|
+
|
|
159
|
+
def gaming_roll(self, sides: int = 6, count: int = 1) -> dict:
|
|
160
|
+
"""Roll one or more dice with the given number of sides."""
|
|
161
|
+
return self._request("POST", "/gaming/roll", json={"sides": sides, "count": count, "backend": self.backend})
|
|
162
|
+
|
|
163
|
+
def gaming_seed(self, bits: int = 256) -> dict:
|
|
164
|
+
"""Generate a quantum random seed for game engines."""
|
|
165
|
+
return self._request("POST", "/gaming/seed", json={"bits": bits, "backend": self.backend})
|
|
166
|
+
|
|
167
|
+
def gaming_shuffle(self, items: list[str]) -> dict:
|
|
168
|
+
"""Quantum-shuffle a list of items."""
|
|
169
|
+
return self._request("POST", "/gaming/shuffle", json={"items": items, "backend": self.backend})
|
|
170
|
+
|
|
171
|
+
def gaming_loot(self, items: list[dict]) -> dict:
|
|
172
|
+
"""Select a loot drop from weighted items ({name, weight})."""
|
|
173
|
+
return self._request("POST", "/gaming/loot", json={"items": items, "backend": self.backend})
|
|
174
|
+
|
|
175
|
+
def gaming_provable(self, game_id: str, round_id: str) -> dict:
|
|
176
|
+
"""Generate a provably-fair random value for a game round."""
|
|
177
|
+
return self._request("POST", "/gaming/provable", json={"game_id": game_id, "round_id": round_id, "backend": self.backend})
|
|
178
|
+
|
|
179
|
+
# ── Healthcare ────────────────────────────────────────────────────
|
|
180
|
+
|
|
181
|
+
def health_record_seal(self, record_id: str, record_hash: str, provider_id: str) -> dict:
|
|
182
|
+
"""Seal a health record with a quantum-random integrity token."""
|
|
183
|
+
return self._request("POST", "/health/record-seal", json={"record_id": record_id, "record_hash": record_hash, "provider_id": provider_id, "backend": self.backend})
|
|
184
|
+
|
|
185
|
+
def health_rx_sign(self, prescription_id: str, patient_hash: str, provider_id: str) -> dict:
|
|
186
|
+
"""Sign a prescription with a quantum-random token."""
|
|
187
|
+
return self._request("POST", "/health/rx-sign", json={"prescription_id": prescription_id, "patient_hash": patient_hash, "provider_id": provider_id, "backend": self.backend})
|
|
188
|
+
|
|
189
|
+
def health_access_log(self, record_id: str, accessor_id: str, access_type: str) -> dict:
|
|
190
|
+
"""Log a record access event with a quantum-random seal."""
|
|
191
|
+
return self._request("POST", "/health/access-log", json={"record_id": record_id, "accessor_id": accessor_id, "access_type": access_type, "backend": self.backend})
|
|
192
|
+
|
|
193
|
+
def health_consent_seal(self, patient_hash: str, consent_type: str, provider_id: str) -> dict:
|
|
194
|
+
"""Seal a patient consent record with a quantum-random token."""
|
|
195
|
+
return self._request("POST", "/health/consent-seal", json={"patient_hash": patient_hash, "consent_type": consent_type, "provider_id": provider_id, "backend": self.backend})
|
|
196
|
+
|
|
197
|
+
def health_device_id(self, device_type: str, manufacturer_id: str) -> dict:
|
|
198
|
+
"""Generate a quantum-random medical device identifier."""
|
|
199
|
+
return self._request("POST", "/health/device-id", json={"device_type": device_type, "manufacturer_id": manufacturer_id, "backend": self.backend})
|
|
200
|
+
|
|
201
|
+
# ── Legal ─────────────────────────────────────────────────────────
|
|
202
|
+
|
|
203
|
+
def legal_timestamp(self, document_hash: str, document_id: str, party_id: str) -> dict:
|
|
204
|
+
"""Create a quantum-random legal timestamp for a document."""
|
|
205
|
+
return self._request("POST", "/legal/timestamp", json={"document_hash": document_hash, "document_id": document_id, "party_id": party_id, "backend": self.backend})
|
|
206
|
+
|
|
207
|
+
def legal_evidence_seal(self, evidence_id: str, evidence_hash: str, case_id: str) -> dict:
|
|
208
|
+
"""Seal evidence with a quantum-random integrity token."""
|
|
209
|
+
return self._request("POST", "/legal/evidence-seal", json={"evidence_id": evidence_id, "evidence_hash": evidence_hash, "case_id": case_id, "backend": self.backend})
|
|
210
|
+
|
|
211
|
+
def legal_contract_sign(self, contract_id: str, contract_hash: str, signatories: list[str]) -> dict:
|
|
212
|
+
"""Sign a contract with a quantum-random token."""
|
|
213
|
+
return self._request("POST", "/legal/contract-sign", json={"contract_id": contract_id, "contract_hash": contract_hash, "signatories": signatories, "backend": self.backend})
|
|
214
|
+
|
|
215
|
+
def legal_claim_token(self, claim_id: str, policy_id: str, claimant_hash: str) -> dict:
|
|
216
|
+
"""Generate a quantum-random claim token for insurance."""
|
|
217
|
+
return self._request("POST", "/legal/claim-token", json={"claim_id": claim_id, "policy_id": policy_id, "claimant_hash": claimant_hash, "backend": self.backend})
|
|
218
|
+
|
|
219
|
+
def legal_notarize(self, document_hash: str, document_id: str, notary_id: str) -> dict:
|
|
220
|
+
"""Notarize a document with a quantum-random seal."""
|
|
221
|
+
return self._request("POST", "/legal/notarize", json={"document_hash": document_hash, "document_id": document_id, "notary_id": notary_id, "backend": self.backend})
|
|
222
|
+
|
|
223
|
+
# ── Cybersecurity ─────────────────────────────────────────────────
|
|
224
|
+
|
|
225
|
+
def security_keygen(self, algorithm: str = "AES-256", purpose: str = "") -> dict:
|
|
226
|
+
"""Generate a quantum-random cryptographic key."""
|
|
227
|
+
return self._request("POST", "/security/keygen", json={"algorithm": algorithm, "purpose": purpose, "backend": self.backend})
|
|
228
|
+
|
|
229
|
+
def security_entropy_audit(self, sample_size: int = 1024) -> dict:
|
|
230
|
+
"""Audit entropy quality of a quantum random sample."""
|
|
231
|
+
return self._request("POST", "/security/entropy-audit", json={"sample_size": sample_size, "backend": self.backend})
|
|
232
|
+
|
|
233
|
+
def security_token(self, length: int = 32, format: str = "hex") -> dict:
|
|
234
|
+
"""Generate a quantum-random security token."""
|
|
235
|
+
return self._request("POST", "/security/token", json={"length": length, "format": format, "backend": self.backend})
|
|
236
|
+
|
|
237
|
+
def security_salt(self, length: int = 32, purpose: str = "password") -> dict:
|
|
238
|
+
"""Generate a quantum-random salt value."""
|
|
239
|
+
return self._request("POST", "/security/salt", json={"length": length, "purpose": purpose, "backend": self.backend})
|
|
240
|
+
|
|
241
|
+
def security_challenge(self, session_id: str, ttl_seconds: int = 300) -> dict:
|
|
242
|
+
"""Generate a quantum-random authentication challenge."""
|
|
243
|
+
return self._request("POST", "/security/challenge", json={"session_id": session_id, "ttl_seconds": ttl_seconds, "backend": self.backend})
|
|
244
|
+
|
|
245
|
+
# ── IoT ───────────────────────────────────────────────────────────
|
|
246
|
+
|
|
247
|
+
def iot_device_id(self, device_type: str, manufacturer_id: str, batch_id: str = "") -> dict:
|
|
248
|
+
"""Generate a quantum-random IoT device identifier."""
|
|
249
|
+
return self._request("POST", "/iot/device-id", json={"device_type": device_type, "manufacturer_id": manufacturer_id, "batch_id": batch_id, "backend": self.backend})
|
|
250
|
+
|
|
251
|
+
def iot_firmware_sign(self, firmware_hash: str, device_type: str, version: str) -> dict:
|
|
252
|
+
"""Sign IoT firmware with a quantum-random token."""
|
|
253
|
+
return self._request("POST", "/iot/firmware-sign", json={"firmware_hash": firmware_hash, "device_type": device_type, "version": version, "backend": self.backend})
|
|
254
|
+
|
|
255
|
+
def iot_session_key(self, device_id: str, session_duration_seconds: int = 3600) -> dict:
|
|
256
|
+
"""Generate a quantum-random session key for an IoT device."""
|
|
257
|
+
return self._request("POST", "/iot/session-key", json={"device_id": device_id, "session_duration_seconds": session_duration_seconds, "backend": self.backend})
|
|
258
|
+
|
|
259
|
+
def iot_provision(self, fleet_id: str, device_type: str, provisioning_ttl_seconds: int = 300) -> dict:
|
|
260
|
+
"""Generate quantum-random provisioning credentials for an IoT device."""
|
|
261
|
+
return self._request("POST", "/iot/provision", json={"fleet_id": fleet_id, "device_type": device_type, "provisioning_ttl_seconds": provisioning_ttl_seconds, "backend": self.backend})
|
|
262
|
+
|
|
263
|
+
def iot_telemetry_seal(self, device_id: str, data_hash: str, reading_count: int) -> dict:
|
|
264
|
+
"""Seal IoT telemetry data with a quantum-random token."""
|
|
265
|
+
return self._request("POST", "/iot/telemetry-seal", json={"device_id": device_id, "data_hash": data_hash, "reading_count": reading_count, "backend": self.backend})
|
|
266
|
+
|
|
267
|
+
# ── Finance ───────────────────────────────────────────────────────
|
|
268
|
+
|
|
269
|
+
def finance_txid(self) -> dict:
|
|
270
|
+
"""Generate a quantum-random transaction identifier."""
|
|
271
|
+
return self._request("POST", "/finance/txid", json={"backend": self.backend})
|
|
272
|
+
|
|
273
|
+
def finance_otp(self, digits: int = 6) -> dict:
|
|
274
|
+
"""Generate a quantum-random one-time password."""
|
|
275
|
+
return self._request("POST", "/finance/otp", json={"digits": digits, "backend": self.backend})
|
|
276
|
+
|
|
277
|
+
def finance_nonce(self, ttl_seconds: int = 300) -> dict:
|
|
278
|
+
"""Generate a quantum-random nonce with a TTL."""
|
|
279
|
+
return self._request("POST", "/finance/nonce", json={"ttl_seconds": ttl_seconds, "backend": self.backend})
|
|
280
|
+
|
|
281
|
+
def finance_keypair(self) -> dict:
|
|
282
|
+
"""Generate a quantum-random asymmetric key pair."""
|
|
283
|
+
return self._request("POST", "/finance/keypair", json={"backend": self.backend})
|
|
284
|
+
|
|
285
|
+
def finance_audit_sign(self, payload: str) -> dict:
|
|
286
|
+
"""Sign an audit payload with a quantum-random token."""
|
|
287
|
+
return self._request("POST", "/finance/audit-sign", json={"payload": payload, "backend": self.backend})
|
|
288
|
+
|
|
289
|
+
def close(self):
|
|
290
|
+
"""Close the underlying HTTP connection."""
|
|
291
|
+
self._client.close()
|
|
292
|
+
|
|
293
|
+
def __enter__(self):
|
|
294
|
+
return self
|
|
295
|
+
|
|
296
|
+
def __exit__(self, *args):
|
|
297
|
+
self.close()
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: getquantumrand
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Python SDK for the QuantumRand API — true quantum randomness as a service
|
|
5
|
+
License: MIT
|
|
6
|
+
Project-URL: Homepage, https://quantumrand.dev
|
|
7
|
+
Project-URL: Repository, https://github.com/getquantumrand/quantumrand-
|
|
8
|
+
Project-URL: Documentation, https://quantumrand.dev/docs
|
|
9
|
+
Keywords: quantum,random,qrng,cryptography,api
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Topic :: Security :: Cryptography
|
|
15
|
+
Requires-Python: >=3.9
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
Requires-Dist: httpx>=0.24
|
|
18
|
+
|
|
19
|
+
# getquantumrand — Python SDK
|
|
20
|
+
|
|
21
|
+
True quantum randomness as a service.
|
|
22
|
+
|
|
23
|
+
## Install
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
pip install getquantumrand
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Quick Start
|
|
30
|
+
|
|
31
|
+
```python
|
|
32
|
+
from getquantumrand import QuantumRandClient
|
|
33
|
+
|
|
34
|
+
qr = QuantumRandClient("qr_your_api_key")
|
|
35
|
+
|
|
36
|
+
# Generate 256 quantum random bits
|
|
37
|
+
bits = qr.bits(256)
|
|
38
|
+
|
|
39
|
+
# Random hex string
|
|
40
|
+
hex_str = qr.hex(128)
|
|
41
|
+
|
|
42
|
+
# Random integer in range
|
|
43
|
+
number = qr.integer(1, 100)
|
|
44
|
+
|
|
45
|
+
# Cryptographic key (AES-256)
|
|
46
|
+
key = qr.key(256)
|
|
47
|
+
|
|
48
|
+
# Batch: multiple values in one call
|
|
49
|
+
results = qr.batch([
|
|
50
|
+
{"type": "bits", "params": {"n": 64}},
|
|
51
|
+
{"type": "integer", "params": {"min": 1, "max": 6}},
|
|
52
|
+
{"type": "integer", "params": {"min": 1, "max": 6}},
|
|
53
|
+
])
|
|
54
|
+
|
|
55
|
+
# Async webhook delivery
|
|
56
|
+
qr.webhook("https://your-app.com/webhook", type="key", params={"bits": 256})
|
|
57
|
+
|
|
58
|
+
# Usage stats
|
|
59
|
+
print(qr.stats())
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Configuration
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
qr = QuantumRandClient(
|
|
66
|
+
api_key="qr_your_key",
|
|
67
|
+
base_url="https://quantumrand.dev", # default
|
|
68
|
+
backend="origin_cloud", # or "aer_simulator", "origin_wuyuan"
|
|
69
|
+
timeout=30.0,
|
|
70
|
+
)
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Get a Free API Key
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
curl -X POST https://quantumrand.dev/keys/create \
|
|
77
|
+
-H "Content-Type: application/json" \
|
|
78
|
+
-d '{"name": "Your Name", "email": "you@example.com"}'
|
|
79
|
+
```
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
getquantumrand/__init__.py
|
|
4
|
+
getquantumrand/client.py
|
|
5
|
+
getquantumrand.egg-info/PKG-INFO
|
|
6
|
+
getquantumrand.egg-info/SOURCES.txt
|
|
7
|
+
getquantumrand.egg-info/dependency_links.txt
|
|
8
|
+
getquantumrand.egg-info/requires.txt
|
|
9
|
+
getquantumrand.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
httpx>=0.24
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
getquantumrand
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "getquantumrand"
|
|
7
|
+
version = "1.0.0"
|
|
8
|
+
description = "Python SDK for the QuantumRand API — true quantum randomness as a service"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = {text = "MIT"}
|
|
11
|
+
requires-python = ">=3.9"
|
|
12
|
+
dependencies = ["httpx>=0.24"]
|
|
13
|
+
keywords = ["quantum", "random", "qrng", "cryptography", "api"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 4 - Beta",
|
|
16
|
+
"Intended Audience :: Developers",
|
|
17
|
+
"License :: OSI Approved :: MIT License",
|
|
18
|
+
"Programming Language :: Python :: 3",
|
|
19
|
+
"Topic :: Security :: Cryptography",
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
[project.urls]
|
|
23
|
+
Homepage = "https://quantumrand.dev"
|
|
24
|
+
Repository = "https://github.com/getquantumrand/quantumrand-"
|
|
25
|
+
Documentation = "https://quantumrand.dev/docs"
|
|
26
|
+
|
|
27
|
+
[tool.setuptools.packages.find]
|
|
28
|
+
include = ["getquantumrand*"]
|