Skip to content

Instantly share code, notes, and snippets.

@Darkflib
Last active July 29, 2025 20:11
Show Gist options
  • Save Darkflib/f2d19cdfa3caef60678caa87bd678051 to your computer and use it in GitHub Desktop.
Save Darkflib/f2d19cdfa3caef60678caa87bd678051 to your computer and use it in GitHub Desktop.
Example from a current project. I have a language specific file (I actually rolled my own details into them to give defaults on the pyproject and other places) + project files.

Diagrams API

This repository contains the source code for the Diagrams API, which is a web service that allows users to compile diagrams programmatically via mermaid and plantuml. The API is designed to be simple and efficient, providing endpoints for generating diagrams in various formats.

Features

  • Generate diagrams using Mermaid and PlantUML syntax
  • Support for multiple output formats (e.g., PNG, SVG)
  • Easy integration with other applications
  • RESTful API design

Installation

To install the Diagrams API, follow these steps:

  1. Clone the repository:

    git clone https://github.com/yourusername/diagrams-api.git
  2. Navigate to the project directory:

    cd diagrams-api
    uv sync

Configuration

Before running the API, you may need to configure it. The configuration file is located at config.yaml. You can modify the settings such as port number, logging level, and supported diagram types.

Usage

To use the Diagrams API, you can send HTTP requests to the endpoints provided. Here are some examples:

Generate a Mermaid Diagram

curl -X POST http://localhost:8000/mermaid \
     -H "Content-Type: application/json" \
     -d '{"diagram": "graph TD; A-->B; A-->C; B-->D; C-->D;"}'

Generate a PlantUML Diagram

curl -X POST http://localhost:8000/plantuml \
     -H "Content-Type: application/json" \
     -d '{"diagram": "@startuml\nAlice -> Bob: Hello\n@enduml"}'

Tech Stack

  • Backend: Python with FastAPI
  • Diagram Libraries: Mermaid, PlantUML
  • Testing: Pytest for unit and integration tests
  • Deployment: Docker for containerization
  • Caching: Optional Redis

There is no database required for this API, as it is stateless and does not store any user data, but we recommend using a caching layer for performance optimization.

Testing

To run the tests, ensure you have pytest installed, then execute:

pytest tests/

Documentation

The API documentation is available at http://localhost:8000/docs when the server is running. It provides detailed information about the available endpoints, request parameters, and response formats.

Contributing

Contributions are welcome! If you have suggestions for improvements or new features, please open an issue or submit a pull request. Please ensure that your code adheres to the project's coding standards and includes appropriate tests.

License

This project is licensed under the MIT License.

Contact

For any questions or support, please contact the project maintainer at [email protected].

Copilot Instructions for Diagrams API

Architecture Overview

This is a stateless FastAPI microservice that generates diagrams by shelling out to external tools (mmdc for Mermaid, plantuml.jar for PlantUML). The core pattern is:

  1. Accept diagram content via REST API
  2. Write content to temporary files
  3. Execute external CLI tools to generate images
  4. Return base64-encoded results or raw image responses

Key architectural principle: No persistence layer - all state lives in temporary files during request processing.

Critical Components

Service Layer Pattern

  • services/mermaid_service.py & services/plantuml_service.py - Handle subprocess execution and file I/O
  • Both services use identical patterns: temp files → CLI execution → file cleanup → response building
  • PlantUML requires Java with -Djava.awt.headless=true flag for headless environments

Request/Response Models

  • models/diagram.py defines unified DiagramRequest/DiagramResponse models
  • OutputFormat enum supports PNG (base64) and SVG (raw text) formats
  • Consistent error handling via success boolean + optional error field

Router Pattern

  • Routers in routers/ expose three endpoints per diagram type:
    • POST / - JSON response with base64/SVG data
    • POST /raw - Direct image/SVG response for downloads
    • GET /view - Browser-accessible with query parameters

Development Workflow

Dependencies & Environment

uv sync                    # Install dependencies
uv run uvicorn src.diagrams_api.main:app --reload  # Development server
uv run pytest tests/      # Run tests

