Skip to main content

Local Development Setup

This guide walks you through setting up a local development environment for the WispHub API. This is ideal for development, testing, and debugging.

Prerequisites

  • Python 3.12 or higher
  • pip (Python package manager)
  • git
  • WispHub API credentials (API key and host URL)
Python 3.12 is required to match the production environment. Check your version:
python3 --version

Installation Steps

1

Clone the Repository

git clone <repository-url>
cd wisphub-api
2

Create Virtual Environment

Create an isolated Python environment:
python3 -m venv venv
This creates a venv directory containing the Python interpreter and packages.
3

Activate Virtual Environment

Linux/macOS:
source venv/bin/activate
Windows:
venv\Scripts\activate
Your prompt should now be prefixed with (venv) to indicate the virtual environment is active.
4

Install Dependencies

Install both application and development dependencies:
pip install -r requirements.txt
pip install -r requirements-dev.txt
Application dependencies (requirements.txt):
httpx==0.28.1
pydantic==2.12.5
pydantic-settings==2.12.0
pydantic_core==2.41.5
python-multipart==0.0.22
fastapi[all]==0.128.0
uvicorn[standard]==0.40.0
gunicorn==21.2.0
async-lru==2.2.0
Development dependencies (requirements-dev.txt):
locust==2.43.3
pytest==9.0.2
pytest-asyncio==1.3.0
respx==0.22.0
async-lru==2.2.0
5

Configure Environment

Create a .env file in the project root:
touch .env
Add your WispHub credentials:
.env
WISPHUB_NET_KEY=<Your_WispHub_API_Key>
WISPHUB_NET_HOST=https://api.wisphub.net
MAX_ACTIVE_TICKETS_PER_ZONE=3
Never commit the .env file. Ensure it’s in .gitignore.

Running the Development Server

Uvicorn provides hot-reload functionality for rapid development:
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
Flags:
  • --reload: Automatically restart on code changes
  • --host 0.0.0.0: Listen on all network interfaces
  • --port 8000: Port to bind to
Expected output:
INFO:     Will watch for changes in these directories: ['/path/to/wisphub-api']
INFO:     Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
INFO:     Started reloader process [12345] using StatReload
INFO:     Started server process [12346]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
With --reload enabled, any changes to Python files will automatically restart the server. No need to manually restart!

Using Gunicorn (Production-like)

To test the production configuration locally:
gunicorn app.main:app \
  --workers 4 \
  --worker-class uvicorn.workers.UvicornWorker \
  --bind 0.0.0.0:8000
Gunicorn doesn’t support --reload. Use Uvicorn for development.

Verify Installation

Health Check

Test the health endpoint:
curl http://localhost:8000/health
Expected response:
{
  "ok": true,
  "type": "success",
  "action": null,
  "data": {
    "status": "ok",
    "service": "WispHub Local API"
  },
  "message": null,
  "meta": null
}

Interactive API Documentation

Open your browser to:
http://localhost:8000/docs
This provides:
  • Interactive API explorer (Swagger UI)
  • Complete endpoint documentation
  • Request/response schemas
  • Try-it-out functionality

Alternative Documentation

ReDoc format:
http://localhost:8000/redoc

Running Tests

Unit and Integration Tests

Run the full test suite with pytest:
pytest tests/ -v
Flags:
  • -v: Verbose output
  • -s: Show print statements
  • --tb=short: Shorter traceback format

Run Specific Test File

pytest tests/api/test_clients.py -v

Run Specific Test Function

pytest tests/api/test_clients.py::test_get_client_by_document_endpoint_found -v

Test Configuration

The test suite uses pytest.ini for configuration:
pytest.ini
[pytest]
asyncio_mode = auto
asyncio_default_fixture_loop_scope = function
pythonpath = .

Test Structure

tests/
├── conftest.py              # Shared fixtures
├── api/
│   ├── test_clients.py      # Client endpoint tests
│   ├── test_tickets.py      # Ticket endpoint tests
│   ├── test_internet_plans.py
│   └── test_network.py
└── services/
    ├── test_clients_service.py
    ├── test_tickets_service.py
    └── test_internet_plans_service.py

Example Test

tests/api/test_clients.py
import pytest
from unittest.mock import patch

