Skip to content

Commit 8467be3

Browse files
committed
enable direct response env variable
1 parent d641f12 commit 8467be3

File tree

4 files changed

+70
-15
lines changed

4 files changed

+70
-15
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,15 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
1616
## [v4.0.0a2] - 2025-04-20
1717

1818
### Added
19-
- Enabled `enable_direct_response` to improve response performance by bypassing FastAPI's jsonable_encoder and Pydantic serialization when returning Response objects. This change significantly improves performance for large search responses, as profiled in [this issue](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/issues/347) [#359](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/pull/359)
19+
- Added support for high-performance direct response mode for both Elasticsearch and Opensearch backends, controlled by the `ENABLE_DIRECT_RESPONSE` environment variable. When enabled (`ENABLE_DIRECT_RESPONSE=true`), endpoints return Starlette Response objects directly, bypassing FastAPI's jsonable_encoder and Pydantic serialization for significantly improved performance on large search responses. **Note:** In this mode, all FastAPI dependencies (including authentication, custom status codes, and validation) are disabled for all routes. Default is `false` for safety. A warning is logged at startup if enabled. See [issue #347](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/issues/347) and [PR #359](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/pull/359).
2020

2121
### Changed
2222
- Updated test suite to use `httpx.ASGITransport(app=...)` for FastAPI app testing (removes deprecation warning). [#359](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/pull/359)
2323
- Updated stac-fastapi parent libraries to 5.2.0. [#359](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/pull/359)
2424
- Migrated Elasticsearch index template creation from legacy `put_template` to composable `put_index_template` API in `database_logic.py`. This resolves deprecation warnings and ensures compatibility with Elasticsearch 7.x and 8.x. [#359](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/pull/359)
2525
- Updated all Pydantic models to use `ConfigDict` instead of class-based `Config` for Pydantic v2 compatibility. This resolves deprecation warnings and prepares for Pydantic v3. [#359](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/pull/359)
2626
- Migrated all Pydantic `@root_validator` validators to `@model_validator` for Pydantic v2 compatibility. [#359](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/pull/359)
27+
- Migrated startup event handling from deprecated `@app.on_event("startup")` to FastAPI's recommended lifespan context manager. This removes deprecation warnings and ensures compatibility with future FastAPI versions. [#359](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/pull/359)
2728

2829
### Fixed
2930

README.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,13 @@
3232

3333
### Performance Note
3434

35-
The `enable_direct_response` option is provided by the stac-fastapi core library (introduced in stac-fastapi 5.2.0) and is available in this project starting from v4.0.0. When enabled, it allows endpoints to return Starlette Response objects directly, bypassing FastAPI's default serialization for improved performance.
35+
The `enable_direct_response` option is provided by the stac-fastapi core library (introduced in stac-fastapi 5.2.0) and is available in this project starting from v4.0.0.
36+
37+
**You can now control this setting via the `ENABLE_DIRECT_RESPONSE` environment variable.**
38+
39+
When enabled (`ENABLE_DIRECT_RESPONSE=true`), endpoints return Starlette Response objects directly, bypassing FastAPI's default serialization for improved performance. **However, all FastAPI dependencies (including authentication, custom status codes, and validation) are disabled for all routes.**
40+
41+
This mode is best suited for public or read-only APIs where authentication and custom logic are not required. Default is `false` for safety.
3642

3743
See: [issue #347](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/issues/347)
3844

@@ -80,6 +86,7 @@ file named `.env` in the same directory you run Docker Compose from:
8086
```shell
8187
ELASTICSEARCH_VERSION=7.17.1
8288
OPENSEARCH_VERSION=2.11.0
89+
ENABLE_DIRECT_RESPONSE=false
8390
```
8491
The most recent Elasticsearch 7.x versions should also work. See the [opensearch-py docs](https://github.com/opensearch-project/opensearch-py/blob/main/COMPATIBILITY.md) for compatibility information.
8592

@@ -104,7 +111,8 @@ You can customize additional settings in your `.env` file:
104111
| `RELOAD` | Enable auto-reload for development. | `true` | Optional |
105112
| `STAC_FASTAPI_RATE_LIMIT` | API rate limit per client. | `200/minute` | Optional |
106113
| `BACKEND` | Tests-related variable | `elasticsearch` or `opensearch` based on the backend | Optional |
107-
| `ELASTICSEARCH_VERSION` | ElasticSearch version | `7.17.1` | Optional |
114+
| `ELASTICSEARCH_VERSION` | Version of Elasticsearch to use. | N/A | Optional |
115+
| `ENABLE_DIRECT_RESPONSE` | Enable direct response for maximum performance (disables all FastAPI dependencies, including authentication, custom status codes, and validation) | `false` | Optional |
108116
| `OPENSEARCH_VERSION` | OpenSearch version | `2.11.0` | Optional |
109117

110118
> [!NOTE]

stac_fastapi/elasticsearch/stac_fastapi/elasticsearch/config.py

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"""API configuration."""
22

3+
import logging
34
import os
45
import ssl
56
from typing import Any, Dict, Set
@@ -71,28 +72,50 @@ def _es_config() -> Dict[str, Any]:
7172

7273

7374
class ElasticsearchSettings(ApiSettings, ApiBaseSettings):
74-
"""API settings."""
75+
"""
76+
API settings.
77+
78+
Set enable_direct_response via the ENABLE_DIRECT_RESPONSE environment variable.
79+
If enabled, all API routes use direct response for maximum performance, but ALL FastAPI dependencies (including authentication, custom status codes, and validation) are disabled.
80+
Default is False for safety.
81+
"""
7582

76-
# Fields which are defined by STAC but not included in the database model
7783
forbidden_fields: Set[str] = _forbidden_fields
7884
indexed_fields: Set[str] = {"datetime"}
7985
enable_response_models: bool = False
80-
enable_direct_response: bool = True
86+
enable_direct_response: bool = (
87+
os.getenv("ENABLE_DIRECT_RESPONSE", "false").lower() == "true"
88+
)
8189

8290
@property
8391
def create_client(self):
8492
"""Create es client."""
8593
return Elasticsearch(**_es_config())
8694

8795

96+
# Warn at import if direct response is enabled
97+
if ElasticsearchSettings.enable_direct_response:
98+
logging.basicConfig(level=logging.WARNING)
99+
logging.warning(
100+
"ENABLE_DIRECT_RESPONSE is True: All FastAPI dependencies (including authentication) are DISABLED for all routes!"
101+
)
102+
103+
88104
class AsyncElasticsearchSettings(ApiSettings, ApiBaseSettings):
89-
"""API settings."""
105+
"""
106+
API settings.
107+
108+
Set enable_direct_response via the ENABLE_DIRECT_RESPONSE environment variable.
109+
If enabled, all API routes use direct response for maximum performance, but ALL FastAPI dependencies (including authentication, custom status codes, and validation) are disabled.
110+
Default is False for safety.
111+
"""
90112

91-
# Fields which are defined by STAC but not included in the database model
92113
forbidden_fields: Set[str] = _forbidden_fields
93114
indexed_fields: Set[str] = {"datetime"}
94115
enable_response_models: bool = False
95-
enable_direct_response: bool = True
116+
enable_direct_response: bool = (
117+
os.getenv("ENABLE_DIRECT_RESPONSE", "false").lower() == "true"
118+
)
96119

97120
@property
98121
def create_client(self):

stac_fastapi/opensearch/stac_fastapi/opensearch/config.py

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""API configuration."""
2+
import logging
23
import os
34
import ssl
45
from typing import Any, Dict, Set
@@ -69,28 +70,50 @@ def _es_config() -> Dict[str, Any]:
6970

7071

7172
class OpensearchSettings(ApiSettings, ApiBaseSettings):
72-
"""API settings."""
73+
"""
74+
API settings.
75+
76+
Set enable_direct_response via the ENABLE_DIRECT_RESPONSE environment variable.
77+
If enabled, all API routes use direct response for maximum performance, but ALL FastAPI dependencies (including authentication, custom status codes, and validation) are disabled.
78+
Default is False for safety.
79+
"""
7380

74-
# Fields which are defined by STAC but not included in the database model
7581
forbidden_fields: Set[str] = _forbidden_fields
7682
indexed_fields: Set[str] = {"datetime"}
7783
enable_response_models: bool = False
78-
enable_direct_response: bool = True
84+
enable_direct_response: bool = (
85+
os.getenv("ENABLE_DIRECT_RESPONSE", "false").lower() == "true"
86+
)
7987

8088
@property
8189
def create_client(self):
8290
"""Create es client."""
8391
return OpenSearch(**_es_config())
8492

8593

94+
# Warn at import if direct response is enabled
95+
if OpensearchSettings.enable_direct_response:
96+
logging.basicConfig(level=logging.WARNING)
97+
logging.warning(
98+
"ENABLE_DIRECT_RESPONSE is True: All FastAPI dependencies (including authentication) are DISABLED for all routes!"
99+
)
100+
101+
86102
class AsyncOpensearchSettings(ApiSettings, ApiBaseSettings):
87-
"""API settings."""
103+
"""
104+
API settings.
105+
106+
Set enable_direct_response via the ENABLE_DIRECT_RESPONSE environment variable.
107+
If enabled, all API routes use direct response for maximum performance, but ALL FastAPI dependencies (including authentication, custom status codes, and validation) are disabled.
108+
Default is False for safety.
109+
"""
88110

89-
# Fields which are defined by STAC but not included in the database model
90111
forbidden_fields: Set[str] = _forbidden_fields
91112
indexed_fields: Set[str] = {"datetime"}
92113
enable_response_models: bool = False
93-
enable_direct_response: bool = True
114+
enable_direct_response: bool = (
115+
os.getenv("ENABLE_DIRECT_RESPONSE", "false").lower() == "true"
116+
)
94117

95118
@property
96119
def create_client(self):

0 commit comments

Comments
 (0)