External Tool Dependencies

  • Mermaid: Requires mmdc CLI (Node.js package: @mermaid-js/mermaid-cli)
  • PlantUML: Requires plantuml.jar in project root + Java runtime
  • Both tools must be available in PATH or configured via config.yaml

Configuration Hierarchy

  1. Environment variables (.env file)
  2. config.yaml file
  3. Pydantic defaults in settings.py

Key configs: mermaid_cli_path, plantuml_jar_path, redis_url (for optional caching)

Project-Specific Patterns

Subprocess Error Handling

# Standard pattern used in both services:
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode != 0:
    return DiagramResponse(success=False, error=f"Tool failed: {result.stderr}")

Temporary File Management

  • Use tempfile.NamedTemporaryFile(delete=False) for input files
  • Always clean up with os.unlink() in try/finally blocks
  • PlantUML generates output files with predictable naming conventions

Base64 vs Raw Response Handling

  • PNG images: Always base64-encoded in JSON responses, decoded for raw endpoints
  • SVG content: Raw text in JSON, direct text for raw endpoints
  • Raw endpoints use FastAPI Response objects with proper Content-Type headers

Testing Strategy

Test Client Pattern

from fastapi.testclient import TestClient
from src.diagrams_api.main import app
client = TestClient(app)

Integration Testing

  • Tests hit actual endpoints but may require external tools to be installed
  • Mock subprocess calls for unit tests of service classes
  • Use pytest-asyncio for async service method testing

Debugging & Troubleshooting

Common Issues

  • PlantUML GUI errors: Add -Djava.awt.headless=true to Java command
  • Tool not found: Check PATH and config.yaml tool paths
  • Permission errors: Ensure temp directory is writable

Log Patterns

  • Service classes log subprocess commands and results
  • Router level logs request/response metadata
  • Configure via LOG_LEVEL environment variable

Extension Points

Adding New Diagram Types

  1. Create service class following mermaid/plantuml patterns
  2. Add router with three endpoint variants
  3. Update supported_diagram_types in config
  4. Include tool installation in Docker setup

Caching Layer

  • enable_caching=true + redis_url in config enables Redis caching
  • Cache key should include content hash + format + dimensions
  • Implement in service layer before subprocess calls
applyTo
**

Python Development Guidelines

Github username: darkflib Email for github/dev: [email protected] Name: Mike Location: UK TZ: Europe/London Minimal Python Version: 3.11

Development Environment

  • Python Version: Minimum Python 3.11 - prefer latest stable version
  • IDE: Visual Studio Code with Python extension
  • Extensions:
    • Python extension for VS Code
    • Pylance for type checking and IntelliSense
    • Prettier for code formatting
    • GitHub Pull Requests and Issues for collaboration
  • Environment Management:
    • Use uv for virtual environments and dependency management
    • Run commands with uv run or activate with . .venv/bin/activate
    • Use uv pip <pip args> for pip functionality
  • Containerization:
    • Use devcontainers or WSL for Windows development
    • Docker for application containerization
    • Docker Compose for local development services
    • No virtual environments needed inside containers

Project Structure

  • Web Applications:
    • Flask for standard web applications (with blueprints)
    • FastAPI for high-performance async APIs (with routers)
    • Clear separation of concerns in code organization
  • Database:
    • SQLAlchemy for database interactions
    • SQLite for development, PostgreSQL for production
    • Alembic for database migrations
  • Configuration:
    • Pydantic for settings management and data validation
    • Dotenv for environment variable management
    • Secrets via environment variables (dev) or GCP Secret Manager (prod)
  • Testing:
    • Structure tests in a tests/ directory at the project root
    • Use subdirectories matching the application's package structure
    • Name test files with test_ prefix
    • Example structure:
      tests/
      ├── conftest.py            # Shared fixtures
      ├── unit/                  # Unit tests
      │   ├── test_models.py
      │   └── test_utils.py
      ├── integration/           # Integration tests
      │   ├── test_api.py
      │   └── test_db.py
      └── functional/            # End-to-end tests
          └── test_endpoints.py
      

