stac-fastapi-opensearch 6.7.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,143 @@
1
+ elasticsearch/snapshots/
2
+
3
+ # Byte-compiled / optimized / DLL files
4
+ __pycache__/
5
+ *.py[cod]
6
+ *$py.class
7
+
8
+ # C extensions
9
+ *.so
10
+
11
+ # Distribution / packaging
12
+ .Python
13
+ build/
14
+ develop-eggs/
15
+ dist/
16
+ downloads/
17
+ eggs/
18
+ .eggs/
19
+ lib/
20
+ lib64/
21
+ parts/
22
+ sdist/
23
+ var/
24
+ wheels/
25
+ pip-wheel-metadata/
26
+ share/python-wheels/
27
+ *.egg-info/
28
+ .installed.cfg
29
+ *.egg
30
+ MANIFEST
31
+
32
+ # PyInstaller
33
+ # Usually these files are written by a python script from a template
34
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
35
+ *.manifest
36
+ *.spec
37
+
38
+ # Installer logs
39
+ pip-log.txt
40
+ pip-delete-this-directory.txt
41
+
42
+ # Unit test / coverage reports
43
+ htmlcov/
44
+ .tox/
45
+ .nox/
46
+ .coverage
47
+ .coverage.*
48
+ .cache
49
+ nosetests.xml
50
+ coverage.xml
51
+ *.cover
52
+ *.py,cover
53
+ .hypothesis/
54
+ .pytest_cache/
55
+
56
+ # Translations
57
+ *.mo
58
+ *.pot
59
+
60
+ # Django stuff:
61
+ *.log
62
+ local_settings.py
63
+ db.sqlite3
64
+ db.sqlite3-journal
65
+
66
+ # Flask stuff:
67
+ instance/
68
+ .webassets-cache
69
+
70
+ # Scrapy stuff:
71
+ .scrapy
72
+
73
+ # Sphinx documentation
74
+ docs/_build/
75
+
76
+ # PyBuilder
77
+ target/
78
+
79
+ # Jupyter Notebook
80
+ .ipynb_checkpoints
81
+
82
+ # IPython
83
+ profile_default/
84
+ ipython_config.py
85
+
86
+ # pyenv
87
+ .python-version
88
+
89
+ # pipenv
90
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
91
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
92
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
93
+ # install all needed dependencies.
94
+ #Pipfile.lock
95
+
96
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow
97
+ __pypackages__/
98
+
99
+ # Celery stuff
100
+ celerybeat-schedule
101
+ celerybeat.pid
102
+
103
+ # SageMath parsed files
104
+ *.sage.py
105
+
106
+ # Environments
107
+ .env
108
+ .venv
109
+ env/
110
+ venv/
111
+ ENV/
112
+ env.bak/
113
+ venv.bak/
114
+
115
+ # Spyder project settings
116
+ .spyderproject
117
+ .spyproject
118
+
119
+ # Rope project settings
120
+ .ropeproject
121
+
122
+ # mkdocs documentation
123
+ /site
124
+
125
+ # mypy
126
+ .mypy_cache/
127
+ .dmypy.json
128
+ dmypy.json
129
+
130
+ # Pyre type checker
131
+ .pyre/
132
+
133
+ /esdata
134
+
135
+ # Virtualenv
136
+ venv
137
+
138
+ # VSCode folder
139
+ .vscode
140
+
141
+ /docs/src/api/*
142
+
143
+ .DS_Store
@@ -0,0 +1,71 @@
1
+ Metadata-Version: 2.4
2
+ Name: stac_fastapi_opensearch
3
+ Version: 6.7.3
4
+ Summary: An implementation of STAC API based on the FastAPI framework with Opensearch.
5
+ Project-URL: Homepage, https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch
6
+ License: MIT
7
+ Keywords: FastAPI,Opensearch,STAC,STAC-API,stac-fastapi
8
+ Classifier: Intended Audience :: Developers
9
+ Classifier: Intended Audience :: Information Technology
10
+ Classifier: Intended Audience :: Science/Research
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Programming Language :: Python :: 3.9
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Programming Language :: Python :: 3.14
18
+ Requires-Python: >=3.9
19
+ Requires-Dist: opensearch-py[async]~=2.8.0
20
+ Requires-Dist: opensearch-py~=2.8.0
21
+ Requires-Dist: sfeos-helpers==6.7.3
22
+ Requires-Dist: stac-fastapi-core==6.7.3
23
+ Requires-Dist: starlette<0.36.0,>=0.35.0
24
+ Requires-Dist: uvicorn~=0.23.0
25
+ Provides-Extra: dev
26
+ Requires-Dist: ciso8601~=2.3.0; extra == 'dev'
27
+ Requires-Dist: httpx<0.28.0,>=0.24.0; extra == 'dev'
28
+ Requires-Dist: pre-commit~=3.0.0; extra == 'dev'
29
+ Requires-Dist: pytest-asyncio~=0.21.0; extra == 'dev'
30
+ Requires-Dist: pytest-cov~=4.0.0; extra == 'dev'
31
+ Requires-Dist: pytest~=8.0; extra == 'dev'
32
+ Provides-Extra: docs
33
+ Requires-Dist: mkdocs-material~=9.0.0; extra == 'docs'
34
+ Requires-Dist: mkdocs~=1.4.0; extra == 'docs'
35
+ Requires-Dist: pdocs~=1.2.0; extra == 'docs'
36
+ Provides-Extra: server
37
+ Requires-Dist: uvicorn[standard]~=0.23.0; extra == 'server'
38
+ Description-Content-Type: text/markdown
39
+
40
+ # stac-fastapi-opensearch
41
+
42
+ <p align="left">
43
+ <img src="https://raw.githubusercontent.com/stac-utils/stac-fastapi-elasticsearch-opensearch/refs/heads/main/assets/sfeos.png" width=1000>
44
+ </p>
45
+
46
+ [![Downloads](https://static.pepy.tech/badge/stac-fastapi-core?color=blue)](https://pepy.tech/project/stac-fastapi-core)
47
+ [![GitHub contributors](https://img.shields.io/github/contributors/stac-utils/stac-fastapi-elasticsearch-opensearch?color=blue)](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/graphs/contributors)
48
+ [![GitHub stars](https://img.shields.io/github/stars/stac-utils/stac-fastapi-elasticsearch-opensearch.svg?color=blue)](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/stargazers)
49
+ [![GitHub forks](https://img.shields.io/github/forks/stac-utils/stac-fastapi-elasticsearch-opensearch.svg?color=blue)](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/network/members)
50
+ [![PyPI version](https://img.shields.io/pypi/v/stac-fastapi-elasticsearch.svg?color=blue)](https://pypi.org/project/stac-fastapi-elasticsearch/)
51
+ [![STAC](https://img.shields.io/badge/STAC-1.1.0-blue.svg)](https://github.com/radiantearth/stac-spec/tree/v1.1.0)
52
+ [![stac-fastapi](https://img.shields.io/badge/stac--fastapi-6.0.0-blue.svg)](https://github.com/stac-utils/stac-fastapi)
53
+
54
+ This is the OpenSearch backend for stac-fastapi. For full documentation, please see the [main README](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/blob/main/README.md).
55
+
56
+ ## Package Information
57
+
58
+ - **Package name**: stac-fastapi-opensearch
59
+ - **Description**: An implementation of STAC API based on the FastAPI framework with OpenSearch.
60
+ - **Documentation**: [https://stac-utils.github.io/stac-fastapi-elasticsearch-opensearch/](https://stac-utils.github.io/stac-fastapi-elasticsearch-opensearch/)
61
+ - **Source**: [GitHub Repository](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/)
62
+
63
+ ## Installation
64
+
65
+ ```bash
66
+ pip install stac-fastapi-opensearch
67
+ ```
68
+
69
+ ## Quick Start
70
+
71
+ For detailed usage and examples, please refer to the [main documentation](https://stac-utils.github.io/stac-fastapi-elasticsearch-opensearch/).
@@ -0,0 +1,32 @@
1
+ # stac-fastapi-opensearch
2
+
3
+ <p align="left">
4
+ <img src="https://raw.githubusercontent.com/stac-utils/stac-fastapi-elasticsearch-opensearch/refs/heads/main/assets/sfeos.png" width=1000>
5
+ </p>
6
+
7
+ [![Downloads](https://static.pepy.tech/badge/stac-fastapi-core?color=blue)](https://pepy.tech/project/stac-fastapi-core)
8
+ [![GitHub contributors](https://img.shields.io/github/contributors/stac-utils/stac-fastapi-elasticsearch-opensearch?color=blue)](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/graphs/contributors)
9
+ [![GitHub stars](https://img.shields.io/github/stars/stac-utils/stac-fastapi-elasticsearch-opensearch.svg?color=blue)](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/stargazers)
10
+ [![GitHub forks](https://img.shields.io/github/forks/stac-utils/stac-fastapi-elasticsearch-opensearch.svg?color=blue)](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/network/members)
11
+ [![PyPI version](https://img.shields.io/pypi/v/stac-fastapi-elasticsearch.svg?color=blue)](https://pypi.org/project/stac-fastapi-elasticsearch/)
12
+ [![STAC](https://img.shields.io/badge/STAC-1.1.0-blue.svg)](https://github.com/radiantearth/stac-spec/tree/v1.1.0)
13
+ [![stac-fastapi](https://img.shields.io/badge/stac--fastapi-6.0.0-blue.svg)](https://github.com/stac-utils/stac-fastapi)
14
+
15
+ This is the OpenSearch backend for stac-fastapi. For full documentation, please see the [main README](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/blob/main/README.md).
16
+
17
+ ## Package Information
18
+
19
+ - **Package name**: stac-fastapi-opensearch
20
+ - **Description**: An implementation of STAC API based on the FastAPI framework with OpenSearch.
21
+ - **Documentation**: [https://stac-utils.github.io/stac-fastapi-elasticsearch-opensearch/](https://stac-utils.github.io/stac-fastapi-elasticsearch-opensearch/)
22
+ - **Source**: [GitHub Repository](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/)
23
+
24
+ ## Installation
25
+
26
+ ```bash
27
+ pip install stac-fastapi-opensearch
28
+ ```
29
+
30
+ ## Quick Start
31
+
32
+ For detailed usage and examples, please refer to the [main documentation](https://stac-utils.github.io/stac-fastapi-elasticsearch-opensearch/).
@@ -0,0 +1,72 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "stac_fastapi_opensearch"
7
+ description = "An implementation of STAC API based on the FastAPI framework with Opensearch."
8
+ readme = "README.md"
9
+ requires-python = ">=3.9"
10
+ license = {text = "MIT"}
11
+ authors = []
12
+ classifiers = [
13
+ "Intended Audience :: Developers",
14
+ "Intended Audience :: Information Technology",
15
+ "Intended Audience :: Science/Research",
16
+ "Programming Language :: Python :: 3.9",
17
+ "Programming Language :: Python :: 3.10",
18
+ "Programming Language :: Python :: 3.11",
19
+ "Programming Language :: Python :: 3.12",
20
+ "Programming Language :: Python :: 3.13",
21
+ "Programming Language :: Python :: 3.14",
22
+ "License :: OSI Approved :: MIT License",
23
+ ]
24
+ keywords = [
25
+ "STAC",
26
+ "STAC-API",
27
+ "FastAPI",
28
+ "Opensearch",
29
+ "stac-fastapi",
30
+ ]
31
+ dynamic = ["version"]
32
+ dependencies = [
33
+ "stac-fastapi-core==6.7.3",
34
+ "sfeos-helpers==6.7.3",
35
+ "opensearch-py~=2.8.0",
36
+ "opensearch-py[async]~=2.8.0",
37
+ "uvicorn~=0.23.0",
38
+ "starlette>=0.35.0,<0.36.0",
39
+ ]
40
+
41
+ [project.urls]
42
+ Homepage = "https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch"
43
+
44
+ [project.optional-dependencies]
45
+ dev = [
46
+ "pytest~=8.0",
47
+ "pytest-cov~=4.0.0",
48
+ "pytest-asyncio~=0.21.0",
49
+ "pre-commit~=3.0.0",
50
+ "ciso8601~=2.3.0",
51
+ "httpx>=0.24.0,<0.28.0",
52
+ ]
53
+ docs = [
54
+ "mkdocs~=1.4.0",
55
+ "mkdocs-material~=9.0.0",
56
+ "pdocs~=1.2.0",
57
+ ]
58
+ server = [
59
+ "uvicorn[standard]~=0.23.0",
60
+ ]
61
+
62
+ [project.scripts]
63
+ stac-fastapi-opensearch = "stac_fastapi.opensearch.app:run"
64
+
65
+ [tool.hatch.version]
66
+ path = "stac_fastapi/opensearch/version.py"
67
+
68
+ [tool.hatch.build.targets.sdist]
69
+ exclude = ["alembic", "tests", "scripts"]
70
+
71
+ [tool.hatch.build.targets.wheel]
72
+ only-include = ["stac_fastapi"]
@@ -0,0 +1,4 @@
1
+ [pytest]
2
+ testpaths = tests
3
+ addopts = -sv
4
+ asyncio_mode = auto
@@ -0,0 +1 @@
1
+ """opensearch submodule."""
@@ -0,0 +1,295 @@
1
+ """FastAPI application."""
2
+
3
+ import logging
4
+ import os
5
+ from contextlib import asynccontextmanager
6
+
7
+ from fastapi import FastAPI
8
+
9
+ from stac_fastapi.api.app import StacApi
10
+ from stac_fastapi.api.models import (
11
+ ItemCollectionUri,
12
+ create_get_request_model,
13
+ create_post_request_model,
14
+ create_request_model,
15
+ )
16
+ from stac_fastapi.core.core import (
17
+ BulkTransactionsClient,
18
+ CoreClient,
19
+ TransactionsClient,
20
+ )
21
+ from stac_fastapi.core.extensions import QueryExtension
22
+ from stac_fastapi.core.extensions.aggregation import (
23
+ EsAggregationExtensionGetRequest,
24
+ EsAggregationExtensionPostRequest,
25
+ )
26
+ from stac_fastapi.core.extensions.collections_search import (
27
+ CollectionsSearchEndpointExtension,
28
+ )
29
+ from stac_fastapi.core.extensions.fields import FieldsExtension
30
+ from stac_fastapi.core.rate_limit import setup_rate_limit
31
+ from stac_fastapi.core.route_dependencies import get_route_dependencies
32
+ from stac_fastapi.core.session import Session
33
+ from stac_fastapi.core.utilities import get_bool_env
34
+ from stac_fastapi.extensions.core import (
35
+ AggregationExtension,
36
+ CollectionSearchExtension,
37
+ CollectionSearchFilterExtension,
38
+ CollectionSearchPostExtension,
39
+ FilterExtension,
40
+ FreeTextExtension,
41
+ SortExtension,
42
+ TokenPaginationExtension,
43
+ TransactionExtension,
44
+ )
45
+ from stac_fastapi.extensions.core.fields import FieldsConformanceClasses
46
+ from stac_fastapi.extensions.core.filter import FilterConformanceClasses
47
+ from stac_fastapi.extensions.core.free_text import FreeTextConformanceClasses
48
+ from stac_fastapi.extensions.core.query import QueryConformanceClasses
49
+ from stac_fastapi.extensions.core.sort import SortConformanceClasses
50
+ from stac_fastapi.extensions.third_party import BulkTransactionExtension
51
+ from stac_fastapi.opensearch.config import OpensearchSettings
52
+ from stac_fastapi.opensearch.database_logic import (
53
+ DatabaseLogic,
54
+ create_collection_index,
55
+ create_index_templates,
56
+ )
57
+ from stac_fastapi.sfeos_helpers.aggregation import EsAsyncBaseAggregationClient
58
+ from stac_fastapi.sfeos_helpers.filter import EsAsyncBaseFiltersClient
59
+
60
+ logging.basicConfig(level=logging.INFO)
61
+ logger = logging.getLogger(__name__)
62
+
63
+ TRANSACTIONS_EXTENSIONS = get_bool_env("ENABLE_TRANSACTIONS_EXTENSIONS", default=True)
64
+ ENABLE_COLLECTIONS_SEARCH = get_bool_env("ENABLE_COLLECTIONS_SEARCH", default=True)
65
+ ENABLE_COLLECTIONS_SEARCH_ROUTE = get_bool_env(
66
+ "ENABLE_COLLECTIONS_SEARCH_ROUTE", default=False
67
+ )
68
+ logger.info("TRANSACTIONS_EXTENSIONS is set to %s", TRANSACTIONS_EXTENSIONS)
69
+ logger.info("ENABLE_COLLECTIONS_SEARCH is set to %s", ENABLE_COLLECTIONS_SEARCH)
70
+ logger.info(
71
+ "ENABLE_COLLECTIONS_SEARCH_ROUTE is set to %s", ENABLE_COLLECTIONS_SEARCH_ROUTE
72
+ )
73
+
74
+ settings = OpensearchSettings()
75
+ session = Session.create_from_settings(settings)
76
+
77
+ database_logic = DatabaseLogic()
78
+
79
+ filter_extension = FilterExtension(
80
+ client=EsAsyncBaseFiltersClient(database=database_logic)
81
+ )
82
+ filter_extension.conformance_classes.append(
83
+ FilterConformanceClasses.ADVANCED_COMPARISON_OPERATORS
84
+ )
85
+
86
+ aggregation_extension = AggregationExtension(
87
+ client=EsAsyncBaseAggregationClient(
88
+ database=database_logic, session=session, settings=settings
89
+ )
90
+ )
91
+ aggregation_extension.POST = EsAggregationExtensionPostRequest
92
+ aggregation_extension.GET = EsAggregationExtensionGetRequest
93
+
94
+ fields_extension = FieldsExtension()
95
+ fields_extension.conformance_classes.append(FieldsConformanceClasses.ITEMS)
96
+
97
+ search_extensions = [
98
+ fields_extension,
99
+ QueryExtension(),
100
+ SortExtension(),
101
+ TokenPaginationExtension(),
102
+ filter_extension,
103
+ FreeTextExtension(),
104
+ ]
105
+
106
+
107
+ if TRANSACTIONS_EXTENSIONS:
108
+ search_extensions.insert(
109
+ 0,
110
+ TransactionExtension(
111
+ client=TransactionsClient(
112
+ database=database_logic, session=session, settings=settings
113
+ ),
114
+ settings=settings,
115
+ ),
116
+ )
117
+ search_extensions.insert(
118
+ 1,
119
+ BulkTransactionExtension(
120
+ client=BulkTransactionsClient(
121
+ database=database_logic,
122
+ session=session,
123
+ settings=settings,
124
+ )
125
+ ),
126
+ )
127
+
128
+ extensions = [aggregation_extension] + search_extensions
129
+
130
+ # Collection search related variables
131
+ collections_get_request_model = None
132
+
133
+ if ENABLE_COLLECTIONS_SEARCH or ENABLE_COLLECTIONS_SEARCH_ROUTE:
134
+ # Create collection search extensions
135
+ collection_search_extensions = [
136
+ QueryExtension(conformance_classes=[QueryConformanceClasses.COLLECTIONS]),
137
+ SortExtension(conformance_classes=[SortConformanceClasses.COLLECTIONS]),
138
+ FieldsExtension(conformance_classes=[FieldsConformanceClasses.COLLECTIONS]),
139
+ CollectionSearchFilterExtension(
140
+ conformance_classes=[FilterConformanceClasses.COLLECTIONS]
141
+ ),
142
+ FreeTextExtension(conformance_classes=[FreeTextConformanceClasses.COLLECTIONS]),
143
+ ]
144
+
145
+ # Initialize collection search with its extensions
146
+ collection_search_ext = CollectionSearchExtension.from_extensions(
147
+ collection_search_extensions
148
+ )
149
+ collections_get_request_model = collection_search_ext.GET
150
+
151
+ # Create a post request model for collection search
152
+ collection_search_post_request_model = create_post_request_model(
153
+ collection_search_extensions
154
+ )
155
+
156
+ # Create collection search extensions if enabled
157
+ if ENABLE_COLLECTIONS_SEARCH:
158
+ # Initialize collection search POST extension
159
+ collection_search_post_ext = CollectionSearchPostExtension(
160
+ client=CoreClient(
161
+ database=database_logic,
162
+ session=session,
163
+ post_request_model=collection_search_post_request_model,
164
+ landing_page_id=os.getenv("STAC_FASTAPI_LANDING_PAGE_ID", "stac-fastapi"),
165
+ ),
166
+ settings=settings,
167
+ POST=collection_search_post_request_model,
168
+ conformance_classes=[
169
+ "https://api.stacspec.org/v1.0.0-rc.1/collection-search",
170
+ QueryConformanceClasses.COLLECTIONS,
171
+ FilterConformanceClasses.COLLECTIONS,
172
+ FreeTextConformanceClasses.COLLECTIONS,
173
+ SortConformanceClasses.COLLECTIONS,
174
+ FieldsConformanceClasses.COLLECTIONS,
175
+ ],
176
+ )
177
+ extensions.append(collection_search_ext)
178
+ extensions.append(collection_search_post_ext)
179
+
180
+ if ENABLE_COLLECTIONS_SEARCH_ROUTE:
181
+ # Initialize collections-search endpoint extension
182
+ collections_search_endpoint_ext = CollectionsSearchEndpointExtension(
183
+ client=CoreClient(
184
+ database=database_logic,
185
+ session=session,
186
+ post_request_model=collection_search_post_request_model,
187
+ landing_page_id=os.getenv("STAC_FASTAPI_LANDING_PAGE_ID", "stac-fastapi"),
188
+ ),
189
+ settings=settings,
190
+ GET=collections_get_request_model,
191
+ POST=collection_search_post_request_model,
192
+ conformance_classes=[
193
+ "https://api.stacspec.org/v1.0.0-rc.1/collection-search",
194
+ QueryConformanceClasses.COLLECTIONS,
195
+ FilterConformanceClasses.COLLECTIONS,
196
+ FreeTextConformanceClasses.COLLECTIONS,
197
+ SortConformanceClasses.COLLECTIONS,
198
+ FieldsConformanceClasses.COLLECTIONS,
199
+ ],
200
+ )
201
+ extensions.append(collections_search_endpoint_ext)
202
+
203
+
204
+ database_logic.extensions = [type(ext).__name__ for ext in extensions]
205
+
206
+ post_request_model = create_post_request_model(search_extensions)
207
+
208
+ items_get_request_model = create_request_model(
209
+ model_name="ItemCollectionUri",
210
+ base_model=ItemCollectionUri,
211
+ extensions=[
212
+ SortExtension(
213
+ conformance_classes=[SortConformanceClasses.ITEMS],
214
+ ),
215
+ QueryExtension(
216
+ conformance_classes=[QueryConformanceClasses.ITEMS],
217
+ ),
218
+ filter_extension,
219
+ FieldsExtension(conformance_classes=[FieldsConformanceClasses.ITEMS]),
220
+ ],
221
+ request_type="GET",
222
+ )
223
+
224
+ app_config = {
225
+ "title": os.getenv("STAC_FASTAPI_TITLE", "stac-fastapi-opensearch"),
226
+ "description": os.getenv("STAC_FASTAPI_DESCRIPTION", "stac-fastapi-opensearch"),
227
+ "api_version": os.getenv("STAC_FASTAPI_VERSION", "6.0.0"),
228
+ "settings": settings,
229
+ "extensions": extensions,
230
+ "client": CoreClient(
231
+ database=database_logic,
232
+ session=session,
233
+ post_request_model=post_request_model,
234
+ landing_page_id=os.getenv("STAC_FASTAPI_LANDING_PAGE_ID", "stac-fastapi"),
235
+ ),
236
+ "collections_get_request_model": collections_get_request_model,
237
+ "search_get_request_model": create_get_request_model(search_extensions),
238
+ "search_post_request_model": post_request_model,
239
+ "items_get_request_model": items_get_request_model,
240
+ "route_dependencies": get_route_dependencies(),
241
+ }
242
+
243
+ # Add collections_get_request_model if it was created
244
+ if collections_get_request_model:
245
+ app_config["collections_get_request_model"] = collections_get_request_model
246
+
247
+ api = StacApi(**app_config)
248
+
249
+
250
+ @asynccontextmanager
251
+ async def lifespan(app: FastAPI):
252
+ """Lifespan handler for FastAPI app. Initializes index templates and collections at startup."""
253
+ await create_index_templates()
254
+ await create_collection_index()
255
+ yield
256
+
257
+
258
+ app = api.app
259
+ app.router.lifespan_context = lifespan
260
+ app.root_path = os.getenv("STAC_FASTAPI_ROOT_PATH", "")
261
+ # Add rate limit
262
+ setup_rate_limit(app, rate_limit=os.getenv("STAC_FASTAPI_RATE_LIMIT"))
263
+
264
+
265
+ def run() -> None:
266
+ """Run app from command line using uvicorn if available."""
267
+ try:
268
+ import uvicorn
269
+
270
+ uvicorn.run(
271
+ "stac_fastapi.opensearch.app:app",
272
+ host=settings.app_host,
273
+ port=settings.app_port,
274
+ log_level="info",
275
+ reload=settings.reload,
276
+ )
277
+ except ImportError:
278
+ raise RuntimeError("Uvicorn must be installed in order to use command")
279
+
280
+
281
+ if __name__ == "__main__":
282
+ run()
283
+
284
+
285
+ def create_handler(app):
286
+ """Create a handler to use with AWS Lambda if mangum available."""
287
+ try:
288
+ from mangum import Mangum
289
+
290
+ return Mangum(app)
291
+ except ImportError:
292
+ return None
293
+
294
+
295
+ handler = create_handler(app)