[{"data":1,"prerenderedAt":1690},["ShallowReactive",2],{"nav":3,"page-\u002Fcore-architecture-routing-patterns\u002Fconfiguration-management\u002Fmanaging-environment-variables-with-pydantic-settings\u002F":152,"surround-\u002Fcore-architecture-routing-patterns\u002Fconfiguration-management\u002Fmanaging-environment-variables-with-pydantic-settings\u002F":1688},[4,72],{"title":5,"path":6,"stem":7,"children":8},"Advanced Pydantic Validation Serialization","\u002Fadvanced-pydantic-validation-serialization","advanced-pydantic-validation-serialization",[9,12,24,36,48,54,66],{"title":10,"path":6,"stem":11},"Advanced Pydantic Validation & Serialization","advanced-pydantic-validation-serialization\u002Findex",{"title":13,"path":14,"stem":15,"children":16},"Custom Validators & Field Constraints in FastAPI & Pydantic V2","\u002Fadvanced-pydantic-validation-serialization\u002Fcustom-validators-field-constraints","advanced-pydantic-validation-serialization\u002Fcustom-validators-field-constraints\u002Findex",[17,18],{"title":13,"path":14,"stem":15},{"title":19,"path":20,"stem":21,"children":22},"Creating Reusable Custom Validators in Pydantic: Production Patterns","\u002Fadvanced-pydantic-validation-serialization\u002Fcustom-validators-field-constraints\u002Fcreating-reusable-custom-validators-in-pydantic","advanced-pydantic-validation-serialization\u002Fcustom-validators-field-constraints\u002Fcreating-reusable-custom-validators-in-pydantic\u002Findex",[23],{"title":19,"path":20,"stem":21},{"title":25,"path":26,"stem":27,"children":28},"JSON Schema Customization","\u002Fadvanced-pydantic-validation-serialization\u002Fjson-schema-customization","advanced-pydantic-validation-serialization\u002Fjson-schema-customization\u002Findex",[29,30],{"title":25,"path":26,"stem":27},{"title":31,"path":32,"stem":33,"children":34},"Customizing OpenAPI Schema Generation in FastAPI: Production Implementation Guide","\u002Fadvanced-pydantic-validation-serialization\u002Fjson-schema-customization\u002Fcustomizing-openapi-schema-generation-in-fastapi","advanced-pydantic-validation-serialization\u002Fjson-schema-customization\u002Fcustomizing-openapi-schema-generation-in-fastapi\u002Findex",[35],{"title":31,"path":32,"stem":33},{"title":37,"path":38,"stem":39,"children":40},"Mastering Nested Model Serialization in FastAPI","\u002Fadvanced-pydantic-validation-serialization\u002Fnested-model-serialization","advanced-pydantic-validation-serialization\u002Fnested-model-serialization\u002Findex",[41,42],{"title":37,"path":38,"stem":39},{"title":43,"path":44,"stem":45,"children":46},"Handling Deeply Nested JSON Models Efficiently in FastAPI","\u002Fadvanced-pydantic-validation-serialization\u002Fnested-model-serialization\u002Fhandling-deeply-nested-json-models-efficiently","advanced-pydantic-validation-serialization\u002Fnested-model-serialization\u002Fhandling-deeply-nested-json-models-efficiently\u002Findex",[47],{"title":43,"path":44,"stem":45},{"title":49,"path":50,"stem":51,"children":52},"Performance Optimization for Models in FastAPI","\u002Fadvanced-pydantic-validation-serialization\u002Fperformance-optimization-for-models","advanced-pydantic-validation-serialization\u002Fperformance-optimization-for-models\u002Findex",[53],{"title":49,"path":50,"stem":51},{"title":55,"path":56,"stem":57,"children":58},"Pydantic V2 Migration Guide: FastAPI Production Patterns","\u002Fadvanced-pydantic-validation-serialization\u002Fpydantic-v2-migration-guide","advanced-pydantic-validation-serialization\u002Fpydantic-v2-migration-guide\u002Findex",[59,60],{"title":55,"path":56,"stem":57},{"title":61,"path":62,"stem":63,"children":64},"Migrating from Pydantic v1 to v2 without breaking APIs","\u002Fadvanced-pydantic-validation-serialization\u002Fpydantic-v2-migration-guide\u002Fmigrating-from-pydantic-v1-to-v2-without-breaking-apis","advanced-pydantic-validation-serialization\u002Fpydantic-v2-migration-guide\u002Fmigrating-from-pydantic-v1-to-v2-without-breaking-apis\u002Findex",[65],{"title":61,"path":62,"stem":63},{"title":67,"path":68,"stem":69,"children":70},"Type Hinting & IDE Integration in FastAPI: Advanced Pydantic Patterns","\u002Fadvanced-pydantic-validation-serialization\u002Ftype-hinting-ide-integration","advanced-pydantic-validation-serialization\u002Ftype-hinting-ide-integration\u002Findex",[71],{"title":67,"path":68,"stem":69},{"title":73,"path":74,"stem":75,"children":76},"Core Architecture Routing Patterns","\u002Fcore-architecture-routing-patterns","core-architecture-routing-patterns",[77,80,92,104,116,128,140],{"title":78,"path":74,"stem":79},"Core Architecture & Routing Patterns in FastAPI: A Production-Ready Blueprint","core-architecture-routing-patterns\u002Findex",{"title":81,"path":82,"stem":83,"children":84},"Application Factory Patterns in FastAPI: Production Architecture Guide","\u002Fcore-architecture-routing-patterns\u002Fapplication-factory-patterns","core-architecture-routing-patterns\u002Fapplication-factory-patterns\u002Findex",[85,86],{"title":81,"path":82,"stem":83},{"title":87,"path":88,"stem":89,"children":90},"FastAPI App Factory Pattern for Testing and Deployment: Production Guide","\u002Fcore-architecture-routing-patterns\u002Fapplication-factory-patterns\u002Ffastapi-app-factory-pattern-for-testing-and-deployment","core-architecture-routing-patterns\u002Fapplication-factory-patterns\u002Ffastapi-app-factory-pattern-for-testing-and-deployment\u002Findex",[91],{"title":87,"path":88,"stem":89},{"title":93,"path":94,"stem":95,"children":96},"Configuration Management in FastAPI: Production-Ready Patterns & Security","\u002Fcore-architecture-routing-patterns\u002Fconfiguration-management","core-architecture-routing-patterns\u002Fconfiguration-management\u002Findex",[97,98],{"title":93,"path":94,"stem":95},{"title":99,"path":100,"stem":101,"children":102},"Managing Environment Variables with Pydantic Settings in FastAPI","\u002Fcore-architecture-routing-patterns\u002Fconfiguration-management\u002Fmanaging-environment-variables-with-pydantic-settings","core-architecture-routing-patterns\u002Fconfiguration-management\u002Fmanaging-environment-variables-with-pydantic-settings\u002Findex",[103],{"title":99,"path":100,"stem":101},{"title":105,"path":106,"stem":107,"children":108},"Dependency Injection Strategies","\u002Fcore-architecture-routing-patterns\u002Fdependency-injection-strategies","core-architecture-routing-patterns\u002Fdependency-injection-strategies\u002Findex",[109,110],{"title":105,"path":106,"stem":107},{"title":111,"path":112,"stem":113,"children":114},"Best Practices for FastAPI Dependency Injection","\u002Fcore-architecture-routing-patterns\u002Fdependency-injection-strategies\u002Fbest-practices-for-fastapi-dependency-injection","core-architecture-routing-patterns\u002Fdependency-injection-strategies\u002Fbest-practices-for-fastapi-dependency-injection\u002Findex",[115],{"title":111,"path":112,"stem":113},{"title":117,"path":118,"stem":119,"children":120},"Error Handling & Global Exceptions in FastAPI","\u002Fcore-architecture-routing-patterns\u002Ferror-handling-global-exceptions","core-architecture-routing-patterns\u002Ferror-handling-global-exceptions\u002Findex",[121,122],{"title":117,"path":118,"stem":119},{"title":123,"path":124,"stem":125,"children":126},"Global Exception Handlers for Consistent API Responses","\u002Fcore-architecture-routing-patterns\u002Ferror-handling-global-exceptions\u002Fglobal-exception-handlers-for-consistent-api-responses","core-architecture-routing-patterns\u002Ferror-handling-global-exceptions\u002Fglobal-exception-handlers-for-consistent-api-responses\u002Findex",[127],{"title":123,"path":124,"stem":125},{"title":129,"path":130,"stem":131,"children":132},"Middleware Implementation","\u002Fcore-architecture-routing-patterns\u002Fmiddleware-implementation","core-architecture-routing-patterns\u002Fmiddleware-implementation\u002Findex",[133,134],{"title":129,"path":130,"stem":131},{"title":135,"path":136,"stem":137,"children":138},"Implementing Custom Middleware for Request Tracing in FastAPI","\u002Fcore-architecture-routing-patterns\u002Fmiddleware-implementation\u002Fimplementing-custom-middleware-for-request-tracing","core-architecture-routing-patterns\u002Fmiddleware-implementation\u002Fimplementing-custom-middleware-for-request-tracing\u002Findex",[139],{"title":135,"path":136,"stem":137},{"title":141,"path":142,"stem":143,"children":144},"Modular Router Organization in FastAPI: Production-Grade Architecture","\u002Fcore-architecture-routing-patterns\u002Fmodular-router-organization","core-architecture-routing-patterns\u002Fmodular-router-organization\u002Findex",[145,146],{"title":141,"path":142,"stem":143},{"title":147,"path":148,"stem":149,"children":150},"How to Structure Large FastAPI Projects for Scale","\u002Fcore-architecture-routing-patterns\u002Fmodular-router-organization\u002Fhow-to-structure-large-fastapi-projects-for-scale","core-architecture-routing-patterns\u002Fmodular-router-organization\u002Fhow-to-structure-large-fastapi-projects-for-scale\u002Findex",[151],{"title":147,"path":148,"stem":149},{"id":153,"title":99,"body":154,"description":1683,"extension":1684,"meta":1685,"navigation":243,"path":100,"seo":1686,"stem":101,"__hash__":1687},"content\u002Fcore-architecture-routing-patterns\u002Fconfiguration-management\u002Fmanaging-environment-variables-with-pydantic-settings\u002Findex.md",{"type":155,"value":156,"toc":1674},"minimark",[157,161,176,181,197,539,543,555,565,730,746,750,761,1049,1060,1064,1067,1232,1237,1382,1386,1389,1407,1478,1517,1521,1610,1614,1619,1625,1633,1654,1659,1670],[158,159,99],"h1",{"id":160},"managing-environment-variables-with-pydantic-settings-in-fastapi",[162,163,164,165,170,171,175],"p",{},"Secure and predictable application configuration is non-negotiable in production. This guide demonstrates how to implement robust ",[166,167,169],"a",{"href":168},"\u002Fcore-architecture-routing-patterns\u002Fconfiguration-management\u002F","Configuration Management"," using ",[172,173,174],"code",{},"pydantic-settings",", ensuring strict type validation, secure secret handling, and seamless environment overrides. By validating at startup, you eliminate runtime crashes caused by malformed or missing variables, enforce explicit contracts for deployment pipelines, and integrate cleanly with FastAPI's dependency injection system.",[177,178,180],"h2",{"id":179},"installation-base-settings-architecture","Installation & Base Settings Architecture",[162,182,183,184,187,188,191,192,196],{},"Install the modern v2 package: ",[172,185,186],{},"pip install pydantic-settings>=2.0.0",". Inherit directly from ",[172,189,190],{},"BaseSettings"," and enforce explicit type hints for every field. This approach aligns with established ",[166,193,195],{"href":194},"\u002Fcore-architecture-routing-patterns\u002F","Core Architecture & Routing Patterns"," by decoupling configuration from business logic and enforcing immutability across your service mesh.",[198,199,204],"pre",{"className":200,"code":201,"language":202,"meta":203,"style":203},"language-python shiki shiki-themes github-light","from pydantic_settings import BaseSettings, SettingsConfigDict\nfrom pydantic import field_validator\n\nclass Settings(BaseSettings):\n # Explicit type hints enforce strict validation at startup\n app_name: str = \"FastAPI App\"\n database_url: str\n debug: bool = False\n cors_origins: list[str] = []\n\n @field_validator(\"database_url\")\n @classmethod\n def validate_db_url(cls, v: str) -> str:\n allowed_schemes = (\"postgresql:\u002F\u002F\", \"postgresql+asyncpg:\u002F\u002F\", \"sqlite:\u002F\u002F\")\n if not v.startswith(allowed_schemes):\n raise ValueError(f\"Invalid database URL scheme. Must start with {allowed_schemes}\")\n return v\n\n # Pydantic v2 replaces the deprecated class Config with model_config\n model_config = SettingsConfigDict(\n env_file=\".env\",\n env_file_encoding=\"utf-8\",\n case_sensitive=False,\n extra=\"ignore\" # Silently ignore unexpected OS env vars\n )\n","python","",[172,205,206,225,238,245,263,270,287,296,310,327,332,346,355,377,404,416,447,456,461,467,478,493,506,519,533],{"__ignoreMap":203},[207,208,211,215,219,222],"span",{"class":209,"line":210},"line",1,[207,212,214],{"class":213},"sD7c4","from",[207,216,218],{"class":217},"sgsFI"," pydantic_settings ",[207,220,221],{"class":213},"import",[207,223,224],{"class":217}," BaseSettings, SettingsConfigDict\n",[207,226,228,230,233,235],{"class":209,"line":227},2,[207,229,214],{"class":213},[207,231,232],{"class":217}," pydantic ",[207,234,221],{"class":213},[207,236,237],{"class":217}," field_validator\n",[207,239,241],{"class":209,"line":240},3,[207,242,244],{"emptyLinePlaceholder":243},true,"\n",[207,246,248,251,255,258,260],{"class":209,"line":247},4,[207,249,250],{"class":213},"class",[207,252,254],{"class":253},"s7eDp"," Settings",[207,256,257],{"class":217},"(",[207,259,190],{"class":253},[207,261,262],{"class":217},"):\n",[207,264,266],{"class":209,"line":265},5,[207,267,269],{"class":268},"sAwPA"," # Explicit type hints enforce strict validation at startup\n",[207,271,273,276,280,283],{"class":209,"line":272},6,[207,274,275],{"class":217}," app_name: ",[207,277,279],{"class":278},"sYu0t","str",[207,281,282],{"class":213}," =",[207,284,286],{"class":285},"sYBdl"," \"FastAPI App\"\n",[207,288,290,293],{"class":209,"line":289},7,[207,291,292],{"class":217}," database_url: ",[207,294,295],{"class":278},"str\n",[207,297,299,302,305,307],{"class":209,"line":298},8,[207,300,301],{"class":217}," debug: ",[207,303,304],{"class":278},"bool",[207,306,282],{"class":213},[207,308,309],{"class":278}," False\n",[207,311,313,316,318,321,324],{"class":209,"line":312},9,[207,314,315],{"class":217}," cors_origins: list[",[207,317,279],{"class":278},[207,319,320],{"class":217},"] ",[207,322,323],{"class":213},"=",[207,325,326],{"class":217}," []\n",[207,328,330],{"class":209,"line":329},10,[207,331,244],{"emptyLinePlaceholder":243},[207,333,335,338,340,343],{"class":209,"line":334},11,[207,336,337],{"class":253}," @field_validator",[207,339,257],{"class":217},[207,341,342],{"class":285},"\"database_url\"",[207,344,345],{"class":217},")\n",[207,347,349,352],{"class":209,"line":348},12,[207,350,351],{"class":253}," @",[207,353,354],{"class":278},"classmethod\n",[207,356,358,361,364,367,369,372,374],{"class":209,"line":357},13,[207,359,360],{"class":213}," def",[207,362,363],{"class":253}," validate_db_url",[207,365,366],{"class":217},"(cls, v: ",[207,368,279],{"class":278},[207,370,371],{"class":217},") -> ",[207,373,279],{"class":278},[207,375,376],{"class":217},":\n",[207,378,380,383,385,388,391,394,397,399,402],{"class":209,"line":379},14,[207,381,382],{"class":217}," allowed_schemes ",[207,384,323],{"class":213},[207,386,387],{"class":217}," (",[207,389,390],{"class":285},"\"postgresql:\u002F\u002F\"",[207,392,393],{"class":217},", ",[207,395,396],{"class":285},"\"postgresql+asyncpg:\u002F\u002F\"",[207,398,393],{"class":217},[207,400,401],{"class":285},"\"sqlite:\u002F\u002F\"",[207,403,345],{"class":217},[207,405,407,410,413],{"class":209,"line":406},15,[207,408,409],{"class":213}," if",[207,411,412],{"class":213}," not",[207,414,415],{"class":217}," v.startswith(allowed_schemes):\n",[207,417,419,422,425,427,430,433,436,439,442,445],{"class":209,"line":418},16,[207,420,421],{"class":213}," raise",[207,423,424],{"class":278}," ValueError",[207,426,257],{"class":217},[207,428,429],{"class":213},"f",[207,431,432],{"class":285},"\"Invalid database URL scheme. Must start with ",[207,434,435],{"class":278},"{",[207,437,438],{"class":217},"allowed_schemes",[207,440,441],{"class":278},"}",[207,443,444],{"class":285},"\"",[207,446,345],{"class":217},[207,448,450,453],{"class":209,"line":449},17,[207,451,452],{"class":213}," return",[207,454,455],{"class":217}," v\n",[207,457,459],{"class":209,"line":458},18,[207,460,244],{"emptyLinePlaceholder":243},[207,462,464],{"class":209,"line":463},19,[207,465,466],{"class":268}," # Pydantic v2 replaces the deprecated class Config with model_config\n",[207,468,470,473,475],{"class":209,"line":469},20,[207,471,472],{"class":217}," model_config ",[207,474,323],{"class":213},[207,476,477],{"class":217}," SettingsConfigDict(\n",[207,479,481,485,487,490],{"class":209,"line":480},21,[207,482,484],{"class":483},"sqxcx"," env_file",[207,486,323],{"class":213},[207,488,489],{"class":285},"\".env\"",[207,491,492],{"class":217},",\n",[207,494,496,499,501,504],{"class":209,"line":495},22,[207,497,498],{"class":483}," env_file_encoding",[207,500,323],{"class":213},[207,502,503],{"class":285},"\"utf-8\"",[207,505,492],{"class":217},[207,507,509,512,514,517],{"class":209,"line":508},23,[207,510,511],{"class":483}," case_sensitive",[207,513,323],{"class":213},[207,515,516],{"class":278},"False",[207,518,492],{"class":217},[207,520,522,525,527,530],{"class":209,"line":521},24,[207,523,524],{"class":483}," extra",[207,526,323],{"class":213},[207,528,529],{"class":285},"\"ignore\"",[207,531,532],{"class":268}," # Silently ignore unexpected OS env vars\n",[207,534,536],{"class":209,"line":535},25,[207,537,538],{"class":217}," )\n",[177,540,542],{"id":541},"environment-specific-overrides-env-precedence","Environment-Specific Overrides & .env Precedence",[162,544,545,546,554],{},"Pydantic Settings resolves values using a strict precedence chain: ",[547,548,549,550,553],"strong",{},"OS Environment Variables > ",[172,551,552],{},".env"," file > Class Defaults",". This hierarchy prevents accidental local overrides in staging or production pipelines.",[162,556,557,558,393,561,564],{},"To dynamically load environment-specific files (e.g., ",[172,559,560],{},".env.production",[172,562,563],{},".env.staging","), compute the path before instantiation:",[198,566,568],{"className":200,"code":567,"language":202,"meta":203,"style":203},"import os\nfrom pathlib import Path\nfrom pydantic_settings import BaseSettings, SettingsConfigDict\n\nENV = os.getenv(\"APP_ENV\", \"development\")\nENV_FILE = Path(f\".env.{ENV}\")\n\nclass DynamicSettings(BaseSettings):\n database_url: str\n api_timeout: int = 30\n\n model_config = SettingsConfigDict(\n env_file=ENV_FILE if ENV_FILE.exists() else None,\n env_file_encoding=\"utf-8\"\n )\n",[172,569,570,577,589,599,603,623,645,649,662,668,681,685,693,717,726],{"__ignoreMap":203},[207,571,572,574],{"class":209,"line":210},[207,573,221],{"class":213},[207,575,576],{"class":217}," os\n",[207,578,579,581,584,586],{"class":209,"line":227},[207,580,214],{"class":213},[207,582,583],{"class":217}," pathlib ",[207,585,221],{"class":213},[207,587,588],{"class":217}," Path\n",[207,590,591,593,595,597],{"class":209,"line":240},[207,592,214],{"class":213},[207,594,218],{"class":217},[207,596,221],{"class":213},[207,598,224],{"class":217},[207,600,601],{"class":209,"line":247},[207,602,244],{"emptyLinePlaceholder":243},[207,604,605,608,610,613,616,618,621],{"class":209,"line":265},[207,606,607],{"class":278},"ENV",[207,609,282],{"class":213},[207,611,612],{"class":217}," os.getenv(",[207,614,615],{"class":285},"\"APP_ENV\"",[207,617,393],{"class":217},[207,619,620],{"class":285},"\"development\"",[207,622,345],{"class":217},[207,624,625,628,630,633,635,638,641,643],{"class":209,"line":272},[207,626,627],{"class":278},"ENV_FILE",[207,629,282],{"class":213},[207,631,632],{"class":217}," Path(",[207,634,429],{"class":213},[207,636,637],{"class":285},"\".env.",[207,639,640],{"class":278},"{ENV}",[207,642,444],{"class":285},[207,644,345],{"class":217},[207,646,647],{"class":209,"line":289},[207,648,244],{"emptyLinePlaceholder":243},[207,650,651,653,656,658,660],{"class":209,"line":298},[207,652,250],{"class":213},[207,654,655],{"class":253}," DynamicSettings",[207,657,257],{"class":217},[207,659,190],{"class":253},[207,661,262],{"class":217},[207,663,664,666],{"class":209,"line":312},[207,665,292],{"class":217},[207,667,295],{"class":278},[207,669,670,673,676,678],{"class":209,"line":329},[207,671,672],{"class":217}," api_timeout: ",[207,674,675],{"class":278},"int",[207,677,282],{"class":213},[207,679,680],{"class":278}," 30\n",[207,682,683],{"class":209,"line":334},[207,684,244],{"emptyLinePlaceholder":243},[207,686,687,689,691],{"class":209,"line":348},[207,688,472],{"class":217},[207,690,323],{"class":213},[207,692,477],{"class":217},[207,694,695,697,699,701,703,706,709,712,715],{"class":209,"line":357},[207,696,484],{"class":483},[207,698,323],{"class":213},[207,700,627],{"class":278},[207,702,409],{"class":213},[207,704,705],{"class":278}," ENV_FILE",[207,707,708],{"class":217},".exists() ",[207,710,711],{"class":213},"else",[207,713,714],{"class":278}," None",[207,716,492],{"class":217},[207,718,719,721,723],{"class":209,"line":379},[207,720,498],{"class":483},[207,722,323],{"class":213},[207,724,725],{"class":285},"\"utf-8\"\n",[207,727,728],{"class":209,"line":406},[207,729,538],{"class":217},[162,731,732,735,736,738,739,741,742,745],{},[547,733,734],{},"Production Constraint:"," Never commit ",[172,737,560],{}," to version control. Rely on CI\u002FCD secret injection or Kubernetes ConfigMaps to populate OS-level variables, which will always take precedence over local ",[172,740,552],{}," files. If your deployment runner injects variables directly into the container environment, ",[172,743,744],{},"env_file"," becomes a fallback for local development only.",[177,747,749],{"id":748},"advanced-validation-custom-parsers","Advanced Validation & Custom Parsers",[162,751,752,753,756,757,760],{},"Environment variables are inherently strings. Complex types like database URLs, CORS origins, or JSON payloads require explicit parsing. Use ",[172,754,755],{},"@field_validator"," with ",[172,758,759],{},"mode=\"before\""," to transform raw strings before type coercion.",[198,762,764],{"className":200,"code":763,"language":202,"meta":203,"style":203},"import json\nfrom typing import List\nfrom pydantic import field_validator\nfrom pydantic_settings import BaseSettings\n\nclass AdvancedSettings(BaseSettings):\n redis_hosts: List[str] = []\n feature_flags: dict = {}\n\n @field_validator(\"redis_hosts\", mode=\"before\")\n @classmethod\n def parse_comma_separated(cls, v):\n if isinstance(v, str):\n return [host.strip() for host in v.split(\",\") if host.strip()]\n return v\n\n @field_validator(\"feature_flags\", mode=\"before\")\n @classmethod\n def parse_json_flags(cls, v):\n if isinstance(v, str):\n try:\n return json.loads(v)\n except json.JSONDecodeError as e:\n raise ValueError(f\"Invalid JSON for feature_flags: {e}\")\n return v\n",[172,765,766,773,785,795,806,810,823,836,849,853,874,880,890,904,935,941,945,964,970,979,991,998,1005,1019,1043],{"__ignoreMap":203},[207,767,768,770],{"class":209,"line":210},[207,769,221],{"class":213},[207,771,772],{"class":217}," json\n",[207,774,775,777,780,782],{"class":209,"line":227},[207,776,214],{"class":213},[207,778,779],{"class":217}," typing ",[207,781,221],{"class":213},[207,783,784],{"class":217}," List\n",[207,786,787,789,791,793],{"class":209,"line":240},[207,788,214],{"class":213},[207,790,232],{"class":217},[207,792,221],{"class":213},[207,794,237],{"class":217},[207,796,797,799,801,803],{"class":209,"line":247},[207,798,214],{"class":213},[207,800,218],{"class":217},[207,802,221],{"class":213},[207,804,805],{"class":217}," BaseSettings\n",[207,807,808],{"class":209,"line":265},[207,809,244],{"emptyLinePlaceholder":243},[207,811,812,814,817,819,821],{"class":209,"line":272},[207,813,250],{"class":213},[207,815,816],{"class":253}," AdvancedSettings",[207,818,257],{"class":217},[207,820,190],{"class":253},[207,822,262],{"class":217},[207,824,825,828,830,832,834],{"class":209,"line":289},[207,826,827],{"class":217}," redis_hosts: List[",[207,829,279],{"class":278},[207,831,320],{"class":217},[207,833,323],{"class":213},[207,835,326],{"class":217},[207,837,838,841,844,846],{"class":209,"line":298},[207,839,840],{"class":217}," feature_flags: ",[207,842,843],{"class":278},"dict",[207,845,282],{"class":213},[207,847,848],{"class":217}," {}\n",[207,850,851],{"class":209,"line":312},[207,852,244],{"emptyLinePlaceholder":243},[207,854,855,857,859,862,864,867,869,872],{"class":209,"line":329},[207,856,337],{"class":253},[207,858,257],{"class":217},[207,860,861],{"class":285},"\"redis_hosts\"",[207,863,393],{"class":217},[207,865,866],{"class":483},"mode",[207,868,323],{"class":213},[207,870,871],{"class":285},"\"before\"",[207,873,345],{"class":217},[207,875,876,878],{"class":209,"line":334},[207,877,351],{"class":253},[207,879,354],{"class":278},[207,881,882,884,887],{"class":209,"line":348},[207,883,360],{"class":213},[207,885,886],{"class":253}," parse_comma_separated",[207,888,889],{"class":217},"(cls, v):\n",[207,891,892,894,897,900,902],{"class":209,"line":357},[207,893,409],{"class":213},[207,895,896],{"class":278}," isinstance",[207,898,899],{"class":217},"(v, ",[207,901,279],{"class":278},[207,903,262],{"class":217},[207,905,906,908,911,914,917,920,923,926,929,932],{"class":209,"line":379},[207,907,452],{"class":213},[207,909,910],{"class":217}," [host.strip() ",[207,912,913],{"class":213},"for",[207,915,916],{"class":217}," host ",[207,918,919],{"class":213},"in",[207,921,922],{"class":217}," v.split(",[207,924,925],{"class":285},"\",\"",[207,927,928],{"class":217},") ",[207,930,931],{"class":213},"if",[207,933,934],{"class":217}," host.strip()]\n",[207,936,937,939],{"class":209,"line":406},[207,938,452],{"class":213},[207,940,455],{"class":217},[207,942,943],{"class":209,"line":418},[207,944,244],{"emptyLinePlaceholder":243},[207,946,947,949,951,954,956,958,960,962],{"class":209,"line":449},[207,948,337],{"class":253},[207,950,257],{"class":217},[207,952,953],{"class":285},"\"feature_flags\"",[207,955,393],{"class":217},[207,957,866],{"class":483},[207,959,323],{"class":213},[207,961,871],{"class":285},[207,963,345],{"class":217},[207,965,966,968],{"class":209,"line":458},[207,967,351],{"class":253},[207,969,354],{"class":278},[207,971,972,974,977],{"class":209,"line":463},[207,973,360],{"class":213},[207,975,976],{"class":253}," parse_json_flags",[207,978,889],{"class":217},[207,980,981,983,985,987,989],{"class":209,"line":469},[207,982,409],{"class":213},[207,984,896],{"class":278},[207,986,899],{"class":217},[207,988,279],{"class":278},[207,990,262],{"class":217},[207,992,993,996],{"class":209,"line":480},[207,994,995],{"class":213}," try",[207,997,376],{"class":217},[207,999,1000,1002],{"class":209,"line":495},[207,1001,452],{"class":213},[207,1003,1004],{"class":217}," json.loads(v)\n",[207,1006,1007,1010,1013,1016],{"class":209,"line":508},[207,1008,1009],{"class":213}," except",[207,1011,1012],{"class":217}," json.JSONDecodeError ",[207,1014,1015],{"class":213},"as",[207,1017,1018],{"class":217}," e:\n",[207,1020,1021,1023,1025,1027,1029,1032,1034,1037,1039,1041],{"class":209,"line":521},[207,1022,421],{"class":213},[207,1024,424],{"class":278},[207,1026,257],{"class":217},[207,1028,429],{"class":213},[207,1030,1031],{"class":285},"\"Invalid JSON for feature_flags: ",[207,1033,435],{"class":278},[207,1035,1036],{"class":217},"e",[207,1038,441],{"class":278},[207,1040,444],{"class":285},[207,1042,345],{"class":217},[207,1044,1045,1047],{"class":209,"line":535},[207,1046,452],{"class":213},[207,1048,455],{"class":217},[162,1050,1051,1052,1055,1056,1059],{},"This pattern guarantees that malformed strings raise descriptive ",[172,1053,1054],{},"ValidationError"," exceptions during app initialization, rather than causing silent failures or ",[172,1057,1058],{},"AttributeError"," crashes mid-request.",[177,1061,1063],{"id":1062},"fastapi-dependency-injection-integration","FastAPI Dependency Injection Integration",[162,1065,1066],{},"Avoid global singletons. They break test isolation, complicate hot-reloading, and introduce thread-safety risks. Instead, wire settings into FastAPI using a cached dependency.",[198,1068,1070],{"className":200,"code":1069,"language":202,"meta":203,"style":203},"from functools import lru_cache\nfrom fastapi import Depends, FastAPI\n\napp = FastAPI()\n\n@lru_cache(maxsize=1)\ndef get_settings() -> Settings:\n \"\"\"\n Caches the Settings instance. Environment variables are parsed exactly once\n per worker process, eliminating redundant I\u002FO on every request.\n \"\"\"\n return Settings()\n\n@app.get(\"\u002Fhealth\")\nasync def health_check(settings: Settings = Depends(get_settings)):\n return {\"status\": \"ok\", \"app\": settings.app_name, \"debug\": settings.debug}\n",[172,1071,1072,1084,1096,1100,1110,1114,1131,1142,1147,1152,1157,1161,1168,1172,1184,1202],{"__ignoreMap":203},[207,1073,1074,1076,1079,1081],{"class":209,"line":210},[207,1075,214],{"class":213},[207,1077,1078],{"class":217}," functools ",[207,1080,221],{"class":213},[207,1082,1083],{"class":217}," lru_cache\n",[207,1085,1086,1088,1091,1093],{"class":209,"line":227},[207,1087,214],{"class":213},[207,1089,1090],{"class":217}," fastapi ",[207,1092,221],{"class":213},[207,1094,1095],{"class":217}," Depends, FastAPI\n",[207,1097,1098],{"class":209,"line":240},[207,1099,244],{"emptyLinePlaceholder":243},[207,1101,1102,1105,1107],{"class":209,"line":247},[207,1103,1104],{"class":217},"app ",[207,1106,323],{"class":213},[207,1108,1109],{"class":217}," FastAPI()\n",[207,1111,1112],{"class":209,"line":265},[207,1113,244],{"emptyLinePlaceholder":243},[207,1115,1116,1119,1121,1124,1126,1129],{"class":209,"line":272},[207,1117,1118],{"class":253},"@lru_cache",[207,1120,257],{"class":217},[207,1122,1123],{"class":483},"maxsize",[207,1125,323],{"class":213},[207,1127,1128],{"class":278},"1",[207,1130,345],{"class":217},[207,1132,1133,1136,1139],{"class":209,"line":289},[207,1134,1135],{"class":213},"def",[207,1137,1138],{"class":253}," get_settings",[207,1140,1141],{"class":217},"() -> Settings:\n",[207,1143,1144],{"class":209,"line":298},[207,1145,1146],{"class":285}," \"\"\"\n",[207,1148,1149],{"class":209,"line":312},[207,1150,1151],{"class":285}," Caches the Settings instance. Environment variables are parsed exactly once\n",[207,1153,1154],{"class":209,"line":329},[207,1155,1156],{"class":285}," per worker process, eliminating redundant I\u002FO on every request.\n",[207,1158,1159],{"class":209,"line":334},[207,1160,1146],{"class":285},[207,1162,1163,1165],{"class":209,"line":348},[207,1164,452],{"class":213},[207,1166,1167],{"class":217}," Settings()\n",[207,1169,1170],{"class":209,"line":357},[207,1171,244],{"emptyLinePlaceholder":243},[207,1173,1174,1177,1179,1182],{"class":209,"line":379},[207,1175,1176],{"class":253},"@app.get",[207,1178,257],{"class":217},[207,1180,1181],{"class":285},"\"\u002Fhealth\"",[207,1183,345],{"class":217},[207,1185,1186,1189,1191,1194,1197,1199],{"class":209,"line":406},[207,1187,1188],{"class":213},"async",[207,1190,360],{"class":213},[207,1192,1193],{"class":253}," health_check",[207,1195,1196],{"class":217},"(settings: Settings ",[207,1198,323],{"class":213},[207,1200,1201],{"class":217}," Depends(get_settings)):\n",[207,1203,1204,1206,1209,1212,1215,1218,1220,1223,1226,1229],{"class":209,"line":418},[207,1205,452],{"class":213},[207,1207,1208],{"class":217}," {",[207,1210,1211],{"class":285},"\"status\"",[207,1213,1214],{"class":217},": ",[207,1216,1217],{"class":285},"\"ok\"",[207,1219,393],{"class":217},[207,1221,1222],{"class":285},"\"app\"",[207,1224,1225],{"class":217},": settings.app_name, ",[207,1227,1228],{"class":285},"\"debug\"",[207,1230,1231],{"class":217},": settings.debug}\n",[162,1233,1234],{},[547,1235,1236],{},"Testing Override Pattern:",[198,1238,1240],{"className":200,"code":1239,"language":202,"meta":203,"style":203},"from fastapi.testclient import TestClient\n\ndef test_health_check():\n client = TestClient(app)\n # Override the cached dependency for isolated testing\n app.dependency_overrides[get_settings] = lambda: Settings(\n database_url=\"sqlite:\u002F\u002F\u002Ftest.db\",\n debug=True,\n cors_origins=[\"http:\u002F\u002Flocalhost:3000\"]\n )\n response = client.get(\"\u002Fhealth\")\n assert response.json()[\"debug\"] is True\n # Clean up to prevent cross-test pollution\n app.dependency_overrides.clear()\n",[172,1241,1242,1254,1258,1268,1278,1283,1296,1308,1320,1336,1340,1354,1372,1377],{"__ignoreMap":203},[207,1243,1244,1246,1249,1251],{"class":209,"line":210},[207,1245,214],{"class":213},[207,1247,1248],{"class":217}," fastapi.testclient ",[207,1250,221],{"class":213},[207,1252,1253],{"class":217}," TestClient\n",[207,1255,1256],{"class":209,"line":227},[207,1257,244],{"emptyLinePlaceholder":243},[207,1259,1260,1262,1265],{"class":209,"line":240},[207,1261,1135],{"class":213},[207,1263,1264],{"class":253}," test_health_check",[207,1266,1267],{"class":217},"():\n",[207,1269,1270,1273,1275],{"class":209,"line":247},[207,1271,1272],{"class":217}," client ",[207,1274,323],{"class":213},[207,1276,1277],{"class":217}," TestClient(app)\n",[207,1279,1280],{"class":209,"line":265},[207,1281,1282],{"class":268}," # Override the cached dependency for isolated testing\n",[207,1284,1285,1288,1290,1293],{"class":209,"line":272},[207,1286,1287],{"class":217}," app.dependency_overrides[get_settings] ",[207,1289,323],{"class":213},[207,1291,1292],{"class":213}," lambda",[207,1294,1295],{"class":217},": Settings(\n",[207,1297,1298,1301,1303,1306],{"class":209,"line":289},[207,1299,1300],{"class":483}," database_url",[207,1302,323],{"class":213},[207,1304,1305],{"class":285},"\"sqlite:\u002F\u002F\u002Ftest.db\"",[207,1307,492],{"class":217},[207,1309,1310,1313,1315,1318],{"class":209,"line":298},[207,1311,1312],{"class":483}," debug",[207,1314,323],{"class":213},[207,1316,1317],{"class":278},"True",[207,1319,492],{"class":217},[207,1321,1322,1325,1327,1330,1333],{"class":209,"line":312},[207,1323,1324],{"class":483}," cors_origins",[207,1326,323],{"class":213},[207,1328,1329],{"class":217},"[",[207,1331,1332],{"class":285},"\"http:\u002F\u002Flocalhost:3000\"",[207,1334,1335],{"class":217},"]\n",[207,1337,1338],{"class":209,"line":329},[207,1339,538],{"class":217},[207,1341,1342,1345,1347,1350,1352],{"class":209,"line":334},[207,1343,1344],{"class":217}," response ",[207,1346,323],{"class":213},[207,1348,1349],{"class":217}," client.get(",[207,1351,1181],{"class":285},[207,1353,345],{"class":217},[207,1355,1356,1359,1362,1364,1366,1369],{"class":209,"line":348},[207,1357,1358],{"class":213}," assert",[207,1360,1361],{"class":217}," response.json()[",[207,1363,1228],{"class":285},[207,1365,320],{"class":217},[207,1367,1368],{"class":213},"is",[207,1370,1371],{"class":278}," True\n",[207,1373,1374],{"class":209,"line":357},[207,1375,1376],{"class":268}," # Clean up to prevent cross-test pollution\n",[207,1378,1379],{"class":209,"line":379},[207,1380,1381],{"class":217}," app.dependency_overrides.clear()\n",[177,1383,1385],{"id":1384},"debugging-production-troubleshooting","Debugging & Production Troubleshooting",[162,1387,1388],{},"When configuration fails in live environments, follow this diagnostic workflow:",[1390,1391,1392],"ol",{},[1393,1394,1395,1398,1399,1402,1403,1406],"li",{},[547,1396,1397],{},"Safe State Logging:"," Use ",[172,1400,1401],{},"settings.model_dump()"," to log non-sensitive configuration states. Never log raw ",[172,1404,1405],{},"__dict__"," or secrets.",[198,1408,1410],{"className":200,"code":1409,"language":202,"meta":203,"style":203},"import logging\nlogger = logging.getLogger(__name__)\n# Excludes sensitive fields explicitly\nlogger.info(f\"Loaded config: {settings.model_dump(exclude={'database_url', 'api_keys'})}\")\n",[172,1411,1412,1419,1434,1439],{"__ignoreMap":203},[207,1413,1414,1416],{"class":209,"line":210},[207,1415,221],{"class":213},[207,1417,1418],{"class":217}," logging\n",[207,1420,1421,1424,1426,1429,1432],{"class":209,"line":227},[207,1422,1423],{"class":217},"logger ",[207,1425,323],{"class":213},[207,1427,1428],{"class":217}," logging.getLogger(",[207,1430,1431],{"class":278},"__name__",[207,1433,345],{"class":217},[207,1435,1436],{"class":209,"line":240},[207,1437,1438],{"class":268},"# Excludes sensitive fields explicitly\n",[207,1440,1441,1444,1446,1449,1451,1454,1457,1459,1461,1464,1466,1469,1472,1474,1476],{"class":209,"line":247},[207,1442,1443],{"class":217},"logger.info(",[207,1445,429],{"class":213},[207,1447,1448],{"class":285},"\"Loaded config: ",[207,1450,435],{"class":278},[207,1452,1453],{"class":217},"settings.model_dump(",[207,1455,1456],{"class":483},"exclude",[207,1458,323],{"class":213},[207,1460,435],{"class":217},[207,1462,1463],{"class":285},"'database_url'",[207,1465,393],{"class":217},[207,1467,1468],{"class":285},"'api_keys'",[207,1470,1471],{"class":217},"})",[207,1473,441],{"class":278},[207,1475,444],{"class":285},[207,1477,345],{"class":217},[1390,1479,1480,1490],{"start":227},[1393,1481,1482,1485,1486,1489],{},[547,1483,1484],{},"Traceback Analysis:"," Pydantic v2 provides highly structured validation errors. Look for ",[172,1487,1488],{},"pydantic_core._pydantic_core.ValidationError"," in your container logs. The traceback explicitly names the missing field, the expected type, and the raw input value.",[1393,1491,1492,1495,1496,1499,1500,1502,1503,1505,1506,1509,1510,1513,1514,1516],{},[547,1493,1494],{},"Docker\u002FKubernetes Secret Paths:"," If using mounted secrets (",[172,1497,1498],{},"\u002Frun\u002Fsecrets\u002Fdb_pass","), ensure your ",[172,1501,190],{}," points to the correct path via ",[172,1504,744],{}," or reads them directly from the OS environment. K8s mounts create files, not env vars, unless explicitly mapped via ",[172,1507,1508],{},"envFrom",". Use an entrypoint script or ",[172,1511,1512],{},"envsubst"," to bridge the gap, or read the file directly in a ",[172,1515,755],{},".",[177,1518,1520],{"id":1519},"common-pitfalls-anti-patterns","Common Pitfalls & Anti-Patterns",[1522,1523,1524,1540],"table",{},[1525,1526,1527],"thead",{},[1528,1529,1530,1534,1537],"tr",{},[1531,1532,1533],"th",{},"Pitfall",[1531,1535,1536],{},"Impact",[1531,1538,1539],{},"Resolution",[1541,1542,1543,1560,1588],"tbody",{},[1528,1544,1545,1551,1554],{},[1546,1547,1548],"td",{},[547,1549,1550],{},"Mutable Globals",[1546,1552,1553],{},"Breaks test isolation, leaks secrets to VCS",[1546,1555,1556,1557,1559],{},"Enforce ",[172,1558,190],{}," instantiation via DI. Treat config as immutable.",[1528,1561,1562,1567,1581],{},[1546,1563,1564],{},[547,1565,1566],{},"Silent Type Coercion",[1546,1568,1569,1572,1573,393,1575,1572,1578,1580],{},[172,1570,1571],{},"\"true\""," vs ",[172,1574,1317],{},[172,1576,1577],{},"\"0\"",[172,1579,516],{}," misconfigurations",[1546,1582,1583,1584,1587],{},"Use ",[172,1585,1586],{},"pydantic.StrictBool"," or explicit validators. Validate complex strings manually.",[1528,1589,1590,1595,1601],{},[1546,1591,1592],{},[547,1593,1594],{},"Uncached Dependencies",[1546,1596,1597,1598,1600],{},"High latency, memory overhead, redundant ",[172,1599,552],{}," reads",[1546,1602,1603,1604,756,1607,1516],{},"Always wrap ",[172,1605,1606],{},"get_settings()",[172,1608,1609],{},"@lru_cache(maxsize=1)",[177,1611,1613],{"id":1612},"faq","FAQ",[162,1615,1616],{},[547,1617,1618],{},"How do I handle missing environment variables in production?",[162,1620,1621,1622,1624],{},"Define required fields without default values. Pydantic will raise a ",[172,1623,1054],{}," at startup, preventing the application from booting with incomplete configuration. This is a fail-fast strategy that protects against partial deployments.",[162,1626,1627],{},[547,1628,1629,1630,1632],{},"Can I use multiple ",[172,1631,552],{}," files for different environments?",[162,1634,1635,1636,1638,1639,1642,1643,1646,1647,1650,1651,1653],{},"Yes. Dynamically compute the ",[172,1637,744],{}," path in ",[172,1640,1641],{},"model_config"," based on an ",[172,1644,1645],{},"APP_ENV"," or ",[172,1648,1649],{},"STAGE"," variable. Alternatively, pass ",[172,1652,744],{}," explicitly during instantiation in your entrypoint script.",[162,1655,1656],{},[547,1657,1658],{},"Does Pydantic Settings support nested dictionaries from JSON env vars?",[162,1660,1661,1662,1665,1666,1669],{},"Yes. Use ",[172,1663,1664],{},"pydantic.Json"," type hints or a ",[172,1667,1668],{},"@field_validator(mode=\"before\")"," to parse JSON strings into native Python dictionaries. Ensure your CI\u002FCD pipeline properly escapes quotes when injecting JSON payloads into environment variables.",[1671,1672,1673],"style",{},"html pre.shiki code .sD7c4, html code.shiki .sD7c4{--shiki-default:#D73A49}html pre.shiki code .sgsFI, html code.shiki .sgsFI{--shiki-default:#24292E}html pre.shiki code .s7eDp, html code.shiki .s7eDp{--shiki-default:#6F42C1}html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}html pre.shiki code .sYu0t, html code.shiki .sYu0t{--shiki-default:#005CC5}html pre.shiki code .sYBdl, html code.shiki .sYBdl{--shiki-default:#032F62}html pre.shiki code .sqxcx, html code.shiki .sqxcx{--shiki-default:#E36209}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":203,"searchDepth":227,"depth":227,"links":1675},[1676,1677,1678,1679,1680,1681,1682],{"id":179,"depth":227,"text":180},{"id":541,"depth":227,"text":542},{"id":748,"depth":227,"text":749},{"id":1062,"depth":227,"text":1063},{"id":1384,"depth":227,"text":1385},{"id":1519,"depth":227,"text":1520},{"id":1612,"depth":227,"text":1613},"Secure and predictable application configuration is non-negotiable in production. This guide demonstrates how to implement robust Configuration Management…","md",{},{"title":99,"description":1683},"GgsPkjm6glNCGRBdGHaYacnzkvI5TbFXiyC0DgbpvIc",[1689,1689],null,1778082655313]