diff --git a/backend/bec_atlas/router/scan_router.py b/backend/bec_atlas/router/scan_router.py index c1ff772..99497e4 100644 --- a/backend/bec_atlas/router/scan_router.py +++ b/backend/bec_atlas/router/scan_router.py @@ -1,6 +1,9 @@ +from __future__ import annotations + import json -from fastapi import APIRouter, Depends, Query +from bson import ObjectId +from fastapi import APIRouter, Depends, HTTPException, Query from bec_atlas.authentication import get_current_user from bec_atlas.datasources.mongodb.mongodb import MongoDBDatasource @@ -26,7 +29,7 @@ class ScanRouter(BaseRouter): self.scans_with_id, methods=["GET"], description="Get a single scan by id for a session", - response_model=ScanStatusPartial, + response_model=ScanStatusPartial | None, response_model_exclude_none=True, ) self.router.add_api_route( @@ -73,19 +76,18 @@ class ScanRouter(BaseRouter): """ if fields: - fields = { - field: 1 - for field in fields - if field in ScanStatusPartial.model_json_schema()["properties"].keys() - } + fields = self._update_fields(fields) + if not ObjectId.is_valid(session_id): + raise HTTPException(status_code=400, detail="Invalid session ID") filters = {"session_id": session_id} + if filter: - filter = json.loads(filter) + filter = self._update_filter(filter) filters.update(filter) if sort: - sort = json.loads(sort) + sort = self._update_sort(sort) return self.db.find( "scans", @@ -111,15 +113,12 @@ class ScanRouter(BaseRouter): scan_id (str): The scan id """ if fields: - fields = { - field: 1 - for field in fields - if field in ScanStatusPartial.model_json_schema()["properties"].keys() - } + fields = self._update_fields(fields) return self.db.find_one( collection="scans", query_filter={"_id": scan_id}, dtype=ScanStatusPartial, + fields=fields, user=current_user, ) @@ -145,7 +144,7 @@ class ScanRouter(BaseRouter): return_document=True, ) if out is None: - return {"message": "Scan not found."} + raise HTTPException(status_code=404, detail="Scan not found") return {"message": "Scan user data updated."} async def count_scans( @@ -163,11 +162,81 @@ class ScanRouter(BaseRouter): """ pipeline = [] if filter: - filter = json.loads(filter) + filter = self._update_filter(filter) pipeline.append({"$match": filter}) pipeline.append({"$count": "count"}) out = self.db.aggregate("scans", pipeline=pipeline, dtype=None, user=current_user) if out: return out[0] - return {"count": 0} + # I don't think this will ever be reached + else: # pragma: no cover + return {"count": 0} + + def _update_filter(self, filter: str) -> dict: + """ + Update the filter for the query. + + Args: + filter (str): JSON filter for the query, e.g. '{"name": "test"}' + + Returns: + dict: The filter for the query + """ + exc = HTTPException(status_code=400, detail="Invalid filter. Must be a JSON object.") + try: + filter = json.loads(filter) + except json.JSONDecodeError: + # pylint: disable=raise-missing-from + raise exc + if not isinstance(filter, dict): + raise exc + return filter + + def _update_fields(self, fields: list[str]) -> dict: + """ + Update the fields to return in the query. + + Args: + fields (list[str]): List of fields to return + + Returns: + dict: The fields to return + """ + exc = HTTPException( + status_code=400, detail="Invalid fields. Must be a list of valid fields." + ) + if not all( + field in ScanStatusPartial.model_json_schema()["properties"].keys() for field in fields + ): + raise exc + fields = {field: 1 for field in fields} + return fields + + def _update_sort(self, sort: str) -> dict: + """ + Update the sort order for the query. + + Args: + sort (str): Sort order for the query, e.g. '{"name": 1}' for ascending order, + '{"name": -1}' for descending order. Multiple fields can be sorted by + separating them with a comma, e.g. '{"name": 1, "description": -1}' + + Returns: + dict: The sort order + """ + exc = HTTPException( + status_code=400, detail="Invalid sort order. Must be a JSON object with valid keys." + ) + try: + sort = json.loads(sort) + except json.JSONDecodeError: + # pylint: disable=raise-missing-from + raise exc + if not isinstance(sort, dict): + raise exc + if not all( + key in ScanStatusPartial.model_json_schema()["properties"].keys() for key in sort.keys() + ): + raise exc + return sort diff --git a/backend/tests/conftest.py b/backend/tests/conftest.py index 9651836..e546b3b 100644 --- a/backend/tests/conftest.py +++ b/backend/tests/conftest.py @@ -73,13 +73,13 @@ def convert_to_object_id(data): return data -@pytest.fixture(scope="session") +@pytest.fixture() def redis_server(): redis_server = fakeredis.FakeServer() yield redis_server -@pytest.fixture(scope="session") +@pytest.fixture() def backend(redis_server): def _fake_redis(host, port): diff --git a/backend/tests/test_data/bec_atlas.scans.json b/backend/tests/test_data/bec_atlas.scans.json index d04b286..118cb94 100644 --- a/backend/tests/test_data/bec_atlas.scans.json +++ b/backend/tests/test_data/bec_atlas.scans.json @@ -1,14 +1,14 @@ [ { - "_id": "2f372a7b-e562-4df5-9ad6-bbf5ef5692a4", + "_id": "82fd9bff-d882-4d0b-a427-32b381ff004b", "metadata": {}, - "scan_id": "2f372a7b-e562-4df5-9ad6-bbf5ef5692a4", + "scan_id": "82fd9bff-d882-4d0b-a427-32b381ff004b", "status": "closed", - "scan_number": 2254, + "scan_number": 2251, "num_points": 400, "scan_name": "line_scan", "scan_type": "step", - "dataset_number": 2253, + "dataset_number": 2250, "scan_report_devices": ["samx"], "user_metadata": {}, "readout_priority": { @@ -238,12 +238,22 @@ "optim_trajectory": null, "return_to_start": false, "relative": false, - "system_config": { "file_suffix": null, "file_directory": null } + "system_config": { + "file_suffix": null, + "file_directory": null + } }, "request_inputs": { "arg_bundle": ["samx", -20, 20], "inputs": {}, - "kwargs": { "steps": 400, "relative": false, "system_config": { "file_suffix": null, "file_directory": null } } + "kwargs": { + "steps": 400, + "relative": false, + "system_config": { + "file_suffix": null, + "file_directory": null + } + } }, "info": { "readout_priority": { @@ -468,13 +478,13 @@ "file_suffix": null, "file_directory": null, "user_metadata": {}, - "RID": "22a3a0e0-64f8-426d-b58e-1de75ef58c6f", - "scan_id": "2f372a7b-e562-4df5-9ad6-bbf5ef5692a4", - "queue_id": "a8984b11-214e-41ac-9a03-2690600b3f3c", + "RID": "114a7d41-2f64-4556-b70e-3a423561a1a3", + "scan_id": "82fd9bff-d882-4d0b-a427-32b381ff004b", + "queue_id": "955a0a86-c10d-4732-95df-361165f5deb9", "scan_motors": ["samx"], "num_points": 400, "positions": [ - [-20.0], + [-20], [-19.899749373433583], [-19.79949874686717], [-19.69924812030075], @@ -873,7 +883,2830 @@ [19.69924812030075], [19.799498746867165], [19.89974937343358], - [20.0] + [20] + ], + "scan_name": "line_scan", + "scan_type": "step", + "scan_number": 2251, + "dataset_number": 2250, + "exp_time": 0, + "frames_per_trigger": 1, + "settling_time": 0, + "readout_time": 0, + "scan_report_devices": ["samx"], + "monitor_sync": "bec", + "scan_parameters": { + "exp_time": 0, + "frames_per_trigger": 1, + "settling_time": 0, + "readout_time": 0, + "optim_trajectory": null, + "return_to_start": false, + "relative": false, + "system_config": { + "file_suffix": null, + "file_directory": null + } + }, + "request_inputs": { + "arg_bundle": ["samx", -20, 20], + "inputs": {}, + "kwargs": { + "steps": 400, + "relative": false, + "system_config": { + "file_suffix": null, + "file_directory": null + } + } + }, + "scan_msgs": [ + "metadata={'file_suffix': None, 'file_directory': None, 'user_metadata': {}, 'RID': '114a7d41-2f64-4556-b70e-3a423561a1a3'} scan_type='line_scan' parameter={'args': {'samx': [-20, 20]}, 'kwargs': {'steps': 400, 'relative': False, 'system_config': {'file_suffix': None, 'file_directory': None}}} queue='primary'" + ], + "args": { + "samx": [-20, 20] + }, + "kwargs": { + "steps": 400, + "relative": false, + "system_config": { + "file_suffix": null, + "file_directory": null + } + } + }, + "timestamp": 1737730079.4184341, + "owner_groups": ["admin"], + "access_groups": ["admin"], + "session_id": "6792392e3e28ff5364050c85" + }, + { + "_id": "096a9fbd-36fc-4e55-a9a0-7a581408d40d", + "metadata": {}, + "scan_id": "096a9fbd-36fc-4e55-a9a0-7a581408d40d", + "status": "closed", + "scan_number": 2252, + "num_points": 400, + "scan_name": "line_scan", + "scan_type": "step", + "dataset_number": 2251, + "scan_report_devices": ["samx"], + "user_metadata": {}, + "readout_priority": { + "monitored": [ + "bpm4xm", + "bpm5a", + "bpm5x", + "ring_current_sim", + "bpm4b", + "bpm3b", + "bpm6d", + "bpm6y", + "ebpmuy", + "bpm4d", + "bpm3i", + "bpm6z", + "bpm4z", + "ebpmdy", + "bpm6i", + "bpm4s", + "bpm3d", + "bpm3z", + "bpm4ym", + "ebpmux", + "bpm4y", + "ftp", + "bpm6x", + "bpm4xf", + "bpm5i", + "diode", + "temp", + "bpm5b", + "bpm6c", + "ebpmdx", + "bpm3a", + "bpm3c", + "bpm3x", + "bpm6a", + "bpm5d", + "bpm4i", + "bpm5z", + "bpm4x", + "bpm3y", + "bpm4a", + "bpm5y", + "transd", + "samx", + "bpm6b", + "curr", + "bpm4c", + "bpm5c", + "bpm4yf" + ], + "baseline": [ + "bm5trx", + "sl3wv", + "dttrx", + "dttrz", + "bm4try", + "fsh1x", + "sl2tryt", + "mobdbo", + "sl4tryt", + "stroy", + "sl0wh", + "eyefoc", + "hroy", + "pinz", + "ebfi2", + "idgap", + "moth1", + "sl5tryb", + "moth2e", + "moth1e", + "bs2x", + "sl2tryb", + "bm1trx", + "rt_controller", + "dtth", + "sl4trxi", + "sl3tryb", + "bm1try", + "hroz", + "bpm5r", + "ebtrx", + "mobdco", + "bpm4r", + "eyex", + "hy", + "sl0ch", + "motrz1", + "sl2wv", + "samz", + "moroll2", + "bm6trx", + "bim2x", + "burstn", + "dtpush", + "mitry3", + "bm5try", + "hrox", + "sttrx", + "sl5trxo", + "sl4wh", + "eyey", + "fttrz", + "dyn_signals", + "sl0trxo", + "sl1trxo", + "ebtrz", + "mibd2", + "sl5tryt", + "sl3ch", + "bm3trx", + "bim2y", + "mith", + "ddg1c", + "sl1trxi", + "aptrx", + "hx", + "bm2trx", + "ddg1e", + "mitry1", + "sl5ch", + "sl5trxi", + "sl1cv", + "ebtry", + "sttry", + "motrx2", + "motry", + "sl1tryb", + "mibd1", + "ebfi1", + "mitry2", + "ddg1a", + "samy", + "bm4trx", + "ddg1b", + "bm2try", + "ddg1f", + "ebcsy", + "sl3trxi", + "sl4cv", + "ebfi3", + "strox", + "sl1ch", + "mokev", + "ebfzpx", + "fsh2x", + "mobdai", + "sl3wh", + "stroz", + "bm3try", + "moyaw2", + "piny", + "sl5wh", + "sl3trxo", + "mitry", + "dettrx", + "fi1try", + "motry2", + "pseudo_signal1", + "sl5wv", + "hz", + "ebfzpy", + "motrz1e", + "ddg1h", + "moth2", + "sl3tryt", + "sl4trxo", + "bm6try", + "sl4ch", + "di2try", + "sl2wh", + "sl2ch", + "sl0trxi", + "sl4tryb", + "hexapod", + "mobd", + "bs1y", + "bs2y", + "sl2trxo", + "sl1wh", + "sl1wv", + "sl4wv", + "di2trx", + "mbsx", + "ebcsx", + "mopush1", + "bs1x", + "fttrx1", + "mopush2", + "dttry", + "fttrx2", + "miroll", + "burstr", + "mibd", + "sl1tryt", + "fi3try", + "mobddi", + "fttry1", + "sl2trxi", + "aptry", + "pinx", + "ftrans", + "ebfi4", + "sl3cv", + "sl2cv", + "ddg1d", + "sl5cv", + "moroll1", + "fttry2", + "mitrx", + "mbsy", + "ddg1g", + "fi2try" + ], + "async": ["monitor_async"], + "continuous": [], + "on_request": ["flyer_sim"] + }, + "scan_parameters": { + "exp_time": 0, + "frames_per_trigger": 1, + "settling_time": 0, + "readout_time": 0, + "optim_trajectory": null, + "return_to_start": false, + "relative": false, + "system_config": { + "file_suffix": null, + "file_directory": null + } + }, + "request_inputs": { + "arg_bundle": ["samx", -20, 20], + "inputs": {}, + "kwargs": { + "steps": 400, + "relative": false, + "system_config": { + "file_suffix": null, + "file_directory": null + } + } + }, + "info": { + "readout_priority": { + "monitored": [ + "bpm4xm", + "bpm5a", + "bpm5x", + "ring_current_sim", + "bpm4b", + "bpm3b", + "bpm6d", + "bpm6y", + "ebpmuy", + "bpm4d", + "bpm3i", + "bpm6z", + "bpm4z", + "ebpmdy", + "bpm6i", + "bpm4s", + "bpm3d", + "bpm3z", + "bpm4ym", + "ebpmux", + "bpm4y", + "ftp", + "bpm6x", + "bpm4xf", + "bpm5i", + "diode", + "temp", + "bpm5b", + "bpm6c", + "ebpmdx", + "bpm3a", + "bpm3c", + "bpm3x", + "bpm6a", + "bpm5d", + "bpm4i", + "bpm5z", + "bpm4x", + "bpm3y", + "bpm4a", + "bpm5y", + "transd", + "samx", + "bpm6b", + "curr", + "bpm4c", + "bpm5c", + "bpm4yf" + ], + "baseline": [ + "bm5trx", + "sl3wv", + "dttrx", + "dttrz", + "bm4try", + "fsh1x", + "sl2tryt", + "mobdbo", + "sl4tryt", + "stroy", + "sl0wh", + "eyefoc", + "hroy", + "pinz", + "ebfi2", + "idgap", + "moth1", + "sl5tryb", + "moth2e", + "moth1e", + "bs2x", + "sl2tryb", + "bm1trx", + "rt_controller", + "dtth", + "sl4trxi", + "sl3tryb", + "bm1try", + "hroz", + "bpm5r", + "ebtrx", + "mobdco", + "bpm4r", + "eyex", + "hy", + "sl0ch", + "motrz1", + "sl2wv", + "samz", + "moroll2", + "bm6trx", + "bim2x", + "burstn", + "dtpush", + "mitry3", + "bm5try", + "hrox", + "sttrx", + "sl5trxo", + "sl4wh", + "eyey", + "fttrz", + "dyn_signals", + "sl0trxo", + "sl1trxo", + "ebtrz", + "mibd2", + "sl5tryt", + "sl3ch", + "bm3trx", + "bim2y", + "mith", + "ddg1c", + "sl1trxi", + "aptrx", + "hx", + "bm2trx", + "ddg1e", + "mitry1", + "sl5ch", + "sl5trxi", + "sl1cv", + "ebtry", + "sttry", + "motrx2", + "motry", + "sl1tryb", + "mibd1", + "ebfi1", + "mitry2", + "ddg1a", + "samy", + "bm4trx", + "ddg1b", + "bm2try", + "ddg1f", + "ebcsy", + "sl3trxi", + "sl4cv", + "ebfi3", + "strox", + "sl1ch", + "mokev", + "ebfzpx", + "fsh2x", + "mobdai", + "sl3wh", + "stroz", + "bm3try", + "moyaw2", + "piny", + "sl5wh", + "sl3trxo", + "mitry", + "dettrx", + "fi1try", + "motry2", + "pseudo_signal1", + "sl5wv", + "hz", + "ebfzpy", + "motrz1e", + "ddg1h", + "moth2", + "sl3tryt", + "sl4trxo", + "bm6try", + "sl4ch", + "di2try", + "sl2wh", + "sl2ch", + "sl0trxi", + "sl4tryb", + "hexapod", + "mobd", + "bs1y", + "bs2y", + "sl2trxo", + "sl1wh", + "sl1wv", + "sl4wv", + "di2trx", + "mbsx", + "ebcsx", + "mopush1", + "bs1x", + "fttrx1", + "mopush2", + "dttry", + "fttrx2", + "miroll", + "burstr", + "mibd", + "sl1tryt", + "fi3try", + "mobddi", + "fttry1", + "sl2trxi", + "aptry", + "pinx", + "ftrans", + "ebfi4", + "sl3cv", + "sl2cv", + "ddg1d", + "sl5cv", + "moroll1", + "fttry2", + "mitrx", + "mbsy", + "ddg1g", + "fi2try" + ], + "async": ["monitor_async"], + "continuous": [], + "on_request": ["flyer_sim"] + }, + "file_suffix": null, + "file_directory": null, + "user_metadata": {}, + "RID": "86908980-7d06-4a79-a15f-62746010e44e", + "scan_id": "096a9fbd-36fc-4e55-a9a0-7a581408d40d", + "queue_id": "82551a71-c270-4f8d-8131-6c06acaf4401", + "scan_motors": ["samx"], + "num_points": 400, + "positions": [ + [-20], + [-19.899749373433583], + [-19.79949874686717], + [-19.69924812030075], + [-19.598997493734338], + [-19.49874686716792], + [-19.398496240601503], + [-19.29824561403509], + [-19.19799498746867], + [-19.097744360902254], + [-18.99749373433584], + [-18.897243107769423], + [-18.796992481203006], + [-18.696741854636592], + [-18.596491228070175], + [-18.49624060150376], + [-18.395989974937343], + [-18.295739348370926], + [-18.195488721804512], + [-18.095238095238095], + [-17.99498746867168], + [-17.894736842105264], + [-17.794486215538846], + [-17.694235588972433], + [-17.593984962406015], + [-17.493734335839598], + [-17.393483709273184], + [-17.293233082706767], + [-17.19298245614035], + [-17.092731829573935], + [-16.992481203007518], + [-16.892230576441104], + [-16.791979949874687], + [-16.69172932330827], + [-16.591478696741856], + [-16.49122807017544], + [-16.390977443609025], + [-16.290726817042607], + [-16.19047619047619], + [-16.090225563909776], + [-15.989974937343359], + [-15.889724310776943], + [-15.789473684210527], + [-15.68922305764411], + [-15.588972431077694], + [-15.488721804511279], + [-15.388471177944862], + [-15.288220551378446], + [-15.18796992481203], + [-15.087719298245615], + [-14.9874686716792], + [-14.887218045112782], + [-14.786967418546366], + [-14.68671679197995], + [-14.586466165413533], + [-14.486215538847118], + [-14.385964912280702], + [-14.285714285714286], + [-14.18546365914787], + [-14.085213032581454], + [-13.984962406015038], + [-13.884711779448622], + [-13.784461152882205], + [-13.68421052631579], + [-13.583959899749374], + [-13.483709273182958], + [-13.383458646616543], + [-13.283208020050125], + [-13.18295739348371], + [-13.082706766917294], + [-12.982456140350877], + [-12.882205513784461], + [-12.781954887218046], + [-12.68170426065163], + [-12.581453634085214], + [-12.481203007518797], + [-12.380952380952381], + [-12.280701754385966], + [-12.180451127819548], + [-12.080200501253133], + [-11.979949874686717], + [-11.879699248120302], + [-11.779448621553886], + [-11.679197994987469], + [-11.578947368421053], + [-11.478696741854638], + [-11.37844611528822], + [-11.278195488721805], + [-11.177944862155389], + [-11.077694235588973], + [-10.977443609022558], + [-10.87719298245614], + [-10.776942355889725], + [-10.67669172932331], + [-10.576441102756892], + [-10.476190476190476], + [-10.37593984962406], + [-10.275689223057645], + [-10.17543859649123], + [-10.075187969924812], + [-9.974937343358397], + [-9.874686716791981], + [-9.774436090225564], + [-9.674185463659148], + [-9.573934837092732], + [-9.473684210526317], + [-9.373433583959901], + [-9.273182957393484], + [-9.172932330827068], + [-9.072681704260653], + [-8.972431077694235], + [-8.87218045112782], + [-8.771929824561404], + [-8.671679197994989], + [-8.571428571428573], + [-8.471177944862156], + [-8.37092731829574], + [-8.270676691729324], + [-8.170426065162907], + [-8.070175438596491], + [-7.969924812030076], + [-7.86967418546366], + [-7.769423558897245], + [-7.669172932330827], + [-7.568922305764412], + [-7.468671679197996], + [-7.368421052631579], + [-7.268170426065163], + [-7.167919799498748], + [-7.067669172932332], + [-6.967418546365916], + [-6.867167919799499], + [-6.766917293233083], + [-6.666666666666668], + [-6.5664160401002505], + [-6.466165413533835], + [-6.365914786967419], + [-6.265664160401004], + [-6.165413533834588], + [-6.065162907268171], + [-5.964912280701755], + [-5.86466165413534], + [-5.764411027568922], + [-5.664160401002507], + [-5.563909774436091], + [-5.463659147869675], + [-5.36340852130326], + [-5.2631578947368425], + [-5.162907268170427], + [-5.062656641604011], + [-4.962406015037594], + [-4.862155388471178], + [-4.761904761904763], + [-4.661654135338347], + [-4.561403508771932], + [-4.461152882205514], + [-4.360902255639099], + [-4.260651629072683], + [-4.160401002506266], + [-4.06015037593985], + [-3.9598997493734345], + [-3.859649122807017], + [-3.7593984962406033], + [-3.659147869674186], + [-3.558897243107772], + [-3.4586466165413547], + [-3.3583959899749374], + [-3.2581453634085236], + [-3.157894736842106], + [-3.057644110275689], + [-2.957393483709275], + [-2.8571428571428577], + [-2.7568922305764403], + [-2.6566416040100265], + [-2.556390977443609], + [-2.4561403508771953], + [-2.355889724310778], + [-2.2556390977443606], + [-2.1553884711779467], + [-2.0551378446115294], + [-1.9548872180451156], + [-1.8546365914786982], + [-1.7543859649122808], + [-1.654135338345867], + [-1.5538847117794496], + [-1.4536340852130323], + [-1.3533834586466185], + [-1.253132832080201], + [-1.1528822055137837], + [-1.05263157894737], + [-0.9523809523809526], + [-0.8521303258145387], + [-0.7518796992481214], + [-0.651629072681704], + [-0.5513784461152902], + [-0.4511278195488728], + [-0.350877192982459], + [-0.25062656641604164], + [-0.15037593984962427], + [-0.05012531328321046], + [0.05012531328320691], + [0.15037593984962427], + [0.2506265664160381], + [0.35087719298245545], + [0.4511278195488728], + [0.5513784461152866], + [0.651629072681704], + [0.7518796992481178], + [0.8521303258145352], + [0.9523809523809526], + [1.0526315789473664], + [1.1528822055137837], + [1.2531328320801975], + [1.353383458646615], + [1.4536340852130323], + [1.553884711779446], + [1.6541353383458635], + [1.7543859649122808], + [1.8546365914786946], + [1.954887218045112], + [2.0551378446115294], + [2.155388471177943], + [2.2556390977443606], + [2.3558897243107744], + [2.4561403508771917], + [2.556390977443609], + [2.656641604010023], + [2.7568922305764403], + [2.857142857142854], + [2.9573934837092715], + [3.057644110275689], + [3.1578947368421026], + [3.25814536340852], + [3.3583959899749374], + [3.458646616541351], + [3.5588972431077686], + [3.659147869674186], + [3.7593984962405997], + [3.859649122807017], + [3.959899749373431], + [4.060150375939848], + [4.160401002506266], + [4.2606516290726795], + [4.360902255639097], + [4.461152882205511], + [4.561403508771928], + [4.661654135338345], + [4.761904761904759], + [4.862155388471177], + [4.962406015037594], + [5.062656641604008], + [5.162907268170425], + [5.2631578947368425], + [5.363408521303256], + [5.463659147869674], + [5.5639097744360875], + [5.664160401002505], + [5.764411027568922], + [5.864661654135336], + [5.964912280701753], + [6.065162907268167], + [6.165413533834585], + [6.265664160401002], + [6.365914786967416], + [6.466165413533833], + [6.5664160401002505], + [6.666666666666664], + [6.766917293233082], + [6.867167919799499], + [6.967418546365913], + [7.06766917293233], + [7.167919799498744], + [7.268170426065161], + [7.368421052631579], + [7.468671679197993], + [7.56892230576441], + [7.669172932330824], + [7.769423558897241], + [7.8696741854636585], + [7.969924812030072], + [8.07017543859649], + [8.170426065162907], + [8.27067669172932], + [8.370927318295738], + [8.471177944862156], + [8.57142857142857], + [8.671679197994987], + [8.7719298245614], + [8.872180451127818], + [8.972431077694235], + [9.07268170426065], + [9.172932330827066], + [9.27318295739348], + [9.373433583959898], + [9.473684210526315], + [9.573934837092729], + [9.674185463659146], + [9.774436090225564], + [9.874686716791977], + [9.974937343358395], + [10.075187969924812], + [10.175438596491226], + [10.275689223057643], + [10.375939849624057], + [10.476190476190474], + [10.576441102756892], + [10.676691729323306], + [10.776942355889723], + [10.877192982456137], + [10.977443609022554], + [11.077694235588972], + [11.177944862155385], + [11.278195488721803], + [11.37844611528822], + [11.478696741854634], + [11.578947368421051], + [11.679197994987469], + [11.779448621553883], + [11.8796992481203], + [11.979949874686714], + [12.080200501253131], + [12.180451127819545], + [12.280701754385966], + [12.38095238095238], + [12.481203007518793], + [12.581453634085214], + [12.681704260651628], + [12.781954887218042], + [12.882205513784456], + [12.982456140350877], + [13.08270676691729], + [13.182957393483704], + [13.283208020050125], + [13.383458646616539], + [13.483709273182953], + [13.583959899749374], + [13.684210526315788], + [13.784461152882201], + [13.884711779448622], + [13.984962406015036], + [14.08521303258145], + [14.18546365914787], + [14.285714285714285], + [14.385964912280699], + [14.48621553884712], + [14.586466165413533], + [14.686716791979947], + [14.78696741854636], + [14.887218045112782], + [14.987468671679196], + [15.08771929824561], + [15.18796992481203], + [15.288220551378444], + [15.388471177944858], + [15.488721804511279], + [15.588972431077693], + [15.689223057644107], + [15.789473684210527], + [15.889724310776941], + [15.989974937343355], + [16.09022556390977], + [16.19047619047619], + [16.290726817042604], + [16.390977443609017], + [16.49122807017544], + [16.591478696741852], + [16.691729323308266], + [16.791979949874687], + [16.8922305764411], + [16.992481203007515], + [17.092731829573935], + [17.19298245614035], + [17.293233082706763], + [17.393483709273184], + [17.493734335839598], + [17.59398496240601], + [17.694235588972433], + [17.794486215538846], + [17.89473684210526], + [17.994987468671674], + [18.095238095238095], + [18.19548872180451], + [18.295739348370923], + [18.395989974937343], + [18.496240601503757], + [18.59649122807017], + [18.696741854636592], + [18.796992481203006], + [18.89724310776942], + [18.99749373433584], + [19.097744360902254], + [19.197994987468668], + [19.298245614035082], + [19.398496240601503], + [19.498746867167917], + [19.59899749373433], + [19.69924812030075], + [19.799498746867165], + [19.89974937343358], + [20] + ], + "scan_name": "line_scan", + "scan_type": "step", + "scan_number": 2252, + "dataset_number": 2251, + "exp_time": 0, + "frames_per_trigger": 1, + "settling_time": 0, + "readout_time": 0, + "scan_report_devices": ["samx"], + "monitor_sync": "bec", + "scan_parameters": { + "exp_time": 0, + "frames_per_trigger": 1, + "settling_time": 0, + "readout_time": 0, + "optim_trajectory": null, + "return_to_start": false, + "relative": false, + "system_config": { + "file_suffix": null, + "file_directory": null + } + }, + "request_inputs": { + "arg_bundle": ["samx", -20, 20], + "inputs": {}, + "kwargs": { + "steps": 400, + "relative": false, + "system_config": { + "file_suffix": null, + "file_directory": null + } + } + }, + "scan_msgs": [ + "metadata={'file_suffix': None, 'file_directory': None, 'user_metadata': {}, 'RID': '86908980-7d06-4a79-a15f-62746010e44e'} scan_type='line_scan' parameter={'args': {'samx': [-20, 20]}, 'kwargs': {'steps': 400, 'relative': False, 'system_config': {'file_suffix': None, 'file_directory': None}}} queue='primary'" + ], + "args": { + "samx": [-20, 20] + }, + "kwargs": { + "steps": 400, + "relative": false, + "system_config": { + "file_suffix": null, + "file_directory": null + } + } + }, + "timestamp": 1737748407.423161, + "owner_groups": ["admin"], + "access_groups": ["admin"], + "session_id": "6792392e3e28ff5364050c85" + }, + { + "_id": "cb9d11d0-10ab-4ea5-b9b9-8add6a784087", + "metadata": {}, + "scan_id": "cb9d11d0-10ab-4ea5-b9b9-8add6a784087", + "status": "closed", + "scan_number": 2253, + "num_points": 400, + "scan_name": "line_scan", + "scan_type": "step", + "dataset_number": 2252, + "scan_report_devices": ["samx"], + "user_metadata": {}, + "readout_priority": { + "monitored": [ + "bpm4xm", + "bpm5a", + "bpm5x", + "ring_current_sim", + "bpm4b", + "bpm3b", + "bpm6d", + "bpm6y", + "ebpmuy", + "bpm4d", + "bpm3i", + "bpm6z", + "bpm4z", + "ebpmdy", + "bpm6i", + "bpm4s", + "bpm3d", + "bpm3z", + "bpm4ym", + "ebpmux", + "bpm4y", + "ftp", + "bpm6x", + "bpm4xf", + "bpm5i", + "diode", + "temp", + "bpm5b", + "bpm6c", + "ebpmdx", + "bpm3a", + "bpm3c", + "bpm3x", + "bpm6a", + "bpm5d", + "bpm4i", + "bpm5z", + "bpm4x", + "bpm3y", + "bpm4a", + "bpm5y", + "transd", + "samx", + "bpm6b", + "curr", + "bpm4c", + "bpm5c", + "bpm4yf" + ], + "baseline": [ + "bm5trx", + "sl3wv", + "dttrx", + "dttrz", + "bm4try", + "fsh1x", + "sl2tryt", + "mobdbo", + "sl4tryt", + "stroy", + "sl0wh", + "eyefoc", + "hroy", + "pinz", + "ebfi2", + "idgap", + "moth1", + "sl5tryb", + "moth2e", + "moth1e", + "bs2x", + "sl2tryb", + "bm1trx", + "rt_controller", + "dtth", + "sl4trxi", + "sl3tryb", + "bm1try", + "hroz", + "bpm5r", + "ebtrx", + "mobdco", + "bpm4r", + "eyex", + "hy", + "sl0ch", + "motrz1", + "sl2wv", + "samz", + "moroll2", + "bm6trx", + "bim2x", + "burstn", + "dtpush", + "mitry3", + "bm5try", + "hrox", + "sttrx", + "sl5trxo", + "sl4wh", + "eyey", + "fttrz", + "dyn_signals", + "sl0trxo", + "sl1trxo", + "ebtrz", + "mibd2", + "sl5tryt", + "sl3ch", + "bm3trx", + "bim2y", + "mith", + "ddg1c", + "sl1trxi", + "aptrx", + "hx", + "bm2trx", + "ddg1e", + "mitry1", + "sl5ch", + "sl5trxi", + "sl1cv", + "ebtry", + "sttry", + "motrx2", + "motry", + "sl1tryb", + "mibd1", + "ebfi1", + "mitry2", + "ddg1a", + "samy", + "bm4trx", + "ddg1b", + "bm2try", + "ddg1f", + "ebcsy", + "sl3trxi", + "sl4cv", + "ebfi3", + "strox", + "sl1ch", + "mokev", + "ebfzpx", + "fsh2x", + "mobdai", + "sl3wh", + "stroz", + "bm3try", + "moyaw2", + "piny", + "sl5wh", + "sl3trxo", + "mitry", + "dettrx", + "fi1try", + "motry2", + "pseudo_signal1", + "sl5wv", + "hz", + "ebfzpy", + "motrz1e", + "ddg1h", + "moth2", + "sl3tryt", + "sl4trxo", + "bm6try", + "sl4ch", + "di2try", + "sl2wh", + "sl2ch", + "sl0trxi", + "sl4tryb", + "hexapod", + "mobd", + "bs1y", + "bs2y", + "sl2trxo", + "sl1wh", + "sl1wv", + "sl4wv", + "di2trx", + "mbsx", + "ebcsx", + "mopush1", + "bs1x", + "fttrx1", + "mopush2", + "dttry", + "fttrx2", + "miroll", + "burstr", + "mibd", + "sl1tryt", + "fi3try", + "mobddi", + "fttry1", + "sl2trxi", + "aptry", + "pinx", + "ftrans", + "ebfi4", + "sl3cv", + "sl2cv", + "ddg1d", + "sl5cv", + "moroll1", + "fttry2", + "mitrx", + "mbsy", + "ddg1g", + "fi2try" + ], + "async": ["monitor_async"], + "continuous": [], + "on_request": ["flyer_sim"] + }, + "scan_parameters": { + "exp_time": 0, + "frames_per_trigger": 1, + "settling_time": 0, + "readout_time": 0, + "optim_trajectory": null, + "return_to_start": false, + "relative": false, + "system_config": { + "file_suffix": null, + "file_directory": null + } + }, + "request_inputs": { + "arg_bundle": ["samx", -20, 20], + "inputs": {}, + "kwargs": { + "steps": 400, + "relative": false, + "system_config": { + "file_suffix": null, + "file_directory": null + } + } + }, + "info": { + "readout_priority": { + "monitored": [ + "bpm4xm", + "bpm5a", + "bpm5x", + "ring_current_sim", + "bpm4b", + "bpm3b", + "bpm6d", + "bpm6y", + "ebpmuy", + "bpm4d", + "bpm3i", + "bpm6z", + "bpm4z", + "ebpmdy", + "bpm6i", + "bpm4s", + "bpm3d", + "bpm3z", + "bpm4ym", + "ebpmux", + "bpm4y", + "ftp", + "bpm6x", + "bpm4xf", + "bpm5i", + "diode", + "temp", + "bpm5b", + "bpm6c", + "ebpmdx", + "bpm3a", + "bpm3c", + "bpm3x", + "bpm6a", + "bpm5d", + "bpm4i", + "bpm5z", + "bpm4x", + "bpm3y", + "bpm4a", + "bpm5y", + "transd", + "samx", + "bpm6b", + "curr", + "bpm4c", + "bpm5c", + "bpm4yf" + ], + "baseline": [ + "bm5trx", + "sl3wv", + "dttrx", + "dttrz", + "bm4try", + "fsh1x", + "sl2tryt", + "mobdbo", + "sl4tryt", + "stroy", + "sl0wh", + "eyefoc", + "hroy", + "pinz", + "ebfi2", + "idgap", + "moth1", + "sl5tryb", + "moth2e", + "moth1e", + "bs2x", + "sl2tryb", + "bm1trx", + "rt_controller", + "dtth", + "sl4trxi", + "sl3tryb", + "bm1try", + "hroz", + "bpm5r", + "ebtrx", + "mobdco", + "bpm4r", + "eyex", + "hy", + "sl0ch", + "motrz1", + "sl2wv", + "samz", + "moroll2", + "bm6trx", + "bim2x", + "burstn", + "dtpush", + "mitry3", + "bm5try", + "hrox", + "sttrx", + "sl5trxo", + "sl4wh", + "eyey", + "fttrz", + "dyn_signals", + "sl0trxo", + "sl1trxo", + "ebtrz", + "mibd2", + "sl5tryt", + "sl3ch", + "bm3trx", + "bim2y", + "mith", + "ddg1c", + "sl1trxi", + "aptrx", + "hx", + "bm2trx", + "ddg1e", + "mitry1", + "sl5ch", + "sl5trxi", + "sl1cv", + "ebtry", + "sttry", + "motrx2", + "motry", + "sl1tryb", + "mibd1", + "ebfi1", + "mitry2", + "ddg1a", + "samy", + "bm4trx", + "ddg1b", + "bm2try", + "ddg1f", + "ebcsy", + "sl3trxi", + "sl4cv", + "ebfi3", + "strox", + "sl1ch", + "mokev", + "ebfzpx", + "fsh2x", + "mobdai", + "sl3wh", + "stroz", + "bm3try", + "moyaw2", + "piny", + "sl5wh", + "sl3trxo", + "mitry", + "dettrx", + "fi1try", + "motry2", + "pseudo_signal1", + "sl5wv", + "hz", + "ebfzpy", + "motrz1e", + "ddg1h", + "moth2", + "sl3tryt", + "sl4trxo", + "bm6try", + "sl4ch", + "di2try", + "sl2wh", + "sl2ch", + "sl0trxi", + "sl4tryb", + "hexapod", + "mobd", + "bs1y", + "bs2y", + "sl2trxo", + "sl1wh", + "sl1wv", + "sl4wv", + "di2trx", + "mbsx", + "ebcsx", + "mopush1", + "bs1x", + "fttrx1", + "mopush2", + "dttry", + "fttrx2", + "miroll", + "burstr", + "mibd", + "sl1tryt", + "fi3try", + "mobddi", + "fttry1", + "sl2trxi", + "aptry", + "pinx", + "ftrans", + "ebfi4", + "sl3cv", + "sl2cv", + "ddg1d", + "sl5cv", + "moroll1", + "fttry2", + "mitrx", + "mbsy", + "ddg1g", + "fi2try" + ], + "async": ["monitor_async"], + "continuous": [], + "on_request": ["flyer_sim"] + }, + "file_suffix": null, + "file_directory": null, + "user_metadata": {}, + "RID": "b52016e6-6280-4404-ad30-3c36cd6b0c28", + "scan_id": "cb9d11d0-10ab-4ea5-b9b9-8add6a784087", + "queue_id": "61af4ef6-3e25-4552-967d-f391ca83f914", + "scan_motors": ["samx"], + "num_points": 400, + "positions": [ + [-20], + [-19.899749373433583], + [-19.79949874686717], + [-19.69924812030075], + [-19.598997493734338], + [-19.49874686716792], + [-19.398496240601503], + [-19.29824561403509], + [-19.19799498746867], + [-19.097744360902254], + [-18.99749373433584], + [-18.897243107769423], + [-18.796992481203006], + [-18.696741854636592], + [-18.596491228070175], + [-18.49624060150376], + [-18.395989974937343], + [-18.295739348370926], + [-18.195488721804512], + [-18.095238095238095], + [-17.99498746867168], + [-17.894736842105264], + [-17.794486215538846], + [-17.694235588972433], + [-17.593984962406015], + [-17.493734335839598], + [-17.393483709273184], + [-17.293233082706767], + [-17.19298245614035], + [-17.092731829573935], + [-16.992481203007518], + [-16.892230576441104], + [-16.791979949874687], + [-16.69172932330827], + [-16.591478696741856], + [-16.49122807017544], + [-16.390977443609025], + [-16.290726817042607], + [-16.19047619047619], + [-16.090225563909776], + [-15.989974937343359], + [-15.889724310776943], + [-15.789473684210527], + [-15.68922305764411], + [-15.588972431077694], + [-15.488721804511279], + [-15.388471177944862], + [-15.288220551378446], + [-15.18796992481203], + [-15.087719298245615], + [-14.9874686716792], + [-14.887218045112782], + [-14.786967418546366], + [-14.68671679197995], + [-14.586466165413533], + [-14.486215538847118], + [-14.385964912280702], + [-14.285714285714286], + [-14.18546365914787], + [-14.085213032581454], + [-13.984962406015038], + [-13.884711779448622], + [-13.784461152882205], + [-13.68421052631579], + [-13.583959899749374], + [-13.483709273182958], + [-13.383458646616543], + [-13.283208020050125], + [-13.18295739348371], + [-13.082706766917294], + [-12.982456140350877], + [-12.882205513784461], + [-12.781954887218046], + [-12.68170426065163], + [-12.581453634085214], + [-12.481203007518797], + [-12.380952380952381], + [-12.280701754385966], + [-12.180451127819548], + [-12.080200501253133], + [-11.979949874686717], + [-11.879699248120302], + [-11.779448621553886], + [-11.679197994987469], + [-11.578947368421053], + [-11.478696741854638], + [-11.37844611528822], + [-11.278195488721805], + [-11.177944862155389], + [-11.077694235588973], + [-10.977443609022558], + [-10.87719298245614], + [-10.776942355889725], + [-10.67669172932331], + [-10.576441102756892], + [-10.476190476190476], + [-10.37593984962406], + [-10.275689223057645], + [-10.17543859649123], + [-10.075187969924812], + [-9.974937343358397], + [-9.874686716791981], + [-9.774436090225564], + [-9.674185463659148], + [-9.573934837092732], + [-9.473684210526317], + [-9.373433583959901], + [-9.273182957393484], + [-9.172932330827068], + [-9.072681704260653], + [-8.972431077694235], + [-8.87218045112782], + [-8.771929824561404], + [-8.671679197994989], + [-8.571428571428573], + [-8.471177944862156], + [-8.37092731829574], + [-8.270676691729324], + [-8.170426065162907], + [-8.070175438596491], + [-7.969924812030076], + [-7.86967418546366], + [-7.769423558897245], + [-7.669172932330827], + [-7.568922305764412], + [-7.468671679197996], + [-7.368421052631579], + [-7.268170426065163], + [-7.167919799498748], + [-7.067669172932332], + [-6.967418546365916], + [-6.867167919799499], + [-6.766917293233083], + [-6.666666666666668], + [-6.5664160401002505], + [-6.466165413533835], + [-6.365914786967419], + [-6.265664160401004], + [-6.165413533834588], + [-6.065162907268171], + [-5.964912280701755], + [-5.86466165413534], + [-5.764411027568922], + [-5.664160401002507], + [-5.563909774436091], + [-5.463659147869675], + [-5.36340852130326], + [-5.2631578947368425], + [-5.162907268170427], + [-5.062656641604011], + [-4.962406015037594], + [-4.862155388471178], + [-4.761904761904763], + [-4.661654135338347], + [-4.561403508771932], + [-4.461152882205514], + [-4.360902255639099], + [-4.260651629072683], + [-4.160401002506266], + [-4.06015037593985], + [-3.9598997493734345], + [-3.859649122807017], + [-3.7593984962406033], + [-3.659147869674186], + [-3.558897243107772], + [-3.4586466165413547], + [-3.3583959899749374], + [-3.2581453634085236], + [-3.157894736842106], + [-3.057644110275689], + [-2.957393483709275], + [-2.8571428571428577], + [-2.7568922305764403], + [-2.6566416040100265], + [-2.556390977443609], + [-2.4561403508771953], + [-2.355889724310778], + [-2.2556390977443606], + [-2.1553884711779467], + [-2.0551378446115294], + [-1.9548872180451156], + [-1.8546365914786982], + [-1.7543859649122808], + [-1.654135338345867], + [-1.5538847117794496], + [-1.4536340852130323], + [-1.3533834586466185], + [-1.253132832080201], + [-1.1528822055137837], + [-1.05263157894737], + [-0.9523809523809526], + [-0.8521303258145387], + [-0.7518796992481214], + [-0.651629072681704], + [-0.5513784461152902], + [-0.4511278195488728], + [-0.350877192982459], + [-0.25062656641604164], + [-0.15037593984962427], + [-0.05012531328321046], + [0.05012531328320691], + [0.15037593984962427], + [0.2506265664160381], + [0.35087719298245545], + [0.4511278195488728], + [0.5513784461152866], + [0.651629072681704], + [0.7518796992481178], + [0.8521303258145352], + [0.9523809523809526], + [1.0526315789473664], + [1.1528822055137837], + [1.2531328320801975], + [1.353383458646615], + [1.4536340852130323], + [1.553884711779446], + [1.6541353383458635], + [1.7543859649122808], + [1.8546365914786946], + [1.954887218045112], + [2.0551378446115294], + [2.155388471177943], + [2.2556390977443606], + [2.3558897243107744], + [2.4561403508771917], + [2.556390977443609], + [2.656641604010023], + [2.7568922305764403], + [2.857142857142854], + [2.9573934837092715], + [3.057644110275689], + [3.1578947368421026], + [3.25814536340852], + [3.3583959899749374], + [3.458646616541351], + [3.5588972431077686], + [3.659147869674186], + [3.7593984962405997], + [3.859649122807017], + [3.959899749373431], + [4.060150375939848], + [4.160401002506266], + [4.2606516290726795], + [4.360902255639097], + [4.461152882205511], + [4.561403508771928], + [4.661654135338345], + [4.761904761904759], + [4.862155388471177], + [4.962406015037594], + [5.062656641604008], + [5.162907268170425], + [5.2631578947368425], + [5.363408521303256], + [5.463659147869674], + [5.5639097744360875], + [5.664160401002505], + [5.764411027568922], + [5.864661654135336], + [5.964912280701753], + [6.065162907268167], + [6.165413533834585], + [6.265664160401002], + [6.365914786967416], + [6.466165413533833], + [6.5664160401002505], + [6.666666666666664], + [6.766917293233082], + [6.867167919799499], + [6.967418546365913], + [7.06766917293233], + [7.167919799498744], + [7.268170426065161], + [7.368421052631579], + [7.468671679197993], + [7.56892230576441], + [7.669172932330824], + [7.769423558897241], + [7.8696741854636585], + [7.969924812030072], + [8.07017543859649], + [8.170426065162907], + [8.27067669172932], + [8.370927318295738], + [8.471177944862156], + [8.57142857142857], + [8.671679197994987], + [8.7719298245614], + [8.872180451127818], + [8.972431077694235], + [9.07268170426065], + [9.172932330827066], + [9.27318295739348], + [9.373433583959898], + [9.473684210526315], + [9.573934837092729], + [9.674185463659146], + [9.774436090225564], + [9.874686716791977], + [9.974937343358395], + [10.075187969924812], + [10.175438596491226], + [10.275689223057643], + [10.375939849624057], + [10.476190476190474], + [10.576441102756892], + [10.676691729323306], + [10.776942355889723], + [10.877192982456137], + [10.977443609022554], + [11.077694235588972], + [11.177944862155385], + [11.278195488721803], + [11.37844611528822], + [11.478696741854634], + [11.578947368421051], + [11.679197994987469], + [11.779448621553883], + [11.8796992481203], + [11.979949874686714], + [12.080200501253131], + [12.180451127819545], + [12.280701754385966], + [12.38095238095238], + [12.481203007518793], + [12.581453634085214], + [12.681704260651628], + [12.781954887218042], + [12.882205513784456], + [12.982456140350877], + [13.08270676691729], + [13.182957393483704], + [13.283208020050125], + [13.383458646616539], + [13.483709273182953], + [13.583959899749374], + [13.684210526315788], + [13.784461152882201], + [13.884711779448622], + [13.984962406015036], + [14.08521303258145], + [14.18546365914787], + [14.285714285714285], + [14.385964912280699], + [14.48621553884712], + [14.586466165413533], + [14.686716791979947], + [14.78696741854636], + [14.887218045112782], + [14.987468671679196], + [15.08771929824561], + [15.18796992481203], + [15.288220551378444], + [15.388471177944858], + [15.488721804511279], + [15.588972431077693], + [15.689223057644107], + [15.789473684210527], + [15.889724310776941], + [15.989974937343355], + [16.09022556390977], + [16.19047619047619], + [16.290726817042604], + [16.390977443609017], + [16.49122807017544], + [16.591478696741852], + [16.691729323308266], + [16.791979949874687], + [16.8922305764411], + [16.992481203007515], + [17.092731829573935], + [17.19298245614035], + [17.293233082706763], + [17.393483709273184], + [17.493734335839598], + [17.59398496240601], + [17.694235588972433], + [17.794486215538846], + [17.89473684210526], + [17.994987468671674], + [18.095238095238095], + [18.19548872180451], + [18.295739348370923], + [18.395989974937343], + [18.496240601503757], + [18.59649122807017], + [18.696741854636592], + [18.796992481203006], + [18.89724310776942], + [18.99749373433584], + [19.097744360902254], + [19.197994987468668], + [19.298245614035082], + [19.398496240601503], + [19.498746867167917], + [19.59899749373433], + [19.69924812030075], + [19.799498746867165], + [19.89974937343358], + [20] + ], + "scan_name": "line_scan", + "scan_type": "step", + "scan_number": 2253, + "dataset_number": 2252, + "exp_time": 0, + "frames_per_trigger": 1, + "settling_time": 0, + "readout_time": 0, + "scan_report_devices": ["samx"], + "monitor_sync": "bec", + "scan_parameters": { + "exp_time": 0, + "frames_per_trigger": 1, + "settling_time": 0, + "readout_time": 0, + "optim_trajectory": null, + "return_to_start": false, + "relative": false, + "system_config": { + "file_suffix": null, + "file_directory": null + } + }, + "request_inputs": { + "arg_bundle": ["samx", -20, 20], + "inputs": {}, + "kwargs": { + "steps": 400, + "relative": false, + "system_config": { + "file_suffix": null, + "file_directory": null + } + } + }, + "scan_msgs": [ + "metadata={'file_suffix': None, 'file_directory': None, 'user_metadata': {}, 'RID': 'b52016e6-6280-4404-ad30-3c36cd6b0c28'} scan_type='line_scan' parameter={'args': {'samx': [-20, 20]}, 'kwargs': {'steps': 400, 'relative': False, 'system_config': {'file_suffix': None, 'file_directory': None}}} queue='primary'" + ], + "args": { + "samx": [-20, 20] + }, + "kwargs": { + "steps": 400, + "relative": false, + "system_config": { + "file_suffix": null, + "file_directory": null + } + } + }, + "timestamp": 1737748453.817934, + "owner_groups": ["admin"], + "access_groups": ["admin"], + "session_id": "6792392e3e28ff5364050c85" + }, + { + "_id": "2f372a7b-e562-4df5-9ad6-bbf5ef5692a4", + "metadata": {}, + "scan_id": "2f372a7b-e562-4df5-9ad6-bbf5ef5692a4", + "status": "closed", + "scan_number": 2254, + "num_points": 400, + "scan_name": "line_scan", + "scan_type": "step", + "dataset_number": 2253, + "scan_report_devices": ["samx"], + "user_metadata": {}, + "readout_priority": { + "monitored": [ + "bpm4xm", + "bpm5a", + "bpm5x", + "ring_current_sim", + "bpm4b", + "bpm3b", + "bpm6d", + "bpm6y", + "ebpmuy", + "bpm4d", + "bpm3i", + "bpm6z", + "bpm4z", + "ebpmdy", + "bpm6i", + "bpm4s", + "bpm3d", + "bpm3z", + "bpm4ym", + "ebpmux", + "bpm4y", + "ftp", + "bpm6x", + "bpm4xf", + "bpm5i", + "diode", + "temp", + "bpm5b", + "bpm6c", + "ebpmdx", + "bpm3a", + "bpm3c", + "bpm3x", + "bpm6a", + "bpm5d", + "bpm4i", + "bpm5z", + "bpm4x", + "bpm3y", + "bpm4a", + "bpm5y", + "transd", + "samx", + "bpm6b", + "curr", + "bpm4c", + "bpm5c", + "bpm4yf" + ], + "baseline": [ + "bm5trx", + "sl3wv", + "dttrx", + "dttrz", + "bm4try", + "fsh1x", + "sl2tryt", + "mobdbo", + "sl4tryt", + "stroy", + "sl0wh", + "eyefoc", + "hroy", + "pinz", + "ebfi2", + "idgap", + "moth1", + "sl5tryb", + "moth2e", + "moth1e", + "bs2x", + "sl2tryb", + "bm1trx", + "rt_controller", + "dtth", + "sl4trxi", + "sl3tryb", + "bm1try", + "hroz", + "bpm5r", + "ebtrx", + "mobdco", + "bpm4r", + "eyex", + "hy", + "sl0ch", + "motrz1", + "sl2wv", + "samz", + "moroll2", + "bm6trx", + "bim2x", + "burstn", + "dtpush", + "mitry3", + "bm5try", + "hrox", + "sttrx", + "sl5trxo", + "sl4wh", + "eyey", + "fttrz", + "dyn_signals", + "sl0trxo", + "sl1trxo", + "ebtrz", + "mibd2", + "sl5tryt", + "sl3ch", + "bm3trx", + "bim2y", + "mith", + "ddg1c", + "sl1trxi", + "aptrx", + "hx", + "bm2trx", + "ddg1e", + "mitry1", + "sl5ch", + "sl5trxi", + "sl1cv", + "ebtry", + "sttry", + "motrx2", + "motry", + "sl1tryb", + "mibd1", + "ebfi1", + "mitry2", + "ddg1a", + "samy", + "bm4trx", + "ddg1b", + "bm2try", + "ddg1f", + "ebcsy", + "sl3trxi", + "sl4cv", + "ebfi3", + "strox", + "sl1ch", + "mokev", + "ebfzpx", + "fsh2x", + "mobdai", + "sl3wh", + "stroz", + "bm3try", + "moyaw2", + "piny", + "sl5wh", + "sl3trxo", + "mitry", + "dettrx", + "fi1try", + "motry2", + "pseudo_signal1", + "sl5wv", + "hz", + "ebfzpy", + "motrz1e", + "ddg1h", + "moth2", + "sl3tryt", + "sl4trxo", + "bm6try", + "sl4ch", + "di2try", + "sl2wh", + "sl2ch", + "sl0trxi", + "sl4tryb", + "hexapod", + "mobd", + "bs1y", + "bs2y", + "sl2trxo", + "sl1wh", + "sl1wv", + "sl4wv", + "di2trx", + "mbsx", + "ebcsx", + "mopush1", + "bs1x", + "fttrx1", + "mopush2", + "dttry", + "fttrx2", + "miroll", + "burstr", + "mibd", + "sl1tryt", + "fi3try", + "mobddi", + "fttry1", + "sl2trxi", + "aptry", + "pinx", + "ftrans", + "ebfi4", + "sl3cv", + "sl2cv", + "ddg1d", + "sl5cv", + "moroll1", + "fttry2", + "mitrx", + "mbsy", + "ddg1g", + "fi2try" + ], + "async": ["monitor_async"], + "continuous": [], + "on_request": ["flyer_sim"] + }, + "scan_parameters": { + "exp_time": 0, + "frames_per_trigger": 1, + "settling_time": 0, + "readout_time": 0, + "optim_trajectory": null, + "return_to_start": false, + "relative": false, + "system_config": { + "file_suffix": null, + "file_directory": null + } + }, + "request_inputs": { + "arg_bundle": ["samx", -20, 20], + "inputs": {}, + "kwargs": { + "steps": 400, + "relative": false, + "system_config": { + "file_suffix": null, + "file_directory": null + } + } + }, + "info": { + "readout_priority": { + "monitored": [ + "bpm4xm", + "bpm5a", + "bpm5x", + "ring_current_sim", + "bpm4b", + "bpm3b", + "bpm6d", + "bpm6y", + "ebpmuy", + "bpm4d", + "bpm3i", + "bpm6z", + "bpm4z", + "ebpmdy", + "bpm6i", + "bpm4s", + "bpm3d", + "bpm3z", + "bpm4ym", + "ebpmux", + "bpm4y", + "ftp", + "bpm6x", + "bpm4xf", + "bpm5i", + "diode", + "temp", + "bpm5b", + "bpm6c", + "ebpmdx", + "bpm3a", + "bpm3c", + "bpm3x", + "bpm6a", + "bpm5d", + "bpm4i", + "bpm5z", + "bpm4x", + "bpm3y", + "bpm4a", + "bpm5y", + "transd", + "samx", + "bpm6b", + "curr", + "bpm4c", + "bpm5c", + "bpm4yf" + ], + "baseline": [ + "bm5trx", + "sl3wv", + "dttrx", + "dttrz", + "bm4try", + "fsh1x", + "sl2tryt", + "mobdbo", + "sl4tryt", + "stroy", + "sl0wh", + "eyefoc", + "hroy", + "pinz", + "ebfi2", + "idgap", + "moth1", + "sl5tryb", + "moth2e", + "moth1e", + "bs2x", + "sl2tryb", + "bm1trx", + "rt_controller", + "dtth", + "sl4trxi", + "sl3tryb", + "bm1try", + "hroz", + "bpm5r", + "ebtrx", + "mobdco", + "bpm4r", + "eyex", + "hy", + "sl0ch", + "motrz1", + "sl2wv", + "samz", + "moroll2", + "bm6trx", + "bim2x", + "burstn", + "dtpush", + "mitry3", + "bm5try", + "hrox", + "sttrx", + "sl5trxo", + "sl4wh", + "eyey", + "fttrz", + "dyn_signals", + "sl0trxo", + "sl1trxo", + "ebtrz", + "mibd2", + "sl5tryt", + "sl3ch", + "bm3trx", + "bim2y", + "mith", + "ddg1c", + "sl1trxi", + "aptrx", + "hx", + "bm2trx", + "ddg1e", + "mitry1", + "sl5ch", + "sl5trxi", + "sl1cv", + "ebtry", + "sttry", + "motrx2", + "motry", + "sl1tryb", + "mibd1", + "ebfi1", + "mitry2", + "ddg1a", + "samy", + "bm4trx", + "ddg1b", + "bm2try", + "ddg1f", + "ebcsy", + "sl3trxi", + "sl4cv", + "ebfi3", + "strox", + "sl1ch", + "mokev", + "ebfzpx", + "fsh2x", + "mobdai", + "sl3wh", + "stroz", + "bm3try", + "moyaw2", + "piny", + "sl5wh", + "sl3trxo", + "mitry", + "dettrx", + "fi1try", + "motry2", + "pseudo_signal1", + "sl5wv", + "hz", + "ebfzpy", + "motrz1e", + "ddg1h", + "moth2", + "sl3tryt", + "sl4trxo", + "bm6try", + "sl4ch", + "di2try", + "sl2wh", + "sl2ch", + "sl0trxi", + "sl4tryb", + "hexapod", + "mobd", + "bs1y", + "bs2y", + "sl2trxo", + "sl1wh", + "sl1wv", + "sl4wv", + "di2trx", + "mbsx", + "ebcsx", + "mopush1", + "bs1x", + "fttrx1", + "mopush2", + "dttry", + "fttrx2", + "miroll", + "burstr", + "mibd", + "sl1tryt", + "fi3try", + "mobddi", + "fttry1", + "sl2trxi", + "aptry", + "pinx", + "ftrans", + "ebfi4", + "sl3cv", + "sl2cv", + "ddg1d", + "sl5cv", + "moroll1", + "fttry2", + "mitrx", + "mbsy", + "ddg1g", + "fi2try" + ], + "async": ["monitor_async"], + "continuous": [], + "on_request": ["flyer_sim"] + }, + "file_suffix": null, + "file_directory": null, + "user_metadata": {}, + "RID": "22a3a0e0-64f8-426d-b58e-1de75ef58c6f", + "scan_id": "2f372a7b-e562-4df5-9ad6-bbf5ef5692a4", + "queue_id": "a8984b11-214e-41ac-9a03-2690600b3f3c", + "scan_motors": ["samx"], + "num_points": 400, + "positions": [ + [-20], + [-19.899749373433583], + [-19.79949874686717], + [-19.69924812030075], + [-19.598997493734338], + [-19.49874686716792], + [-19.398496240601503], + [-19.29824561403509], + [-19.19799498746867], + [-19.097744360902254], + [-18.99749373433584], + [-18.897243107769423], + [-18.796992481203006], + [-18.696741854636592], + [-18.596491228070175], + [-18.49624060150376], + [-18.395989974937343], + [-18.295739348370926], + [-18.195488721804512], + [-18.095238095238095], + [-17.99498746867168], + [-17.894736842105264], + [-17.794486215538846], + [-17.694235588972433], + [-17.593984962406015], + [-17.493734335839598], + [-17.393483709273184], + [-17.293233082706767], + [-17.19298245614035], + [-17.092731829573935], + [-16.992481203007518], + [-16.892230576441104], + [-16.791979949874687], + [-16.69172932330827], + [-16.591478696741856], + [-16.49122807017544], + [-16.390977443609025], + [-16.290726817042607], + [-16.19047619047619], + [-16.090225563909776], + [-15.989974937343359], + [-15.889724310776943], + [-15.789473684210527], + [-15.68922305764411], + [-15.588972431077694], + [-15.488721804511279], + [-15.388471177944862], + [-15.288220551378446], + [-15.18796992481203], + [-15.087719298245615], + [-14.9874686716792], + [-14.887218045112782], + [-14.786967418546366], + [-14.68671679197995], + [-14.586466165413533], + [-14.486215538847118], + [-14.385964912280702], + [-14.285714285714286], + [-14.18546365914787], + [-14.085213032581454], + [-13.984962406015038], + [-13.884711779448622], + [-13.784461152882205], + [-13.68421052631579], + [-13.583959899749374], + [-13.483709273182958], + [-13.383458646616543], + [-13.283208020050125], + [-13.18295739348371], + [-13.082706766917294], + [-12.982456140350877], + [-12.882205513784461], + [-12.781954887218046], + [-12.68170426065163], + [-12.581453634085214], + [-12.481203007518797], + [-12.380952380952381], + [-12.280701754385966], + [-12.180451127819548], + [-12.080200501253133], + [-11.979949874686717], + [-11.879699248120302], + [-11.779448621553886], + [-11.679197994987469], + [-11.578947368421053], + [-11.478696741854638], + [-11.37844611528822], + [-11.278195488721805], + [-11.177944862155389], + [-11.077694235588973], + [-10.977443609022558], + [-10.87719298245614], + [-10.776942355889725], + [-10.67669172932331], + [-10.576441102756892], + [-10.476190476190476], + [-10.37593984962406], + [-10.275689223057645], + [-10.17543859649123], + [-10.075187969924812], + [-9.974937343358397], + [-9.874686716791981], + [-9.774436090225564], + [-9.674185463659148], + [-9.573934837092732], + [-9.473684210526317], + [-9.373433583959901], + [-9.273182957393484], + [-9.172932330827068], + [-9.072681704260653], + [-8.972431077694235], + [-8.87218045112782], + [-8.771929824561404], + [-8.671679197994989], + [-8.571428571428573], + [-8.471177944862156], + [-8.37092731829574], + [-8.270676691729324], + [-8.170426065162907], + [-8.070175438596491], + [-7.969924812030076], + [-7.86967418546366], + [-7.769423558897245], + [-7.669172932330827], + [-7.568922305764412], + [-7.468671679197996], + [-7.368421052631579], + [-7.268170426065163], + [-7.167919799498748], + [-7.067669172932332], + [-6.967418546365916], + [-6.867167919799499], + [-6.766917293233083], + [-6.666666666666668], + [-6.5664160401002505], + [-6.466165413533835], + [-6.365914786967419], + [-6.265664160401004], + [-6.165413533834588], + [-6.065162907268171], + [-5.964912280701755], + [-5.86466165413534], + [-5.764411027568922], + [-5.664160401002507], + [-5.563909774436091], + [-5.463659147869675], + [-5.36340852130326], + [-5.2631578947368425], + [-5.162907268170427], + [-5.062656641604011], + [-4.962406015037594], + [-4.862155388471178], + [-4.761904761904763], + [-4.661654135338347], + [-4.561403508771932], + [-4.461152882205514], + [-4.360902255639099], + [-4.260651629072683], + [-4.160401002506266], + [-4.06015037593985], + [-3.9598997493734345], + [-3.859649122807017], + [-3.7593984962406033], + [-3.659147869674186], + [-3.558897243107772], + [-3.4586466165413547], + [-3.3583959899749374], + [-3.2581453634085236], + [-3.157894736842106], + [-3.057644110275689], + [-2.957393483709275], + [-2.8571428571428577], + [-2.7568922305764403], + [-2.6566416040100265], + [-2.556390977443609], + [-2.4561403508771953], + [-2.355889724310778], + [-2.2556390977443606], + [-2.1553884711779467], + [-2.0551378446115294], + [-1.9548872180451156], + [-1.8546365914786982], + [-1.7543859649122808], + [-1.654135338345867], + [-1.5538847117794496], + [-1.4536340852130323], + [-1.3533834586466185], + [-1.253132832080201], + [-1.1528822055137837], + [-1.05263157894737], + [-0.9523809523809526], + [-0.8521303258145387], + [-0.7518796992481214], + [-0.651629072681704], + [-0.5513784461152902], + [-0.4511278195488728], + [-0.350877192982459], + [-0.25062656641604164], + [-0.15037593984962427], + [-0.05012531328321046], + [0.05012531328320691], + [0.15037593984962427], + [0.2506265664160381], + [0.35087719298245545], + [0.4511278195488728], + [0.5513784461152866], + [0.651629072681704], + [0.7518796992481178], + [0.8521303258145352], + [0.9523809523809526], + [1.0526315789473664], + [1.1528822055137837], + [1.2531328320801975], + [1.353383458646615], + [1.4536340852130323], + [1.553884711779446], + [1.6541353383458635], + [1.7543859649122808], + [1.8546365914786946], + [1.954887218045112], + [2.0551378446115294], + [2.155388471177943], + [2.2556390977443606], + [2.3558897243107744], + [2.4561403508771917], + [2.556390977443609], + [2.656641604010023], + [2.7568922305764403], + [2.857142857142854], + [2.9573934837092715], + [3.057644110275689], + [3.1578947368421026], + [3.25814536340852], + [3.3583959899749374], + [3.458646616541351], + [3.5588972431077686], + [3.659147869674186], + [3.7593984962405997], + [3.859649122807017], + [3.959899749373431], + [4.060150375939848], + [4.160401002506266], + [4.2606516290726795], + [4.360902255639097], + [4.461152882205511], + [4.561403508771928], + [4.661654135338345], + [4.761904761904759], + [4.862155388471177], + [4.962406015037594], + [5.062656641604008], + [5.162907268170425], + [5.2631578947368425], + [5.363408521303256], + [5.463659147869674], + [5.5639097744360875], + [5.664160401002505], + [5.764411027568922], + [5.864661654135336], + [5.964912280701753], + [6.065162907268167], + [6.165413533834585], + [6.265664160401002], + [6.365914786967416], + [6.466165413533833], + [6.5664160401002505], + [6.666666666666664], + [6.766917293233082], + [6.867167919799499], + [6.967418546365913], + [7.06766917293233], + [7.167919799498744], + [7.268170426065161], + [7.368421052631579], + [7.468671679197993], + [7.56892230576441], + [7.669172932330824], + [7.769423558897241], + [7.8696741854636585], + [7.969924812030072], + [8.07017543859649], + [8.170426065162907], + [8.27067669172932], + [8.370927318295738], + [8.471177944862156], + [8.57142857142857], + [8.671679197994987], + [8.7719298245614], + [8.872180451127818], + [8.972431077694235], + [9.07268170426065], + [9.172932330827066], + [9.27318295739348], + [9.373433583959898], + [9.473684210526315], + [9.573934837092729], + [9.674185463659146], + [9.774436090225564], + [9.874686716791977], + [9.974937343358395], + [10.075187969924812], + [10.175438596491226], + [10.275689223057643], + [10.375939849624057], + [10.476190476190474], + [10.576441102756892], + [10.676691729323306], + [10.776942355889723], + [10.877192982456137], + [10.977443609022554], + [11.077694235588972], + [11.177944862155385], + [11.278195488721803], + [11.37844611528822], + [11.478696741854634], + [11.578947368421051], + [11.679197994987469], + [11.779448621553883], + [11.8796992481203], + [11.979949874686714], + [12.080200501253131], + [12.180451127819545], + [12.280701754385966], + [12.38095238095238], + [12.481203007518793], + [12.581453634085214], + [12.681704260651628], + [12.781954887218042], + [12.882205513784456], + [12.982456140350877], + [13.08270676691729], + [13.182957393483704], + [13.283208020050125], + [13.383458646616539], + [13.483709273182953], + [13.583959899749374], + [13.684210526315788], + [13.784461152882201], + [13.884711779448622], + [13.984962406015036], + [14.08521303258145], + [14.18546365914787], + [14.285714285714285], + [14.385964912280699], + [14.48621553884712], + [14.586466165413533], + [14.686716791979947], + [14.78696741854636], + [14.887218045112782], + [14.987468671679196], + [15.08771929824561], + [15.18796992481203], + [15.288220551378444], + [15.388471177944858], + [15.488721804511279], + [15.588972431077693], + [15.689223057644107], + [15.789473684210527], + [15.889724310776941], + [15.989974937343355], + [16.09022556390977], + [16.19047619047619], + [16.290726817042604], + [16.390977443609017], + [16.49122807017544], + [16.591478696741852], + [16.691729323308266], + [16.791979949874687], + [16.8922305764411], + [16.992481203007515], + [17.092731829573935], + [17.19298245614035], + [17.293233082706763], + [17.393483709273184], + [17.493734335839598], + [17.59398496240601], + [17.694235588972433], + [17.794486215538846], + [17.89473684210526], + [17.994987468671674], + [18.095238095238095], + [18.19548872180451], + [18.295739348370923], + [18.395989974937343], + [18.496240601503757], + [18.59649122807017], + [18.696741854636592], + [18.796992481203006], + [18.89724310776942], + [18.99749373433584], + [19.097744360902254], + [19.197994987468668], + [19.298245614035082], + [19.398496240601503], + [19.498746867167917], + [19.59899749373433], + [19.69924812030075], + [19.799498746867165], + [19.89974937343358], + [20] ], "scan_name": "line_scan", "scan_type": "step", @@ -893,22 +3726,41 @@ "optim_trajectory": null, "return_to_start": false, "relative": false, - "system_config": { "file_suffix": null, "file_directory": null } + "system_config": { + "file_suffix": null, + "file_directory": null + } }, "request_inputs": { "arg_bundle": ["samx", -20, 20], "inputs": {}, - "kwargs": { "steps": 400, "relative": false, "system_config": { "file_suffix": null, "file_directory": null } } + "kwargs": { + "steps": 400, + "relative": false, + "system_config": { + "file_suffix": null, + "file_directory": null + } + } }, "scan_msgs": [ "metadata={'file_suffix': None, 'file_directory': None, 'user_metadata': {}, 'RID': '22a3a0e0-64f8-426d-b58e-1de75ef58c6f'} scan_type='line_scan' parameter={'args': {'samx': [-20, 20]}, 'kwargs': {'steps': 400, 'relative': False, 'system_config': {'file_suffix': None, 'file_directory': None}}} queue='primary'" ], - "args": { "samx": [-20, 20] }, - "kwargs": { "steps": 400, "relative": false, "system_config": { "file_suffix": null, "file_directory": null } } + "args": { + "samx": [-20, 20] + }, + "kwargs": { + "steps": 400, + "relative": false, + "system_config": { + "file_suffix": null, + "file_directory": null + } + } }, - "timestamp": 1.7377484829922938e9, + "timestamp": 1737748482.9922938, "owner_groups": ["admin"], "access_groups": ["admin"], - "session_id": "6792392e3e28ff5364050c85" + "session_id": "6792392e3e28ff5364050c80" } ] diff --git a/backend/tests/test_scans_router.py b/backend/tests/test_scans_router.py new file mode 100644 index 0000000..941b996 --- /dev/null +++ b/backend/tests/test_scans_router.py @@ -0,0 +1,383 @@ +import json + +import pytest +from bson import ObjectId + + +@pytest.fixture +def logged_in_client(backend): + client, _ = backend + response = client.post( + "/api/v1/user/login", json={"username": "admin@bec_atlas.ch", "password": "admin"} + ) + assert response.status_code == 200 + token = response.json() + assert isinstance(token, str) + assert len(token) > 20 + client.headers.update({"Authorization": f"Bearer {token}"}) + return client + + +def _get_session(client): + deployments = client.get( + "/api/v1/deployments/realm", params={"realm": "demo_beamline_1"} + ).json() + deployment_id = deployments[0]["_id"] + + response = client.get("/api/v1/sessions", params={"deployment_id": deployment_id}) + assert response.status_code == 200 + + session_id = response.json()[0]["_id"] + return session_id + + +@pytest.mark.timeout(60) +def test_get_scans_for_session(logged_in_client): + """ + Test that the scans/sessions endpoint returns the correct number of scans. + """ + client = logged_in_client + + session_id = _get_session(client) + + response = client.get("/api/v1/scans/session", params={"session_id": session_id}) + + assert response.status_code == 200 + scans = response.json() + assert len(scans) == 3 + + # this endpoint should enforce the session_id as param + response = client.get("/api/v1/scans/session") + assert response.status_code == 422 + + +@pytest.mark.timeout(60) +def test_get_scans_for_session_wrong_id(logged_in_client): + """ + Test that the scans/sessions endpoint returns 400 for a wrong session id. + """ + client = logged_in_client + + response = client.get("/api/v1/scans/session", params={"session_id": "wrong_id"}) + + assert response.status_code == 400 + assert response.json() == {"detail": "Invalid session ID"} + + +@pytest.mark.timeout(60) +def test_get_scans_for_session_with_filter(logged_in_client): + """ + Test that the scans/sessions endpoint returns the correct number of scans with a filter. + """ + client = logged_in_client + + session_id = _get_session(client) + + response = client.get( + "/api/v1/scans/session", + params={"session_id": session_id, "filter": '{"scan_number": 2251}'}, + ) + + assert response.status_code == 200 + scans = response.json() + assert len(scans) == 1 + assert scans[0]["scan_number"] == 2251 + + +@pytest.mark.timeout(60) +def test_get_scans_for_session_with_fields(logged_in_client): + """ + Test that the scans/session endpoint returns the correct fields. + """ + client = logged_in_client + + session_id = _get_session(client) + + response = client.get( + "/api/v1/scans/session", params={"session_id": session_id, "fields": ["scan_number"]} + ) + + assert response.status_code == 200 + scans = response.json() + assert len(scans) == 3 + assert "scan_number" in scans[0] + assert "num_points" not in scans[0] + + +@pytest.mark.timeout(60) +def test_get_scans_for_session_with_offset_limit(logged_in_client): + """ + Test that the scans/session endpoint returns the correct number of scans with offset and limit. + """ + client = logged_in_client + + session_id = _get_session(client) + + response = client.get( + "/api/v1/scans/session", params={"session_id": session_id, "offset": 0, "limit": 1} + ) + + assert response.status_code == 200 + scans = response.json() + assert len(scans) == 1 + assert scans[0]["scan_number"] == 2251 + + response = client.get( + "/api/v1/scans/session", params={"session_id": session_id, "offset": 1, "limit": 1} + ) + + assert response.status_code == 200 + scans = response.json() + assert len(scans) == 1 + assert scans[0]["scan_number"] == 2252 + + +@pytest.mark.timeout(60) +def test_get_scans_for_session_with_sort(logged_in_client): + """ + Test that the scans/session endpoint returns the correct number of scans with sort. + """ + client = logged_in_client + + session_id = _get_session(client) + + response = client.get( + "/api/v1/scans/session", params={"session_id": session_id, "sort": '{"scan_number": 1}'} + ) + + assert response.status_code == 200 + scans = response.json() + assert len(scans) == 3 + assert scans[0]["scan_number"] == 2251 + assert scans[1]["scan_number"] == 2252 + assert scans[2]["scan_number"] == 2253 + + response = client.get( + "/api/v1/scans/session", params={"session_id": session_id, "sort": '{"scan_number": -1}'} + ) + + assert response.status_code == 200 + scans = response.json() + assert len(scans) == 3 + assert scans[0]["scan_number"] == 2253 + assert scans[1]["scan_number"] == 2252 + assert scans[2]["scan_number"] == 2251 + + +@pytest.mark.timeout(60) +def test_get_scans_for_session_with_invalid_sort(logged_in_client): + """ + Test that the scans/session endpoint returns 400 for an invalid sort order. + """ + client = logged_in_client + + session_id = _get_session(client) + + response = client.get( + "/api/v1/scans/session", params={"session_id": session_id, "sort": "invalid"} + ) + + assert response.status_code == 400 + assert response.json() == { + "detail": "Invalid sort order. Must be a JSON object with valid keys." + } + + +@pytest.mark.timeout(60) +@pytest.mark.parametrize( + "fields", ["invalid", "{'scan_number': 2251}", 123, [123], ["scan_number", 123]] +) +def test_get_scans_for_session_with_invalid_fields(logged_in_client, fields): + """ + Test that the scans/sessions endpoint returns 400 for invalid fields. + """ + client = logged_in_client + + session_id = _get_session(client) + + response = client.get( + "/api/v1/scans/session", params={"session_id": session_id, "fields": fields} + ) + + assert response.status_code == 400 + assert response.json() == {"detail": "Invalid fields. Must be a list of valid fields."} + + +@pytest.mark.timeout(60) +@pytest.mark.parametrize( + "filter", ["invalid", 123, [123], '{"scan_number": 2251', '{"scan_number": 2251}}'] +) +def test_get_scans_for_session_with_invalid_filter(logged_in_client, filter): + """ + Test that the scans/sessions endpoint returns 400 for invalid filter. + """ + client = logged_in_client + + session_id = _get_session(client) + + response = client.get( + "/api/v1/scans/session", params={"session_id": session_id, "filter": filter} + ) + + assert response.status_code == 400 + assert response.json() == {"detail": "Invalid filter. Must be a JSON object."} + + +@pytest.mark.timeout(60) +@pytest.mark.parametrize( + "sort", ["invalid", 123, [123], '{"scan_number": 1', '{"scan_number": 1}}', '{"invalid": 1}'] +) +def test_get_scans_for_session_with_invalid_sort_key(logged_in_client, sort): + """ + Test that the scans/sessions endpoint returns 400 for invalid sort key. + """ + client = logged_in_client + + session_id = _get_session(client) + + response = client.get("/api/v1/scans/session", params={"session_id": session_id, "sort": sort}) + + assert response.status_code == 400 + assert response.json() == { + "detail": "Invalid sort order. Must be a JSON object with valid keys." + } + + +@pytest.mark.timeout(60) +def test_get_scan_with_id(logged_in_client): + """ + Test that scans/id endpoint returns the correct scan. + """ + client = logged_in_client + + session_id = _get_session(client) + + response = client.get("/api/v1/scans/session", params={"session_id": session_id}) + assert response.status_code == 200 + scan_id = response.json()[0]["scan_id"] + + response = client.get("/api/v1/scans/id", params={"scan_id": scan_id}) + assert response.status_code == 200 + scan = response.json() + assert scan["scan_id"] == scan_id + + +@pytest.mark.timeout(60) +def test_get_scan_with_id_wrong_id(logged_in_client): + """ + Test that the scans/id endpoint returns None for a wrong scan id. + """ + client = logged_in_client + + response = client.get("/api/v1/scans/id", params={"scan_id": "wrong_id"}) + assert response.status_code == 200 + assert response.json() is None + + +@pytest.mark.timeout(60) +def test_get_scan_with_id_and_fields(logged_in_client): + """ + Test that the scans/id endpoint returns the correct fields. + """ + client = logged_in_client + + session_id = _get_session(client) + + response = client.get("/api/v1/scans/session", params={"session_id": session_id}) + assert response.status_code == 200 + scan_id = response.json()[0]["scan_id"] + + response = client.get( + "/api/v1/scans/id", params={"scan_id": scan_id, "fields": ["scan_number"]} + ) + assert response.status_code == 200 + scan = response.json() + assert "scan_number" in scan + assert "dataset_number" not in scan + + +@pytest.mark.timeout(60) +def test_update_scan_user_data(logged_in_client): + """ + Test that the scans/id endpoint updates the user_data. + """ + client = logged_in_client + + session_id = _get_session(client) + + response = client.get("/api/v1/scans/session", params={"session_id": session_id}) + assert response.status_code == 200 + scan_id = response.json()[0]["scan_id"] + + response = client.get("/api/v1/scans/id", params={"scan_id": scan_id}) + assert response.status_code == 200 + scan = response.json() + assert "scan_data" not in scan + + response = client.patch( + "/api/v1/scans/user_data", + params={"scan_id": scan_id}, + json={"name": "test", "user_rating": 5}, + ) + assert response.status_code == 200 + + response = client.get("/api/v1/scans/id", params={"scan_id": scan_id}) + assert response.status_code == 200 + scan = response.json() + assert scan["user_data"] == {"name": "test", "user_rating": 5} + + +@pytest.mark.timeout(60) +def test_update_scan_user_data_wrong_id(logged_in_client): + """ + Test that the scans/id endpoint returns 404 for a wrong scan id. + """ + client = logged_in_client + + response = client.patch( + "/api/v1/scans/user_data", + params={"scan_id": "wrong_id"}, + json={"name": "test", "user_rating": 5}, + ) + assert response.status_code == 404 + assert response.json() == {"detail": "Scan not found"} + + +@pytest.mark.timeout(60) +@pytest.mark.parametrize( + "filter, count", [({}, 4), ('{"scan_number": 2251}', 1), ('{"scan_number": 2}', 0)] +) +def test_count_scans(logged_in_client, filter, count): + """ + Test that the scans/count endpoint returns the correct number of scans. + """ + client = logged_in_client + + response = client.get("/api/v1/scans/count", params={"filter": filter}) + assert response.status_code == 200 + assert response.json() == {"count": count} + + +@pytest.mark.timeout(60) +def test_count_scans_with_invalid_filter(logged_in_client): + """ + Test that the scans/count endpoint returns 400 for an invalid filter. + """ + client = logged_in_client + + response = client.get("/api/v1/scans/count", params={"filter": "invalid"}) + assert response.status_code == 400 + assert response.json() == {"detail": "Invalid filter. Must be a JSON object."} + + +@pytest.mark.timeout(60) +def test_count_scans_with_no_results(logged_in_client): + """ + Test that the scans/count endpoint returns 0 for no results. + """ + client = logged_in_client + + _filter = {"session_id": str(ObjectId())} + response = client.get("/api/v1/scans/count", params={"filter": json.dumps(_filter)}) + assert response.status_code == 200 + assert response.json() == {"count": 0}