API Reference

REST endpoints and Python API documentation

Overview

AI-Viewer provides both a REST API for HTTP access and a Python API for programmatic control. This reference covers all available endpoints and classes.

REST API

Document Routes

GET /

Document selector page listing all registered documents.

Response: HTML page

GET /doc/{alias}/viewer

Main interactive viewer for a document.

Parameters:

Parameter Type Description
alias path Document identifier
page query Starting page (optional)
style query CSS style to apply (optional)

Example:

GET /doc/E57/viewer
GET /doc/E57/viewer?page=25
GET /doc/E57/viewer?page=25&style=scholarly

GET /doc/{alias}/config

Document configuration as JSON.

Response:

{
  "name": "E57",
  "title": "Inquisitio Physica...",
  "page_count": 105,
  "has_manifest": true,
  "has_segments": true,
  "available_layers": ["html", "translation-english"]
}

GET /doc/{alias}/manifest

Full manifest.json content.

Response:

{
  "document": {
    "name": "E57",
    "title": "Inquisitio Physica in Causam Fluxus ac Refluxus Maris",
    "page_count": 105
  },
  "segments": {
    "chapters": { ... },
    "paragraphs": { ... }
  }
}

Content Routes

GET /doc/{alias}/zip/html/{filename}

Serve page HTML content.

Parameters:

Parameter Type Description
alias path Document identifier
filename path HTML filename (e.g., page_000.html)

Response: HTML content

Example:

GET /doc/E57/zip/html/page_025.html

GET /doc/{alias}/zip/images/{filename}

Serve page images.

Parameters:

Parameter Type Description
alias path Document identifier
filename path Image filename (e.g., page_000.png)

Response: PNG image

Example:

GET /doc/E57/zip/images/page_025.png
GET /doc/E57/zip/images/fig_p012_n_1.png

GET /doc/{alias}/segments/{type}

List segments of a specific type.

Parameters:

Parameter Type Description
alias path Document identifier
type path Segment type (e.g., letters, chapters)

Response:

{
  "type": "letters",
  "items": [
    {
      "id": "1",
      "number": 1,
      "from": "Euler",
      "to": "Goldbach",
      "date": "1729-10-13",
      "pages": [3, 4, 5]
    }
  ]
}

API Routes

GET /doc/{alias}/api/info

Document information.

Response:

{
  "name": "E57",
  "title": "Inquisitio Physica...",
  "page_count": 105,
  "format": "PDAI",
  "has_images": true,
  "has_html": true,
  "has_manifest": true
}

GET /doc/{alias}/api/page/{page_number}

Get specific page data.

Parameters:

Parameter Type Description
alias path Document identifier
page_number path Page number (0-indexed)

Response:

{
  "page_number": 25,
  "image_url": "/doc/E57/zip/images/page_025.png",
  "html_url": "/doc/E57/zip/html/page_025.html",
  "has_math": true,
  "segment_info": {
    "chapter": "CAPUT III",
    "paragraphs": [45, 46, 47]
  }
}

GET /doc/{alias}/api/layers

Available agent output layers.

Response:

{
  "layers": [
    {"id": "html", "name": "Original HTML", "source": "html/"},
    {"id": "translation-english", "name": "English Translation", "source": "ai/"},
    {"id": "translation-german", "name": "German Translation", "source": "ai/"}
  ]
}

GET /doc/{alias}/api/page/{n}/layer/{layer_id}

Get page content from a specific layer.

Parameters:

Parameter Type Description
alias path Document identifier
n path Page number (0-indexed)
layer_id path Layer identifier

Response: HTML/XML content from the specified layer

POST /doc/{alias}/api/brew

Trigger an AI-Scholar agent (requires ai-scholar installation).

Request Body:

{
  "agent": "translation-english",
  "pages": [0, 1, 2, 3, 4]
}

Response:

{
  "status": "started",
  "job_id": "abc123",
  "agent": "translation-english",
  "pages": [0, 1, 2, 3, 4]
}

Python API

PdaiPublicationServer

Main server class for serving PDAI documents.

Constructor

from ai_viewer import PdaiPublicationServer

server = PdaiPublicationServer(
    document_path="../pdai/E57",
    host="127.0.0.1",
    port=5100,
    debug=False
)

Parameters:

Parameter Type Default Description
document_path str required Path to PDAI document directory
host str “127.0.0.1” Server host address
port int 5100 Server port number
debug bool False Enable debug mode

Methods

start()

Start the FastAPI server.

server = PdaiPublicationServer("../pdai/E57")
server.start()  # Server runs on http://localhost:5100
stop()

Stop the server gracefully.

server.stop()
get_document_info()

Get information about the loaded document.

info = server.get_document_info()
print(f"Document has {info['page_count']} pages")

Returns: dict with document metadata

PdaiDocument

Class for handling PDAI document format and structure.

