Skip to content

Commit 3451f5d

Browse files
Test hdf format
1 parent b3a9fc8 commit 3451f5d

File tree

3 files changed

+142
-0
lines changed

3 files changed

+142
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,3 +167,5 @@ cython_debug/
167167

168168
uv.lock
169169
docker/.env copy
170+
171+
*.DS_Store

tests/test_h5.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# %%
2+
from h5pydantic import H5Dataset, H5Group, H5Int64
3+
4+
5+
class Baseline(H5Group):
6+
temperature: float
7+
humidity: float
8+
9+
10+
class Metadata(H5Group):
11+
start: Baseline
12+
end: Baseline
13+
14+
15+
class Acquisition(H5Dataset, shape=(3, 5), dtype=H5Int64):
16+
beamstop: H5Int64
17+
18+
19+
class Experiment(H5Group):
20+
metadata: Metadata
21+
data: list[Acquisition] = []
22+
23+
24+
# %%
25+
# from model import Experiment, Acquisition, Baseline, Metadata
26+
27+
import numpy as np
28+
from pathlib import Path
29+
from rich.pretty import pprint
30+
31+
experiment = Experiment(
32+
data=[Acquisition(beamstop=11), Acquisition(beamstop=12)],
33+
metadata=Metadata(
34+
start=Baseline(temperature=25.0, humidity=0.4),
35+
end=Baseline(temperature=26.0, humidity=0.4),
36+
),
37+
)
38+
39+
with experiment.dump(Path("experiment.hdf")):
40+
experiment.data[0][()] = np.random.randint(255, size=(3, 5))
41+
experiment.data[1][()] = np.random.randint(255, size=(3, 5))
42+
43+
pprint(experiment)
44+
45+
# %%
46+
experiment
47+
48+
49+
50+
# %%

tests/test_storage.py

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# %%
2+
# with open("./tests/atomic.json", "r") as f:
3+
# circuit = AtomicCircuit.model_validate_json(f.read())
4+
5+
# print(circuit)
6+
7+
# %%
8+
from minio import Minio
9+
import os
10+
11+
os.getenv("127.0.0.1:9000")
12+
13+
user_id = '1234'
14+
job_id = '4321'
15+
16+
client = Minio(
17+
"127.0.0.1:9000",
18+
access_key="admin",
19+
secret_key="password",
20+
secure=False
21+
)
22+
23+
# %%
24+
source_file = "./tests/atomic.json"
25+
bucket_name = f"{user_id}"
26+
destination_file = f"{job_id}/artifact1.txt"
27+
28+
#%%
29+
import io
30+
from oqd_core.interface.atomic import AtomicCircuit
31+
32+
circuit = AtomicCircuit.parse_file(source_file)
33+
#%%
34+
35+
36+
37+
json_bytes = circuit.model_dump_json().encode('utf-8')
38+
buffer = io.BytesIO(json_bytes)
39+
40+
client.put_object(
41+
"oqd-cloud-bucket",
42+
"result.txt",
43+
data=buffer,
44+
length=len(json_bytes),
45+
content_type='application/json'
46+
)
47+
48+
#%%
49+
# Make the bucket if it doesn't exist.
50+
found = client.bucket_exists(bucket_name)
51+
if not found:
52+
client.make_bucket(bucket_name)
53+
print("Created bucket", bucket_name)
54+
else:
55+
print("Bucket", bucket_name, "already exists")
56+
57+
58+
client.fput_object(
59+
bucket_name, destination_file, source_file,
60+
)
61+
print(
62+
source_file, "successfully uploaded as object",
63+
destination_file, "to bucket", bucket_name,
64+
)
65+
66+
#%%
67+
# Server should:
68+
# 1. Run the job, submitting to the requested backend
69+
# 2. The backend returns the result as a HDF5/Pydantic model, which is dumped to as a Minio artifact [jobid.hdf5]
70+
# 3. When client requests results, the server checks if successful, generates a temporary link, and returns the url
71+
# 4. The Client class will automatically
72+
73+
# %% [SERVER] creates a minio link for the file, with a expiry time
74+
from datetime import timedelta
75+
76+
url = client.get_presigned_url(
77+
"GET",
78+
bucket_name,
79+
destination_file,
80+
expires=timedelta(hours=2),
81+
)
82+
83+
#%% [CLIENT] saves to provided filename
84+
import urllib.request
85+
file = urllib.request.urlretrieve(url, "result.txt")
86+
87+
#%% [CLIENT] loads directly to memory
88+
with urllib.request.urlopen(url) as f:
89+
html = f.read()#.decode('utf-8')
90+
# %%

0 commit comments

Comments
 (0)