Skip to content

Commit 818e72f

Browse files
authored
Support getting data and metadata from tables (#40)
1 parent 9cfe855 commit 818e72f

File tree

5 files changed

+225
-1
lines changed

5 files changed

+225
-1
lines changed

resources/metadata_table.json

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
{
2+
"data": {
3+
"id": "internal",
4+
"attributes": {
5+
"ancestors": [
6+
"4866611f-e6d9-4517-bedf-fc5526df57ad",
7+
"primary"
8+
],
9+
"structure_family": "table",
10+
"specs": [],
11+
"metadata": {
12+
"stage-x": {
13+
"dtype": "number",
14+
"shape": [],
15+
"dtype_numpy": "<f8",
16+
"source": "ca://BL01T-MO-SIMC-01:M1.RBV",
17+
"units": "degrees",
18+
"precision": 5,
19+
"limits": {
20+
"control": {
21+
"low": -20000,
22+
"high": 20000
23+
},
24+
"display": {
25+
"low": -20000,
26+
"high": 20000
27+
}
28+
},
29+
"object_name": "stage-x"
30+
}
31+
},
32+
"structure": {
33+
"arrow_schema": "data:application/vnd.apache.arrow.file;base64,/////xgBAAAQAAAAAAAKAAwABgAFAAgACgAAAAABBAAMAAAACAAIAAAABAAIAAAABAAAAAQAAACsAAAAaAAAADgAAAAEAAAAdP///wAAAQMQAAAAHAAAAAQAAAAAAAAACgAAAHRzX3N0YWdlLXgAAKr///8AAAIApP///wAAAQMQAAAAGAAAAAQAAAAAAAAABwAAAHN0YWdlLXgA1v///wAAAgDQ////AAABAxAAAAAcAAAABAAAAAAAAAAEAAAAdGltZQAABgAIAAYABgAAAAAAAgAQABQACAAGAAcADAAAABAAEAAAAAAAAQIQAAAAIAAAAAQAAAAAAAAABwAAAHNlcV9udW0ACAAMAAgABwAIAAAAAAAAAUAAAAAAAAAA",
34+
"npartitions": 1,
35+
"columns": [
36+
"seq_num",
37+
"time",
38+
"stage-x",
39+
"ts_stage-x"
40+
],
41+
"resizable": false
42+
},
43+
"access_blob": {},
44+
"sorting": null,
45+
"data_sources": null
46+
},
47+
"links": {
48+
"self": "http://127.0.0.1:8000/api/v1/metadata/4866611f-e6d9-4517-bedf-fc5526df57ad/primary/internal",
49+
"full": "http://127.0.0.1:8000/api/v1/table/full/4866611f-e6d9-4517-bedf-fc5526df57ad/primary/internal",
50+
"partition": "http://127.0.0.1:8000/api/v1/table/partition/4866611f-e6d9-4517-bedf-fc5526df57ad/primary/internal?partition={index}"
51+
},
52+
"meta": null
53+
},
54+
"error": null,
55+
"links": null,
56+
"meta": {}
57+
}

resources/table_full.json

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"seq_num": [
3+
1,
4+
2,
5+
3,
6+
4,
7+
5
8+
],
9+
"time": [
10+
1762787606.459906,
11+
1762787609.4694269,
12+
1762787612.4223065,
13+
1762787615.400967,
14+
1762787618.4348016
15+
],
16+
"stage-x": [
17+
0,
18+
2.5,
19+
5,
20+
7.5,
21+
10
22+
],
23+
"ts_stage-x": [
24+
631152000,
25+
1762787609.198412,
26+
1762787612.10868,
27+
1762787615.118978,
28+
1762787618.129375
29+
]
30+
}

src/clients.rs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use serde::de::DeserializeOwned;
66
use tracing::{info, instrument};
77
use uuid::Uuid;
88

9-
use crate::model::{app, event_stream, run};
9+
use crate::model::{app, event_stream, run, table};
1010

1111
pub type ClientResult<T> = Result<T, ClientError>;
1212

@@ -46,6 +46,30 @@ impl TiledClient {
4646
self.request(&format!("/api/v1/metadata/{id}/{stream}"), None)
4747
.await
4848
}
49+
pub async fn table_metadata(
50+
&self,
51+
id: Uuid,
52+
stream: String,
53+
table: String,
54+
) -> ClientResult<table::TableMetadataRoot> {
55+
self.request(&format!("/api/v1/metadata/{id}/{stream}/{table}"), None)
56+
.await
57+
}
58+
pub async fn table_full(
59+
&self,
60+
id: Uuid,
61+
stream: String,
62+
table: String,
63+
) -> ClientResult<table::Table> {
64+
let mut headers = HeaderMap::new();
65+
headers.insert("accept", "application/json".parse().unwrap());
66+
67+
self.request(
68+
&format!("/api/v1/table/full/{id}/{stream}/{table}"),
69+
Some(headers),
70+
)
71+
.await
72+
}
4973
pub async fn search_root(&self) -> ClientResult<run::RunRoot> {
5074
self.request("/api/v1/search/", None).await
5175
}

