Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

843 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Quality Gate Status Bugs Code Smells Coverage Duplicated Lines (%) Lines of Code Reliability Rating Security Rating Maintainability Rating Vulnerabilities

StrictDoc Service

A Dockerized service providing a REST API interface to leverage StrictDoc's functionality for documentation and requirements management.

Built on Red Hat Universal Base Image (UBI) for enterprise-grade security, stability, and OpenShift compatibility.

Features

  • Simple REST API to access StrictDoc (version pinned in pyproject.toml)
  • Red Hat UBI 9 base image - Enterprise-grade security and OpenShift compatibility
  • Fast builds - Pre-compiled wheels, millisecond dependency installation with uv
  • Prometheus metrics - Built-in monitoring with dedicated metrics endpoint (port 9183)
  • Compatible with amd64 and arm64 architectures
  • Easily deployable via Docker or Docker Compose
  • Configurable port and logging level
  • Support for multiple export formats:
    • HTML (default) - Web-based documentation
    • JSON - Structured data for programmatic access
    • Excel - Native Microsoft Excel format
    • ReqIF/ReqIFZ - Requirements Interchange Format (XML/compressed)
    • RST - ReStructured Text for documentation
    • SDOC - StrictDoc native format
    • PDF - Not available (requires Chromium/ChromeDriver, which significantly increases image size)

Getting Started

Installation

To install the latest version of the StrictDoc Service, run the following command:

docker pull ghcr.io/schweizerischebundesbahnen/strictdoc-service:latest

Running the Service

Using Docker

To start the StrictDoc service container, execute:

docker run --detach \
  --init \
  --publish 9083:9083 \
  --publish 9183:9183 \
  --name strictdoc-service \
  ghcr.io/schweizerischebundesbahnen/strictdoc-service:latest

The service will be accessible on port 9083, with Prometheus metrics on port 9183.

Using Docker Compose

A production-ready docker-compose.yml file is provided with the repository. To use it:

# Start the service
docker-compose up -d

# Check logs
docker-compose logs -f

# Stop the service
docker-compose down

You can customize the environment variables by creating a .env file:

# .env example
APP_VERSION=1.0.0
LOG_LEVEL=DEBUG

Using as a Base Image

To extend or customize the service, use it as a base image in the Dockerfile:

FROM ghcr.io/schweizerischebundesbahnen/strictdoc-service:latest

Development

Prerequisites

This project uses uv for fast and modern Python dependency management.

Install uv:

curl -LsSf https://astral.sh/uv/install.sh | sh

Local Development Setup

  1. Clone the repository:

    git clone https://github.com/SchweizerischeBundesbahnen/strictdoc-service.git
    cd strictdoc-service
  2. Install dependencies:

    uv sync --all-groups
  3. Run the service locally:

    uv run python -m app.strictdoc_service_application --port 9083

Code Quality

# Format and lint code
uv run ruff format
uv run ruff check

# Type checking
uv run mypy .

# Run all linting
uv run tox -e lint

Testing

# Run all tests with coverage
uv run pytest --cov=app tests/ --cov-report=term-missing

# Run tests with tox
uv run tox

See tests/README.md for detailed test organization and instructions.

Building the Docker Image

IMPORTANT: Always use Docker BuildKit for optimal build performance:

# Enable BuildKit for cache mount support (REQUIRED)
DOCKER_BUILDKIT=1 docker build \
  --build-arg APP_IMAGE_VERSION=0.0.0 \
  --tag strictdoc-service:0.0.0 .

Replace 0.0.0 with the desired version number.

About the Base Image

This service uses Red Hat Universal Base Image (UBI) 9 Minimal for optimal performance and compatibility:

  • Image size: ~604MB (optimized for enterprise deployment)
  • Python installation: Python 3.13 via uv (installed to /opt/python for non-root access)
  • Dependency management: Ultra-fast installation with pre-compiled wheels (milliseconds vs minutes)
  • Security: Regular security updates from Red Hat, enterprise-grade support
  • Compatibility: OpenShift ready, glibc-based for maximum package compatibility

Why not Alpine? While Alpine Linux produces smaller images, it uses musl libc which causes compilation issues with some Python packages (tree-sitter) on arm64 architecture. UBI provides the best balance of size, speed, and compatibility.

Running the Development Container

To start the Docker container with your custom-built image:

docker run --detach \
  --init \
  --publish 9083:9083 \
  --publish 9183:9183 \
  --name strictdoc-service \
  strictdoc-service:0.0.0

Stopping the Container

To stop the running container, execute:

docker container stop strictdoc-service

Access service

StrictDoc Service provides the following endpoints:


Getting version info

GET /version
Responses
HTTP code Content-Type Response
200 application/json { "python": "3.13.7", "strictdoc": "0.14.0", "strictdocService": "0.0.0", "timestamp": "2025-10-08T12:23:09Z" }
Example cURL
 curl -X GET -H "Content-Type: application/json" http://localhost:9083/version

Monitoring

Prometheus & Grafana Integration

The service exposes Prometheus-compatible metrics for comprehensive monitoring and observability through Grafana dashboards.

Metrics Endpoint: /metrics on port 9183 (dedicated metrics port)

