Skip to content

Commit 9e65176

Browse files
authored
Client subcommand for interacting with service (#104)
Provides a more convenient way of generating and passing auth tokens and saves writing graphql queries in the terminal to test things using curl. New features are behind the `client` subcommand which itself has three further commands: * configuration: Show/query existing configurations * configure: Update/add new configurations * visit-directory: Generate the visit directory for the given instrument As part of the changes, the '--db' option has been made specific to the serve command as it is not required elsewhere.
1 parent 74fc3f3 commit 9e65176

File tree

17 files changed

+1240
-18
lines changed

17 files changed

+1240
-18
lines changed

Cargo.lock

Lines changed: 525 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ rust-version = "1.83"
1010
[lints.clippy]
1111
unwrap_used = "deny"
1212

13+
[features]
14+
default = ["client"]
15+
client = ["dep:dirs", "dep:graphql_client", "dep:openidconnect", "dep:toml"]
16+
1317
[dependencies]
1418
async-graphql = { version = "7.0.16", features = ["tracing"] }
1519
async-graphql-axum = "7.0.16"
@@ -32,6 +36,12 @@ tracing-opentelemetry = "0.30.0"
3236
tracing-subscriber = { version = "0.3.19", features = ["env-filter"] }
3337
url = "2.5.4"
3438

39+
# Dependencies required if building with client subcommand
40+
dirs = { version = "6.0.0", optional = true }
41+
graphql_client = { version = "0.14.0", optional = true }
42+
openidconnect = { version = "4.0.0", optional = true }
43+
toml = { version = "0.8.20", optional = true }
44+
3545
[dev-dependencies]
3646
assert_matches = "1.5.0"
3747
async-std = { version = "1.13.1", features = ["attributes"], default-features = false }

Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ COPY ./.env ./.env
1414
COPY ./src ./src
1515
COPY ./.sqlx ./.sqlx
1616
COPY ./migrations ./migrations
17+
COPY ./queries ./queries
1718
COPY ./static ./static
1819
# Copy the git directory purely so that the commit information can be included
1920
# build details provided by the 'built' library. See #99

README.md

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,5 +298,109 @@ mutation {
298298
}
299299
```
300300

301+
## Using CLI client
302+
303+
If the application is built with the `client` feature enabled, there is a
304+
`client` subcommand available from the CLI to query and configure the service.
305+
The help covers the basic use.
306+
307+
<details><summary>Output from `numtracker client --help`</summary>
308+
309+
```
310+
View and update beamline configurations provided by an instance of the service
311+
312+
Usage: numtracker client [OPTIONS] <COMMAND>
313+
314+
Commands:
315+
configuration Query existing configurations
316+
configure Update or add new configurations
317+
visit-directory Query for templated data
318+
help Print this message or the help of the given subcommand(s)
319+
320+
Options:
321+
-H, --host <HOST> [env: NUMTRACKER_SERVICE_HOST=]
322+
--auth <AUTH> [env: NUMTRACKER_AUTH_HOST=]
323+
-h, --help Print help
324+
325+
Logging/Debug:
326+
-v, --verbose... Increase the level of logs written to stderr
327+
-q, --quiet Disable all output to stderr/stdout
328+
```
329+
</details>
330+
331+
### Configure
332+
333+
The `configure` subcommand corresponds to the `configure` mutation from graphql.
334+
If a beamline is already present, this can be used to update individual fields.
335+
If the beamline is not present, all template fields must be present.
336+
337+
```bash
338+
$ numtracker client configure i22 \
339+
--visit '/tmp/{instrument}/data/{year}/{visit}'\
340+
--scan '{subdirectory}/{instrument}-{scan_number}'\
341+
--detector '{subdirectory}/{scan_number}/{instrument}-{scan_number}-{detector}'
342+
Visit Template: /tmp/{instrument}/data/{year}/{visit}
343+
Scan Template: {subdirectory}/{instrument}-{scan_number}
344+
Detector Template: {subdirectory}/{scan_number}/{instrument}-{scan_number}-{detector}
345+
DB Scan Number: 0
346+
File Scan Number: 122
347+
Tracker File Extension: None
348+
```
349+
350+
### Configurations
351+
352+
The `configuration` subcommand corresponds to the `configurations` graphql
353+
query. If no beamlines are included in the command, all configurations are
354+
returned, otherwise only those matching the given beamlines are returned
355+
(possible none if no beamlines match).
356+
357+
#### List all configurations
358+
```bash
359+
$ numtracker client configuration
360+
Beamline: i11
361+
Visit Template: ...
362+
Scan Template: ...
363+
Detector Template: ...
364+
DB Scan Number: ...
365+
File Scan Number: ...
366+
Tracker File Extension: ...
367+
Beamline: i22
368+
Visit Template: ...
369+
Scan Template: ...
370+
Detector Template: ...
371+
DB Scan Number: ...
372+
File Scan Number: ...
373+
Tracker File Extension: ...
374+
Beamline: b21
375+
Visit Template: ...
376+
Scan Template: ...
377+
Detector Template: ...
378+
DB Scan Number: ...
379+
File Scan Number: ...
380+
Tracker File Extension: ...
381+
```
382+
383+
#### Filter configurations
384+
```bash
385+
$ numtracker client configuration -b i22
386+
Beamline: i22
387+
Visit Template: ...
388+
Scan Template: ...
389+
Detector Template: ...
390+
DB Scan Number: ...
391+
File Scan Number: ...
392+
Tracker File Extension: ...
393+
```
394+
395+
### Visit Directory
396+
397+
The `visit-directory` subcommand is a reduced version of the `paths` graphql
398+
query. It only returns the directory path.
399+
400+
```bash
401+
$ numtracker client visit-directory i22 cm12345-6
402+
/tmp/i22/data/2025/cm12345-6/
403+
```
404+
301405
[_graphiql]:https://github.com/graphql/graphiql/
302406
[_jq]:https://jqlang.github.io/jq/

build.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
fn main() {
22
println!("cargo::rerun-if-changed=migrations");
3+
println!("cargo::rerun-if-changed=queries");
34
built::write_built_file().expect("Failed to write build time information");
45
// Force the application to be rebuilt after committing to ensure build info is up to date
56
println!("cargo::rerun-if-changed=.git/refs");

catalog-info.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,4 @@ spec:
3131
lifecycle: production
3232
owner: group:data-acquisition
3333
definition:
34-
$text: ./static/service_schema
34+
$text: ./static/service_schema.graphql

queries/configuration.graphql

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
query ConfigurationQuery($instrument: [String!]) {
2+
configurations(instrumentFilters: $instrument) {
3+
instrument
4+
scanTemplate
5+
directoryTemplate
6+
detectorTemplate
7+
fileScanNumber
8+
dbScanNumber
9+
trackerFileExtension
10+
}
11+
}

queries/configure.graphql

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
mutation ConfigureMutation($instrument: String!, $scan: String, $directory: String, $detector: String, $scan_number: Int, $ext: String) {
2+
configure(instrument: $instrument, config: {
3+
scan: $scan,
4+
directory: $directory,
5+
detector: $detector,
6+
scanNumber: $scan_number,
7+
trackerFileExtension: $ext
8+
}) {
9+
directoryTemplate
10+
scanTemplate
11+
detectorTemplate
12+
dbScanNumber
13+
fileScanNumber
14+
trackerFileExtension
15+
}
16+
}

queries/path.graphql

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
query PathQuery($instrument: String!, $instrumentSession: String!) {
2+
paths(instrument: $instrument, instrumentSession: $instrumentSession) {
3+
path
4+
}
5+
}

src/cli/client.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
use clap::{Parser, Subcommand};
2+
use url::Url;
3+
4+
#[derive(Debug, Parser)]
5+
pub struct ClientOptions {
6+
#[clap(flatten)]
7+
pub connection: ConnectionOptions,
8+
#[clap(subcommand)]
9+
pub command: ClientCommand,
10+
}
11+
12+
#[derive(Debug, Parser)]
13+
pub struct ConnectionOptions {
14+
#[clap(long, short = 'H', env = "NUMTRACKER_SERVICE_HOST")]
15+
pub host: Option<Url>,
16+
#[clap(long, env = "NUMTRACKER_AUTH_HOST")]
17+
pub auth: Option<Url>,
18+
}
19+
20+
#[derive(Debug, Subcommand)]
21+
pub enum ClientCommand {
22+
/// Query existing configurations
23+
Configuration {
24+
#[clap(short)]
25+
beamline: Option<Vec<String>>,
26+
},
27+
/// Update or add new configurations
28+
Configure {
29+
beamline: String,
30+
#[clap(flatten)]
31+
config: ConfigurationOptions,
32+
},
33+
/// Query for templated data
34+
VisitDirectory { beamline: String, visit: String },
35+
}
36+
37+
#[derive(Debug, Parser)]
38+
pub struct ConfigurationOptions {
39+
#[clap(long)]
40+
pub directory: Option<String>,
41+
#[clap(long)]
42+
pub scan: Option<String>,
43+
#[clap(long, alias = "det")]
44+
pub detector: Option<String>,
45+
#[clap(long = "number")]
46+
pub scan_number: Option<i64>,
47+
#[clap(long, alias = "ext")]
48+
pub tracker_file_extension: Option<String>,
49+
}

0 commit comments

Comments
 (0)