Files
sunday/static/openapi.yaml

328 lines
11 KiB
YAML

openapi: 3.0.3
info:
title: Webcomic API
description: API for accessing webcomic data
version: 1.0.0
contact:
url: http://127.0.0.1:3000
servers:
- url: http://127.0.0.1:3000
description: Development server
- url: https://your-production-domain.com
description: Production server (update with your actual domain)
paths:
/api/comics:
get:
summary: Get all comics
description: |
Returns all comics with enriched metadata. Supports optional pagination and section grouping.
**Without pagination parameters:** Returns a simple array of all comics (newest first when using pagination, original order otherwise).
**With pagination parameters:** Returns paginated response with section grouping (if enabled globally or via `group_by_section` parameter).
operationId: getAllComics
tags:
- Comics
parameters:
- name: page
in: query
description: Page number for pagination (1-indexed). When provided, triggers paginated response format.
required: false
schema:
type: integer
minimum: 1
default: 1
example: 1
- name: per_page
in: query
description: Number of comics per page (max 100). When provided, triggers paginated response format.
required: false
schema:
type: integer
minimum: 1
maximum: 100
default: 24
example: 24
- name: group_by_section
in: query
description: Force section grouping in response (even when SECTIONS_ENABLED is false). When true, triggers paginated response format.
required: false
schema:
type: boolean
default: false
example: false
responses:
'200':
description: Successful response
content:
application/json:
schema:
oneOf:
- type: array
description: Simple array response (when no pagination parameters provided)
items:
$ref: '#/components/schemas/Comic'
- $ref: '#/components/schemas/PaginatedComicsResponse'
examples:
simpleArray:
summary: Simple array response (default)
value:
- number: 1
title: "First Comic"
filename: "comic-001.jpg"
mobile_filename: "comic-001-mobile.jpg"
date: "2025-01-01"
alt_text: "The very first comic"
author_note: "This is where your comic journey begins!"
full_width: true
plain: true
formatted_date: "Wednesday, January 1, 2025"
author_note_is_html: false
- number: 2
filename: "comic-002.jpg"
date: "2025-01-08"
alt_text: "The second comic"
full_width: true
plain: true
formatted_date: "Wednesday, January 8, 2025"
author_note_is_html: false
paginatedResponse:
summary: Paginated response (when using page/per_page parameters)
value:
sections:
- section_title: "Chapter 1"
comics:
- number: 2
filename: "comic-002.jpg"
date: "2025-01-08"
alt_text: "The second comic"
full_width: true
plain: true
formatted_date: "Wednesday, January 8, 2025"
author_note_is_html: false
- section_title: null
comics:
- number: 1
title: "First Comic"
filename: "comic-001.jpg"
date: "2025-01-01"
alt_text: "The very first comic"
full_width: true
plain: true
formatted_date: "Wednesday, January 1, 2025"
author_note_is_html: false
page: 1
per_page: 24
total_comics: 2
has_more: false
/api/comics/{comic_id}:
get:
summary: Get a specific comic
description: Returns a single comic by its number/ID with enriched metadata
operationId: getComicById
tags:
- Comics
parameters:
- name: comic_id
in: path
description: Comic number/ID
required: true
schema:
type: integer
minimum: 1
example: 1
responses:
'200':
description: Successful response with comic data
content:
application/json:
schema:
$ref: '#/components/schemas/Comic'
example:
number: 1
title: "First Comic"
filename: "comic-001.jpg"
mobile_filename: "comic-001-mobile.jpg"
date: "2025-01-01"
alt_text: "The very first comic"
author_note: "This is where your comic journey begins!"
full_width: true
plain: true
formatted_date: "Wednesday, January 1, 2025"
author_note_is_html: false
'404':
description: Comic not found
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
error: "Comic not found"
components:
schemas:
Comic:
type: object
required:
- number
- filename
- date
- alt_text
- full_width
- plain
- formatted_date
- author_note_is_html
- filenames
- alt_texts
- is_multi_image
properties:
number:
type: integer
description: Sequential comic number (unique identifier)
minimum: 1
example: 1
title:
type: string
description: Comic title (optional, defaults to "#X" if not provided)
example: "First Comic"
filename:
oneOf:
- type: string
description: Single image filename in static/images/comics/
- type: array
description: Multiple image filenames for webtoon-style comics
items:
type: string
example: "comic-001.jpg"
filenames:
type: array
description: Normalized array of image filenames (computed field, always an array even for single images)
items:
type: string
example: ["comic-001.jpg"]
mobile_filename:
type: string
description: Optional mobile version of the comic image
example: "comic-001-mobile.jpg"
date:
type: string
format: date
description: Publication date in YYYY-MM-DD format
example: "2025-01-01"
alt_text:
oneOf:
- type: string
description: Accessibility text for single image or shared text for all images
- type: array
description: Individual accessibility text for each image in multi-image comics
items:
type: string
example: "The very first comic"
alt_texts:
type: array
description: Normalized array of alt texts matching filenames (computed field)
items:
type: string
example: ["The very first comic"]
is_multi_image:
type: boolean
description: Indicates if this is a multi-image comic (computed field)
example: false
author_note:
type: string
description: Author's note about the comic (plain text or HTML from markdown)
example: "This is where your comic journey begins!"
author_note_md:
type: string
description: Filename or path to markdown file for author note
example: "2025-01-01.md"
section:
type: string
description: Section/chapter title (appears on archive page when SECTIONS_ENABLED is true)
example: "Chapter 1: Origins"
full_width:
type: boolean
description: Whether the comic should display in full-width mode (computed from global default and per-comic override)
example: true
plain:
type: boolean
description: Whether the comic should display in plain mode without header/borders (computed from global default and per-comic override)
example: true
formatted_date:
type: string
description: Human-readable formatted date (computed field)
example: "Wednesday, January 1, 2025"
author_note_is_html:
type: boolean
description: Indicates whether author_note contains HTML (from markdown) or plain text (computed field)
example: false
ComicSection:
type: object
required:
- section_title
- comics
properties:
section_title:
type: string
nullable: true
description: Section/chapter title (null for comics without a section)
example: "Chapter 1"
comics:
type: array
description: Comics in this section
items:
$ref: '#/components/schemas/Comic'
PaginatedComicsResponse:
type: object
required:
- sections
- page
- per_page
- total_comics
- has_more
properties:
sections:
type: array
description: Comics grouped by section
items:
$ref: '#/components/schemas/ComicSection'
page:
type: integer
description: Current page number
minimum: 1
example: 1
per_page:
type: integer
description: Number of comics per page
minimum: 1
maximum: 100
example: 24
total_comics:
type: integer
description: Total number of comics across all pages
minimum: 0
example: 100
has_more:
type: boolean
description: Whether there are more pages available
example: true
Error:
type: object
required:
- error
properties:
error:
type: string
description: Error message
example: "Comic not found"
tags:
- name: Comics
description: Operations for accessing comic data