Skip to content

Commit

Permalink
Merge pull request #8 from Fatal1ty/mashumaro-plugins
Browse files Browse the repository at this point in the history
Add ability to use mashumaro plugins
  • Loading branch information
Fatal1ty authored Nov 25, 2024
2 parents c8d968c + ac4564a commit 610f169
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 9 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
Expand Down
36 changes: 32 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1089,10 +1089,10 @@ following openapify dataclasses defined in `openapify.core.models`:
* `QueryParam`

Out of the box, the schema is generated by using
[`mashumaro`](https://github.com/Fatal1ty/mashumaro) library, but support
for third-party entity schema generators can be achieved through
`schema_helper` method. For example, here's what a plugin for pydantic models
might look like:
[`mashumaro`](https://github.com/Fatal1ty/mashumaro) library (see the note
below), but support for third-party entity schema generators can be achieved
through `schema_helper` method. For example, here's what a plugin for pydantic
models might look like:

```python
from typing import Any
Expand All @@ -1116,6 +1116,34 @@ class PydanticSchemaPlugin(BasePlugin):
return schema
```

> [!NOTE]\
> The [`BaseSchemaPlugin`](https://github.com/Fatal1ty/openapify/blob/master/openapify/core/base_plugins.py#L41-L64),
> which is enabled by default and has the lowest priority, is responsible for
> generating the schema. This plugin utilizes the mashumaro library for schema
> generation, which in turn incorporates its own [plugin system](https://github.com/Fatal1ty/mashumaro?tab=readme-ov-file#json-schema-plugins),
> enabling customization of JSON Schema generation and support for additional
> data types. For more nuanced modifications, particularly within nested data
> models, you can employ `BaseSchemaPlugin` with a specified list of mashumaro JSON
> Schema plugins. This approach allows for finer control over schema generation
> when needed:
> ```python
> from mashumaro.jsonschema.plugins import DocstringDescriptionPlugin
>
> from openapify import build_spec
> from openapify.core.base_plugins import BaseSchemaPlugin
>
> spec = build_spec(
> routes=[...],
> plugins=[
> BaseSchemaPlugin(
> plugins=[
> DocstringDescriptionPlugin(),
> ]
> ),
> ],
> )
> ```

### media_type_helper

A media type is used in OpenAPI Request
Expand Down
9 changes: 8 additions & 1 deletion openapify/core/base_plugins.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from collections.abc import Sequence
from typing import Any, Dict, Optional, Union

from mashumaro.jsonschema import OPEN_API_3_1, JSONSchemaBuilder
from mashumaro.jsonschema.plugins import BasePlugin as BaseJSONSchemaPlugin

from openapify.core.models import Body, Cookie, Header, QueryParam
from openapify.core.utils import get_value_type
Expand Down Expand Up @@ -37,13 +39,18 @@ def media_type_helper(


class BaseSchemaPlugin(BasePlugin):
def __init__(self, plugins: Sequence[BaseJSONSchemaPlugin] = ()):
self.json_schema_plugins = plugins

def schema_helper(
self,
obj: Union[Body, Cookie, Header, QueryParam],
name: Optional[str] = None,
) -> Optional[Dict[str, Any]]:
builder = JSONSchemaBuilder(
dialect=OPEN_API_3_1, ref_prefix="#/components/schemas"
dialect=OPEN_API_3_1,
ref_prefix="#/components/schemas",
plugins=self.json_schema_plugins,
)
try:
json_schema = builder.build(obj.value_type)
Expand Down
8 changes: 7 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ ignore_missing_imports = true
disallow_untyped_defs = true
disallow_incomplete_defs = true

[[tool.mypy.overrides]]
module = [
'openapify.core.openapi.models',
]
disable_error_code = 'override'

[flake8]
max-line-length = 79

Expand All @@ -15,4 +21,4 @@ ensure_newline_before_comments = true

[tool.black]
line-length = 79
target-version = ['py37', 'py38', 'py39', 'py310', 'py311']
target-version = ['py39', 'py310', 'py311', 'py312']
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@
"License :: OSI Approved :: Apache Software License",
"Intended Audience :: Developers",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Development Status :: 3 - Alpha",
],
license="Apache License, Version 2.0",
Expand All @@ -31,7 +31,7 @@
python_requires=">=3.8",
install_requires=[
"apispec",
"mashumaro>=3.7",
"mashumaro>=3.15",
],
extras_require={
"aiohttp": ["aiohttp"],
Expand Down

0 comments on commit 610f169

Please sign in to comment.