quantum-random 1.4.0__tar.gz → 1.4.2__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.
- quantum_random-1.4.2/.github/workflows/publish.yml +24 -0
- quantum_random-1.4.2/.github/workflows/tests.yml +51 -0
- quantum_random-1.4.2/.gitignore +3 -0
- quantum_random-1.4.2/.python-version +1 -0
- {quantum_random-1.4.0 → quantum_random-1.4.2}/PKG-INFO +14 -22
- {quantum_random-1.4.0 → quantum_random-1.4.2}/README.md +1 -2
- quantum_random-1.4.2/analysis/README.md +15 -0
- quantum_random-1.4.2/analysis/generate_plot.py +53 -0
- quantum_random-1.4.2/analysis/random.png +0 -0
- quantum_random-1.4.2/analysis/requirements.txt +3 -0
- quantum_random-1.4.2/analysis/uniform.md +21 -0
- quantum_random-1.4.2/pyproject.toml +79 -0
- quantum_random-1.4.2/tests/conftest.py +120 -0
- quantum_random-1.4.2/tests/data/fetch_data.py +56 -0
- quantum_random-1.4.2/tests/data/responses.json +1 -0
- quantum_random-1.4.2/tests/test_api.py +184 -0
- quantum_random-1.4.2/tests/test_cli.py +100 -0
- quantum_random-1.4.2/tests/test_generator.py +89 -0
- quantum_random-1.4.2/tests/test_numpy_support.py +11 -0
- quantum_random-1.4.2/tests/test_qrandom.py +5 -0
- quantum_random-1.4.2/uv.lock +612 -0
- quantum_random-1.4.0/pyproject.toml +0 -69
- {quantum_random-1.4.0 → quantum_random-1.4.2}/LICENSE +0 -0
- {quantum_random-1.4.0 → quantum_random-1.4.2}/src/qrandom/__init__.py +0 -0
- {quantum_random-1.4.0 → quantum_random-1.4.2}/src/qrandom/_api.py +0 -0
- {quantum_random-1.4.0 → quantum_random-1.4.2}/src/qrandom/_cli.py +0 -0
- {quantum_random-1.4.0 → quantum_random-1.4.2}/src/qrandom/_generator.py +0 -0
- {quantum_random-1.4.0 → quantum_random-1.4.2}/src/qrandom/numpy.py +0 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
name: Publish
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- '*'
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
release:
|
|
10
|
+
permissions:
|
|
11
|
+
id-token: write
|
|
12
|
+
name: Release
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
steps:
|
|
15
|
+
- name: Checkout repo
|
|
16
|
+
uses: actions/checkout@v4
|
|
17
|
+
- name: Install uv
|
|
18
|
+
uses: astral-sh/setup-uv@v3
|
|
19
|
+
with:
|
|
20
|
+
version: "0.5.4"
|
|
21
|
+
- name: Build
|
|
22
|
+
run: uv build
|
|
23
|
+
- name: Publish
|
|
24
|
+
run: uv publish
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
name: Tests
|
|
2
|
+
|
|
3
|
+
on: push
|
|
4
|
+
|
|
5
|
+
jobs:
|
|
6
|
+
test:
|
|
7
|
+
name: Tests and type checks
|
|
8
|
+
runs-on: ${{ matrix.os }}
|
|
9
|
+
strategy:
|
|
10
|
+
matrix:
|
|
11
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
12
|
+
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']
|
|
13
|
+
defaults:
|
|
14
|
+
run:
|
|
15
|
+
shell: bash
|
|
16
|
+
steps:
|
|
17
|
+
- name: Checkout repo
|
|
18
|
+
uses: actions/checkout@v4
|
|
19
|
+
- name: Install uv
|
|
20
|
+
uses: astral-sh/setup-uv@v3
|
|
21
|
+
with:
|
|
22
|
+
version: "0.5.4"
|
|
23
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
24
|
+
run: uv python install ${{ matrix.python-version }}
|
|
25
|
+
- name: Install the project
|
|
26
|
+
run: uv sync --all-extras --dev
|
|
27
|
+
- name: Run pytest
|
|
28
|
+
run: QRANDOM_API_KEY=key uv run pytest
|
|
29
|
+
- name: Run mypy
|
|
30
|
+
run: uv run mypy --install-types --non-interactive .
|
|
31
|
+
|
|
32
|
+
lint:
|
|
33
|
+
name: Lint
|
|
34
|
+
runs-on: ubuntu-latest
|
|
35
|
+
steps:
|
|
36
|
+
- name: Checkout repo
|
|
37
|
+
uses: actions/checkout@v4
|
|
38
|
+
- name: Install uv
|
|
39
|
+
uses: astral-sh/setup-uv@v3
|
|
40
|
+
with:
|
|
41
|
+
version: "0.5.4"
|
|
42
|
+
- name: Set up Python
|
|
43
|
+
run: uv python install
|
|
44
|
+
- name: Install the project
|
|
45
|
+
run: uv sync --all-extras --dev
|
|
46
|
+
- name: Run black
|
|
47
|
+
run: uv run black --check .
|
|
48
|
+
- name: Run isort
|
|
49
|
+
run: uv run isort --check .
|
|
50
|
+
- name: Run flake8
|
|
51
|
+
run: uv run flake8 --extend-exclude .venv
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.12
|
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
2
|
Name: quantum-random
|
|
3
|
-
Version: 1.4.
|
|
3
|
+
Version: 1.4.2
|
|
4
4
|
Summary: Quantum random numbers
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
Project-URL: Homepage, https://github.com/sbalian/quantum-random
|
|
6
|
+
Project-URL: Repository, https://github.com/sbalian/quantum-random
|
|
7
|
+
Author-email: Seto Balian <seto.balian@gmail.com>
|
|
8
|
+
Maintainer-email: Seto Balian <seto.balian@gmail.com>
|
|
9
|
+
License: MIT License
|
|
7
10
|
Keywords: quantum,random,statistics
|
|
8
|
-
Author: Seto Balian
|
|
9
|
-
Author-email: seto.balian@gmail.com
|
|
10
|
-
Maintainer: Seto Balian
|
|
11
|
-
Maintainer-email: seto.balian@gmail.com
|
|
12
|
-
Requires-Python: >=3.9,<4.0
|
|
13
11
|
Classifier: Intended Audience :: Developers
|
|
14
12
|
Classifier: Intended Audience :: Science/Research
|
|
15
13
|
Classifier: License :: OSI Approved :: MIT License
|
|
@@ -18,20 +16,16 @@ Classifier: Operating System :: Microsoft :: Windows
|
|
|
18
16
|
Classifier: Operating System :: Unix
|
|
19
17
|
Classifier: Programming Language :: Python
|
|
20
18
|
Classifier: Programming Language :: Python :: 3
|
|
21
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
22
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
23
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
24
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
25
19
|
Classifier: Topic :: Scientific/Engineering
|
|
26
20
|
Classifier: Topic :: Software Development
|
|
27
21
|
Classifier: Typing :: Typed
|
|
22
|
+
Requires-Python: >=3.9
|
|
23
|
+
Requires-Dist: click>=8.1.7
|
|
24
|
+
Requires-Dist: requests>=2.32.3
|
|
25
|
+
Requires-Dist: xdg>=6.0.0
|
|
28
26
|
Provides-Extra: numpy
|
|
29
|
-
Requires-Dist:
|
|
30
|
-
Requires-Dist:
|
|
31
|
-
Requires-Dist: randomgen (>=1.26.1,<2.0.0) ; extra == "numpy"
|
|
32
|
-
Requires-Dist: requests (>=2.31.0,<3.0.0)
|
|
33
|
-
Requires-Dist: xdg (>=6.0.0,<7.0.0)
|
|
34
|
-
Project-URL: Repository, https://github.com/sbalian/quantum-random/
|
|
27
|
+
Requires-Dist: numpy>=2.0.2; extra == 'numpy'
|
|
28
|
+
Requires-Dist: randomgen>=2.1.1; extra == 'numpy'
|
|
35
29
|
Description-Content-Type: text/markdown
|
|
36
30
|
|
|
37
31
|
# Quantum random numbers in Python
|
|
@@ -125,7 +119,7 @@ if you need to pre-fetch at the start of your computation.
|
|
|
125
119
|
## Tests
|
|
126
120
|
|
|
127
121
|
The tests run for Python 3.9 - 3.12 on the latest Windows,
|
|
128
|
-
macOS and Ubuntu runner images.
|
|
122
|
+
macOS and Ubuntu runner images.
|
|
129
123
|
|
|
130
124
|
See [here](./analysis/uniform.md) for a visualisation and a Kolmogorov–Smirnov
|
|
131
125
|
test.
|
|
@@ -150,7 +144,5 @@ See [LICENCE](./LICENSE).
|
|
|
150
144
|
[anu]: https://quantumnumbers.anu.edu.au
|
|
151
145
|
[anupricing]: https://quantumnumbers.anu.edu.au/pricing
|
|
152
146
|
[pyrandom]: https://docs.python.org/3/library/random.html
|
|
153
|
-
[tox]: https://tox.wiki/en/latest/
|
|
154
147
|
[numpy]: https://numpy.org
|
|
155
148
|
[randomgen]: https://github.com/bashtage/randomgen
|
|
156
|
-
|
|
@@ -89,7 +89,7 @@ if you need to pre-fetch at the start of your computation.
|
|
|
89
89
|
## Tests
|
|
90
90
|
|
|
91
91
|
The tests run for Python 3.9 - 3.12 on the latest Windows,
|
|
92
|
-
macOS and Ubuntu runner images.
|
|
92
|
+
macOS and Ubuntu runner images.
|
|
93
93
|
|
|
94
94
|
See [here](./analysis/uniform.md) for a visualisation and a Kolmogorov–Smirnov
|
|
95
95
|
test.
|
|
@@ -114,6 +114,5 @@ See [LICENCE](./LICENSE).
|
|
|
114
114
|
[anu]: https://quantumnumbers.anu.edu.au
|
|
115
115
|
[anupricing]: https://quantumnumbers.anu.edu.au/pricing
|
|
116
116
|
[pyrandom]: https://docs.python.org/3/library/random.html
|
|
117
|
-
[tox]: https://tox.wiki/en/latest/
|
|
118
117
|
[numpy]: https://numpy.org
|
|
119
118
|
[randomgen]: https://github.com/bashtage/randomgen
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Analysis
|
|
2
|
+
|
|
3
|
+
To run the analysis, first install the requirements (includes `quantum-random`):
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
pip install -r requirements.txt
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Then run the script to generate the plot in `uniform.md`:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
python generate_plot.py
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
The output is written to `random.png`.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import random
|
|
2
|
+
from typing import List, Tuple
|
|
3
|
+
|
|
4
|
+
import matplotlib.pyplot as plt
|
|
5
|
+
from scipy import stats
|
|
6
|
+
|
|
7
|
+
import qrandom
|
|
8
|
+
|
|
9
|
+
DataType = Tuple[Tuple[List[float], str], Tuple[List[float], str]]
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def generate_data() -> DataType:
|
|
13
|
+
numbers = [qrandom.random() for _ in range(10000)]
|
|
14
|
+
py_numbers = [random.random() for _ in range(10000)]
|
|
15
|
+
return (numbers, "Quantum random"), (py_numbers, "Python pseudo-random")
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def plot(data: DataType) -> None:
|
|
19
|
+
quantum, python = data
|
|
20
|
+
numbers, quantum_title = quantum
|
|
21
|
+
py_numbers, python_title = python
|
|
22
|
+
|
|
23
|
+
plt.figure(figsize=(8, 3))
|
|
24
|
+
plt.subplot(1, 2, 1)
|
|
25
|
+
plt.hist(numbers, edgecolor="black")
|
|
26
|
+
plt.title(quantum_title)
|
|
27
|
+
plt.subplot(1, 2, 2)
|
|
28
|
+
plt.hist(py_numbers, edgecolor="black")
|
|
29
|
+
plt.title(python_title)
|
|
30
|
+
plt.tight_layout()
|
|
31
|
+
plt.savefig("random.png", dpi=120, bbox_inches="tight")
|
|
32
|
+
return
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def kstest(data: DataType) -> None:
|
|
36
|
+
quantum, python = data
|
|
37
|
+
numbers, quantum_title = quantum
|
|
38
|
+
py_numbers, python_title = python
|
|
39
|
+
|
|
40
|
+
print(quantum_title, stats.kstest(numbers, "uniform"))
|
|
41
|
+
print(python_title, stats.kstest(py_numbers, "uniform"))
|
|
42
|
+
return
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def main() -> None:
|
|
46
|
+
data = generate_data()
|
|
47
|
+
plot(data)
|
|
48
|
+
kstest(data)
|
|
49
|
+
return
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
if __name__ == "__main__":
|
|
53
|
+
main()
|
|
Binary file
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Visualise and test if the quantum randoms are uniformly distributed in [0.0, 1)
|
|
2
|
+
|
|
3
|
+
Calling `qrandom.random()` 10,000 times, and comparing it to `random.random()`:
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
The [Kolmogorov–Smirnov statistics][kstest] with the reference distribution
|
|
8
|
+
`scipy.uniform` gives the following results.
|
|
9
|
+
|
|
10
|
+
| Trial | Quantum statistic | Quantum p-value | Std. statistic | Std. p-value |
|
|
11
|
+
| ----- | ----------------- | --------------- | ---------------| -------------|
|
|
12
|
+
| 1 | 0.01 | 0.2 | 0.005 | 0.9 |
|
|
13
|
+
| 2 | 0.007 | 0.7 | 0.005 | 1.0 |
|
|
14
|
+
| 3 | 0.006 | 0.9 | 0.008 | 0.6 |
|
|
15
|
+
| 4 | 0.01 | 0.3 | 0.008 | 0.5 |
|
|
16
|
+
|
|
17
|
+
Each trial is a different run of [`scipy.stats.kstest`][scipy-kstest] with
|
|
18
|
+
10,000 numbers. The plot shows the numbers for the last trial.
|
|
19
|
+
|
|
20
|
+
[kstest]: https://en.wikipedia.org/wiki/Kolmogorov%E2%80%93Smirnov_test
|
|
21
|
+
[scipy-kstest]: https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.kstest.html
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "quantum-random"
|
|
3
|
+
version = "1.4.2"
|
|
4
|
+
description = "Quantum random numbers"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
license = {text = "MIT License"}
|
|
7
|
+
authors = [
|
|
8
|
+
{ name = "Seto Balian", email = "seto.balian@gmail.com" }
|
|
9
|
+
]
|
|
10
|
+
maintainers = [
|
|
11
|
+
{ name = "Seto Balian", email = "seto.balian@gmail.com" }
|
|
12
|
+
]
|
|
13
|
+
keywords = ["quantum", "random", "statistics"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Intended Audience :: Science/Research",
|
|
16
|
+
"Intended Audience :: Developers",
|
|
17
|
+
"Programming Language :: Python",
|
|
18
|
+
"Programming Language :: Python :: 3",
|
|
19
|
+
"Topic :: Software Development",
|
|
20
|
+
"Topic :: Scientific/Engineering",
|
|
21
|
+
"Typing :: Typed",
|
|
22
|
+
"Operating System :: Microsoft :: Windows",
|
|
23
|
+
"Operating System :: Unix",
|
|
24
|
+
"Operating System :: MacOS",
|
|
25
|
+
"License :: OSI Approved :: MIT License",
|
|
26
|
+
]
|
|
27
|
+
requires-python = ">=3.9"
|
|
28
|
+
dependencies = [
|
|
29
|
+
"click>=8.1.7",
|
|
30
|
+
"requests>=2.32.3",
|
|
31
|
+
"xdg>=6.0.0",
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
[project.optional-dependencies]
|
|
35
|
+
numpy = [
|
|
36
|
+
"numpy>=2.0.2",
|
|
37
|
+
"randomgen>=2.1.1",
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
[dependency-groups]
|
|
41
|
+
dev = [
|
|
42
|
+
"pytest-mock>=3.14.0",
|
|
43
|
+
"pytest>=8.3.3",
|
|
44
|
+
"responses>=0.25.3",
|
|
45
|
+
"mypy>=1.13.0",
|
|
46
|
+
"flake8>=7.1.1",
|
|
47
|
+
"isort>=5.13.2",
|
|
48
|
+
"black>=24.10.0",
|
|
49
|
+
"pip>=24.3.1",
|
|
50
|
+
]
|
|
51
|
+
|
|
52
|
+
[project.scripts]
|
|
53
|
+
qrandom-init = "qrandom._cli:main"
|
|
54
|
+
|
|
55
|
+
[project.urls]
|
|
56
|
+
Homepage = "https://github.com/sbalian/quantum-random"
|
|
57
|
+
Repository = "https://github.com/sbalian/quantum-random"
|
|
58
|
+
|
|
59
|
+
[build-system]
|
|
60
|
+
requires = ["hatchling"]
|
|
61
|
+
build-backend = "hatchling.build"
|
|
62
|
+
|
|
63
|
+
[tool.hatch.build.targets.wheel]
|
|
64
|
+
packages = ["src/qrandom"]
|
|
65
|
+
|
|
66
|
+
[tool.pytest.ini_options]
|
|
67
|
+
addopts = "--verbose"
|
|
68
|
+
testpaths = "tests"
|
|
69
|
+
|
|
70
|
+
[tool.mypy]
|
|
71
|
+
ignore_missing_imports = true
|
|
72
|
+
|
|
73
|
+
[tool.black]
|
|
74
|
+
line-length = 79
|
|
75
|
+
|
|
76
|
+
[tool.isort]
|
|
77
|
+
profile = "black"
|
|
78
|
+
line_length = 79
|
|
79
|
+
known_first_party = ["qrandom"]
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import json
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
import responses
|
|
5
|
+
|
|
6
|
+
from qrandom import _api, _generator
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@pytest.fixture
|
|
10
|
+
def mocked_responses():
|
|
11
|
+
with responses.RequestsMock() as rsps:
|
|
12
|
+
yield rsps
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@pytest.fixture
|
|
16
|
+
def test_responses():
|
|
17
|
+
with open("tests/data/responses.json") as f:
|
|
18
|
+
return json.load(f)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@pytest.fixture
|
|
22
|
+
def anu_url():
|
|
23
|
+
return "https://api.quantumnumbers.anu.edu.au"
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@pytest.fixture
|
|
27
|
+
def api_client_with_successful_api_call(
|
|
28
|
+
mocked_responses, anu_url, test_responses
|
|
29
|
+
):
|
|
30
|
+
mocked_responses.get(
|
|
31
|
+
anu_url,
|
|
32
|
+
json={"data": test_responses[0]["data"], "success": True},
|
|
33
|
+
status=200,
|
|
34
|
+
)
|
|
35
|
+
return _api.Client("key")
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@pytest.fixture
|
|
39
|
+
def api_client_with_failed_api_call(mocked_responses, anu_url):
|
|
40
|
+
mocked_responses.get(
|
|
41
|
+
anu_url,
|
|
42
|
+
json={"success": False},
|
|
43
|
+
status=400,
|
|
44
|
+
)
|
|
45
|
+
return _api.Client("key")
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@pytest.fixture
|
|
49
|
+
def api_client_with_failed_api_call_and_no_json_response(
|
|
50
|
+
mocked_responses, anu_url
|
|
51
|
+
):
|
|
52
|
+
mocked_responses.get(
|
|
53
|
+
anu_url,
|
|
54
|
+
status=400,
|
|
55
|
+
)
|
|
56
|
+
return _api.Client("key")
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
@pytest.fixture
|
|
60
|
+
def api_client_with_failed_api_call_with_200_status(mocked_responses, anu_url):
|
|
61
|
+
mocked_responses.get(
|
|
62
|
+
anu_url,
|
|
63
|
+
json={"success": False},
|
|
64
|
+
status=200,
|
|
65
|
+
)
|
|
66
|
+
return _api.Client("key")
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
@pytest.fixture
|
|
70
|
+
def api_client_with_mocked_fetch_hex_raw(mocker, test_responses):
|
|
71
|
+
mocker.patch(
|
|
72
|
+
"qrandom._api.Client.fetch_hex_raw",
|
|
73
|
+
return_value=test_responses[0],
|
|
74
|
+
)
|
|
75
|
+
return _api.Client("key")
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
@pytest.fixture
|
|
79
|
+
def quantum_random_with_no_api_calls():
|
|
80
|
+
return _generator.QuantumRandom()
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
@pytest.fixture
|
|
84
|
+
def quantum_random_with_mocked_fetch_hex_raw(mocker, test_responses):
|
|
85
|
+
mocker.patch(
|
|
86
|
+
"qrandom._api.Client.fetch_hex_raw",
|
|
87
|
+
return_value=test_responses[0],
|
|
88
|
+
)
|
|
89
|
+
return _generator.QuantumRandom()
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
@pytest.fixture
|
|
93
|
+
def quantum_random_with_mocked_fetch_hex_raw_twice(mocker, test_responses):
|
|
94
|
+
mocker.patch(
|
|
95
|
+
"qrandom._api.Client.fetch_hex_raw",
|
|
96
|
+
side_effect=[test_responses[0], test_responses[1]],
|
|
97
|
+
)
|
|
98
|
+
return _generator.QuantumRandom()
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
@pytest.fixture
|
|
102
|
+
def quantum_random_with_mocked_fetch_hex_raw_five_times(
|
|
103
|
+
mocker, test_responses
|
|
104
|
+
):
|
|
105
|
+
mocker.patch(
|
|
106
|
+
"qrandom._api.Client.fetch_hex_raw",
|
|
107
|
+
side_effect=[test_responses[i] for i in range(5)],
|
|
108
|
+
)
|
|
109
|
+
return _generator.QuantumRandom()
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
@pytest.fixture
|
|
113
|
+
def quantum_random_with_mocked_fetch_hex_raw_for_all_data(
|
|
114
|
+
mocker, test_responses
|
|
115
|
+
):
|
|
116
|
+
mocker.patch(
|
|
117
|
+
"qrandom._api.Client.fetch_hex_raw",
|
|
118
|
+
side_effect=test_responses,
|
|
119
|
+
)
|
|
120
|
+
return _generator.QuantumRandom()
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import pathlib
|
|
3
|
+
|
|
4
|
+
import click
|
|
5
|
+
|
|
6
|
+
from qrandom import _api
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@click.command()
|
|
10
|
+
@click.option(
|
|
11
|
+
"--num-hits",
|
|
12
|
+
"-n",
|
|
13
|
+
type=int,
|
|
14
|
+
default=10,
|
|
15
|
+
show_default=True,
|
|
16
|
+
help="Number of API calls.",
|
|
17
|
+
)
|
|
18
|
+
@click.option(
|
|
19
|
+
"--output-directory",
|
|
20
|
+
"-o",
|
|
21
|
+
type=click.Path(
|
|
22
|
+
exists=True,
|
|
23
|
+
file_okay=False,
|
|
24
|
+
resolve_path=True,
|
|
25
|
+
path_type=pathlib.Path,
|
|
26
|
+
),
|
|
27
|
+
default=pathlib.Path("."),
|
|
28
|
+
help="Output directory.",
|
|
29
|
+
show_default=True,
|
|
30
|
+
)
|
|
31
|
+
def main(num_hits, output_directory) -> None:
|
|
32
|
+
"""Write a JSON file of responses from the ANU API for testing purposes."""
|
|
33
|
+
|
|
34
|
+
output_path = output_directory / "responses.json"
|
|
35
|
+
if output_path.exists():
|
|
36
|
+
click.confirm(
|
|
37
|
+
f"Would you like to overwrite {output_path}?",
|
|
38
|
+
abort=True,
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
key = _api.find_api_key()
|
|
42
|
+
client = _api.Client(key)
|
|
43
|
+
|
|
44
|
+
click.echo("Fetching data ...")
|
|
45
|
+
with click.progressbar(range(num_hits)) as bar:
|
|
46
|
+
responses = [client.fetch_hex_raw() for _ in bar]
|
|
47
|
+
click.echo("Writing responses ...")
|
|
48
|
+
with open(pathlib.Path(output_path), "w") as f:
|
|
49
|
+
json.dump(responses, f)
|
|
50
|
+
click.echo(f"Wrote responses to {output_path} .")
|
|
51
|
+
|
|
52
|
+
return
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
if __name__ == "__main__":
|
|
56
|
+
main()
|