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:

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