One of the first hurdles developers face when starting with Python is organizing their project structure and managing dependencies cleanly. Unlike frameworks with standardized scaffolding (like Laravel or Rails), Python gives developers full freedom. However, unorganized project setups lead to circular import bugs, broken imports in production, and dependency conflicts.
This guide establishes a production-standard Python project setup step by step.
1. The Standard src Layout
The src layout is the recommended directory structure for modern Python applications and microservices. It prevents accidental imports of uninstalled local packages and forces clean packaging boundary checks.
my_python_app/
โโโ src/
โ โโโ my_app/
โ โโโ __init__.py
โ โโโ main.py
โ โโโ config.py
โ โโโ api/
โ โ โโโ __init__.py
โ โ โโโ routes.py
โ โโโ services/
โ โ โโโ user_service.py
โ โโโ models/
โ โโโ user.py
โโโ tests/
โ โโโ __init__.py
โ โโโ test_routes.py
โ โโโ test_services.py
โโโ .gitignore
โโโ README.md
โโโ pyproject.toml
2. Managing Dependencies with Poetry or uv
Legacy Python projects relied on requirements.txt and manual venv creation. Modern production projects use pyproject.toml managed by Poetry or uv (an extremely fast Python package installer written in Rust).
Using Poetry:
# Initialize project
poetry init
# Add dependencies
poetry add fastapi uvicorn pydantic pydantic-settings
poetry add pytest httpx --group dev
# Run application inside virtualenv
poetry run uvicorn src.my_app.main:app --reload
Using uv (Lightning Fast Alternative):
# Create virtualenv instantly
uv venv
# Activate environment
source .venv/bin/activate
# Install dependencies at high speed
uv pip install fastapi uvicorn pydantic
3. Environment Configuration with Pydantic BaseSettings
Never hardcode API keys or database URLs. Use pydantic-settings to parse environment variables safely with strict type validation.
# src/my_app/config.py
from pydantic_settings import BaseSettings
class Settings(BaseSettings):
app_name: str = "My Python API"
environment: str = "development"
database_url: str
openai_api_key: str
class Config:
env_file = ".env"
settings = Settings()
If DATABASE_URL is missing from the .env file, the app fails to start immediately on launch with an explicit error message, preventing runtime crashes halfway through execution.
Summary
By using the src/ directory layout, locking dependencies with pyproject.toml (via Poetry or uv), and enforcing settings with Pydantic, your Python project is organized, reproducible, and ready for production deployment.
Need guidance setting up scalable Python microservices? Check out my AI integration services or Hire Python Developer.