Skip to content

Repository files navigation

async-playground

A small, production-style async Python playground built to learn:

  • Modern asyncio patterns
  • Async HTTP with httpx
  • Concurrency vs parallelism (threads vs processes)
  • Timeouts & cancellation
  • A tiny FastAPI service with background jobs
  • Project best practices (pyproject, linters, tests, Docker, Makefile)

Features

  • 🧠 Async basics: async / await, tasks, asyncio.gather, semaphores
  • 🌐 Async HTTP client using httpx.AsyncClient
  • 🔧 Config via environment / .env using pydantic-settings
  • 📜 Logging with configurable log level
  • 🚀 FastAPI API:
    • POST /fetch → concurrent HTTP fetch
    • POST /jobs → starts a background job
    • GET /jobs/{id} → check job status / result
  • 🔬 Testing with pytest + pytest-asyncio
  • 📦 Containerized with Docker
  • 🛠️ Developer-friendly Makefile + shell scripts

Prerequisites

  • Python 3.11+
  • Make (optional, for using the Makefile)
  • Docker (optional, for containerization)

Installation

  1. Clone the repository:

    git clone https://github.com/Conacious/python-async-playground.git
    cd python-async-playground
  2. Create a virtual environment:

    make venv
    # Or manually: python -m venv .venv
  3. Install dependencies:

    make deps
    # Or manually: pip install -e ".[dev]"

Configuration

The application uses pydantic-settings to load configuration from environment variables or a .env file.

  1. Create a .env file (optional, defaults are provided):

    cp .env.example .env  # If you have an example, otherwise just create one
  2. Available Environment Variables:

    Variable Default Description
    ASYNC_PLAYGROUND_LOG_LEVEL INFO Logging level (DEBUG, INFO, WARNING, ERROR)
    ASYNC_PLAYGROUND_HTTP_TIMEOUT 10.0 Timeout for HTTP requests in seconds
    ASYNC_PLAYGROUND_HTTP_MAX_CONCURRENT 5 Max concurrent HTTP requests
    ASYNC_PLAYGROUND_HTTP_GLOBAL_TIMEOUT None Global timeout for batch operations

Usage

You can run the application in different modes using the CLI or start the API server.

CLI Modes

Run the async-playground command (installed via pip install -e .) or use python -m async_playground.

  1. HTTP Fetch Demo (Concurrent requests):

    make cli-http
    # Or: python -m async_playground --mode http
  2. Async Sleep Demo (Basic asyncio mechanics):

    make cli-sleep
    # Or: python -m async_playground --mode sleep
  3. Blocking Tasks Demo (Threads vs Processes):

    make cli-blocking
    # Or: python -m async_playground --mode blocking

API Server

Start the FastAPI server:

make api
# Or: uvicorn async_playground.api:app --reload

The API will be available at http://localhost:8000.

Example API Calls

You can use the helper scripts in scripts/ or curl:

  • Fetch URLs concurrently:

    ./scripts/call_fetch.sh https://www.python.org https://fastapi.tiangolo.com
  • Start a background job:

    ./scripts/start_job.sh https://www.python.org
  • Check job status:

    ./scripts/check_job.sh <JOB_ID>

Development

Project Structure

async_playground/
├─ src/
│  └─ async_playground/
│     ├─ __init__.py
│     ├─ __main__.py          # enables: python -m async_playground
│     ├─ cli.py               # CLI entrypoint
│     ├─ api.py               # FastAPI app
│     └─ core/
│        ├─ config.py         # Settings via pydantic-settings
│        ├─ http_client.py    # Async httpx client + concurrency
│        ├─ example_async.py  # Simple asyncio demo
│        ├─ blocking_tasks.py # CPU-bound + threads/processes demo
│        ├─ logging_utils.py  # Logging configuration
│        └─ ...
│
├─ tests/                     # pytest + pytest-asyncio tests
├─ scripts/                   # helper bash scripts to call the API
├─ pyproject.toml             # project + tool configuration
├─ Makefile                   # common developer commands
├─ Dockerfile                 # container image definition
├─ .dockerignore
├─ .env                       # local configuration (not for production)
└─ README.md

Commands

  • Format code: make format (Black)
  • Lint code: make lint (Ruff)
  • Type check: make typecheck (Mypy)
  • Run tests: make test (Pytest)
  • Run all checks: make check

Docker

Build and run the containerized application.

  1. Build image:

    make docker-build
  2. Run container:

    make docker-run

    The API will be accessible at http://localhost:8000.

About

A small, production-style python project to play with concurrency and parallelism

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages