Open allComputableThings opened 2 months ago
In the following, the "something" property is added to the schema, for both classes (this is a mistake, I think).
from multiprocessing import freeze_support
import dataclasses
from sanic import Sanic, text, Request
from sanic_ext.extensions.openapi import openapi
from sanic_ext.extensions.openapi.definitions import Response, RequestBody
from sanic_ext.extensions.openapi.openapi import component
app = Sanic("app")
@component
@dataclasses.dataclass
class MyBody:
email: str
@property
def something(self) -> int:
print("Oh no you didn't!")
return "OK2"
@component
@dataclasses.dataclass
class UserProfile:
name: str
age: int
email: str
@property
def something(self) -> int:
print("Oh no you didn't!")
return "OK"
@app.route("/foo")
def foo(request):
url = app.url_for("handler", _external=True)
return text(f"URL: {url}")
@app.get("/")
@openapi.definition(
body=RequestBody({"application/json": {
"$ref": f"#/components/schemas/{MyBody.__name__}"
}}, required=True), # if body else None,
# body=RequestBody(Body, required=True),
summary="User profile update",
# tag="one",
# description=openapi.description(textwrap.dedent(func.__doc__)) if func.__doc__ else None,
response=[ # Success,
Response({
"application/json": {
"schema": {
"$ref": f"#/components/schemas/{UserProfile.__name__}"
}
}
}, status=200)
# Response(Failure, status=400)
],
)
def root(req: Request, *args, **kw): # body:UserProfile):
"""
Short description
Long Description
"""
return text("Hello")
if __name__ == '__main__':
freeze_support()
app.run(host='0.0.0.0', port=8000,
# access_log=True
)
...
# http://localhost:8000/docs/openapi.json
{"openapi":"3.0.3","info":{"title":"API","version":"1.0.0","contact":{}},"paths":{"/foo":{"get":{"operationId":"get~foo","summary":"Foo","responses":{"default":{"description":"OK"}}}},"/":{"get":{"operationId":"get~root","summary":"User profile update","description":"Long Description","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserProfile"}}},"description":"Default Response"}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MyBody"}}},"required":true}}}},"tags":[],"servers":[],"security":[],"components":{"schemas":{"MyBody":{"type":"object","properties":{"something":{"type":"integer","format":"int32"},"email":{"type":"string","title":"Email"}}},"UserProfile":{"type":"object","properties":{"something":{"type":"integer","format":"int32"},"name":{"type":"string","title":"Name"},"age":{"type":"integer","format":"int32","title":"Age"},"email":{"type":"string","title":"Email"}}}}}}
...
This is failing due to:
It similarly fails without recursion:
...
There's really no need for sanic to inspect property return types to discover model attributes. Dataclasses, Pydantic or type annotations on the class constructor all provide what is needed.