Metadata-Version: 2.5
Name: swastik-codes
Version: 0.1.0
Summary: API documentation and a request collection for FastAPI, Starlette, Flask, Django and any ASGI/WSGI app, from your OpenAPI document. No dependencies.
Project-URL: Homepage, https://swastik.codes/
Project-URL: Support, https://swastik.codes/contact/
Author: Shwastik Tech Solutions Pvt Ltd
License: # Swastik Codes licence
        
        Copyright © 2026 Shwastik Tech Solutions Pvt Ltd. All rights reserved.
        
        Swastik Codes Docs (the `@swastik-codes/docs` npm package and the
        `swastik-codes` Python package) is proprietary software of Shwastik Tech
        Solutions Pvt Ltd. It is not open source.
        
        You may install it, free of charge, and use it to publish documentation and a
        request collection for your own APIs, in development and in production, under
        the Terms of service at https://swastik.codes/terms/ (section 7, "Our
        intellectual property", in particular).
        
        The pages it serves show the Swastik Codes name and logo and a "Run in Swastik
        Codes" button. You may not remove, hide, cover or change them, or make the
        pages appear to be made by anyone else.
        
        You may not copy, modify, decompile, disassemble, reverse engineer, resell,
        sublicense or redistribute the software or any part of it, except where the
        law allows it despite this restriction. Installing it through a package
        registry (npm, PyPI) or a company mirror of one, and bundling it unchanged in
        your application, is not redistribution.
        
        The software is provided "as is", without warranty of any kind, to the extent
        the law allows.
        
        Questions: https://swastik.codes/contact/
License-File: LICENSE.md
Keywords: api-docs,django,documentation,fastapi,flask,openapi,starlette,swagger,swagger-ui,swastik-codes
Classifier: Framework :: Django
Classifier: Framework :: FastAPI
Classifier: Framework :: Flask
Classifier: License :: Other/Proprietary License
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Middleware
Classifier: Topic :: Software Development :: Documentation
Requires-Python: >=3.8
Description-Content-Type: text/markdown

# Swastik Codes Docs for Python

API documentation and a request collection for your Python web app, built from
the OpenAPI document you already have. Install it, add one line, and you get two
pages:

| URL | What it is |
| --- | --- |
| `/swc/docs` | Full documentation: introduction, authentication, every request with its parameters, body, responses, code samples (cURL, JavaScript, Python, Go, PHP) and example responses. Search, deep links, light and dark themes. |
| `/swc/collection` | Every request in a collection tree. Fill in params, auth, headers and body, press **Send**, and read the response (pretty JSON, headers, status, time, size). |
| `/swc/openapi.json` | The document both pages read, with your edits applied. |

