From b319298cdc2ee2dfd28f33d82c25875a9c8777b3 Mon Sep 17 00:00:00 2001 From: Peter Holloway Date: Fri, 17 Jan 2025 15:01:06 +0000 Subject: [PATCH] Add more doc strings to things that appear in the schema --- src/db_service.rs | 1 + src/graphql.rs | 39 ++++++++++++++++++- src/paths.rs | 10 ++++- static/service_schema | 90 +++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 134 insertions(+), 6 deletions(-) diff --git a/src/db_service.rs b/src/db_service.rs index 2c36c68..bc7a79b 100644 --- a/src/db_service.rs +++ b/src/db_service.rs @@ -59,6 +59,7 @@ impl From for RawPathTemplate { } } +/// The current configuration for a beamline #[derive(Debug)] pub struct BeamlineConfiguration { name: String, diff --git a/src/graphql.rs b/src/graphql.rs index 9a621a6..33f09ba 100644 --- a/src/graphql.rs +++ b/src/graphql.rs @@ -131,7 +131,9 @@ struct Mutation; /// GraphQL type to mimic a key-value pair from the map type that GraphQL doesn't have #[derive(SimpleObject)] struct DetectorPath { + /// The name of the detector that should use this path name: String, + /// The path where the detector should write its data path: String, } @@ -174,15 +176,19 @@ impl Display for NonUnicodePath { impl Error for NonUnicodePath {} #[Object] +/// The path to a visit directory and the components used to build it impl VisitPath { + /// The visit for which this is the visit directory #[instrument(skip(self))] async fn visit(&self) -> &str { &self.visit } + /// This beamline for which this is the visit directory #[instrument(skip(self))] async fn beamline(&self) -> &str { &self.info.name() } + /// The absolute path to the visit directory #[instrument(skip(self))] async fn directory(&self) -> async_graphql::Result { Ok(path_to_string(self.info.visit()?.render(self))?) @@ -206,6 +212,7 @@ impl FieldSource for VisitPath { } #[Object] +/// Paths and values related to a specific scan/data collection for a beamline impl ScanPaths { /// The visit used to generate this scan information. Should be the same as the visit passed in #[instrument(skip(self))] @@ -249,22 +256,36 @@ impl ScanPaths { } #[Object] +/// The current configuration for a beamline impl CurrentConfiguration { + /// The template used to build the path to the visit directory for a beamline pub async fn visit_template(&self) -> async_graphql::Result { Ok(self.db_config.visit()?.to_string()) } + /// The template used to build the path of a scan file for a data acquisition, relative to the + /// root of the visit directory. pub async fn scan_template(&self) -> async_graphql::Result { Ok(self.db_config.scan()?.to_string()) } + /// The template used to build the path of a detector's data file for a data acquisition, + /// relative to the root of the visit directory. pub async fn detector_template(&self) -> async_graphql::Result { Ok(self.db_config.detector()?.to_string()) } + /// The latest scan number stored in the DB. This is the last scan number provided by this + /// service but may not reflect the most recent scan number for a beamline if an external + /// service (eg GDA) has incremented its own number tracker. pub async fn db_scan_number(&self) -> async_graphql::Result { Ok(self.db_config.scan_number()) } + /// The highest matching number file for this beamline in the configured tracking directory. + /// May be null if no directory is available for this beamline or if there are no matching + /// number files. pub async fn file_scan_number(&self) -> async_graphql::Result> { Ok(self.high_file) } + /// The file extension used for the file based tracking, eg using an extension of 'ext' + /// would create files `1.ext`, `2.ext` etc pub async fn tracker_file_extension(&self) -> async_graphql::Result> { Ok(self.db_config.tracker_file_extension()) } @@ -290,7 +311,10 @@ impl FieldSource for (&str, &ScanPaths) { } #[Object] +/// Queries relating to numtracker configurations that have no side-effects impl Query { + /// Get the visit directory information for the given beamline and visit. + /// This information is not scan specific #[instrument(skip(self, ctx))] async fn paths( &self, @@ -303,6 +327,7 @@ impl Query { Ok(VisitPath { visit, info }) } + /// Get the current configuration for the given beamline #[instrument(skip(self, ctx))] async fn configuration( &self, @@ -326,8 +351,9 @@ impl Query { } #[Object] +/// Queries that modify the state of the numtracker configuration in some way impl Mutation { - /// Access scan file locations for the next scan + /// Generate scan file locations for the next scan #[instrument(skip(self, ctx))] async fn scan<'ctx>( &self, @@ -367,6 +393,7 @@ impl Mutation { }) } + /// Add or modify the stored configuration for a beamline #[instrument(skip(self, ctx))] async fn configure<'ctx>( &self, @@ -412,12 +439,19 @@ where } } +/// Changes that should be made to a beamline's configuration #[derive(Debug, InputObject)] struct ConfigurationUpdates { + /// New template used to determine the visit directory visit: Option>, + /// New template used to determine the relative path to the main scan file for a collection scan: Option>, + /// New template used to determine the relative path for detector data files detector: Option>, + /// The highest scan number to have been allocated. The next scan files generated will use the + /// next number. scan_number: Option, + /// The extension of the files used to track scan numbers by GDA's numtracker facility tracker_file_extension: Option, } @@ -484,6 +518,8 @@ where } } +/// Name of subdirectory within visit directory where data should be written. +/// Can be nested (eg foo/bar) but cannot include links to parent directories (eg ../foo). // Derived Default is OK without validation as empty path is a valid subdirectory #[derive(Debug, Default)] pub struct Subdirectory(String); @@ -544,6 +580,7 @@ impl Display for Subdirectory { } } +/// Detector name #[derive(Debug)] pub struct Detector(String); diff --git a/src/paths.rs b/src/paths.rs index 91ec460..050ba0c 100644 --- a/src/paths.rs +++ b/src/paths.rs @@ -193,7 +193,10 @@ impl PathSpec for VisitTemplate { const ABSOLUTE: bool = true; fn describe() -> &'static str { - "A template describing the path to the visit directory for a beamline" + concat!( + "A template describing the path to the visit directory for a beamline. ", + "It should be an absolute path and contain placeholders for {instrument} and {visit}." + ) } } @@ -204,7 +207,10 @@ impl PathSpec for ScanTemplate { const ABSOLUTE: bool = false; fn describe() -> &'static str { - "A template describing the location within a visit directory where the root scan file should be written" + concat!( + "A template describing the location within a visit directory where the root scan file should be written. ", + "It should be a relative path and contain a placeholder for {scan_number} to ensure files are unique." + ) } } diff --git a/static/service_schema b/static/service_schema index c103d7a..f4647ab 100644 --- a/static/service_schema +++ b/static/service_schema @@ -1,18 +1,65 @@ +""" +Changes that should be made to a beamline's configuration +""" input ConfigurationUpdates { + """ + New template used to determine the visit directory + """ visit: VisitTemplate + """ + New template used to determine the relative path to the main scan file for a collection + """ scan: ScanTemplate + """ + New template used to determine the relative path for detector data files + """ detector: DetectorTemplate + """ + The highest scan number to have been allocated. The next scan files generated will use the + next number. + """ scanNumber: Int + """ + The extension of the files used to track scan numbers by GDA's numtracker facility + """ trackerFileExtension: String } +""" +The current configuration for a beamline +""" type CurrentConfiguration { + """ + The template used to build the path to the visit directory for a beamline + """ visitTemplate: String! + """ + The template used to build the path of a scan file for a data acquisition, relative to the + root of the visit directory. + """ scanTemplate: String! + """ + The template used to build the path of a detector's data file for a data acquisition, + relative to the root of the visit directory. + """ detectorTemplate: String! + """ + The latest scan number stored in the DB. This is the last scan number provided by this + service but may not reflect the most recent scan number for a beamline if an external + service (eg GDA) has incremented its own number tracker. + """ dbScanNumber: Int! + """ + The highest matching number file for this beamline in the configured tracking directory. + May be null if no directory is available for this beamline or if there are no matching + number files. + """ fileScanNumber: Int + """ + The file extension used for the file based tracking, eg using an extension of 'ext' + would create files `1.ext`, `2.ext` etc + """ trackerFileExtension: String } @@ -22,7 +69,13 @@ scalar Detector GraphQL type to mimic a key-value pair from the map type that GraphQL doesn't have """ type DetectorPath { + """ + The name of the detector that should use this path + """ name: String! + """ + The path where the detector should write its data + """ path: String! } @@ -36,19 +89,38 @@ scalar DetectorTemplate +""" +Queries that modify the state of the numtracker configuration in some way +""" type Mutation { """ - Access scan file locations for the next scan + Generate scan file locations for the next scan """ scan(beamline: String!, visit: String!, sub: Subdirectory): ScanPaths! + """ + Add or modify the stored configuration for a beamline + """ configure(beamline: String!, config: ConfigurationUpdates!): CurrentConfiguration! } +""" +Queries relating to numtracker configurations that have no side-effects +""" type Query { + """ + Get the visit directory information for the given beamline and visit. + This information is not scan specific + """ paths(beamline: String!, visit: String!): VisitPath! + """ + Get the current configuration for the given beamline + """ configuration(beamline: String!): CurrentConfiguration! } +""" +Paths and values related to a specific scan/data collection for a beamline +""" type ScanPaths { """ The visit used to generate this scan information. Should be the same as the visit passed in @@ -75,21 +147,33 @@ type ScanPaths { } """ -A template describing the location within a visit directory where the root scan file should be written +A template describing the location within a visit directory where the root scan file should be written. It should be a relative path and contain a placeholder for {scan_number} to ensure files are unique. """ scalar ScanTemplate scalar Subdirectory +""" +The path to a visit directory and the components used to build it +""" type VisitPath { + """ + The visit for which this is the visit directory + """ visit: String! + """ + This beamline for which this is the visit directory + """ beamline: String! + """ + The absolute path to the visit directory + """ directory: String! } """ -A template describing the path to the visit directory for a beamline +A template describing the path to the visit directory for a beamline. It should be an absolute path and contain placeholders for {instrument} and {visit}. """ scalar VisitTemplate