Skip to content

Commit df59d1d

Browse files
authored
feat: use stac-api's new python feature (#10)
1 parent 00f1fab commit df59d1d

File tree

3 files changed

+21
-94
lines changed

3 files changed

+21
-94
lines changed

Cargo.lock

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

Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@ pyo3-async-runtimes = { version = "0.23.0", features = [
1919
"tokio-runtime",
2020
] }
2121
pythonize = "0.23.0"
22-
serde = "1.0.215"
2322
serde_json = "1.0.133"
24-
stac-api = { version = "0.6.2", git = "https://github.com/stac-utils/stac-rs" }
23+
stac-api = { version = "0.6.2", features = [
24+
"python",
25+
], git = "https://github.com/stac-utils/stac-rs" }
2526
stac = { version = "0.11.0", git = "https://github.com/stac-utils/stac-rs" }
2627
thiserror = "2.0.4"
27-
tokio = "1.41.1"
2828
tokio-postgres = { version = "0.7.12", features = ["with-serde_json-1"] }

src/lib.rs

Lines changed: 11 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
#![deny(unused_crate_dependencies)]
2+
13
use bb8::{Pool, RunError};
24
use bb8_postgres::PostgresConnectionManager;
3-
use geojson::Geometry;
45
use pgstac::Pgstac;
56
use pyo3::{
67
create_exception,
@@ -9,8 +10,7 @@ use pyo3::{
910
types::{PyDict, PyList, PyType},
1011
};
1112
use serde_json::Value;
12-
use stac::Bbox;
13-
use stac_api::{Fields, Filter, Items, Search, Sortby};
13+
use stac_api::python::{StringOrDict, StringOrList};
1414
use std::{future::Future, str::FromStr};
1515
use thiserror::Error;
1616
use tokio_postgres::{Config, NoTls};
@@ -20,18 +20,6 @@ create_exception!(pgstacrs, StacError, PyException);
2020

2121
type PgstacPool = Pool<PostgresConnectionManager<NoTls>>;
2222

23-
#[derive(FromPyObject)]
24-
pub enum StringOrDict {
25-
String(String),
26-
Dict(Py<PyDict>),
27-
}
28-
29-
#[derive(FromPyObject)]
30-
pub enum StringOrList {
31-
String(String),
32-
List(Vec<String>),
33-
}
34-
3523
#[derive(Debug, Error)]
3624
enum Error {
3725
#[error(transparent)]
@@ -290,71 +278,19 @@ impl Client {
290278
query: Option<Bound<'a, PyDict>>,
291279
limit: Option<u64>,
292280
) -> PyResult<Bound<'a, PyAny>> {
293-
// TODO refactor to use https://github.com/gadomski/stacrs/blob/1528d7e1b7185a86efe9fc7c42b0620093c5e9c6/src/search.rs#L128-L162
294-
let mut fields = Fields::default();
295-
if let Some(include) = include {
296-
fields.include = include.into();
297-
}
298-
if let Some(exclude) = exclude {
299-
fields.exclude = exclude.into();
300-
}
301-
let fields = if fields.include.is_empty() && fields.exclude.is_empty() {
302-
None
303-
} else {
304-
Some(fields)
305-
};
306-
let query = query
307-
.map(|query| pythonize::depythonize(&query))
308-
.transpose()?;
309-
let bbox = bbox
310-
.map(|bbox| Bbox::try_from(bbox))
311-
.transpose()
312-
.map_err(Error::from)?;
313-
let sortby = sortby.map(|sortby| {
314-
Vec::<String>::from(sortby)
315-
.into_iter()
316-
.map(|s| s.parse::<Sortby>().unwrap()) // the parse is infallible
317-
.collect::<Vec<_>>()
318-
});
319-
let filter = filter
320-
.map(|filter| match filter {
321-
StringOrDict::Dict(cql_json) => {
322-
pythonize::depythonize(&cql_json.bind_borrowed(py)).map(Filter::Cql2Json)
323-
}
324-
StringOrDict::String(cql2_text) => Ok(Filter::Cql2Text(cql2_text)),
325-
})
326-
.transpose()?;
327-
let filter = filter
328-
.map(|filter| filter.into_cql2_json())
329-
.transpose()
330-
.map_err(Error::from)?;
331-
let items = Items {
281+
let search = stac_api::python::search(
282+
intersects,
283+
ids,
284+
collections,
332285
limit,
333286
bbox,
334287
datetime,
335-
query,
336-
fields,
288+
include,
289+
exclude,
337290
sortby,
338291
filter,
339-
..Default::default()
340-
};
341-
342-
let intersects = intersects
343-
.map(|intersects| match intersects {
344-
StringOrDict::Dict(json) => pythonize::depythonize(&json.bind_borrowed(py))
345-
.map_err(Error::from)
346-
.and_then(|json| Geometry::from_json_object(json).map_err(Error::from)),
347-
StringOrDict::String(s) => s.parse().map_err(Error::from),
348-
})
349-
.transpose()?;
350-
let ids = ids.map(|ids| ids.into());
351-
let collections = collections.map(|ids| ids.into());
352-
let search = Search {
353-
items,
354-
intersects,
355-
ids,
356-
collections,
357-
};
292+
query,
293+
)?;
358294
self.run(py, |pool| async move {
359295
let connection = pool.get().await?;
360296
let page = connection.search(search).await?;
@@ -406,15 +342,6 @@ impl From<Error> for PyErr {
406342
}
407343
}
408344

409-
impl From<StringOrList> for Vec<String> {
410-
fn from(value: StringOrList) -> Vec<String> {
411-
match value {
412-
StringOrList::List(list) => list,
413-
StringOrList::String(s) => vec![s],
414-
}
415-
}
416-
}
417-
418345
#[pymodule]
419346
fn pgstacrs(py: Python<'_>, m: &Bound<'_, PyModule>) -> PyResult<()> {
420347
m.add_class::<Client>()?;

0 commit comments

Comments
 (0)