Skip to content

links

Link helpers.

Create inferred links common to collections and items.

Source code in stac_fastapi/types/stac_fastapi/types/links.py
46
47
48
49
50
51
52
53
54
55
@attr.s
class BaseLinks:
    """Create inferred links common to collections and items."""

    collection_id: str = attr.ib()
    base_url: str = attr.ib()

    def root(self) -> dict[str, Any]:
        """Return the catalog root."""
        return dict(rel=Relations.root, type=MimeTypes.json, href=self.base_url)

root

root() -> dict[str, Any]

Return the catalog root.

Source code in stac_fastapi/types/stac_fastapi/types/links.py
53
54
55
def root(self) -> dict[str, Any]:
    """Return the catalog root."""
    return dict(rel=Relations.root, type=MimeTypes.json, href=self.base_url)

Bases: BaseLinks

Create inferred links specific to collections.

Source code in stac_fastapi/types/stac_fastapi/types/links.py
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
@attr.s
class CollectionLinks(BaseLinks):
    """Create inferred links specific to collections."""

    def self(self) -> dict[str, Any]:
        """Create the `self` link."""
        path = urlsplit(self.base_url).path.rstrip("/")
        return dict(
            rel=Relations.self,
            type=MimeTypes.json,
            href=urljoin(self.base_url, f"{path}/collections/{self.collection_id}"),
        )

    def parent(self) -> dict[str, Any]:
        """Create the `parent` link."""
        return dict(rel=Relations.parent, type=MimeTypes.json, href=self.base_url)

    def items(self) -> dict[str, Any]:
        """Create the `items` link."""
        path = urlsplit(self.base_url).path.rstrip("/")
        return dict(
            rel="items",
            type=MimeTypes.geojson,
            href=urljoin(self.base_url, f"{path}/collections/{self.collection_id}/items"),
        )

    def create_links(self) -> list[dict[str, Any]]:
        """Return all inferred links."""
        return [self.self(), self.parent(), self.items(), self.root()]
create_links() -> list[dict[str, Any]]

Return all inferred links.

Source code in stac_fastapi/types/stac_fastapi/types/links.py
84
85
86
def create_links(self) -> list[dict[str, Any]]:
    """Return all inferred links."""
    return [self.self(), self.parent(), self.items(), self.root()]

items

items() -> dict[str, Any]

Create the items link.

Source code in stac_fastapi/types/stac_fastapi/types/links.py
75
76
77
78
79
80
81
82
def items(self) -> dict[str, Any]:
    """Create the `items` link."""
    path = urlsplit(self.base_url).path.rstrip("/")
    return dict(
        rel="items",
        type=MimeTypes.geojson,
        href=urljoin(self.base_url, f"{path}/collections/{self.collection_id}/items"),
    )

parent

parent() -> dict[str, Any]

Create the parent link.

Source code in stac_fastapi/types/stac_fastapi/types/links.py
71
72
73
def parent(self) -> dict[str, Any]:
    """Create the `parent` link."""
    return dict(rel=Relations.parent, type=MimeTypes.json, href=self.base_url)

self

self() -> dict[str, Any]

Create the self link.

Source code in stac_fastapi/types/stac_fastapi/types/links.py
62
63
64
65
66
67
68
69
def self(self) -> dict[str, Any]:
    """Create the `self` link."""
    path = urlsplit(self.base_url).path.rstrip("/")
    return dict(
        rel=Relations.self,
        type=MimeTypes.json,
        href=urljoin(self.base_url, f"{path}/collections/{self.collection_id}"),
    )

Bases: BaseLinks

Create inferred links specific to items.

