Skip to main content

Professional FastAPI mock service library with load testing infrastructure and Prometheus metrics

Project description

FastAPI Mock Service

PyPI version Python Version License: MIT

Professional FastAPI mock service library with built-in load testing infrastructure, real-time metrics, and interactive dashboard.

Perfect for:

  • API Development & Testing
  • Load Testing Infrastructure
  • Service Virtualization
  • Performance Monitoring
  • Development & Integration Testing

Features

Core Features

  • FastAPI-style decorators - Familiar @mock.get(), @mock.post() syntax
  • Automatic parameter validation - Built-in request validation with custom error handlers
  • Flexible response configuration - Support for custom error codes and response formats
  • Database integration - SQLite-based test results storage

Load Testing & Monitoring

  • Built-in Prometheus metrics - Request counts, response times, error rates
  • Real-time dashboard - Interactive web UI with live charts
  • Multiple chart views - Overview, per-endpoint, and error code analysis
  • Test session management - Start/stop tests with automatic reporting

Professional UI

  • Responsive dashboard - Modern web interface for monitoring
  • Collapsible sections - Organized, space-efficient layout
  • Real-time updates - Live metrics and request logs
  • Export capabilities - Test results and metrics export

Installation

pip install fastapi-mock-service

Quick Start

Basic Usage

from fastapi_mock_service import MockService
from pydantic import BaseModel

# Create mock service
mock = MockService()

class User(BaseModel):
    id: int
    name: str
    email: str

# Simple endpoint
@mock.get("/api/users/{user_id}")
def get_user(user_id: int):
    return User(id=user_id, name=f"User {user_id}", email=f"user{user_id}@example.com")

# Run the service
if __name__ == "__main__":
    mock.run()

Advanced Usage with Custom Error Codes

from fastapi_mock_service import MockService
from pydantic import BaseModel
from typing import List, Optional, Dict
from datetime import datetime, timezone

# Create mock service
mock = MockService()

# Define custom error codes
API_ERRORS = {
    "validation": {"code": "API.01000", "message": "Validation error"},
    "not_found": {"code": "API.01001", "message": "Resource not found"},
    "unauthorized": {"code": "API.01002", "message": "Unauthorized access"},
    "server_error": {"code": "API.01003", "message": "Internal server error"},
}

# Response models
class StandardResult(BaseModel):
    timestamp: str
    status: int
    code: str
    message: str

class UserResponse(BaseModel):
    result: StandardResult
    data: Optional[dict] = None

def create_responses_from_errors(error_dict: Dict, success_code: str) -> List[Dict]:
    """Dynamically create response list from error dictionary"""
    responses = [{"code": success_code, "description": "Success"}]
    for error_key, error_info in error_dict.items():
        responses.append({
            "code": error_info["code"],
            "description": error_info["message"]
        })
    return responses

def create_validation_handler(error_code: str, response_class):
    """Create custom validation error handler"""
    def handler(missing_params, endpoint_path, service_name):
        result = StandardResult(
            timestamp=datetime.now(timezone.utc).isoformat(),
            status=200,
            code=error_code,
            message=f"Missing required parameters: {', '.join(missing_params)}"
        )
        return response_class(result=result, data=None)
    return handler

# Create responses and validation handler
API_RESPONSES = create_responses_from_errors(API_ERRORS, "API.00000")
validation_handler = create_validation_handler("API.01000", UserResponse)

# Advanced endpoint with error handling
@mock.get("/api/v1/users/{user_id}",
          responses=API_RESPONSES,
          tags=["users"],
          validation_error_handler=validation_handler)
def get_user(user_id: int):
    """Get user with advanced error handling"""
    
    # Custom logic for different scenarios
    if user_id <= 0:
        return UserResponse(
            result=StandardResult(
                timestamp=datetime.now(timezone.utc).isoformat(),
                status=200,
                code="API.01000",
                message="Invalid user ID"
            ),
            data=None
        )
    
    if user_id > 1000:
        return UserResponse(
            result=StandardResult(
                timestamp=datetime.now(timezone.utc).isoformat(),
                status=200,
                code="API.01001", 
                message="User not found"
            ),
            data=None
        )
    
    # Success response
    return UserResponse(
        result=StandardResult(
            timestamp=datetime.now(timezone.utc).isoformat(),
            status=200,
            code="API.00000",
            message="OK"
        ),
        data={"id": user_id, "name": f"User {user_id}", "email": f"user{user_id}@example.com"}
    )

if __name__ == "__main__":
    mock.run()

Command Line Interface

Generate Examples

# Create basic example
fastapi-mock init basic_example.py

# Create advanced example with error codes
fastapi-mock init advanced_example.py --advanced

Run Mock Service

# Run with default settings
fastapi-mock run my_mock.py

# Run with custom port
fastapi-mock run my_mock.py --port 9000

# Run with auto-reload for development
fastapi-mock run my_mock.py --reload

Dashboard & Monitoring

Once your mock service is running, access:

  • Dashboard: http://localhost:8000 - Interactive monitoring interface
  • Prometheus Metrics: http://localhost:8000/metrics - Raw metrics data
  • API Documentation: http://localhost:8000/docs - Auto-generated OpenAPI docs

Dashboard Features

  • Test Management: Start/stop load tests with one click
  • Real-time Charts: Multiple views (overview, per-endpoint, error codes)
  • Request Logs: Live request/response logging with timestamps
  • Metrics: Request counts, response times, error rates
  • Endpoint Registry: All registered endpoints with possible responses
  • Collapsible Sections: Organized, space-efficient interface

Load Testing Integration

Built-in Test Management