@pytest.mark.asyncio
@patch("app.api.v1.clients.get_client_by_document")
async def test_get_client_by_document_endpoint_found(mock_get_client, async_client):
    mock_get_client.return_value = MOCK_API_CLIENT
    
    response = await async_client.get("/api/v1/clients/by-document/111111")
    assert response.status_code == 200
    
    data = response.json()
    assert data["ok"] is True
    assert data["action"] == ClientAction.FOUND
    assert data["data"]["name"] == "John Doe"
Tests use respx to mock HTTP calls to WispHub Net, ensuring tests don’t require external connectivity.

Code Quality Tools

Linting (Optional)

Consider adding linting tools:
pip install ruff
ruff check app/

Type Checking (Optional)

pip install mypy
mypy app/

Code Formatting (Optional)

pip install black
black app/

IDE Configuration

VS Code

Create .vscode/settings.json:
.vscode/settings.json
{
  "python.defaultInterpreterPath": "${workspaceFolder}/venv/bin/python",
  "python.testing.pytestEnabled": true,
  "python.testing.pytestArgs": [
    "tests",
    "-v"
  ],
  "python.linting.enabled": true,
  "python.formatting.provider": "black",
  "[python]": {
    "editor.formatOnSave": true,
    "editor.codeActionsOnSave": {
      "source.organizeImports": true
    }
  }
}

PyCharm

  1. Configure Interpreter: File → Settings → Project → Python Interpreter
  2. Select venv: Choose venv/bin/python as the interpreter
  3. Enable pytest: File → Settings → Tools → Python Integrated Tools → Testing → pytest

Hot Reload Workflow

With Uvicorn’s --reload flag, development is seamless:
  1. Start server: uvicorn app.main:app --reload
  2. Make code changes: Edit any .py file
  3. Auto-restart: Server automatically detects changes and reloads
  4. Test immediately: Send requests to see changes
Example workflow:
# Terminal 1: Run server with hot reload
uvicorn app.main:app --reload

# Terminal 2: Test endpoints
curl http://localhost:8000/api/v1/clients/

# Edit app/api/v1/clients.py
# Server automatically reloads
# Test again
curl http://localhost:8000/api/v1/clients/

Database Seeding (if needed)

The WispHub API doesn’t maintain its own database - it proxies to WispHub Net. No local seeding is required.
For testing, you can:
  1. Point to a WispHub test instance
  2. Use respx mocking in tests
  3. Create a mock WispHub server for integration testing

Debugging

VS Code Debugger

Create .vscode/launch.json:
.vscode/launch.json
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Python: FastAPI",
      "type": "python",
      "request": "launch",
      "module": "uvicorn",
      "args": [
        "app.main:app",
        "--reload",
        "--host",
        "0.0.0.0",
        "--port",
        "8000"
      ],
      "jinja": true,
      "justMyCode": true,
      "env": {
        "WISPHUB_NET_KEY": "your_test_key",
        "WISPHUB_NET_HOST": "https://api.wisphub.net"
      }
    }
  ]
}
Set breakpoints and press F5 to start debugging. Uvicorn shows all print statements:
print(f"Debug: client data = {client}")

Logging

Use Python’s logging module:
import logging

logger = logging.getLogger(__name__)
logger.info(f"Processing client: {client_id}")

Troubleshooting

Issue: “ModuleNotFoundError”

Cause: Virtual environment not activated or dependencies not installed Solution:
source venv/bin/activate  # Activate venv
pip install -r requirements.txt

Issue: “Port 8000 already in use”

Cause: Another process is using port 8000 Solution: Use a different port or kill the existing process:
# Use different port
uvicorn app.main:app --reload --port 8001

# Or kill existing process (Linux/macOS)
lsof -ti:8000 | xargs kill -9

Issue: “Field required” validation error

Cause: Missing environment variables Solution: Ensure .env file exists and contains required variables:
cat .env | grep WISPHUB_NET_KEY

Issue: Tests failing with network errors

Cause: Tests are trying to connect to real WispHub Net Solution: Ensure respx mocking is properly configured in tests. Check conftest.py for fixtures.

Development Best Practices

Use Hot Reload

Always run with --reload during development for instant feedback

Write Tests First

Follow TDD - write tests before implementing features

Mock External APIs

Use respx to mock WispHub Net calls in tests

Check Types

Leverage Pydantic’s type validation for early error detection

Next Steps

Run Tests

Learn about the testing infrastructure

Load Testing

Performance test with Locust

Docker Deployment

Deploy to production with Docker

Architecture

Understand the codebase structure

Build docs developers (and LLMs) love