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