Python
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax and Data Types
-
Section 3: Collections
-
39: Set Operations: Union, Intersection, Difference
-
Section 4: Control Flow
-
Section 5: Functions
-
Section 6: Turtle Graphics and Early Practice Projects
-
Section 7: Working with Files and I/O
-
Section 8: Regular Expressions
-
Section 9: Object-Oriented Python
-
Section 10: Error Handling
-
Section 11: Modules and Packages
-
Section 12: Iterators, Generators, and Functional Tools
-
Section 13: Decorators and Metaprogramming
-
Section 14: Concurrency and Parallelism
-
Section 15: Working with Dates, Times, and Numbers
-
Section 16: Standard Library Deep Dive I: Data Structures
-
Section 17: Standard Library Deep Dive II: System and Introspection
-
Section 18: Standard Library Deep Dive III: Security and Encoding
-
Section 19: Standard Library Deep Dive IV: Text and Data Utilities
-
Section 20: Networking and Web Basics
-
Section 21: Working with Databases
-
Section 22: Testing and Quality
-
Section 23: Advanced Typing
-
Section 24: Context Managers and Resource Handling
-
Section 25: Text, Unicode, and Binary Data
-
Section 26: More Functional and Iteration Tools
-
Section 27: Data Validation and Configuration
-
Section 28: Working with Images and Media
-
Section 29: Property-Based and Documentation Testing
-
Section 30: Packaging and Deployment
-
Section 31: Performance and Internals
-
Section 32: Design Patterns in Python
-
Section 33: GUI Programming
-
Section 34: Security Basics
-
Section 35: Data Structures and Algorithms
-
Section 36: Practical Projects
-
Section 37: Capstone Projects
-
Section 38: Interview and Algorithm Practice
-
Section 39: Writing Idiomatic Python
333: Managing Configuration with python-dotenv
I've seen this happen to almost every junior dev I've mentored. You're building a project, you've got your API keys working perfectly on your laptop, and then you push the code to GitHub. Suddenly, you get a frantic notification from a security bot telling you that your AWS secret key is public. Or, even worse, you deploy the code to a server and the app crashes immediately because the environment variables you set locally aren't present in the production shell.
import os
import requests
# I'm trying to be secure by using environment variables
API_KEY = os.getenv("WEATHER_API_KEY")
CITY = "Seattle"
def get_weather():
# This line crashes with a 401 Unauthorized or a TypeError
# because API_KEY is actually None
url = f"https://api.weatherapi.com/v1/current.json?key={API_KEY}&q={CITY}"
response = requests.get(url)
return response.json()
print(get_weather())
The "NoneType" configuration crash
If you run the code above, it likely won't throw a Python error immediately, but the API call will fail. Why? Because os.getenv() doesn't magically know where your secrets are; it only looks at the environment variables currently loaded into your operating system's process. If you haven't manually run export WEATHER_API_KEY=your_key in your terminal before launching the script, os.getenv simply returns None.
The mistake here is assuming that having a .env file sitting in your project folder is enough. Python doesn't read .env files by default. It's just a text file to the OS. You need a bridge to pull those key-value pairs from the file and inject them into the environment.
Bridging the gap with load_dotenv
This is where python-dotenv comes in. It's a tiny library that does one thing: it reads a file (usually named .env) and loads those variables into os.environ so that os.getenv() can actually find them.
First, you'll need to install it: pip install python-dotenv. Then, you just add two lines to the top of your entry point script.
import os
import requests
from dotenv import load_dotenv
# This is the magic line. It looks for a .env file in the current directory
# and loads the variables into the environment.
load_dotenv()
API_KEY = os.getenv("WEATHER_API_KEY")
CITY = "Seattle"
def get_weather():
if not API_KEY:
raise ValueError("Missing WEATHER_API_KEY! Did you forget the .env file?")
url = f"https://api.weatherapi.com/v1/current.json?key={API_KEY}&q={CITY}"
response = requests.get(url)
return response.json()
print(get_weather())
I added a small check for if not API_KEY. I highly recommend doing this. It's much better to have your app crash with a clear "Missing API Key" message than to spend an hour wondering why your API is returning "Unauthorized" errors.
Keeping your secrets out of Git
Now, here is the most important part of this entire workflow. Your .env file contains secrets. If you commit that file to version control, you've defeated the whole purpose of using environment variables.
I always tell my team to create two files. First, the .env file which stays on your machine. Second, a .env.example file. The example file contains the keys but not the actual values.
Your .env.example should look like this:
# .env.example
WEATHER_API_KEY=your_api_key_here
DATABASE_URL=postgresql://user:password@localhost:5432/mydb
Then, you add .env to your .gitignore file. This way, when a new developer joins your project, they see the example file, copy it to a new .env, and plug in their own keys. It's the industry standard for a reason—it keeps the codebase portable and the secrets private.
📋 Practical Task
Secure a Database Connection String for a User Profile Service
You are building a user profile service that connects to a PostgreSQL database. Currently, the database URL is hardcoded, which is a huge security risk. Your task is to migrate this to a secure configuration using python-dotenv.
Requirements:
- Create a file named
.envcontaining a variableDB_URLset topostgresql://admin:secret_password@localhost:5432/user_db. - Create a
.gitignorefile that ensures the.envfile is never tracked by Git. - Write a Python script that:
- Loads the environment variables from the
.envfile. - Retrieves the
DB_URLusingos.getenv. - Prints a confirmation message:
"Connected to database at: [URL]". - If
DB_URLis missing, prints"Error: Database configuration not found."and exits.
- Loads the environment variables from the
There are no comments for now.