# The dashboard provides buttons for:
# - Start Test: Activates mock endpoints and begins metrics collection
# - Stop Test: Generates comprehensive test report
# - Reset Metrics: Clears all collected data

# Metrics automatically collected:
# - Total requests per endpoint
# - Response time distribution  
# - Error code frequency
# - Request rate (RPS)

Integration with Load Testing Tools

# Use with popular load testing tools:

# curl
curl -s "http://localhost:8000/api/users/123"

# Apache Bench
ab -n 1000 -c 10 http://localhost:8000/api/users/123

# wrk
wrk -t4 -c100 -d30s http://localhost:8000/api/users/123

API Reference

MockService Class

from fastapi_mock_service import MockService

mock = MockService(db_url="sqlite://custom.db")  # Optional custom database

Decorators

All decorators support the same parameters:

@mock.get(path, responses=None, tags=None, validation_error_handler=None)
@mock.post(path, responses=None, tags=None, validation_error_handler=None)  
@mock.put(path, responses=None, tags=None, validation_error_handler=None)
@mock.delete(path, responses=None, tags=None, validation_error_handler=None)
@mock.patch(path, responses=None, tags=None, validation_error_handler=None)

Parameters:

  • path (str): URL path pattern (supports FastAPI path parameters)
  • responses (List[Dict], optional): List of possible responses for UI display
  • tags (List[str], optional): Tags for grouping endpoints in dashboard
  • validation_error_handler (Callable, optional): Custom validation error handler

Response Configuration

# Define possible responses for dashboard display
responses = [
    {"code": "SUCCESS.00000", "description": "Operation successful"},
    {"code": "ERROR.01000", "description": "Validation failed"},
    {"code": "ERROR.01001", "description": "Resource not found"},
]

@mock.get("/api/endpoint", responses=responses, tags=["api-v1"])
def my_endpoint():
    # Your mock implementation
    pass

Use Cases

1. API Development

Mock external dependencies while developing your application:

# Mock external payment service
@mock.post("/payments/process")
def process_payment(payment_data: PaymentRequest):
    # Simulate different payment scenarios
    if payment_data.amount > 10000:
        return {"status": "declined", "reason": "amount_exceeded"}
    return {"status": "approved", "transaction_id": "tx_123"}

2. Load Testing

Create realistic load testing scenarios:

# Mock with realistic delays and error rates
import random
import time

@mock.get("/api/heavy-operation")
def heavy_operation():
    # Simulate processing time
    time.sleep(random.uniform(0.1, 0.5))
    
    # Simulate 5% error rate
    if random.random() < 0.05:
        return {"error": "temporary_failure"}, 500
    
    return {"result": "success", "data": "processed"}

3. Integration Testing

Mock multiple services with consistent behavior:

# User service mock
@mock.get("/users/{user_id}", tags=["users"])
def get_user(user_id: int):
    return {"id": user_id, "name": f"User {user_id}"}

# Order service mock  
@mock.get("/orders/{order_id}", tags=["orders"])
def get_order(order_id: int):
    return {"id": order_id, "user_id": 1, "status": "completed"}

Metrics & Monitoring

Available Metrics

The service automatically exposes Prometheus metrics:

  • http_requests_total - Total HTTP requests by method, endpoint, and status
  • http_request_duration_seconds - Request duration histogram
  • test_requests_total - Test-specific request counter
  • test_code_total - Requests grouped by response code
  • test_endpoint_total - Requests per endpoint during tests

Custom Metrics Integration

from prometheus_client import Counter, Histogram

# Define custom metrics
custom_counter = Counter('my_custom_operations_total', 'Custom operations')
custom_histogram = Histogram('my_operation_duration_seconds', 'Operation duration')

@mock.post("/api/custom-operation")
def custom_operation():
    with custom_histogram.time():
        # Your operation here
        custom_counter.inc()
        return {"status": "completed"}

Development

Project Structure

fastapi_mock_service/
├── __init__.py          # Main exports
├── mock_service.py      # Core MockService class
├── cli.py              # Command-line interface
└── templates/
    └── dashboard.html   # Web dashboard template

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests
  5. Submit a pull request

Development Setup

git clone https://github.com/yourusername/fastapi-mock-service
cd fastapi-mock-service
pip install -e ".[dev]"
pytest

License

This project is licensed under the MIT License - see the LICENSE file for details.

Support

Acknowledgments

Built with:


Made with ❤️ for the API development and testing community

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fastapi_mock_service-1.0.3.tar.gz (36.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fastapi_mock_service-1.0.3-py3-none-any.whl (29.3 kB view details)

Uploaded Python 3

File details

Details for the file fastapi_mock_service-1.0.3.tar.gz.

File metadata

  • Download URL: fastapi_mock_service-1.0.3.tar.gz
  • Upload date:
  • Size: 36.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for fastapi_mock_service-1.0.3.tar.gz
Algorithm Hash digest
SHA256 00390dc60b0047e52b148c986dc7a8d653740c5b4948f6ae5b57068a97baec47
MD5 f83e4a717e0a4671d1b874558b57fd3a
BLAKE2b-256 97434875b0def2ef6149e11e4afaf1f403c369da32c773cecf9a7984794c4aac

See more details on using hashes here.

File details

Details for the file fastapi_mock_service-1.0.3-py3-none-any.whl.

File metadata

File hashes

Hashes for fastapi_mock_service-1.0.3-py3-none-any.whl
Algorithm Hash digest
SHA256 b4cfeb80bc1a9ec84c2a200e7de4b7d46712bea6c3b01dc0d127e02068c45d37
MD5 7c4ca835352ba62db8459b8bac637d24
BLAKE2b-256 4941f508a0021627f3bc4aa92855aa27df7866cdb38a6b91e76880f04bce72fc

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page