Skip to content

Commit d6245b5

Browse files
committed
doc: add lazy loading in GCP Secret Manager
1 parent d6d1b07 commit d6245b5

File tree

1 file changed

+86
-0
lines changed

1 file changed

+86
-0
lines changed

docs/index.md

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2392,6 +2392,92 @@ For nested models, Secret Manager supports the `env_nested_delimiter` setting as
23922392

23932393
For more details on creating and managing secrets in Google Cloud Secret Manager, see the [official Google Cloud documentation](https://cloud.google.com/secret-manager/docs).
23942394

2395+
### Lazy Loading
2396+
2397+
Lazy loading defers field value resolution until fields are actually accessed, rather than eagerly fetching all values during settings initialization. This is particularly useful when working with Google Cloud Secret Manager where each field access triggers an API call, avoiding unnecessary network requests for fields that may never be used.
2398+
2399+
2400+
#### Basic Usage
2401+
2402+
You can enable lazy loading for Google Cloud Secret Manager via the `lazy_load` parameter when configuring `GoogleSecretManagerSettingsSource`:
2403+
2404+
```py
2405+
import logging
2406+
import os
2407+
2408+
from pydantic_settings import (
2409+
BaseSettings,
2410+
GoogleSecretManagerSettingsSource,
2411+
PydanticBaseSettingsSource,
2412+
)
2413+
2414+
logging.basicConfig(level=logging.INFO)
2415+
logger = logging.getLogger(__name__)
2416+
2417+
2418+
class Settings(BaseSettings):
2419+
secret1: str
2420+
secret2: str
2421+
2422+
@classmethod
2423+
def settings_customise_sources(
2424+
cls,
2425+
settings_cls: type[BaseSettings],
2426+
init_settings: PydanticBaseSettingsSource,
2427+
env_settings: PydanticBaseSettingsSource,
2428+
dotenv_settings: PydanticBaseSettingsSource,
2429+
file_secret_settings: PydanticBaseSettingsSource,
2430+
) -> tuple[PydanticBaseSettingsSource, ...]:
2431+
gcp_settings = GoogleSecretManagerSettingsSource(
2432+
settings_cls,
2433+
project_id=os.environ.get('GCP_PROJECT_ID', 'my-project'),
2434+
lazy_load=True,
2435+
)
2436+
return (
2437+
init_settings,
2438+
env_settings,
2439+
dotenv_settings,
2440+
gcp_settings,
2441+
file_secret_settings,
2442+
)
2443+
2444+
2445+
if __name__ == '__main__':
2446+
settings = Settings()
2447+
logger.info('Settings initialized with lazy loading enabled')
2448+
# Only secret1 is fetched from GCP Secret Manager
2449+
s1 = settings.secret1
2450+
2451+
# secret1 is already cached, so this doesn't trigger another API call
2452+
s1_copy = settings.secret1
2453+
2454+
# secret2 is fetched on first access, triggering an API CALL
2455+
s2 = settings.secret2
2456+
2457+
# This triggers fetching of all remaining fields not yet accessed
2458+
all_values = settings.model_dump()
2459+
```
2460+
2461+
#### Behavior and Caching
2462+
2463+
When lazy loading is enabled:
2464+
2465+
1. **Initialization**: Settings are created with minimal overhead. Sources return empty dictionaries instead of eagerly fetching all values.
2466+
2467+
2. **First Access**: When you access a field for the first time (e.g., `settings.api_key`), the value is fetched from the configured source and cached in memory.
2468+
2469+
3. **Subsequent Access**: Accessing the same field again returns the cached value without making another API call.
2470+
2471+
4. **All Fields**: Iteration over all fields (via `model_dump()`, etc.) will trigger resolution of all fields at once.
2472+
2473+
***When to use lazy loading:**
2474+
2475+
* Your settings have many fields but your application only uses a subset of them
2476+
* You want to reduce initialization time and API call costs
2477+
* Network latency to GCP Secret Manager is significant
2478+
2479+
2480+
23952481
## Other settings source
23962482

23972483
Other settings sources are available for common configuration files:

0 commit comments

Comments
 (0)