Constructor

from ai_viewer import PdaiDocument

doc = PdaiDocument("../pdai/E57")

Methods

load_page(page_number)

Load a specific page from the document.

page_data = doc.load_page(25)
print(f"Page 25 image: {page_data['image_path']}")

Parameters:

Parameter Type Description
page_number int Page number (0-indexed)

Returns: dict with page data

get_page_count()

Get total number of pages.

count = doc.get_page_count()
print(f"Document has {count} pages")

Returns: int

validate_format()

Validate PDAI format compliance.

validation = doc.validate_format()
if validation['has_images'] and validation['has_html']:
    print("Valid PDAI document")

Returns: dict with validation results

load_manifest()

Load and parse manifest.json.

manifest = doc.load_manifest()
for segment_type in manifest.get('segments', {}):
    print(f"Found segment type: {segment_type}")

Returns: dict with manifest content or None

Utility Functions

quick_serve()

Quick function to serve a PDAI document.

from ai_viewer import quick_serve

quick_serve(
    document_path="../pdai/E57",
    port=5100,
    host="127.0.0.1",
    open_browser=True
)

Parameters:

Parameter Type Default Description
document_path str required Path to PDAI document
port int 5100 Server port
host str “127.0.0.1” Server host
open_browser bool True Open browser automatically

create_viewer_config()

Create viewer configuration for custom setups.

from ai_viewer import create_viewer_config

config = create_viewer_config(
    document_path="../pdai/E57",
    theme="dark",
    features={
        "math_rendering": True,
        "fullscreen": True,
        "search": False
    }
)

Returns: dict with configuration

Error Handling

HTTP Error Codes

Code Meaning
200 Success
400 Invalid request parameters
404 Document or page not found
500 Server error

Error Response Format

{
  "error": true,
  "code": "DOCUMENT_NOT_FOUND",
  "message": "Document 'Unknown' is not registered",
  "details": {
    "registered_documents": ["E57", "Goldbach"]
  }
}

Python Exceptions

DocumentNotFoundError

from ai_viewer.exceptions import DocumentNotFoundError

try:
    doc = PdaiDocument("nonexistent/path")
except DocumentNotFoundError as e:
    print(f"Document not found: {e}")

InvalidFormatError

from ai_viewer.exceptions import InvalidFormatError

try:
    doc = PdaiDocument("invalid/document")
    doc.validate_format()
except InvalidFormatError as e:
    print(f"Invalid format: {e}")

ServerError

from ai_viewer.exceptions import ServerError

try:
    server = PdaiPublicationServer("../pdai/E57", port=80)
    server.start()
except ServerError as e:
    print(f"Server error: {e}")

Configuration

Environment Variables

Variable Default Description
AI_VIEWER_HOST “127.0.0.1” Default server host
AI_VIEWER_PORT “5100” Default server port
AI_VIEWER_DEBUG “false” Enable debug mode
AI_VIEWER_CACHE_SIZE “100MB” Image cache size

Configuration File

Create ~/.ai-viewer/config.yaml:

server:
  host: "127.0.0.1"
  port: 5100
  debug: false

display:
  theme: "default"
  math_renderer: "mathjax"
  image_quality: "high"

performance:
  cache_size: "100MB"
  preload_pages: 5

features:
  fullscreen: true
  keyboard_navigation: true
  search: true

Integration Examples

Jupyter Notebook

from ai_viewer import quick_serve
from IPython.display import IFrame
import threading

# Start viewer in background
def start_viewer():
    quick_serve("../pdai/E57", port=5100, open_browser=False)

thread = threading.Thread(target=start_viewer)
thread.daemon = True
thread.start()

# Display in notebook
IFrame('http://localhost:5100/doc/E57/viewer', width=1000, height=600)

Flask Integration

from flask import Flask, redirect
from ai_viewer import PdaiPublicationServer
import threading

app = Flask(__name__)

# Start AI Viewer in background
def start_viewer():
    server = PdaiPublicationServer("../pdai/E57", port=5101)
    server.start()

viewer_thread = threading.Thread(target=start_viewer)
viewer_thread.daemon = True
viewer_thread.start()

@app.route('/view/<doc_name>')
def view_document(doc_name):
    return redirect(f'http://localhost:5101/doc/{doc_name}/viewer')

Programmatic Document Access

from ai_viewer import PdaiDocument

# Load document
doc = PdaiDocument("../pdai/E57")

# Get page count
print(f"Pages: {doc.get_page_count()}")

# Load manifest for segment info
manifest = doc.load_manifest()
if manifest:
    segments = manifest.get('segments', {})
    for seg_type, seg_data in segments.items():
        items = seg_data.get('items', [])
        print(f"{seg_type}: {len(items)} items")

# Validate format
validation = doc.validate_format()
print(f"Valid: {validation['valid']}")

See Also