Skip to content

Commit 3360bc8

Browse files
committed
updates to api main and dispatcher
1 parent 9ce3e20 commit 3360bc8

File tree

11 files changed

+414
-21
lines changed

11 files changed

+414
-21
lines changed

gateway/handlers/states.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,15 +91,15 @@ def generate_mem3dg_state(
9191
}
9292

9393
for key, value in parameters_config.items():
94-
doc['config']['parameters'][key] = value
94+
doc['membrane']['config']['parameters'][key] = value
9595

9696
if geometry_parameters is not None and geometry_type is not None:
97-
doc['config']['geometry'] = {
97+
doc['membrane']['config']['geometry'] = {
9898
'type': geometry_type,
9999
'parameters': geometry_parameters
100100
}
101101
else:
102-
doc['config']['mesh_file'] = mesh_file
102+
doc['membrane']['config']['mesh_file'] = mesh_file
103103

104104
return doc
105105

gateway/handlers/submit.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from fastapi import UploadFile, HTTPException
77
from process_bigraph import Composite
88

9-
from shared.data_model import UtcRun, AmiciRun, CobraRun, CopasiRun, TelluriumRun, ValidatedComposition
9+
from shared.data_model import UtcRun, AmiciRun, CobraRun, CopasiRun, TelluriumRun, ValidatedComposition, Mem3dgRun
1010
from shared.database import DatabaseConnector
1111
from shared.environment import DEFAULT_JOB_COLLECTION_NAME, DEFAULT_BUCKET_NAME
1212
from shared.io import write_uploaded_file
@@ -26,6 +26,7 @@ async def submit_pymem3dg_run(
2626
volume: float,
2727
parameters_config: dict[str, float | int],
2828
damping: float,
29+
duration: int,
2930
tolerance: Optional[float] = 1e-11,
3031
geometry_type: Optional[str] = None,
3132
geometry_parameters: Optional[Dict[str, Union[float, int]]] = None,
@@ -51,7 +52,9 @@ async def submit_pymem3dg_run(
5152
job_id=job_id,
5253
last_updated=db_connector.timestamp(),
5354
status="PENDING",
54-
**input_state
55+
simulators=["pymem3dg"],
56+
duration=duration,
57+
spec=input_state
5558
)
5659

5760
# save job to db

gateway/main.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,7 @@ def check_health() -> HealthCheckResponse:
471471
summary="Run a Mem3dg Process",
472472
)
473473
async def run_mem3dg_process(
474+
duration: int = Query(...),
474475
characteristic_time_step: float = Query(...),
475476
tension_modulus: float = Query(...),
476477
preferred_area: float = Query(...),
@@ -479,6 +480,7 @@ async def run_mem3dg_process(
479480
osmotic_strength: float = Query(...),
480481
volume: float = Query(...),
481482
damping: float = Query(...),
483+
bending_kbc: float = Query(...),
482484
tolerance: Optional[float] = Query(default=1e-11),
483485
# geometry_type: Optional[str] = None,
484486
# geometry_parameters: Optional[Dict[str, Union[float, int]]] = None,
@@ -491,6 +493,12 @@ async def run_mem3dg_process(
491493
bucket_name=DEFAULT_BUCKET_NAME,
492494
extension='.ply'
493495
)
496+
497+
parameters = {
498+
"bending": {
499+
"Kbc": bending_kbc,
500+
}
501+
}
494502
mem3dg_run = await submit_pymem3dg_run(
495503
job_id=job_id,
496504
db_connector=db_conn_gateway,
@@ -504,6 +512,8 @@ async def run_mem3dg_process(
504512
damping=damping,
505513
tolerance=tolerance,
506514
mesh_file=uploaded_file_location,
515+
parameters_config=parameters,
516+
duration=duration
507517
)
508518

509519
return mem3dg_run

pyproject.toml

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,17 @@ dependencies = [
2020
"nbformat"
2121
]
2222

23+
# also make sure to install readdy and pymem3dg:
24+
# conda install -n bsp conda-forge::pymem3dg -y \
25+
# && conda install -n bsp conda-forge::readdy -y
26+
2327
[tool.poetry]
2428
packages = [
2529
{include = "gateway"},
2630
{include = "shared"},
2731
{include = "worker"},
28-
{include = "common"}
32+
{include = "common"},
33+
{include = "tests"}
2934
]
3035

3136
[build-system]
@@ -34,6 +39,7 @@ build-backend = "poetry.core.masonry.api"
3439

3540

3641
[tool.pytest.ini_options]
42+
addopts = "-s"
3743
testpaths = ["tests"]
38-
addopts = "--ignore=setup.py"
39-
python_files = "*.py"
44+
asyncio_mode = "auto"
45+
asyncio_default_fixture_loop_scope = "function"

shared/data_model.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,20 @@ class SmoldynRun(Run):
5858
dt: float
5959

6060

61+
62+
@dataclass
63+
class Mem3dgRun(CompositionRun):
64+
"""
65+
:param simulators:
66+
:param duration:
67+
:param spec:
68+
:param results:
69+
"""
70+
pass
71+
72+
6173
@dataclass
62-
class Mem3dgRun(Run):
74+
class _Mem3dgRun(Run):
6375
characteristic_time_step: float
6476
tension_modulus: float
6577
preferred_area: float

shared/log_config.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,5 @@ def setup_logging(fname: str, return_all: bool = False):
3030
# Add the console handler to the root logger and uvicorn logger
3131
root_logger.addHandler(console_handler)
3232

33-
return root_logger, console_handler if return_all else root_logger
33+
# return root_logger, console_handler if return_all else root_logger
34+
return root_logger

tests/test_dispatcher.py

Lines changed: 49 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,61 @@
22
import os
33
import asyncio
44

5+
import pytest
6+
from process_bigraph import Composite
7+
58
from worker.dispatch import JobDispatcher
69

7-
TEST_DIR = os.path.dirname(os.path.abspath(__file__))
10+
# TEST_DIR = os.path.dirname(os.path.abspath(__file__))
11+
12+
13+
@pytest.fixture
14+
def test_dir() -> str:
15+
return os.path.dirname(os.path.abspath(__file__))
16+
17+
18+
@pytest.fixture
19+
@pytest.mark.usefixtures("test_dir")
20+
def payload(test_dir: str) -> dict:
21+
with open(os.path.join(test_dir, "test_fixtures", "test_membrane_request2.json")) as f:
22+
test_request = json.load(f)
23+
return test_request
24+
825

26+
@pytest.mark.usefixtures('payload')
27+
class TestDispatcher:
28+
def setup_method(self):
29+
self.dispatcher = JobDispatcher()
930

10-
async def test_dispatch_composition():
11-
with open(os.path.join(TEST_DIR, "test_fixtures", "test_request.json")) as f:
31+
def test_generate_composition(self, payload: dict):
32+
composition = self.dispatcher.generate_composite(payload)
33+
assert composition is not None
34+
print(f'Got the composition state:\n{composition.state}')
35+
36+
37+
def get_test_dir() -> str:
38+
return os.path.dirname(os.path.abspath(__file__))
39+
40+
41+
def get_payload() -> dict:
42+
test_dir = get_test_dir()
43+
with open(os.path.join(test_dir, "test_fixtures", "test_membrane_request2.json")) as f:
1244
test_request = json.load(f)
45+
return test_request
1346

47+
48+
async def test_generate_composition():
1449
dispatcher = JobDispatcher()
15-
await dispatcher.dispatch_composition(test_request)
50+
payload = get_payload()
51+
await dispatcher.dispatch_composition(payload)
52+
# assert composition is not None
53+
# print(f'Got the composition state:\n{composition.state}')
54+
55+
56+
asyncio.run(test_generate_composition())
1657

58+
# @pytest.mark.asyncio
59+
# async def test_dispatch_composition():
60+
# dispatcher = JobDispatcher()
61+
# await dispatcher.dispatch_composition(test_request)
1762

18-
if __name__ == "__main__":
19-
asyncio.run(test_dispatch_composition())
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
{
2+
"job_id": "composition-9c436329-cede-4680-9628-8483ee6a5528",
3+
"last_updated": "2025-02-11 17:36:41.931444",
4+
"status": "PENDING",
5+
"simulators": [],
6+
"duration": 10,
7+
"spec": {
8+
"membrane": {
9+
"_type": "process",
10+
"address": "local:simple-membrane-process",
11+
"config": {
12+
"characteristic_time_step": 1,
13+
"geometry": {
14+
"type": "icosphere",
15+
"parameters": {
16+
"radius": 1,
17+
"subdivision": 2
18+
}
19+
},
20+
"tension_model": {
21+
"modulus": 0.1,
22+
"preferred_area": 12.4866
23+
},
24+
"osmotic_model": {
25+
"preferred_volume": 2.9306666666666668,
26+
"reservoir_volume": 1,
27+
"strength": 0.02,
28+
"volume": 2.9
29+
},
30+
"parameters": {
31+
"bending": {
32+
"Kbc": 0.0000822
33+
},
34+
"damping": 0.05
35+
},
36+
"tolerance": 1e-11,
37+
"console_output": false
38+
},
39+
"inputs": {
40+
"geometry": [
41+
"geometry_store"
42+
],
43+
"velocities": [
44+
"velocities_store"
45+
],
46+
"protein_density": [
47+
"protein_density_store"
48+
],
49+
"volume": [
50+
"volume_store"
51+
],
52+
"preferred_volume": [
53+
"preferred_volume_store"
54+
],
55+
"reservoir_volume": [
56+
"reservoir_volume_store"
57+
],
58+
"surface_area": [
59+
"surface_area_store"
60+
],
61+
"osmotic_strength": [
62+
"osmotic_strength_store"
63+
]
64+
},
65+
"outputs": {
66+
"geometry": [
67+
"geometry_store"
68+
],
69+
"velocities": [
70+
"velocities_store"
71+
],
72+
"protein_density": [
73+
"protein_density_store"
74+
],
75+
"volume": [
76+
"volume_store"
77+
],
78+
"preferred_volume": [
79+
"preferred_volume_store"
80+
],
81+
"reservoir_volume": [
82+
"reservoir_volume_store"
83+
],
84+
"surface_area": [
85+
"surface_area_store"
86+
],
87+
"net_forces": [
88+
"net_forces_store"
89+
],
90+
"notable_vertices": [
91+
"notable_vertices_store"
92+
]
93+
}
94+
},
95+
"emitter": {
96+
"_type": "step",
97+
"address": "local:ram-emitter",
98+
"config": {
99+
"emit": {
100+
"geometry": "GeometryType",
101+
"velocities": "VelocitiesType",
102+
"protein_density": "ProteinDensityType",
103+
"volume": "float",
104+
"preferred_volume": "float",
105+
"reservoir_volume": "float",
106+
"surface_area": "float",
107+
"net_forces": "MechanicalForcesType",
108+
"notable_vertices": "list[boolean]"
109+
}
110+
},
111+
"inputs": {
112+
"geometry": [
113+
"geometry_store"
114+
],
115+
"velocities": [
116+
"velocities_store"
117+
],
118+
"protein_density": [
119+
"protein_density_store"
120+
],
121+
"volume": [
122+
"volume_store"
123+
],
124+
"preferred_volume": [
125+
"preferred_volume_store"
126+
],
127+
"reservoir_volume": [
128+
"reservoir_volume_store"
129+
],
130+
"surface_area": [
131+
"surface_area_store"
132+
],
133+
"net_forces": [
134+
"net_forces_store"
135+
],
136+
"notable_vertices": [
137+
"notable_vertices_store"
138+
]
139+
}
140+
}
141+
},
142+
"results": {}
143+
}

0 commit comments

Comments
 (0)