Skip to content

Commit

Permalink
🐛 Parse yaml schema from functions docstrings
Browse files Browse the repository at this point in the history
  • Loading branch information
perdy committed Jan 24, 2023
1 parent 7c34bc0 commit 6e122f8
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 101 deletions.
27 changes: 24 additions & 3 deletions flama/schemas/generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import typing as t
from collections import defaultdict

from starlette import schemas as starlette_schemas
import yaml

from flama import routing, schemas
from flama.schemas import Schema, openapi
Expand Down Expand Up @@ -225,7 +225,7 @@ def get_openapi_ref(
return openapi.Reference(ref=reference)


class SchemaGenerator(starlette_schemas.BaseSchemaGenerator):
class SchemaGenerator:
def __init__(
self,
title: str,
Expand Down Expand Up @@ -412,8 +412,29 @@ def _build_endpoint_default_response(self, metadata: typing.Dict[str, typing.Any
},
)

def _parse_docstring(self, func: typing.Callable) -> t.Dict[t.Any, t.Any]:
"""Given a function, parse the docstring as YAML and return a dictionary of info.
:param func: Function to analyze docstring.
:return: Schema extracted.
"""
try:
# It's possible to define a standard docstring along with the schema definition, for doing so the schema
# should start with a line with three dashes "---" as it's the usual notation for starting a yaml file.
schema = yaml.safe_load(func.__doc__.split("---")[-1]) # type: ignore[union-attr]
except AttributeError:
schema = None

if not isinstance(schema, dict):
raise ValueError

return schema

def get_operation_schema(self, endpoint: EndpointInfo) -> openapi.Operation:
docstring_info = self.parse_docstring(endpoint.func)
try:
docstring_info = self._parse_docstring(endpoint.func)
except ValueError:
docstring_info = {}

# Query and Path parameters
parameters = self._build_endpoint_parameters(endpoint, docstring_info)
Expand Down
Loading

0 comments on commit 6e122f8

Please sign in to comment.