📖 Scenario: You are building a simple FastAPI application that needs to use different settings depending on the environment it runs in, such as development or production.This is like having different light switches for day and night: you want the app to behave differently without changing the main code.
🎯 Goal: Create a FastAPI app that loads settings from environment variables using pydantic.BaseSettings. You will define a settings class, set a default environment, and use the settings in a route.
📋 What You'll Learn
Create a Settings class inheriting from pydantic.BaseSettings with a debug boolean field
Add a ENVIRONMENT variable to specify the environment name
Load the settings and use the debug value in a FastAPI route response
💡 Why This Matters
🌍 Real World
Many web applications need to behave differently in development, testing, and production. Using environment-based settings helps keep code clean and secure.
💼 Career
Understanding environment-based configuration is essential for backend developers working with FastAPI or any modern web framework.
Progress0 / 4 steps
1
Create the Settings class
Create a class called Settings that inherits from pydantic.BaseSettings. Add a boolean field called debug with a default value False.
FastAPI
Hint
Use class Settings(BaseSettings): and define debug: bool = False inside.
2
Add environment variable for environment name
Add a variable called ENVIRONMENT and set it to the string 'development'.
FastAPI
Hint
Just write ENVIRONMENT = 'development' below the class.
3
Load settings and create FastAPI app
Import FastAPI from fastapi. Create a variable called settings by instantiating Settings(). Then create a FastAPI app instance called app.
FastAPI
Hint
Use settings = Settings() and app = FastAPI() after importing.
4
Create a route using the settings
Add a GET route at / using @app.get("/"). Define a function called read_root that returns a dictionary with a key debug_mode and value from settings.debug.
FastAPI
Hint
Use @app.get("/") and return {"debug_mode": settings.debug} inside the function.
Practice
(1/5)
1. What is the main purpose of using environment-based settings in a FastAPI application?
easy
A. To change app behavior without modifying the code
Environment-based settings allow configuration changes without changing the code itself.
Step 2: Identify the main benefit in FastAPI
This lets the app behave differently in development, testing, or production by just changing environment variables.
Final Answer:
To change app behavior without modifying the code -> Option A
Quick Check:
Environment-based settings = change behavior without code change [OK]
Hint: Think: change settings without touching code [OK]
Common Mistakes:
Confusing settings with performance improvements
Thinking it automatically adds routes
Assuming it creates UI elements
2. Which of the following is the correct way to define a settings class using Pydantic's BaseSettings in FastAPI?
easy
A. class Settings(BaseModel):\n debug: bool = False
B. class Settings(BaseSettings):\n debug: bool = False
C. class Settings(dict):\n debug: bool = False
D. class Settings(object):\n debug: bool = False
Solution
Step 1: Recall correct base class for environment settings
Pydantic's BaseSettings is designed for environment-based config loading.
Step 2: Check class definition syntax
Using BaseSettings with typed attributes and default values is correct.
Final Answer:
class Settings(BaseSettings):\n debug: bool = False -> Option B
Quick Check:
Use BaseSettings for env config classes [OK]
Hint: Use BaseSettings, not BaseModel, for env configs [OK]
Common Mistakes:
Using BaseModel instead of BaseSettings
Inheriting from dict or object directly
Missing type annotations
3. Given this FastAPI settings class and .env file, what will be the value of settings.debug?
class Settings(BaseSettings):
debug: bool = False
settings = Settings()
.env file content:
DEBUG=true
medium
A. False
B. Error: missing attribute
C. True
D. None
Solution
Step 1: Understand BaseSettings behavior with .env
BaseSettings reads environment variables and overrides defaults if present.
Step 2: Check .env value for DEBUG
The .env file sets DEBUG=true, which overrides the default False.
Final Answer:
True -> Option C
Quick Check:
.env overrides default values in BaseSettings [OK]
Hint: .env values override defaults in BaseSettings [OK]
Common Mistakes:
Assuming default stays despite .env
Confusing string 'true' with boolean
Expecting error if .env exists
4. What is wrong with this FastAPI settings code that tries to load environment variables?
from pydantic import BaseSettings
class Settings(BaseSettings):
api_key: str
settings = Settings()
Assuming no environment variable API_KEY is set.
medium
A. It will silently ignore missing api_key
B. It will set api_key to an empty string
C. It will set api_key to None
D. It will raise a validation error because api_key is required but missing
Solution
Step 1: Check required fields in BaseSettings
Fields without defaults are required and must be provided via env or arguments.
Step 2: Consider missing environment variable
Since API_KEY is not set, BaseSettings raises a validation error on instantiation.
Final Answer:
It will raise a validation error because api_key is required but missing -> Option D
Quick Check:
Missing required env vars cause validation errors [OK]
Hint: Required fields without defaults must be set in env [OK]
Common Mistakes:
Expecting default empty string or None
Thinking missing vars are ignored
Assuming no error on missing required field
5. You want to create a FastAPI settings class that loads a database URL from environment variables but uses a default if none is set. Which code correctly implements this with Pydantic's BaseSettings?
hard
A. class Settings(BaseSettings):\n database_url: str = 'sqlite:///default.db'
B. class Settings(BaseSettings):\n database_url: str
C. class Settings(BaseSettings):\n database_url: str = Field(default_factory=lambda: 'sqlite:///default.db')
D. class Settings(BaseSettings):\n database_url: Optional[str] = None
Solution
Step 1: Understand default values with environment override
Using a default value directly allows configuration from environment variables if present, falling back to the default otherwise.
Step 2: Compare options for correct default and override behavior
class Settings(BaseSettings):\n database_url: str = 'sqlite:///default.db' uses a direct default value, overridden by DATABASE_URL env var if set.
Final Answer:
class Settings(BaseSettings):\n database_url: str = 'sqlite:///default.db' -> Option A
Quick Check:
Direct default = env override if present [OK]
Hint: Direct field default: str = 'default' for env override [OK]
Common Mistakes:
Leaving field required without default
Using Field(default_factory=...) unnecessarily (requires Field import)
Using Optional[str] = None (defaults to None)
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.