Adopt stoplight response schemas, example stoplight dark theme styles

This commit is contained in:
2025-09-14 02:49:55 +03:00
parent 24c7169883
commit 4a5ca2cca7
2 changed files with 77 additions and 18 deletions

View File

@@ -116,7 +116,7 @@ class TestResp:
@dataclass
class TestResp1(TestResp):
hehe = 'haha'
hehe: str = 'haha'
@dataclass
@@ -175,14 +175,54 @@ async def stoplight() -> BasicResponse:
<!-- Embed elements Elements via Web Component -->
<script src="https://unpkg.com/@stoplight/elements/web-components.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/@stoplight/elements/styles.min.css">
<style>.sl-elements {height: 100vh}</style>
<style>
.sl-elements {height: 100vh}
body {background-color: #1c1f26;}
/* :root :not(sl-code-highlight) */
:root {
/* Canvas */
--color-canvas-50: #0d1117;
--color-canvas-100: #1b2432;
--color-canvas-200: #2c3e55;
--color-canvas-300: #3e5a78;
--color-canvas: #1c1f26;
--color-canvas-tint:#252a34;
--color-canvas-pure:#0a0f16;
/* Text */
--color-text: #e9eef7;
--color-text-heading: #f5f7fb;
--color-text-paragraph: #d7deeb;
--color-text-muted: #9caec9;
--color-text-primary: #8cbff2;
--color-text-light: #cfd9ec;
}
.sl-overflow-y-auto {
color-scheme: dark; /* For scrollbar */
}
/* Синтаксис JSON в Examples */
pre code {
color: #e9eef7 !important; /* общий текст */
}
.token.property { color: #8cbff2 !important; } /* ключи (пастельный голубой) */
.token.string { color: #f2a6a6 !important; } /* строки (мягкий красно-розовый) */
.token.number { color: #a6d8f2 !important; } /* числа (светлый голубой) */
.token.boolean { color: #f7c97f !important; } /* true/false (пастельный жёлтый) */
.token.null { color: #cba6f7 !important; } /* null (сиреневый) */
.token.punctuation { color: #9caec9 !important; } /* скобки, запятые */
.token.operator { color: #9caec9 !important; }
</style>
</head>
<body>
<elements-api
apiDescriptionUrl="/openapi.json"
router="hash"
layout="sidebar"
layout="responsive"
/>
</body>

View File

@@ -70,11 +70,16 @@ class HTTPApp(ASGIApp):
contenttype_header = req.headers.get('Accept')
if contenttype_header is None:
return ct
ctypes = set(map(str.strip, contenttype_header.split(',')))
if (self.serialize_selector.default_content_type in ctypes
and self.serialize_selector.default_content_type is not None):
contenttype = self.serialize_selector.default_content_type
charset = None
else:
properties: dict[str, str]
contenttype, properties = parse_content_type(contenttype_header)
properties: dict[str, str]
contenttype, properties = parse_content_type(contenttype_header)
charset = properties.get('charset')
charset = properties.get('charset')
if charset is None:
# TODO: extract default charsets based on content type
@@ -467,7 +472,7 @@ class SlothApp(HTTPApp, WSApp, LifespanApp, MethodRoutersApp):
def decorator(fn: HandlerType):
path_substs = self.router.find_pattern_substs(path_pattern)
fork_with, fn_type_hints = self._integrate_func(fn, path_substs, ok_return_code=ok_return_code)
config, fork_with, fn_type_hints = self._integrate_func(fn, path_substs, ok_return_code=ok_return_code)
tmp_repo = self.inj_repo.fork(fork_with)
p = tmp_repo.create_pipeline(
(Send, BasicRequest),
@@ -496,18 +501,32 @@ class SlothApp(HTTPApp, WSApp, LifespanApp, MethodRoutersApp):
create_di_autodoc_handler(method, path_pattern, p, depgraph))
if self.openapi_app is not None:
responses = {}
if config.return_schema is not None:
for k, v in config.return_schema.code_map.items():
schema = self.schema_from_type(v.body)
self.openapi_app.register_component(v.body)
content = {}
for ctype in self.serialize_selector.serializers.keys():
content[ctype] = MediaType(schema=schema)
headers = None
if v.headers_provided:
pass
responses[k] = Response(
description=f'{v.body}',
content=content,
headers=headers
)
req_body = {}
req_schema = self.construct_req_body(p)
for ctype in self.serialize_selector.serializers.keys():
req_body[ctype] = MediaType(req_schema)
self.openapi_app.register_endpoint(
method,
path_pattern,
self.construct_req_params(p),
{
'200': Response('desc', content={'application/json': MediaType(schema=Schema(type='boolean'))})
},
request_body=OpenApiRequestBody(
{
'application/json': MediaType(self.construct_req_body(p))
}
)
responses,
request_body=OpenApiRequestBody(req_body)
)
self.register_endpoint_components(p)
@@ -645,10 +664,10 @@ class SlothApp(HTTPApp, WSApp, LifespanApp, MethodRoutersApp):
setattr(func, '__turbosloth_config__', config)
return fork_with, fn_type_hints
return config, fork_with, fn_type_hints
def add_injector(self, func: Callable):
fork_with, _ = self._integrate_func(func)
_, fork_with, _ = self._integrate_func(func)
self.inj_repo.add_conversion_points(fork_with)
def mark_injector(self):