Skip to content

Commit 55605be

Browse files
committed
wip
1 parent 829fbb3 commit 55605be

File tree

17 files changed

+1041
-688
lines changed

17 files changed

+1041
-688
lines changed

docs/how-to/use-core-http-api-client.md

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ acquisitions = await client.aget_acquisitions()
6868
### Creating an Acquisition
6969

7070
```python
71-
from src.epu_data_intake.data_model import EpuSessionData
71+
from src.epu_data_intake.model.schemas import EpuSessionData
7272
from datetime import datetime
7373

7474
# Create an acquisition from EPU session data
@@ -139,22 +139,26 @@ Here's an example of creating entities at each level:
139139
acquisition = client.create_acquisition(EpuSessionData(id="acq-1", name="Test Acquisition"))
140140

141141
# Create a grid for the acquisition
142-
from src.epu_data_intake.data_model import Grid
143-
grid = Grid(data_dir="/path/to/grid")
142+
from src.epu_data_intake.model.schemas import GridData
143+
144+
grid = GridData(data_dir="/path/to/grid")
144145
grid_response = client.create_acquisition_grid(acquisition.id, grid)
145146

146147
# Create a grid square for the grid
147-
from src.epu_data_intake.data_model import GridSquareData
148+
from src.epu_data_intake.model.schemas import GridSquareData
149+
148150
gridsquare = GridSquareData(id="gs-1", data_dir="/path/to/gridsquare")
149151
gridsquare_response = client.create_grid_gridsquare(grid_response.id, gridsquare)
150152

151153
# Create a foil hole for the grid square
152-
from src.epu_data_intake.data_model import FoilHoleData
154+
from src.epu_data_intake.model.schemas import FoilHoleData
155+
153156
foilhole = FoilHoleData(id="fh-1", gridsquare_id=gridsquare.id)
154157
foilhole_response = client.create_gridsquare_foilhole(gridsquare_response.id, foilhole)
155158

156159
# Create a micrograph for the foil hole
157-
from src.epu_data_intake.data_model import MicrographData, MicrographManifest
160+
from src.epu_data_intake.model.schemas import MicrographData, MicrographManifest
161+
158162
manifest = MicrographManifest(
159163
unique_id="mic-1",
160164
acquisition_datetime=datetime.now(),

docs/software-architecture.mermaid

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
graph LR
1+
graph TD
22
subgraph k8s["Kubernetes Cluster (Scientific Compute)"]
33
subgraph core["Core Services"]
44
api["SmartEM Core Service & API"]
@@ -44,4 +44,4 @@ graph LR
4444
class infrastructure infra
4545
class ext ext
4646
%% Link styling
47-
linkStyle 0,1,2,3,4,5,6,7,8 stroke:#666
47+
linkStyle 0,1,2,3,4,5,6,7,8 stroke:#666

src/epu_data_intake/__main__.py

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from watchdog.observers import Observer
1010

1111
from src.epu_data_intake.core_http_api_client import SmartEMAPIClient as APIClient
12-
from src.epu_data_intake.data_model import EpuAcquisitionSessionStore
12+
from src.epu_data_intake.model.store import InMemoryDataStore, PersistentDataStore
1313
from src.epu_data_intake.fs_parser import EpuParser
1414
from src.epu_data_intake.fs_watcher import (
1515
DEFAULT_PATTERNS,
@@ -72,15 +72,22 @@ def parse_callback(verbose: int = shared_verbosity_option):
7272
"""Parse group callback to enable verbose flag on parse command"""
7373
pass
7474

75+
7576
@parse_cli.command("dir")
7677
def parse_epu_output_dir(
77-
epu_output_dir: str,
78-
verbose: int = shared_verbosity_option,
78+
epu_output_dir: str,
79+
verbose: int = shared_verbosity_option,
7980
):
8081
"""Parse an entire EPU output directory structure. May contain multiple grids"""
81-
datastore = EpuAcquisitionSessionStore(epu_output_dir)
82+
# Rationale here is that parsers don't persist data to API by design - only watch command does that
83+
datastore = InMemoryDataStore(epu_output_dir)
84+
85+
# Initialize the acquisition_rels dict with a set for the acquisition
86+
datastore.acquisition_rels[datastore.acquisition.uuid] = set()
87+
88+
# The EpuParser.parse_epu_output_dir would need to be updated to work with the new store
8289
datastore = EpuParser.parse_epu_output_dir(datastore)
83-
logging.info(datastore)
90+
False and logging.debug(datastore)
8491

8592

8693
@parse_cli.command("grid")
@@ -91,12 +98,14 @@ def parse_grid(
9198
is_valid, errors = EpuParser.validate_project_dir(Path(grid_data_dir))
9299

93100
if not is_valid:
94-
logging.info("Grid data dir dir is structurally invalid. Found the following issues:\n")
101+
logging.warning("Grid data dir dir is structurally invalid. Found the following issues:\n")
95102
for error in errors:
96-
logging.info(f"- {error}")
103+
logging.warning(f"- {error}")
97104
else:
98-
gridstore = EpuParser.parse_grid_dir(grid_data_dir)
99-
logging.info(gridstore)
105+
# Rationale here is that parsers don't persist data to API by design - only watch command does that
106+
datastore = InMemoryDataStore(grid_data_dir) # TODO confirm this is the dir expected here - top-level watch dir or grid root dir?
107+
grid_uuid = EpuParser.parse_grid_dir(grid_data_dir, datastore)
108+
False and logging.debug(datastore)
100109

101110

102111
@parse_cli.command("session")

src/epu_data_intake/core_http_api_client.py

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@
3535
FoilHoleResponse,
3636
MicrographResponse,
3737
)
38-
from src.epu_data_intake.data_model import (
39-
EpuSessionData,
40-
Grid,
38+
from src.epu_data_intake.model.schemas import (
39+
AcquisitionData,
40+
GridData,
4141
GridSquareData,
4242
FoilHoleData,
4343
MicrographData,
@@ -66,10 +66,11 @@ class EntityConverter:
6666
"""
6767

6868
@staticmethod
69-
def epu_session_to_request(entity: EpuSessionData) -> AcquisitionCreateRequest:
69+
def acquisition_to_request(entity: AcquisitionData) -> AcquisitionCreateRequest:
7070
"""Convert EPU session data to acquisition request model"""
7171
return AcquisitionCreateRequest(
72-
id=entity.id,
72+
uuid=entity.uuid,
73+
# TODO check if natural `id` should also be included
7374
name=entity.name,
7475
start_time=entity.start_time,
7576
storage_path=entity.storage_path,
@@ -80,11 +81,11 @@ def epu_session_to_request(entity: EpuSessionData) -> AcquisitionCreateRequest:
8081
)
8182

8283
@staticmethod
83-
def grid_to_request(entity: Grid, acquisition_id: str) -> GridCreateRequest:
84+
def grid_to_request(entity: GridData, acquisition_id: str) -> GridCreateRequest:
8485
"""Convert Grid data to grid request model"""
8586
return GridCreateRequest(
86-
id=entity.id,
87-
name=entity.session_data.name if entity.session_data else "Unknown",
87+
uuid=entity.uuid,
88+
name=entity.acquisition_data.name if entity.acquisition_data else "Unknown", # Fixed to acquisition_data
8889
acquisition_id=acquisition_id,
8990
data_dir=str(entity.data_dir) if entity.data_dir else None,
9091
atlas_dir=str(entity.atlas_dir) if entity.atlas_dir else None,
@@ -407,11 +408,11 @@ async def aget_acquisitions(self) -> List[AcquisitionResponse]:
407408
get_acquisitions = _sync_wrap(aget_acquisitions)
408409

409410
async def acreate_acquisition(self,
410-
acquisition: Union[AcquisitionCreateRequest, EpuSessionData]) -> AcquisitionResponse:
411+
acquisition: Union[AcquisitionCreateRequest, AcquisitionData]) -> AcquisitionResponse:
411412
"""Create a new acquisition (async)"""
412-
# Convert EpuSessionData to AcquisitionCreateRequest if needed
413-
if isinstance(acquisition, EpuSessionData):
414-
acquisition = EntityConverter.epu_session_to_request(acquisition)
413+
# Convert AcquisitionData to AcquisitionCreateRequest if needed
414+
if isinstance(acquisition, AcquisitionData):
415+
acquisition = EntityConverter.acquisition_to_request(acquisition)
415416

416417
response = await self._request("post", "acquisitions", acquisition, AcquisitionResponse)
417418
# Store ID mapping
@@ -473,11 +474,11 @@ async def aget_acquisition_grids(self, acquisition_id: str) -> List[GridResponse
473474
async def acreate_acquisition_grid(
474475
self,
475476
acquisition_id: str,
476-
grid: Union[GridCreateRequest, Grid]
477+
grid: Union[GridCreateRequest, GridData]
477478
) -> GridResponse:
478479
"""Create a new grid for a specific acquisition (async)"""
479480
# Convert Grid to GridCreateRequest if needed
480-
if isinstance(grid, Grid):
481+
if isinstance(grid, GridData):
481482
grid_request = EntityConverter.grid_to_request(grid, acquisition_id)
482483
else:
483484
grid_request = grid
@@ -787,13 +788,13 @@ def create(self, entity_type: str, entity_id: str, entity: Any, parent: Optional
787788
self._logger.info(f"Creating {entity_type}/{entity_id} via API" +
788789
(f" with parent {parent[0]}/{parent[1]}" if parent else ""))
789790

790-
if entity_type == "acquisition" and isinstance(entity, EpuSessionData):
791+
if entity_type == "acquisition" and isinstance(entity, AcquisitionData):
791792
response = self.create_acquisition(entity)
792793
self._store_entity_id_mapping("acquisition", entity_id, response.id)
793794
self._logger.info(f"Successfully created acquisition {entity_id} (DB ID: {response.id})")
794795
return True
795796

796-
elif entity_type == "grid" and isinstance(entity, Grid):
797+
elif entity_type == "grid" and isinstance(entity, GridData):
797798
if parent and parent[0] == "acquisition":
798799
acquisition_db_id = self._get_db_id("acquisition", parent[1])
799800
if not acquisition_db_id:
@@ -823,6 +824,27 @@ def create(self, entity_type: str, entity_id: str, entity: Any, parent: Optional
823824
self._logger.error("Cannot create gridsquare: No valid grid parent")
824825
return False
825826

827+
# TODO this looks like nonsense, check it can be thrown away:
828+
# elif entity_type == "gridsquare" and isinstance(entity, GridSquareData):
829+
# if parent and parent[0] == "grid":
830+
# grid_uuid = parent[1]
831+
# # Ensure grid_uuid is set on the entity
832+
# if not hasattr(entity, 'grid_uuid') or not entity.grid_uuid:
833+
# entity.grid_uuid = grid_uuid
834+
#
835+
# grid_db_id = self._get_db_id("grid", grid_uuid)
836+
# if not grid_db_id:
837+
# self._logger.error(f"Cannot create gridsquare: Grid {grid_uuid} not found in ID map")
838+
# return False
839+
#
840+
# response = self.create_grid_gridsquare(grid_db_id, entity)
841+
# self._store_entity_id_mapping("gridsquare", entity_id, response.id)
842+
# self._logger.info(f"Successfully created gridsquare {entity_id} (DB ID: {response.id})")
843+
# return True
844+
# else:
845+
# self._logger.error("Cannot create gridsquare: No valid grid parent")
846+
# return False
847+
826848
elif entity_type == "foilhole" and isinstance(entity, FoilHoleData):
827849
if parent and parent[0] == "gridsquare":
828850
gridsquare_db_id = self._get_db_id("gridsquare", parent[1])

0 commit comments

Comments
 (0)