Dependency Management

  • Tool: uv for installation and environment management
  • Definition: Use pyproject.toml for dependency specifications
  • Commands: Use uv pip for pip-compatible operations
  • Pinning: Pin exact versions for reproducible builds
  • Freezing: Generate precise dependency lists with uv freeze

Code Quality & Formatting

  • Linting & Formatting Tools:
    • Black for code formatting
    • isort for import ordering
    • ruff for comprehensive linting
    • mypy for type checking
  • Pre-commit Hooks:
    • Use pre-commit to automate the following checks:
      # Example .pre-commit-config.yaml
      repos:
      - repo: https://github.com/pre-commit/pre-commit-hooks
        rev: v4.4.0
        hooks:
        - id: trailing-whitespace
        - id: end-of-file-fixer
        - id: check-yaml
      
      - repo: https://github.com/pycqa/isort
        rev: 5.12.0
        hooks:
        - id: isort
      
      - repo: https://github.com/psf/black
        rev: 23.3.0
        hooks:
        - id: black
      
      - repo: https://github.com/charliermarsh/ruff-pre-commit
        rev: v0.0.262
        hooks:
        - id: ruff
          args: [--fix, --exit-non-zero-on-fix]
      
      - repo: https://github.com/pre-commit/mirrors-mypy
        rev: v1.3.0
        hooks:
        - id: mypy
          additional_dependencies: [types-all]
  • Type Hints: Required for all function arguments, return values, and variables
  • Docstrings: Required for all modules, classes, and public functions (Google or rST style)

Version Control & Collaboration

  • Source Hosting: GitHub
  • Commit Messages: Use standard "FIXES #123" style messages parsable by tooling
  • Branch Naming: Use "FIX/issue-description" or "FEAT/feature-description"
  • Default Branch: main
  • Repository Standards:
    • Pull .github templates from organization's .github repository
    • Only override CONTRIBUTING.md and other boilerplate when project-specific exceptions exist

Testing

  • Framework: pytest with appropriate plugins:
    • pytest-asyncio for FastAPI
    • pytest-flask for Flask applications
    • pytest-cov for coverage reporting
  • Coverage: Maintain high test coverage (target: >90%)

CI/CD

  • Pipeline: GitHub Actions workflows
  • Templates: Use organization templates (under development)
  • Deployment Target: GCP Cloud Run
  • Container Registry: Push to both GCP Artifact Registry and GitHub

Deployment

  • Web Servers:
    • gunicorn for Flask applications
    • uvicorn for FastAPI applications
  • Cloud Platform: GCP
    • Cloud Build for CI/CD
    • Cloud Run for hosting
    • Artifact Registry for container images
  • Documentation: OpenAPI/Swagger for API documentation

Logging & Error Handling

  • Logging:
    • Structured logging using Python's logging module
    • JSON format for production logs
    • Appropriate log levels (DEBUG, INFO, WARNING, ERROR, CRITICAL)
  • Error Handling:
    • Custom exception classes
    • Meaningful HTTP status codes
    • Consistent error message format

Recommended Libraries

  • HTTP Clients: requests or httpx
  • Console Output: rich
  • Templating: Jinja2
  • REST APIs: Flask-RESTful (with Flask)
  • Async APIs: FastAPI with Pydantic for data validation
  • Authentication: Flask-Security or FastAPI Security for user management

Tech-Stack

Note: RabbitMQ, Redis, nginx, haproxy are the standard tech-stack components, but not required for all projects.

  • Web Servers: gunicorn for Flask, uvicorn for FastAPI
  • Web Frameworks: Flask, FastAPI
  • Database: SQLAlchemy with SQLite/PostgreSQL
  • Configuration: Pydantic, Dotenv

Documentation

  • README.md Structure:
    • Project Name
    • Summary
    • Features
    • Components
    • Installation
    • Usage
    • Configuration
    • Contributing
    • License (default: MIT)
  • API Documentation: OpenAPI/Swagger
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment