Karambir Nain

My Python Programming Workflow - 2025 Edition

The Python ecosystem has evolved dramatically by 2025. While my previous workflow served me well, new tools have emerged that significantly simplify and speed up Python development. Here’s my updated workflow that embraces the latest and greatest tools.

Basic Setup

Python Version Management with uv

Gone are the days of managing multiple version managers. uv has replaced asdf(pyenv), pipx, and Poetry in one unified tool. It’s blazingly fast and handles everything from Python installation to dependency management.

Install uv:

1curl -LsSf https://astral.sh/uv/install.sh | sh

Install Python versions:

1uv python install 3.11 3.12 3.13
2uv python list  # See installed versions

CLI Tools Management

Instead of pipx, use uv to install CLI tools in isolated environments:

1uv tool install cookiecutter
2uv tool install pgcli
3uv tool install pre-commit
4uv tool install bumpver
5uv tool install mkdocs

Project Setup

Initialize Project

Create a new project directory and initialize:

1mkdir my-project && cd my-project
2uv python pin 3.12  # Creates .python-version file
3uv init  # Creates pyproject.toml and basic structure

Virtual Environment and Dependencies

uv automatically manages virtual environments—no more manual venv creation:

1uv add fastapi uvicorn  # Installs packages and creates .venv automatically
2uv add pytest ruff --dev  # Development dependencies
3uv sync  # Install all dependencies from lockfile

Code Quality and Formatting

Ruff - The All-in-One Tool

Ruff has revolutionized Python tooling by replacing multiple tools:

  • Linting: Replaces flake8, pyupgrade and pylint
  • Formatting: Replaces black and isort

Install and configure:

1uv add ruff --dev

Configuration in pyproject.toml:

 1[tool.ruff]
 2line-length = 88
 3target-version = "py312"
 4
 5[tool.ruff.lint]
 6select = ["E", "F", "W", "C", "I", "N", "UP", "B"]
 7ignore = ["E501"]  # Line length handled by formatter
 8
 9[tool.ruff.format]
10quote-style = "double"
11indent-style = "space"

Task Automation

Just instead of Make

Just provides a modern alternative to Makefiles with better syntax and cross-platform support.

Install just:

1uv tool install just

Create a justfile:

 1# Run tests
 2test:
 3    uv run pytest
 4
 5# Format and lint code
 6format:
 7    uv run ruff format .
 8    uv run ruff check --fix .
 9
10# Run development server
11dev:
12    uv run uvicorn main:app --reload
13
14# Install dependencies
15install:
16    uv sync
17
18# Build documentation
19docs:
20    uv run mkdocs serve
21
22# Run pre-commit hooks
23pre-commit:
24    uv run pre-commit run --all-files

Documentation and Versioning

Documentation with MkDocs

Continue using MkDocs for documentation:

1uv add mkdocs mkdocs-material --dev

Version Management with bumpver

bumpver replaces bump2version with better configuration:

1uv add bumpver --dev

Configuration in pyproject.toml:

 1[tool.bumpver]
 2current_version = "0.1.0"
 3version_pattern = "MAJOR.MINOR.PATCH"
 4commit_message = "bump version {old_version} -> {new_version}"
 5commit = true
 6tag = true
 7push = false
 8
 9[tool.bumpver.file_patterns]
10"pyproject.toml" = ['version = "{version}"']
11"src/__init__.py" = ['__version__ = "{version}"']

Editor Setup

Modern AI-Assisted Development

Primary Editors:

  • Cursor - AI-first code editor built on VSCode
  • Zed - Blazingly fast collaborative editor

AI-Assisted Workflow:

  1. Use Cursor’s AI chat for code generation, refactoring and tests
  2. Use Claude code for more complex tasks and code generation
  3. Code reviews assisted by AI tools like Google Gemini Assist

EditorConfig (.editorconfig):

 1root = true
 2
 3[*]
 4charset = utf-8
 5end_of_line = lf
 6insert_final_newline = true
 7trim_trailing_whitespace = true
 8
 9[*.py]
10indent_style = space
11indent_size = 4
12
13[*.{json,yml,yaml,toml}]
14indent_style = space
15indent_size = 2
16
17[*.md]
18trim_trailing_whitespace = false
19
20[justfile]
21indent_style = tab

Testing

