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.2.tar.gz (36.7 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.2-py3-none-any.whl (29.2 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: fastapi_mock_service-1.0.2.tar.gz
  • Upload date:
  • Size: 36.7 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.2.tar.gz
Algorithm Hash digest
SHA256 746249c9373471aa67be11871809356fe5d2563e2f5aad7eace5a3db1c5081b1
MD5 a058074591e461921d0ae98b711dba93
BLAKE2b-256 fcaded7f2b32680f080acddf330f008e07af761e336af817ae9406a941665b7d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for fastapi_mock_service-1.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 ff1a2b931cd049c11d2aaccc774e64c779805d71a4ae7621d0f22ea5530f6ad6
MD5 1b3e37dcee2b12d428f7c716eb4cd6b4
BLAKE2b-256 c48a04cfd76d2b2acd62f5f07ce5901374fdc763f6841b423e15db41917246e0

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