We can add custom tags to generated OPS
This commit is contained in:
@@ -4,7 +4,7 @@ Utility to extract extra OAS description from docstring.
|
||||
|
||||
import re
|
||||
import textwrap
|
||||
from typing import Dict
|
||||
from typing import Dict, List
|
||||
|
||||
|
||||
class LinesIterator:
|
||||
@@ -47,11 +47,10 @@ def _i_extract_block(lines: LinesIterator):
|
||||
except StopIteration:
|
||||
return
|
||||
|
||||
# Get the size of the indentation.
|
||||
if (match := re.search("^ +", line)) is None:
|
||||
return # No block to extract.
|
||||
indent = match.group()
|
||||
yield line[len(indent) :]
|
||||
indent = re.fullmatch("( *).*", line).groups()[0]
|
||||
indentation = len(indent)
|
||||
start_of_other_block = re.compile(f" {{0,{indentation}}}[^ ].*")
|
||||
yield line[indentation:]
|
||||
|
||||
# Yield lines until the indentation is the same or is greater than
|
||||
# the first block line.
|
||||
@@ -59,8 +58,8 @@ def _i_extract_block(lines: LinesIterator):
|
||||
line = next(lines)
|
||||
except StopIteration:
|
||||
return
|
||||
while (is_empty := line.strip() == "") or line.startswith(indent):
|
||||
yield "" if is_empty else line[len(indent) :]
|
||||
while not start_of_other_block.fullmatch(line):
|
||||
yield line[indentation:]
|
||||
try:
|
||||
line = next(lines)
|
||||
except StopIteration:
|
||||
@@ -87,10 +86,13 @@ def status_code(docstring: str) -> Dict[int, str]:
|
||||
iterator = LinesIterator(docstring)
|
||||
for line in iterator:
|
||||
if re.fullmatch("status\\s+codes?\\s*:", line, re.IGNORECASE):
|
||||
iterator.rewind()
|
||||
blocks = []
|
||||
lines = []
|
||||
for line_of_block in _i_extract_block(iterator):
|
||||
if re.search("^\\d{3}\\s*:", line_of_block):
|
||||
i_block = _i_extract_block(iterator)
|
||||
next(i_block)
|
||||
for line_of_block in i_block:
|
||||
if re.search("^\\s*\\d{3}\\s*:", line_of_block):
|
||||
if lines:
|
||||
blocks.append("\n".join(lines))
|
||||
lines = []
|
||||
@@ -105,6 +107,19 @@ def status_code(docstring: str) -> Dict[int, str]:
|
||||
return {}
|
||||
|
||||
|
||||
def tags(docstring: str) -> List[str]:
|
||||
"""
|
||||
Extract the "Tags:" block of the docstring.
|
||||
"""
|
||||
iterator = LinesIterator(docstring)
|
||||
for line in iterator:
|
||||
if re.fullmatch("tags\\s*:.*", line, re.IGNORECASE):
|
||||
iterator.rewind()
|
||||
lines = " ".join(_i_extract_block(iterator))
|
||||
return [" ".join(e.split()) for e in re.split("[,;]", lines.split(":")[1])]
|
||||
return []
|
||||
|
||||
|
||||
def operation(docstring: str) -> str:
|
||||
"""
|
||||
Extract all docstring except the "Status Code:" block.
|
||||
@@ -112,7 +127,8 @@ def operation(docstring: str) -> str:
|
||||
lines = LinesIterator(docstring)
|
||||
ret = []
|
||||
for line in lines:
|
||||
if re.fullmatch("status\\s+codes?\\s*:", line, re.IGNORECASE):
|
||||
if re.fullmatch("status\\s+codes?\\s*:|tags\\s*:.*", line, re.IGNORECASE):
|
||||
lines.rewind()
|
||||
for _ in _i_extract_block(lines):
|
||||
pass
|
||||
else:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
Utility to write Open Api Specifications using the Python language.
|
||||
"""
|
||||
|
||||
from typing import Union
|
||||
from typing import Union, List
|
||||
|
||||
|
||||
class Info:
|
||||
@@ -157,7 +157,7 @@ class Responses:
|
||||
self._spec = spec.setdefault("responses", {})
|
||||
|
||||
def __getitem__(self, status_code: Union[int, str]) -> Response:
|
||||
if not (100 <= int(status_code) < 600):
|
||||
if not 100 <= int(status_code) < 600:
|
||||
raise ValueError("status_code must be between 100 and 599")
|
||||
|
||||
spec = self._spec.setdefault(str(status_code), {})
|
||||
@@ -196,6 +196,17 @@ class OperationObject:
|
||||
def responses(self) -> Responses:
|
||||
return Responses(self._spec)
|
||||
|
||||
@property
|
||||
def tags(self) -> List[str]:
|
||||
return self._spec.get("tags", [])[:]
|
||||
|
||||
@tags.setter
|
||||
def tags(self, tags: List[str]):
|
||||
if tags:
|
||||
self._spec["tags"] = tags[:]
|
||||
else:
|
||||
self._spec.pop("tags", None)
|
||||
|
||||
|
||||
class PathItem:
|
||||
def __init__(self, spec: dict):
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import typing
|
||||
from inspect import getdoc
|
||||
from itertools import count
|
||||
from typing import List, Type, Optional, Dict
|
||||
from typing import List, Type, Optional
|
||||
|
||||
from aiohttp.web import Response, json_response
|
||||
from aiohttp.web_app import Application
|
||||
@@ -86,6 +86,7 @@ def _add_http_method_to_oas(
|
||||
description = getdoc(handler)
|
||||
if description:
|
||||
oas_operation.description = docstring_parser.operation(description)
|
||||
oas_operation.tags = docstring_parser.tags(description)
|
||||
status_code_descriptions = docstring_parser.status_code(description)
|
||||
else:
|
||||
status_code_descriptions = {}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from functools import update_wrapper
|
||||
from inspect import iscoroutinefunction
|
||||
from typing import Any, Callable, Generator, Iterable, Set, ClassVar, Literal
|
||||
from typing import Any, Callable, Generator, Iterable, Set, ClassVar
|
||||
import warnings
|
||||
|
||||
from aiohttp.abc import AbstractView
|
||||
|
||||
Reference in New Issue
Block a user