Security: The metrics endpoint is served on a separate port (9183) from the main API (9083). This allows network-level isolation using security groups or firewall rules to restrict metrics access to your Prometheus server only.

Available Metrics:

Export Metrics:

  • strictdoc_exports_total{format} - Total successful exports (labeled by format: html, json, excel, etc.)
  • strictdoc_export_failures_total{format} - Total failed exports (labeled by format)
  • strictdoc_export_error_rate_percent - Export error rate as percentage

Performance Metrics:

  • strictdoc_export_duration_seconds{format} - Export duration histogram (labeled by format)
  • avg_strictdoc_export_time_seconds - Average export time in seconds
  • strictdoc_request_body_bytes - Input document size histogram
  • strictdoc_response_body_bytes - Output document size histogram

Service Metrics:

  • uptime_seconds - Service uptime
  • active_exports - Current number of active export operations
  • strictdoc_info{version, service_version} - Version information

HTTP Metrics (via prometheus-fastapi-instrumentator):

  • http_request_duration_seconds - HTTP request duration histogram
  • http_requests_total - Total HTTP requests
  • http_requests_inprogress - Current in-progress requests

Prometheus Configuration Example:

scrape_configs:
  - job_name: 'strictdoc-service'
    static_configs:
      - targets: ['strictdoc-service:9183']  # Metrics on dedicated port
    metrics_path: '/metrics'
    scrape_interval: 15s
    scrape_timeout: 10s

Grafana Dashboard Queries:

# Export rate by format (requests per second)
sum(rate(strictdoc_exports_total[5m])) by (format)

# Error rate percentage
strictdoc_export_error_rate_percent


# 95th percentile export duration
histogram_quantile(0.95, rate(strictdoc_export_duration_seconds_bucket[5m]))

# Average export time
avg_strictdoc_export_time_seconds

Docker Compose Example with Prometheus & Grafana:

services:
  strictdoc-service:
    image: ghcr.io/schweizerischebundesbahnen/strictdoc-service:latest
    init: true
    ports:
      - "9083:9083"   # Main API
      - "9183:9183"   # Metrics endpoint

  prometheus:
    image: prom/prometheus:latest
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
      - prometheus-data:/prometheus

  grafana:
    image: grafana/grafana:latest
    ports:
      - "3000:3000"
    volumes:
      - grafana-data:/var/lib/grafana
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin

volumes:
  prometheus-data:
  grafana-data:

Quick Start with Monitoring Stack:

A complete monitoring setup is provided in the monitoring/ directory:

# Start StrictDoc service with Prometheus and Grafana
./monitoring/start-monitoring.sh

# Generate test load
./monitoring/generate-load.sh 100 20

# Stop monitoring stack
./monitoring/stop-monitoring.sh

Access URLs:

Service URL Credentials
StrictDoc Service http://localhost:9083 -
API Docs http://localhost:9083/docs -
Raw Metrics http://localhost:9183/metrics -
Prometheus http://localhost:9090 -
Grafana Dashboard http://localhost:3000/d/strictdoc-service admin/admin

See monitoring/README.md for detailed setup instructions.


Export StrictDoc Document

POST /export
Request Body

Content-Type: application/json

Field Type Data type Description
content required object (dict) Map of .sdoc filename(s) to their text content, e.g. {"doc.sdoc": "[DOCUMENT]\n..."}. Supports multiple files.
format required string Export format: html, html2pdf, rst, json, excel, reqif-sdoc, reqifz-sdoc, sdoc, doxygen, spdx
file_name required string Base name for the output file (without extension)

Note on PDF Export: The html2pdf format is currently not available in this service. PDF generation requires Chromium/ChromeDriver, which would increase the Docker image size by ~300MB+. If you need PDF output, consider:

  1. Using the html format and converting to PDF externally
  2. Using a separate PDF conversion service
  3. Building a custom image with Chromium installed

Note on HTML Export: The html format returns a ZIP archive containing the full HTML site.

Note on Multi-Document Export: When content contains more than one document, the response is always a ZIP archive regardless of the requested format.

Responses
HTTP code Content-Type Response
200 Varies by export format Exported document (single file, or ZIP for HTML/multi-doc)
400 application/json Invalid request (bad format, missing [DOCUMENT], etc.)
422 application/json Validation error
500 application/json Internal server error
Example cURL

Single document export to ReqIF:

curl -X POST \
  -H "Content-Type: application/json" \
  --data '{"content": {"requirements.sdoc": "[DOCUMENT]\nTITLE: My Requirements\n"}, "format": "reqif-sdoc", "file_name": "requirements"}' \
  "http://localhost:9083/export" \
  --output requirements.reqif

Multiple documents export (returns ZIP):

curl -X POST \
  -H "Content-Type: application/json" \
  --data '{"content": {"doc1.sdoc": "[DOCUMENT]\nTITLE: Doc 1\n", "doc2.sdoc": "[DOCUMENT]\nTITLE: Doc 2\n"}, "format": "json", "file_name": "export"}' \
  "http://localhost:9083/export" \
  --output export.zip

About

A Dockerized service providing a REST API interface to leverage StrictDoc's functionality for converting documents from one format into another

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

7 stars

Watchers

3 watching

Forks

Releases

Packages

Used by

Contributors

Languages