Skip to content

Commit 5c8e260

Browse files
committed
feat(python): add migrate_href
1 parent 76d7a9e commit 5c8e260

File tree

4 files changed

+52
-0
lines changed

4 files changed

+52
-0
lines changed

python/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66

77
## [Unreleased]
88

9+
- `main` and entry point script ([#333](https://github.com/stac-utils/stac-rs/pull/333))
10+
- `migrate_href` ([#334](https://github.com/stac-utils/stac-rs/pull/334))
11+
912
## [0.0.3] - 2024-08-29
1013

1114
### Added

python/src/lib.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,45 @@ fn migrate<'py>(value: &Bound<'py, PyDict>, version: Option<&str>) -> PyResult<B
7272
value.downcast_into().map_err(PyErr::from)
7373
}
7474

75+
/// Migrates a STAC dictionary at the given href to another version.
76+
///
77+
/// Migration can be as simple as updating the `stac_version` attribute, but
78+
/// sometimes can be more complicated. For example, when migrating to v1.1.0,
79+
/// [eo:bands and raster:bands should be consolidated to the new bands
80+
/// structure](https://github.com/radiantearth/stac-spec/releases/tag/v1.1.0-beta.1).
81+
///
82+
/// See [the stac-rs
83+
/// documentation](https://docs.rs/stac/latest/stac/enum.Version.html) for
84+
/// supported versions.
85+
///
86+
/// Args:
87+
/// href (str): The href to read the STAC object from
88+
/// version (str | None): The version to migrate to. If not provided, the
89+
/// value will be migrated to the latest stable version.
90+
///
91+
/// Examples:
92+
/// >>> item = stacrs.migrate_href("examples/simple-item.json", "1.1.0-beta.1")
93+
/// >>> assert item["stac_version"] == "1.1.0-beta.1"
94+
#[pyfunction]
95+
#[pyo3(signature = (href, version=None))]
96+
fn migrate_href<'py>(
97+
py: Python<'py>,
98+
href: &str,
99+
version: Option<&str>,
100+
) -> PyResult<Bound<'py, PyDict>> {
101+
let value: Value = stac::read(href).map_err(|err| StacrsError::new_err(err.to_string()))?;
102+
let version = version
103+
.map(|version| version.parse())
104+
.transpose()
105+
.map_err(|err: stac::Error| StacrsError::new_err(err.to_string()))?
106+
.unwrap_or_default();
107+
let value = value
108+
.migrate(version)
109+
.map_err(|err| StacrsError::new_err(err.to_string()))?;
110+
let value = pythonize::pythonize(py, &value)?;
111+
value.downcast_into().map_err(PyErr::from)
112+
}
113+
75114
/// Validates a single href with json-schema.
76115
///
77116
/// Args:
@@ -134,6 +173,7 @@ fn validate_value(value: Value) -> PyResult<()> {
134173
fn stacrs(m: &Bound<'_, PyModule>) -> PyResult<()> {
135174
m.add_function(wrap_pyfunction!(main, m)?)?;
136175
m.add_function(wrap_pyfunction!(migrate, m)?)?;
176+
m.add_function(wrap_pyfunction!(migrate_href, m)?)?;
137177
m.add_function(wrap_pyfunction!(validate_href, m)?)?;
138178
m.add_function(wrap_pyfunction!(validate, m)?)?;
139179
m.add("StacrsError", m.py().get_type_bound::<StacrsError>())?;

python/stacrs.pyi

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ from typing import Any, Optional
33
class StacrsError(Exception): ...
44

55
def main() -> int: ...
6+
def migrate_href(href: str, version: Optional[str] = None) -> dict[str, Any]: ...
67
def migrate(value: dict[str, Any], version: Optional[str] = None) -> dict[str, Any]: ...
78
def validate_href(href: str) -> None: ...
89
def validate(value: dict[str, Any]) -> None: ...

python/tests/test_migrate.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from pathlib import Path
12
from typing import Any
23

34
import stacrs
@@ -6,3 +7,10 @@
67
def test_migrate(item: dict[str, Any]) -> None:
78
item = stacrs.migrate(item, version="1.1.0-beta.1")
89
assert item["stac_version"] == "1.1.0-beta.1"
10+
11+
12+
def test_migrate_href(spec_examples: Path) -> None:
13+
item = stacrs.migrate_href(
14+
str(spec_examples / "simple-item.json"), version="1.1.0-beta.1"
15+
)
16+
assert item["stac_version"] == "1.1.0-beta.1"

0 commit comments

Comments
 (0)