REST API & Web UI - PyCharter
Description: Data Contract Management, ETL Pipelines, and Quality Assurance for Python

Skip to content

# REST API & Web UI

Learn to use PyCharter's REST API and interactive web interface.

## What You'll Learn

- Start the API server
- Use API endpoints for validation, contracts, and quality
- Launch the web UI
- Navigate the UI features
- Integrate API in your applications

## Prerequisites

    pip install pycharter[api,ui]

## Part 1: Starting the API Server

### Basic Start

    # Start with default settings (localhost:8000)
    pycharter api

### Custom Configuration

    # Custom host and port
    pycharter api --host 0.0.0.0 --port 8080

    # With specific database
    export DATABASE_URL="postgresql://user:pass@localhost/pycharter"
    pycharter api

    # With reload for development
    pycharter api --reload

### Using Uvicorn Directly

    uvicorn pycharter.api.main:app --host 0.0.0.0 --port 8000 --reload

### API Documentation

Once running, access:

- Swagger UI: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
- OpenAPI JSON: http://localhost:8000/openapi.json

## Part 2: Core API Endpoints

### Health Check

    curl http://localhost:8000/health

    {
      "status": "healthy",
      "version": "0.0.25"
    }

### Schema Endpoints

#### Store a Schema

    curl -X POST http://localhost:8000/api/v1/schemas \
      -H "Content-Type: application/json" \
      -d '{
        "name": "user",
        "version": "1.0.0",
        "schema": {
          "type": "object",
          "properties": {
            "name": {"type": "string"},
            "email": {"type": "string", "format": "email"}
          },
          "required": ["name", "email"]
        }
      }'

#### Get a Schema

    curl http://localhost:8000/api/v1/schemas/user

#### List Schemas

    curl http://localhost:8000/api/v1/schemas

### Validation Endpoints

#### Validate Single Record

    curl -X POST http://localhost:8000/api/v1/validation/validate \
      -H "Content-Type: application/json" \
      -d '{
        "schema_id": "user",
        "data": {
          "name": "Alice",
          "email": "alice@example.com"
        }
      }'

Response:

    {
      "is_valid": true,
      "data": {
        "name": "Alice",
        "email": "alice@example.com"
      },
      "errors": []
    }

#### Batch Validation

    curl -X POST http://localhost:8000/api/v1/validation/validate-batch \
      -H "Content-Type: application/json" \
      -d '{
        "schema_id": "user",
        "data": [
          {"name": "Alice", "email": "alice@example.com"},
          {"name": "", "email": "invalid"},
          {"name": "Charlie", "email": "charlie@example.com"}
        ]
      }'

Response:

    {
      "results": [
        {"is_valid": true, "data": {...}, "errors": []},
        {"is_valid": false, "data": null, "errors": [...]},
        {"is_valid": true, "data": {...}, "errors": []}
      ],
      "summary": {
        "total": 3,
        "valid": 2,
        "invalid": 1
      }
    }

### Contract Endpoints

#### Parse Contract

    curl -X POST http://localhost:8000/api/v1/contracts/parse \
      -H "Content-Type: application/json" \
      -d '{
        "contract": {
          "schema": {
            "type": "object",
            "version": "1.0.0",
            "properties": {"name": {"type": "string"}}
          },
          "metadata": {"title": "User Contract"}
        }
      }'

#### Build Contract from Store

    curl -X POST http://localhost:8000/api/v1/contracts/{schema_id}/build

### Quality Endpoints

#### Run Quality Check

    curl -X POST http://localhost:8000/api/v1/quality/check \
      -H "Content-Type: application/json" \
      -d '{
        "schema_id": "user",
        "data": [
          {"name": "Alice", "email": "alice@example.com"},
          {"name": "", "email": "invalid"}
        ],
        "options": {
          "calculate_metrics": true,
          "record_violations": true,
          "thresholds": {
            "min_overall_score": 90.0
          }
        }
      }'

#### Get Quality Metrics

    curl http://localhost:8000/api/v1/quality/metrics?schema_id=user&limit=10

### ETL Endpoints

#### Run Pipeline

    curl -X POST http://localhost:8000/api/v1/etl/run \
      -H "Content-Type: application/json" \
      -d '{
        "extract_yaml": "type: http\nurl: https://api.example.com/users",
        "load_yaml": "type: file\nfile_path: /tmp/output.json\nformat: json",
        "variables": {"API_KEY": "secret"}
      }'

## Part 3: Using the Web UI

### Starting the UI

    # Production mode (pre-built static files)
    pycharter ui serve

    # Development mode (with hot reload)
    pycharter ui dev

Access at http://localhost:3000

### UI Features

#### Dashboard

The main dashboard shows:

- Active schemas count
- Recent validations
- Quality score trends
- System health

#### Schema Browser

Navigate to Schemas to:

- View all stored schemas
- Search and filter schemas
- View schema details and versions
- Edit schema metadata

#### Contract Management

Navigate to Contracts to:

- Upload contract files (YAML/JSON)
- Parse and validate contracts
- View contract components
- Build consolidated contracts

#### Validation Workspace

Navigate to Validation to:

- Select a schema
- Paste or upload data
- Run validation
- View detailed errors
- Export results

#### Quality Dashboard

Navigate to Quality to:

- View quality metrics over time
- Set and monitor thresholds
- Browse violations
- Generate reports

#### ETL Monitor

Navigate to ETL to:

- View pipeline runs
- Monitor execution progress
- Check pipeline results
- View error logs

## Part 4: API Client Integration