Source code in stac_fastapi/types/stac_fastapi/types/links.py
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
@attr.s
class ItemLinks(BaseLinks):
    """Create inferred links specific to items."""

    item_id: str = attr.ib()

    def self(self) -> dict[str, Any]:
        """Create the `self` link."""
        path = urlsplit(self.base_url).path.rstrip("/")
        return dict(
            rel=Relations.self,
            type=MimeTypes.geojson,
            href=urljoin(
                self.base_url,
                f"{path}/collections/{self.collection_id}/items/{self.item_id}",
            ),
        )

    def parent(self) -> dict[str, Any]:
        """Create the `parent` link."""
        path = urlsplit(self.base_url).path.rstrip("/")
        return dict(
            rel=Relations.parent,
            type=MimeTypes.json,
            href=urljoin(self.base_url, f"{path}/collections/{self.collection_id}"),
        )

    def collection(self) -> dict[str, Any]:
        """Create the `collection` link."""
        path = urlsplit(self.base_url).path.rstrip("/")
        return dict(
            rel=Relations.collection,
            type=MimeTypes.json,
            href=urljoin(self.base_url, f"{path}/collections/{self.collection_id}"),
        )

    def create_links(self) -> list[dict[str, Any]]:
        """Return all inferred links."""
        links = [
            self.self(),
            self.parent(),
            self.collection(),
            self.root(),
        ]
        return links

collection

collection() -> dict[str, Any]

Create the collection link.

Source code in stac_fastapi/types/stac_fastapi/types/links.py
116
117
118
119
120
121
122
123
def collection(self) -> dict[str, Any]:
    """Create the `collection` link."""
    path = urlsplit(self.base_url).path.rstrip("/")
    return dict(
        rel=Relations.collection,
        type=MimeTypes.json,
        href=urljoin(self.base_url, f"{path}/collections/{self.collection_id}"),
    )
create_links() -> list[dict[str, Any]]

Return all inferred links.

Source code in stac_fastapi/types/stac_fastapi/types/links.py
125
126
127
128
129
130
131
132
133
def create_links(self) -> list[dict[str, Any]]:
    """Return all inferred links."""
    links = [
        self.self(),
        self.parent(),
        self.collection(),
        self.root(),
    ]
    return links

parent

parent() -> dict[str, Any]

Create the parent link.

Source code in stac_fastapi/types/stac_fastapi/types/links.py
107
108
109
110
111
112
113
114
def parent(self) -> dict[str, Any]:
    """Create the `parent` link."""
    path = urlsplit(self.base_url).path.rstrip("/")
    return dict(
        rel=Relations.parent,
        type=MimeTypes.json,
        href=urljoin(self.base_url, f"{path}/collections/{self.collection_id}"),
    )

self

self() -> dict[str, Any]

Create the self link.

Source code in stac_fastapi/types/stac_fastapi/types/links.py
 95
 96
 97
 98
 99
100
101
102
103
104
105
def self(self) -> dict[str, Any]:
    """Create the `self` link."""
    path = urlsplit(self.base_url).path.rstrip("/")
    return dict(
        rel=Relations.self,
        type=MimeTypes.geojson,
        href=urljoin(
            self.base_url,
            f"{path}/collections/{self.collection_id}/items/{self.item_id}",
        ),
    )
filter_links(links: list[dict]) -> list[dict]

Remove inferred links.

Source code in stac_fastapi/types/stac_fastapi/types/links.py
16
17
18
def filter_links(links: list[dict]) -> list[dict]:
    """Remove inferred links."""
    return [link for link in links if link["rel"] not in INFERRED_LINK_RELS]
resolve_links(links: list, base_url: str) -> list[dict]

Convert relative links to absolute links while preserving existing absolute URLs.

This function processes links and applies the base_url and proxy path to relative URLs However, it explicitly preserves absolute URLs (starting with http:// or https://) to prevent mangling of external links stored in STAC items (e.g., license URLs, external documentation links).

Source code in stac_fastapi/types/stac_fastapi/types/links.py
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
def resolve_links(links: list, base_url: str) -> list[dict]:
    """Convert relative links to absolute links while preserving existing absolute URLs.

    This function processes links and applies the base_url and proxy path to relative URLs
    However, it explicitly preserves absolute URLs (starting with http:// or https://) to
    prevent mangling of external links stored in STAC items (e.g., license URLs, external
    documentation links).
    """
    filtered_links = filter_links(links)
    path = urlsplit(base_url).path.rstrip("/")
    for link in filtered_links:
        href = str(link.get("href", ""))

        # Do not mangle URLs that are already absolute
        if href.startswith(("http://", "https://")):
            continue

        # Remove leading slash to prevent urljoin from replacing the entire path
        href = href.lstrip("/")
        # Construct the full path with proxy path preserved
        full_path = f"{path}/{href}" if path else href
        link.update({"href": urljoin(base_url, full_path)})
    return filtered_links