1uv add pytest pytest-cov pytest-asyncio faker --dev

Configure in pyproject.toml:

1[tool.pytest.ini_options]
2testpaths = ["tests"]
3python_files = ["test_*.py"]
4python_classes = ["Test*"]
5python_functions = ["test_*"]
6addopts = "--cov=src --cov-report=html --cov-report=term-missing"

For multiple Python versions, consider using tox with uv:

1uv add tox-uv --dev

Major Packages I Find Awesome (2025 Edition)

Web Frameworks:

  • FastAPI and Starlette (still dominant)
  • Django + Django Rest Framework

Data and Validation:

  • Pydantic - Essential for data validation and serialization
  • SQLAlchemy 2.0+ with async support

Async and Networking:

  • httpx for HTTP clients
  • asyncio-native database drivers

Task Processing:

  • Celery (still relevant)
  • FastAPI Background Tasks for simpler use cases

Utilities:

  • click for CLI applications
  • loguru for structured logging
  • python-dotenv for environment management

Monitoring and Observability:

  • OpenTelemetry for distributed tracing
  • Sentry for error tracking

Pre-commit and CI/CD

Pre-commit Setup

1uv tool install pre-commit

.pre-commit-config.yaml:

 1repos:
 2  - repo: https://github.com/pre-commit/pre-commit-hooks
 3    rev: v5.0.0
 4    hooks:
 5      - id: trailing-whitespace
 6      - id: end-of-file-fixer
 7      - id: check-json
 8      - id: check-toml
 9      - id: check-xml
10      - id: check-yaml
11      - id: debug-statements
12      - id: check-builtin-literals
13      - id: check-case-conflict
14      - id: check-docstring-first
15      - id: detect-private-key
16
17  # Run the Ruff linter.
18  - repo: https://github.com/astral-sh/ruff-pre-commit
19    rev: v0.12.0
20    hooks:
21      # Linter
22      - id: ruff
23        args: [--fix, --exit-non-zero-on-fix]
24      # Formatter
25      - id: ruff-format
26
27  - repo: https://github.com/astral-sh/uv-pre-commit
28    rev: 0.7.13
29    hooks:
30      - id: uv-lock

GitHub Actions CI

.github/workflows/ci.yml:

 1name: CI
 2
 3on: [push, pull_request]
 4
 5jobs:
 6  test:
 7    runs-on: ubuntu-latest
 8    env:
 9      UV_SYSTEM_PYTHON: 1
10    strategy:
11      matrix:
12        python-version: ["3.11", "3.12", "3.13"]
13
14    steps:
15    - uses: actions/checkout@v4
16
17    - name: Install uv
18      uses: astral-sh/setup-uv@v6
19
20    - name: Set up Python
21      uses: actions/setup-python@v5
22      with:
23        python-version-file: ".python-version"
24
25    - name: Install dependencies
26      run: uv sync --locked --all-extras --dev
27
28    - name: Run ruff linter
29      run: uv run ruff check .
30
31    - name: Run ruff formatter
32      run: uv run ruff format --check .
33
34    - name: Run tests
35      run: uv run pytest --cov --cov-report=xml
36
37    - name: Upload coverage
38      uses: codecov/codecov-action@v5

Development Workflow

Daily Development Routine

  1. Start new feature:

    1git checkout -b feature/new-feature
    2uv sync  # Ensure dependencies are up to date
    
  2. Write code with AI assistance:

    • Use Claude for complex logic
    • Use Cursor for fixing typos and formatting issues
    • Generate tests based on implementation
    • Review generated tests and code
  3. Format and check:

    1just format  # Run ruff format and check
    2just test    # Run test suite
    
  4. Commit and push:

    1git add .
    2git commit -m "feat: implement new feature"
    3git push
    

Pre-commit hooks automatically run ruff and tests before each commit.

Key Improvements in 2025

Speed and Simplicity:

  • uv reduces tool count from 4+ to 1
  • Ruff replaces 4+ tools with a single fast implementation
  • just provides cleaner task automation

AI Integration:

  • Code generation and completion
  • Automated test writing
  • Intelligent refactoring suggestions
  • AI-powered code reviews for second opinion

Developer Experience:

  • Fewer configuration files to manage
  • Consistent tooling across projects
  • Faster feedback loops