Skip to content

Input and output

pystac.io

Input and output.

In PySTAC v2.0, reading and writing STAC objects has been split into separate protocols, Read and Write. This should be transparent for most users:

catalog = pystac.read_file("catalog.json")
reader = catalog.get_reader()
for child in catalog.get_children():
    # The default reader is shared for all fetched objects.
    assert child.get_reader() is reader
Note

In PySTAC v1.x, input and output were handled by StacIO.

DefaultReader

A reader that uses only the Python standard library.

Source code in src/pystac/io.py
113
114
115
116
117
118
119
120
121
122
123
124
class DefaultReader:
    """A reader that uses only the Python standard library."""

    def read_json_from_path(self, path: Path) -> Any:
        """Writes JSON to a filesystem path."""
        with open(path) as f:
            return json.load(f)

    def read_json_from_url(self, url: str) -> Any:
        """Reads JSON from a url using `urllib.request`."""
        with urllib.request.urlopen(url) as response:
            return json.load(response)

read_json_from_path

read_json_from_path(path: Path) -> Any

Writes JSON to a filesystem path.

Source code in src/pystac/io.py
116
117
118
119
def read_json_from_path(self, path: Path) -> Any:
    """Writes JSON to a filesystem path."""
    with open(path) as f:
        return json.load(f)

read_json_from_url

read_json_from_url(url: str) -> Any

Reads JSON from a url using urllib.request.

Source code in src/pystac/io.py
121
122
123
124
def read_json_from_url(self, url: str) -> Any:
    """Reads JSON from a url using `urllib.request`."""
    with urllib.request.urlopen(url) as response:
        return json.load(response)

DefaultWriter

A writer.

Source code in src/pystac/io.py
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
class DefaultWriter:
    """A writer."""

    def write_json_to_path(self, data: Any, path: Path) -> None:
        """Writes JSON to a filesystem path.

        Any parent directories will be created.
        """
        path.parent.mkdir(exist_ok=True)
        with open(path, "w") as f:
            json.dump(data, f)

    def write_json_to_url(self, data: Any, url: str) -> None:
        """Writes JSON to a url.

        Always raises a `NotImplementedError`."""
        raise NotImplementedError(
            "The default pystac writer cannot write to urls. Use another writer, "
            "like `pystac.ObstoreWriter` (enabled by `python -m pip install "
            "'pystac[obstore]'`)"
        )

write_json_to_path

write_json_to_path(data: Any, path: Path) -> None

Writes JSON to a filesystem path.

Any parent directories will be created.

Source code in src/pystac/io.py
130
131
132
133
134
135
136
137
def write_json_to_path(self, data: Any, path: Path) -> None:
    """Writes JSON to a filesystem path.

    Any parent directories will be created.
    """
    path.parent.mkdir(exist_ok=True)
    with open(path, "w") as f:
        json.dump(data, f)

write_json_to_url

write_json_to_url(data: Any, url: str) -> None

Writes JSON to a url.

Always raises a NotImplementedError.

Source code in src/pystac/io.py
139
140
141
142
143
144
145
146
147
def write_json_to_url(self, data: Any, url: str) -> None:
    """Writes JSON to a url.

    Always raises a `NotImplementedError`."""
    raise NotImplementedError(
        "The default pystac writer cannot write to urls. Use another writer, "
        "like `pystac.ObstoreWriter` (enabled by `python -m pip install "
        "'pystac[obstore]'`)"
    )

Read

Bases: Protocol

A protocol for anything that can read JSON for pystac.

Source code in src/pystac/io.py
 93
 94
 95
 96
 97
 98
 99
100
class Read(Protocol):
    """A protocol for anything that can read JSON for pystac."""

    def read_json_from_path(self, path: Path) -> Any:
        """Reads JSON from a path."""

    def read_json_from_url(self, url: str) -> Any:
        """Reads JSON from a url."""

read_json_from_path

read_json_from_path(path: Path) -> Any

Reads JSON from a path.

Source code in src/pystac/io.py
96
97
def read_json_from_path(self, path: Path) -> Any:
    """Reads JSON from a path."""

read_json_from_url

read_json_from_url(url: str) -> Any

Reads JSON from a url.

Source code in src/pystac/io.py
 99
100
def read_json_from_url(self, url: str) -> Any:
    """Reads JSON from a url."""

Write

Bases: Protocol

A protocol for anything that can write JSON for pystac.

Source code in src/pystac/io.py
103
104
105
106
107
108
109
110
class Write(Protocol):
    """A protocol for anything that can write JSON for pystac."""

    def write_json_to_path(self, data: Any, path: Path) -> None:
        """Writes JSON to a filesystem path."""

    def write_json_to_url(self, data: Any, url: str) -> None:
        """Writes json to a URL."""

write_json_to_path

write_json_to_path(data: Any, path: Path) -> None

Writes JSON to a filesystem path.