src/model.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ pub(crate) mod container;
33
pub(crate) mod event_stream;
44
pub(crate) mod node;
55
pub(crate) mod run;
6+
pub(crate) mod table;
67

78
use async_graphql::Object;
89
use tracing::instrument;
@@ -31,6 +32,24 @@ impl TiledQuery {
3132
self.0.event_stream_metadata(id, stream).await
3233
}
3334
#[instrument(skip(self))]
35+
async fn table_metadata(
36+
&self,
37+
id: Uuid,
38+
stream: String,
39+
table: String,
40+
) -> Result<table::TableMetadataRoot, ClientError> {
41+
self.0.table_metadata(id, stream, table).await
42+
}
43+
#[instrument(skip(self))]
44+
async fn table_full(
45+
&self,
46+
id: Uuid,
47+
stream: String,
48+
table: String,
49+
) -> Result<table::Table, ClientError> {
50+
self.0.table_full(id, stream, table).await
51+
}
52+
#[instrument(skip(self))]
3453
async fn search_root(&self) -> Result<run::RunRoot, ClientError> {
3554
self.0.search_root().await
3655
}
@@ -104,6 +123,31 @@ mod tests {
104123
mock.assert();
105124
}
106125
#[tokio::test]
126+
async fn table_metadata() {
127+
let id = Uuid::parse_str("4866611f-e6d9-4517-bedf-fc5526df57ad").unwrap();
128+
let stream = "primary";
129+
let table = "internal";
130+
let server = MockServer::start();
131+
let mock = server
132+
.mock_async(|when, then| {
133+
when.method("GET")
134+
.path(format!("/api/v1/metadata/{id}/{stream}/{table}"));
135+
then.status(200)
136+
.body_from_file("resources/metadata_table.json");
137+
})
138+
.await;
139+
let schema = build_schema(&server.base_url());
140+
let query = r#"{ tableMetadata(id:"4866611f-e6d9-4517-bedf-fc5526df57ad", stream:"primary", table:"internal") {data {id}}}"#;
141+
let response = schema.execute(query).await;
142+
let exp = value! ({
143+
"tableMetadata": { "data": {"id": "internal"}}
144+
});
145+
146+
assert_eq!(response.data, exp);
147+
assert_eq!(response.errors, &[]);
148+
mock.assert();
149+
}
150+
#[tokio::test]
107151
async fn search_root() {
108152
let server = MockServer::start();
109153
let mock = server

src/model/table.rs

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
use std::collections::HashMap;
2+
3+
use async_graphql::SimpleObject;
4+
use serde::{Deserialize, Serialize};
5+
use serde_json::Value;
6+
7+
use crate::model::node;
8+
9+
pub type Table = HashMap<String, Vec<Value>>;
10+
11+
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, SimpleObject)]
12+
pub struct TableMetadataRoot {
13+
pub data: TableData,
14+
pub error: Value,
15+
pub links: Option<node::Links>,
16+
pub meta: Value,
17+
}
18+
19+
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, SimpleObject)]
20+
pub struct TableData {
21+
pub id: String,
22+
pub attributes: TableAttributes,
23+
pub links: TableLinks,
24+
pub meta: Value,
25+
}
26+
27+
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, SimpleObject)]
28+
pub struct TableAttributes {
29+
pub ancestors: Vec<Value>,
30+
pub structure_family: String,
31+
pub specs: Option<Vec<Value>>,
32+
pub metadata: HashMap<String, Value>,
33+
pub structure: TableStructure,
34+
pub access_blob: Value,
35+
pub sorting: Value,
36+
pub data_sources: Value,
37+
}
38+
39+
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, SimpleObject)]
40+
pub struct TableStructure {
41+
pub arrow_schema: String,
42+
pub npartitions: i64,
43+
pub columns: Vec<Value>,
44+
pub resizable: bool,
45+
}
46+
47+
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, SimpleObject)]
48+
pub struct TableLinks {
49+
#[serde(rename = "self")]
50+
#[graphql(name = "self")]
51+
pub self_field: String,
52+
pub full: Option<String>,
53+
pub partition: Option<String>,
54+
}
55+
56+
#[cfg(test)]
57+
mod tests {
58+
use crate::model::table;
59+
use crate::test_utils::assert_readable_as;
60+
61+
#[test]
62+
fn table_metadata() {
63+
assert_readable_as::<table::TableMetadataRoot>("resources/metadata_table.json");
64+
}
65+
#[test]
66+
fn table_full() {
67+
assert_readable_as::<table::Table>("resources/table_full.json");
68+
}
69+
}

0 commit comments

Comments
 (0)