Both pages have a **Run in Swastik Codes** button that opens the API in
[Swastik Codes](https://swastik.codes) as a collection.

- **No dependencies.** Standard library only.
- **Small.** The whole UI is one script and one stylesheet, about 22 KB over the wire, precompressed (brotli and gzip) and cached for a year.
- **Cheap to serve.** The merged document is built once and cached until your spec or config changes. Spec responses carry an ETag, so repeat visits get `304`.

## FastAPI

```bash
pip install swastik-codes
```

```python
from fastapi import FastAPI
from swastik_codes import mount

app = FastAPI(title="My API")

# ... your routes ...

mount(app, config="swastik-codes.json")   # /swc/docs and /swc/collection
```

`mount()` reads FastAPI's own cached `app.openapi()`. FastAPI's `/docs` and
`/redoc` keep working. Turn them off with `FastAPI(docs_url=None, redoc_url=None)`
if you only want these pages. To serve them at `/docs` instead, use
`mount(app, prefix="")` together with `docs_url=None`.

Starlette works the same way. Pass `spec=` with your document, because Starlette has no `app.openapi()`.

## Flask

Flask has no OpenAPI generator of its own. Pass the document from the library you use (flask-smorest, apispec, flasgger) or a dict:

```python
from swastik_codes import init_flask

init_flask(app, spec=lambda: api.spec.to_dict(), config="swastik-codes.json")
```

## Django

Use the document from drf-spectacular (or any generator). Cache it so it is built once:

```python
# urls.py (root)
import functools
from drf_spectacular.generators import SchemaGenerator
from swastik_codes import django_urls

spec = functools.cache(lambda: SchemaGenerator().get_schema(request=None, public=True))
urlpatterns += django_urls(spec=spec, config="swastik-codes.json")
```

## Any ASGI or WSGI app

```python
from swastik_codes import SwastikCodesMiddleware, SwastikCodesWSGI

app = SwastikCodesMiddleware(app, spec=my_openapi_dict)        # ASGI: Litestar, Quart, ...
wsgi_app = SwastikCodesWSGI(wsgi_app, spec=my_openapi_dict)    # WSGI: Bottle, Pyramid, ...
```

`spec` is always a dict or a function that returns one. A function is called on
each page load, so it should be cheap or cached. The merge is only redone when it
returns a different object.

## Editing the pages: swastik-codes.json

```bash
python -m swastik_codes init      # writes a starter swastik-codes.json
```

Every field is optional. Your OpenAPI document provides the rest. The file is
re-read when it changes, so you can edit it and reload the page.

```json
{
  "title": "Flight OTA API",
  "version": "2.0",
  "description": "Markdown introduction.\n\n## Getting started\n\n1. Get a token.\n2. Send it as a bearer token.",
  "servers": [
    { "url": "https://sandbox.example.com", "description": "Sandbox" },
    { "url": "https://api.example.com", "description": "Production" }
  ],
  "theme": { "accent": "#0d9488", "mode": "system" },
  "tags": { "Search": { "name": "Flight search", "description": "Find flights." } },
  "groups": [
    { "name": "Start here", "tags": ["Authentication"] },
    { "name": "Flights", "tags": ["Search", "Bookings"] }
  ],
  "operations": {
    "GET /v2/bookings/{booking_id}": { "summary": "Read a held booking", "description": "Markdown." },
    "deleteCache": { "hidden": true }
  },
  "hide": ["/internal/*", "DELETE /admin/*"],
  "pages": [{ "title": "Errors", "body": "Markdown, tables included." }],
  "links": [{ "label": "Support", "url": "https://example.com/support" }],
  "languages": ["curl", "javascript", "python", "go", "php"]
}
```

| Field | Effect |
| --- | --- |
| `title`, `version`, `description` | Replace `info.*`. The description is Markdown. |
| `servers` | Base URLs readers pick from (the first is the default). Readers can also enter their own. |
| `theme` | Accent colour, and the default theme (`system`, `light` or `dark`). |
| `tags` | Display name and description per tag (each tag is a folder). |
| `groups` | Sections that hold tags, in order. |
| `operations` | Per request, keyed by `"METHOD /path"` or `operationId`: `summary`, `description`, `tags`, `deprecated`, `hidden`. |
| `hide` | Paths to leave out. `*` matches anything. Prefix with a method to hide only that method. |
| `pages` | Extra Markdown pages under Introduction. |
| `links` | Links on the introduction. |
| `languages` | Code sample languages and their order. |

The Swastik Codes logo, the "Built with Swastik Codes" credit and the **Run in
Swastik Codes** button are part of the pages. They have no setting. Keys such as
`logo` or `hideRunButton` are ignored with a warning.

## Notes

- **Sending requests.** The collection page sends requests from the browser.
  Requests to the same server always work. Requests to another server need that
  server to allow CORS for your docs origin, the same as Swagger UI.
- **Credentials.** Tokens you enter are kept in the tab's session storage. They
  are never sent anywhere except with your requests.
- **Security headers.** The pages are sent with a strict Content-Security-Policy:
  no inline scripts, and scripts and styles from this server only. Pass
  `csp=False` to turn it off.
- **Run in Swastik Codes** opens `https://swastik.codes/app?import=<your openapi.json>`.
  For an API on `localhost` it offers the file to download instead, because a
  website can't reach your computer.

## Licence

Proprietary, free to use. See [LICENSE.md](LICENSE.md). © Shwastik Tech Solutions Pvt Ltd.
