-
-
Notifications
You must be signed in to change notification settings - Fork 79
/
Copy pathfalcon_asgi_demo.py
119 lines (92 loc) · 2.56 KB
/
falcon_asgi_demo.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import logging
from random import random
import falcon.asgi
import uvicorn
from pydantic import BaseModel, Field
from examples.common import File, FileResp, Query
from spectree import ExternalDocs, Response, SpecTree, Tag
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger()
spec = SpecTree(
"falcon-asgi",
title="Demo Service",
version="0.1.2",
annotations=True,
)
demo = Tag(
name="demo", description="😊", externalDocs=ExternalDocs(url="https://github.com")
)
class Resp(BaseModel):
label: int = Field(
...,
ge=0,
le=9,
)
score: float = Field(
...,
gt=0,
lt=1,
)
class BadLuck(BaseModel):
loc: str
msg: str
typ: str
class Data(BaseModel):
uid: str
limit: int
vip: bool
class Ping:
def check(self):
pass
@spec.validate(tags=[demo])
async def on_get(self, req, resp):
"""
health check
"""
self.check()
logger.debug("ping <> pong")
resp.media = {"msg": "pong"}
class Classification:
"""
classification demo
"""
@spec.validate(tags=[demo])
async def on_get(self, req, resp, source, target):
"""
API summary
description here: test information with `source` and `target`
"""
resp.media = {"msg": f"hello from {source} to {target}"}
@spec.validate(resp=Response(HTTP_200=Resp, HTTP_403=BadLuck))
async def on_post(self, req, resp, source, target, query: Query, json: Data):
"""
post demo
demo for `query`, `data`, `resp`
"""
logger.debug("%s => %s", source, target)
logger.info(query)
logger.info(json)
if random() < 0.5:
resp.status = falcon.HTTP_403
resp.media = {"loc": "unknown", "msg": "bad luck", "typ": "random"}
return
resp.media = {"label": int(10 * random()), "score": random()}
class FileUpload:
"""
file-handling demo
"""
@spec.validate(resp=Response(HTTP_200=FileResp), tags=["file-upload"])
async def on_post(self, req, resp, form: File):
"""
post multipart/form-data demo
demo for 'form'
"""
file = req.context.form.file
resp.media = {"filename": file.filename, "type": file.type}
if __name__ == "__main__":
app = falcon.asgi.App()
app.add_route("/ping", Ping())
app.add_route("/api/{source}/{target}", Classification())
app.add_route("/api/file_upload", FileUpload())
spec.register(app)
uvicorn.run(app, log_level="info")