Source code in src/pystac/io.py
106
107
def write_json_to_path(self, data: Any, path: Path) -> None:
    """Writes JSON to a filesystem path."""

write_json_to_url

write_json_to_url(data: Any, url: str) -> None

Writes json to a URL.

Source code in src/pystac/io.py
109
110
def write_json_to_url(self, data: Any, url: str) -> None:
    """Writes json to a URL."""

read_file

read_file(
    href: str | Path,
    stac_io: Any = None,
    *,
    reader: Read | None = None,
) -> STACObject

Reads a file from a href.

Parameters:

Name Type Description Default
href str | Path

The href to read

required
reader Read | None

The [Read][pystac.Read] to use for reading

None

Returns:

Type Description
STACObject

The STAC object

Source code in src/pystac/io.py
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
def read_file(
    href: str | Path,
    stac_io: Any = None,
    *,
    reader: Read | None = None,
) -> STACObject:
    """Reads a file from a href.

    Args:
        href: The href to read
        reader: The [Read][pystac.Read] to use for reading

    Returns:
        The STAC object
    """
    if stac_io:
        deprecate.argument("stac_io")
    return STACObject.from_file(href, reader=reader)

write_file

write_file(
    obj: STACObject,
    include_self_link: bool | None = None,
    dest_href: str | Path | None = None,
    stac_io: Any = None,
    *,
    writer: Write | None = None,
) -> None

Writes a STAC object to a file, using its href.

If the href is not set, this will throw and error.

Parameters:

Name Type Description Default
obj STACObject

The STAC object to write

required
dest_href str | Path | None

The href to write the STAC object to

None
writer Write | None

The [Write][pystac.Write] to use for writing

None
Source code in src/pystac/io.py
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
def write_file(
    obj: STACObject,
    include_self_link: bool | None = None,
    dest_href: str | Path | None = None,
    stac_io: Any = None,
    *,
    writer: Write | None = None,
) -> None:
    """Writes a STAC object to a file, using its href.

    If the href is not set, this will throw and error.

    Args:
        obj: The STAC object to write
        dest_href: The href to write the STAC object to
        writer: The [Write][pystac.Write] to use for writing
    """
    if include_self_link is not None:
        deprecate.argument("include_self_link")
    if stac_io:
        deprecate.argument("stac_io")

    if writer is None:
        writer = DefaultWriter()

    if dest_href is None:
        dest_href = obj.href
    if dest_href is None:
        raise PySTACError(f"cannot write {obj} without an href")
    d = obj.to_dict()
    if isinstance(dest_href, Path):
        writer.write_json_to_path(d, dest_href)
    else:
        url = urllib.parse.urlparse(dest_href)
        if url.scheme:
            writer.write_json_to_url(d, dest_href)
        else:
            writer.write_json_to_path(d, Path(dest_href))

pystac.obstore

Read and write with obstore.

Using these classes requires obstore to be present on your system, e.g.:

python -m pip install 'pystac[obstore]'

ObstoreReader

A reader that uses obstore.

Source code in src/pystac/obstore.py
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
class ObstoreReader:
    """A reader that uses [obstore](https://github.com/developmentseed/obstore)."""

    def __init__(self, **kwargs: Any) -> None:
        """Creates a new obstore reader.

        Args:
            kwargs: Configuration values. Store-specific configuration is done
                with a prefix, e.g. `aws_` for AWS.  See the [obstore
                docs](https://developmentseed.org/obstore/latest/getting-started/#constructing-a-store)
                for more.
        """
        self._config = kwargs
        super().__init__()

    def read_json_from_path(self, path: Path) -> Any:
        store = LocalStore()
        result = obstore.get(store, str(path))
        return json.loads(bytes(result.bytes()))

    def read_json_from_url(self, url: str) -> Any:
        parsed_url = urllib.parse.urlparse(url)
        path = parsed_url.path
        base = parsed_url._replace(path="")
        store = obstore.store.from_url(
            urllib.parse.urlunparse(base), **self._config
        )  # TODO config
        result = obstore.get(store, path)
        return json.loads(bytes(result.bytes()))  # TODO can we parse directly?

__init__

__init__(**kwargs: Any) -> None

Creates a new obstore reader.

Parameters:

Name Type Description Default
kwargs Any

Configuration values. Store-specific configuration is done with a prefix, e.g. aws_ for AWS. See the obstore docs for more.

{}
Source code in src/pystac/obstore.py
23
24
25
26
27
28
29
30
31
32
33
def __init__(self, **kwargs: Any) -> None:
    """Creates a new obstore reader.

    Args:
        kwargs: Configuration values. Store-specific configuration is done
            with a prefix, e.g. `aws_` for AWS.  See the [obstore
            docs](https://developmentseed.org/obstore/latest/getting-started/#constructing-a-store)
            for more.
    """
    self._config = kwargs
    super().__init__()