-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
05c2361
commit 3090439
Showing
80 changed files
with
16,588 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
include LICENSE | ||
include README.md | ||
recursive-include openapidocs *.html *.md | ||
|
||
# Stubs | ||
include openapidocs/py.typed |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,32 +1,105 @@ | ||
![Build](https://github.com/Neoteroi/essentials-openapi/workflows/Build/badge.svg) | ||
[![pypi](https://img.shields.io/pypi/v/essentials-openapi.svg)](https://pypi.python.org/pypi/essentials-openapi) | ||
[![versions](https://img.shields.io/pypi/pyversions/essentials-openapi.svg)](https://github.com/neoteroi/essentials-openapi) | ||
[![license](https://img.shields.io/github/license/neoteroi/essentials-openapi.svg)](https://github.com/neoteroi/essentials-openapi/blob/master/LICENSE) | ||
[![license](https://img.shields.io/github/license/neoteroi/essentials-openapi.svg)](https://github.com/neoteroi/essentials-openapi/blob/main/LICENSE) | ||
[![codecov](https://codecov.io/gh/Neoteroi/essentials-openapi/branch/main/graph/badge.svg?token=WEZ8YECJDF)](https://codecov.io/gh/Neoteroi/essentials-openapi) | ||
|
||
# essentials-openapi | ||
|
||
Classes to generate OpenAPI Documentation v3 and v2, in JSON and YAML. | ||
Classes to generate [OpenAPI Documentation](https://swagger.io/specification/) | ||
v3 and v2, in JSON and YAML, and to generate other kinds of documents from | ||
OpenAPI Documentation files. | ||
|
||
```bash | ||
pip install essentials-openapi | ||
``` | ||
|
||
To install with dependencies to generate other kinds of artifacts from source | ||
OpenAPI Documentation files: | ||
|
||
```bash | ||
pip install essentials-openapi[full] | ||
``` | ||
|
||
## Useful links | ||
|
||
* https://swagger.io/specification/ | ||
* https://editor.swagger.io | ||
|
||
## Usage | ||
This library has been created to implement generation of OpenAPI Documentation | ||
This library has been originally created to implement generation of OpenAPI Documentation | ||
in the [`BlackSheep` web framework](https://github.com/RobertoPrevato/BlackSheep). | ||
This package contains only parts that belong logically to the OpenAPI specification, | ||
and can be reused for other applications. | ||
However, this package is abstracted from that web framework and can be reused for other | ||
applications. Today this library also offers functions to generate documentation from | ||
source OpenAPI Documentation files. | ||
|
||
## Features to generate artifacts from Open API Documentation | ||
|
||
These require the full package: install it using `pip install essentials-openapi[full]`. | ||
|
||
To generate output for [MkDocs](https://www.mkdocs.org) and [PyMdown extentions](https://facelessuser.github.io/pymdown-extensions/): | ||
|
||
```bash | ||
oad gen-docs -s example1-openapi.json -d output.md | ||
``` | ||
|
||
![Example MkDocs documentation](./docs/example-1.png) | ||
|
||
_Example of MkDocs documentation generated using [Neoteroi/mkdocs-plugins](https://github.com/Neoteroi/mkdocs-plugins)._ | ||
|
||
--- | ||
|
||
To generate a [PlantUML](https://plantuml.com) [class | ||
diagram](https://plantuml.com/class-diagram) of the components schemas: | ||
|
||
```bash | ||
oad gen-docs -s source-openapi.json -d schemas.wsd --style "PLANTUML_SCHEMAS" | ||
``` | ||
|
||
![Example schemas](./docs/example-schemas.png) | ||
|
||
_Example of PlantUML diagram generated from components schemas._ | ||
|
||
### Goals | ||
|
||
* Provide an API to generate OpenAPI Documentation files. | ||
* Providing functions to handle OpenAPI Documentation, like those to generate | ||
other kinds of documentation from source OpenAPI Documentation files. | ||
* Support enough features to be useful for the most common API scenarios, | ||
especially for OAD files that are generated automatically from web frameworks. | ||
|
||
### Non-Goals | ||
|
||
* To implement the whole OAD Specification. | ||
* For the features that generate artifacts: OpenAPI Documentation files are | ||
**supposed to be coming from trusted sources**. Trying to handle source files | ||
from untrusted sources and potentially causing HTML injection is out of the | ||
scope of this library. | ||
|
||
## Limitations | ||
|
||
* Partial support for Parameter properties: `style` , `allow_reserved` , | ||
`explode` are not handled | ||
* Doesn't implement validation of values, currently it is only concerned in | ||
generating code from a higher level API (it might be extended in the future | ||
with classes for validation) | ||
* Partial support for Parameter properties: `style`, `allow_reserved`, `explode` are not | ||
handled. | ||
* Doesn't implement validation of values, currently it is only concerned in generating | ||
code from a higher level API (it might be extended in the future with classes for | ||
validation). | ||
* The features to generate artifacts from OpenAPI Documentation currently support only | ||
Version 3 of the specification. | ||
|
||
### Styles | ||
|
||
| Style | Int value | Description | | ||
| ---------------- | --------- | -------------------------------------------- | | ||
| MKDOCS | 1 | Markdown for MkDocs and PyMdown extensions. | | ||
| MARKDOWN | 2 | Basic Markdown. | | ||
| HTML | 3 | Plain HTML _(planned, not yet implemented)_. | | ||
| PLANTUML_SCHEMAS | 100 | PlantUML schema for components schemas. | | ||
|
||
### Supported sources for OpenAPI Documentation | ||
|
||
| Source | Example | | ||
| ------------------------------ | ---------------------------------------------------- | | ||
| YAML file | `./docs/swagger.yaml` | | ||
| JSON file | `./docs/swagger.json` | | ||
| URL returning YAML on HTTP GET | `https://example-domain.net/swagger/v1/swagger.yaml` | | ||
| URL returning JSON on HTTP GET | `https://example-domain.net/swagger/v1/swagger.json` | |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
VERSION = "1.0.0" |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
from typing import Union | ||
|
||
import click | ||
|
||
from openapidocs.logs import logger | ||
from openapidocs.mk.generate import generate_document | ||
from openapidocs.mk.jinja import OutputStyle | ||
|
||
|
||
@click.command(name="gen-docs") | ||
@click.option( | ||
"-s", | ||
"--source", | ||
help=( | ||
"Source of the OpenAPI Documentation file. " | ||
"This can be either a public URL or a path to a file." | ||
), | ||
required=True, | ||
) | ||
@click.option( | ||
"-d", | ||
"--destination", | ||
help="Destination file path.", | ||
required=True, | ||
) | ||
@click.option( | ||
"-t", | ||
"--style", | ||
help="The style of the output.", | ||
required=False, | ||
default="MKDOCS", | ||
show_default=True, | ||
) | ||
def generate_documents_command(source: str, destination: str, style: Union[int, str]): | ||
""" | ||
Generates other kinds of documents from source OpenAPI Documentation files. | ||
For example, to generate Markdown for MkDocs and PyMdown: | ||
$ openapidocs gen-docs -s source-openapi.json -d output.md | ||
JSON and YAML sources are supported. | ||
It is also possible to fetch the specification file from a public URL: | ||
$ openapidocs gen-docs -s https://.../source-openapi.json -d output.md | ||
For more information, refer to the documentation at | ||
https://github.com/Neoteroi/essentials-openapi | ||
""" | ||
try: | ||
generate_document(source, destination, style) | ||
except KeyboardInterrupt: # pragma: nocover | ||
logger.info("User interrupted") | ||
exit(1) | ||
except ValueError as value_error: | ||
logger.error(value_error) | ||
exit(2) | ||
|
||
|
||
@click.command(name="list-styles") | ||
def list_styles_command(): | ||
""" | ||
Displays the supported output styles on the screen. | ||
""" | ||
try: | ||
for value in OutputStyle: | ||
logger.info("%s: %s", value.name, value.value) | ||
except KeyboardInterrupt: # pragma: nocover | ||
logger.info("User interrupted") | ||
exit(1) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import logging | ||
import logging.handlers | ||
|
||
from rich.logging import RichHandler | ||
|
||
logger = logging.getLogger("openapidocs") | ||
logger.setLevel(logging.INFO) | ||
logger.addHandler(RichHandler()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import logging | ||
import sys | ||
|
||
import click | ||
|
||
from openapidocs import VERSION | ||
from openapidocs.commands.docs import generate_documents_command, list_styles_command | ||
from openapidocs.logs import logger | ||
|
||
sys.path.append(".") | ||
|
||
|
||
@click.group() | ||
@click.option( | ||
"--verbose", default=False, help="Whether to display debug output.", is_flag=True | ||
) | ||
@click.version_option(version=VERSION) | ||
def main(verbose: bool): | ||
""" | ||
Essentials OpenAPI CLI. | ||
https://github.com/Neoteroi/essentials-openapi | ||
""" | ||
if verbose: # pragma: nocover | ||
logger.setLevel(logging.DEBUG) | ||
|
||
logger.debug("Running in --verbose mode") | ||
|
||
|
||
main.add_command(generate_documents_command) | ||
main.add_command(list_styles_command) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
""" | ||
This module provides common functions to generate other kinds of representations from | ||
source OpenAPI Documentation files. | ||
""" | ||
import re | ||
from http import HTTPStatus | ||
|
||
import markupsafe | ||
|
||
|
||
def get_http_status_phrase(status_code) -> str: | ||
try: | ||
http_status = HTTPStatus(int(status_code)) | ||
return http_status.phrase | ||
except ValueError: | ||
return "" | ||
|
||
|
||
def read_dict(obj, *args, default=None): | ||
""" | ||
Reads properties in a source dictionary, returning None if any | ||
Example: | ||
read_dict({"a": {"b": {"c": True}}}, "a", "b", "c") --> True | ||
""" | ||
assert isinstance(obj, dict) | ||
|
||
value = obj | ||
for part in args: | ||
for key in part.split(): | ||
if not isinstance(value, dict): | ||
raise ValueError(f"Invalid sub-path: {repr(args)}") | ||
|
||
value = value.get(key) | ||
|
||
if value is None: | ||
return default | ||
|
||
if value is None or value is obj: | ||
return default | ||
|
||
return value | ||
|
||
|
||
def sort_dict(obj): | ||
""" | ||
Yields (key, value) of a dictionary with keys in alphabetical order. | ||
""" | ||
for key in sorted(obj, key=str.lower): | ||
yield key, obj[key] | ||
|
||
|
||
def highlight_params(path: str) -> str: | ||
def replacer(match): | ||
value = match.group() | ||
return f'<span class="route-param">{markupsafe.escape(value)}</span>' | ||
|
||
return re.sub(r"\{[^\}]+\}", replacer, path) |
Oops, something went wrong.