### Python Client

    import httpx

    class PyCharterClient:
        def __init__(self, base_url="http://localhost:8000"):
            self.base_url = base_url
            self.client = httpx.Client(base_url=base_url)

        def validate(self, schema_id: str, data: dict) -> dict:
            response = self.client.post(
                "/api/v1/validation/validate",
                json={"schema_id": schema_id, "data": data}
            )
            response.raise_for_status()
            return response.json()

        def validate_batch(self, schema_id: str, data: list) -> dict:
            response = self.client.post(
                "/api/v1/validation/validate-batch",
                json={"schema_id": schema_id, "data": data}
            )
            response.raise_for_status()
            return response.json()

        def get_schema(self, schema_id: str) -> dict:
            response = self.client.get(f"/api/v1/schemas/{schema_id}")
            response.raise_for_status()
            return response.json()

        def quality_check(self, schema_id: str, data: list, thresholds: dict = None) -> dict:
            response = self.client.post(
                "/api/v1/quality/check",
                json={
                    "schema_id": schema_id,
                    "data": data,
                    "options": {
                        "calculate_metrics": True,
                        "thresholds": thresholds or {}
                    }
                }
            )
            response.raise_for_status()
            return response.json()

    # Usage
    client = PyCharterClient()
    result = client.validate("user", {"name": "Alice", "email": "alice@example.com"})
    print(f"Valid: {result['is_valid']}")

### Async Python Client

    import httpx

    class AsyncPyCharterClient:
        def __init__(self, base_url="http://localhost:8000"):
            self.base_url = base_url

        async def validate(self, schema_id: str, data: dict) -> dict:
            async with httpx.AsyncClient(base_url=self.base_url) as client:
                response = await client.post(
                    "/api/v1/validation/validate",
                    json={"schema_id": schema_id, "data": data}
                )
                response.raise_for_status()
                return response.json()

    # Usage
    import asyncio

    async def main():
        client = AsyncPyCharterClient()
        result = await client.validate("user", {"name": "Alice", "email": "alice@example.com"})
        print(f"Valid: {result['is_valid']}")

    asyncio.run(main())

### JavaScript/TypeScript Client

    class PyCharterClient {
      constructor(private baseUrl: string = 'http://localhost:8000') {}

      async validate(schemaId: string, data: Record<string, any>) {
        const response = await fetch(`${this.baseUrl}/api/v1/validation/validate`, {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ schema_id: schemaId, data })
        });

        if (!response.ok) {
          throw new Error(`HTTP error! status: ${response.status}`);
        }

        return response.json();
      }

      async validateBatch(schemaId: string, data: Record<string, any>[]) {
        const response = await fetch(`${this.baseUrl}/api/v1/validation/validate-batch`, {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ schema_id: schemaId, data })
        });

        if (!response.ok) {
          throw new Error(`HTTP error! status: ${response.status}`);
        }

        return response.json();
      }
    }

    // Usage
    const client = new PyCharterClient();
    const result = await client.validate('user', { name: 'Alice', email: 'alice@example.com' });
    console.log(`Valid: ${result.is_valid}`);

## Part 5: Authentication & Security

### API Key Authentication

    # Configure API key in environment
    export PYCHARTER_API_KEY="your-secret-key"

    # Start server with auth enabled
    pycharter api --auth

Using API key:

    curl -H "X-API-Key: your-secret-key" \
      http://localhost:8000/api/v1/schemas

### CORS Configuration

    # In your custom FastAPI app
    from fastapi.middleware.cors import CORSMiddleware

    app.add_middleware(
        CORSMiddleware,
        allow_origins=["http://localhost:3000"],
        allow_credentials=True,
        allow_methods=["*"],
        allow_headers=["*"],
    )

## Part 6: Production Deployment

### Docker

    FROM python:3.11-slim

    WORKDIR /app

    COPY . .
    RUN pip install pycharter[api]

    EXPOSE 8000

    CMD ["pycharter", "api", "--host", "0.0.0.0"]

    docker build -t pycharter-api .
    docker run -p 8000:8000 pycharter-api

### Docker Compose

    version: '3.8'

    services:
      api:
        build: .
        ports:
          - "8000:8000"
        environment:
          - DATABASE_URL=postgresql://user:pass@db/pycharter
        depends_on:
          - db

      db:
        image: postgres:15
        environment:
          - POSTGRES_USER=user
          - POSTGRES_PASSWORD=pass
          - POSTGRES_DB=pycharter
        volumes:
          - postgres_data:/var/lib/postgresql/data

    volumes:
      postgres_data:

### Kubernetes

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: pycharter-api
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: pycharter-api
      template:
        metadata:
          labels:
            app: pycharter-api
        spec:
          containers:
          - name: api
            image: pycharter-api:latest
            ports:
            - containerPort: 8000
            env:
            - name: DATABASE_URL
              valueFrom:
                secretKeyRef:
                  name: pycharter-secrets
                  key: database-url
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: pycharter-api
    spec:
      selector:
        app: pycharter-api
      ports:
      - port: 80
        targetPort: 8000

## Exercises

1. API Basics: Start the API server and use curl to store a schema and validate data.

2. Client Library: Create a Python client class that wraps the validation endpoints.

3. UI Exploration: Launch the UI and explore all features (schemas, validation, quality).

4. Integration: Build a FastAPI app that uses PyCharter API for input validation.

5. Deployment: Create a Docker setup for PyCharter API with PostgreSQL.

## Next Steps

- Production Deployment Guide - Full deployment instructions
- API Reference - Complete API documentation
- Custom Validators Guide - Extend validation