1
Fork 0
mirror of https://github.com/RYGhub/royalnet.git synced 2024-11-23 19:44:20 +00:00
This commit is contained in:
Steffo 2020-03-09 00:43:42 +01:00
parent c95bd59c96
commit 7bb3db0145
8 changed files with 87 additions and 57 deletions

View file

@ -5,7 +5,7 @@
[tool.poetry] [tool.poetry]
name = "royalnet" name = "royalnet"
version = "5.5" version = "5.6"
description = "A multipurpose bot and web framework" description = "A multipurpose bot and web framework"
authors = ["Stefano Pigozzi <ste.pigozzi@gmail.com>"] authors = ["Stefano Pigozzi <ste.pigozzi@gmail.com>"]
license = "AGPL-3.0+" license = "AGPL-3.0+"

View file

@ -4,6 +4,8 @@ from .api_login_royalnet import ApiLoginRoyalnetStar
from .api_token_info import ApiTokenInfoStar from .api_token_info import ApiTokenInfoStar
from .api_token_passwd import ApiTokenPasswdStar from .api_token_passwd import ApiTokenPasswdStar
from .api_token_create import ApiTokenCreateStar from .api_token_create import ApiTokenCreateStar
from .api_docs import ApiDocsStar
from .docs import DocsStar
# Enter the PageStars of your Pack here! # Enter the PageStars of your Pack here!
available_page_stars = [ available_page_stars = [
@ -12,6 +14,8 @@ available_page_stars = [
ApiTokenInfoStar, ApiTokenInfoStar,
ApiTokenPasswdStar, ApiTokenPasswdStar,
ApiTokenCreateStar, ApiTokenCreateStar,
ApiDocsStar,
DocsStar,
] ]
# Don't change this, it should automatically generate __all__ # Don't change this, it should automatically generate __all__

View file

@ -0,0 +1,10 @@
import royalnet.utils as ru
from royalnet.constellation.api import *
from royalnet.version import semantic
class ApiDocsStar(ApiStar):
path = "/api/docs"
async def api(self, data: ApiData) -> ru.JSON:
return

View file

@ -0,0 +1,45 @@
import json
from typing import *
from royalnet.constellation import PageStar
from royalnet.constellation.api import ApiStar
from starlette.requests import Request
from starlette.responses import Response, HTMLResponse
from royalnet.version import semantic
class DocsStar(PageStar):
path = "/docs"
async def page(self, request: Request) -> Response:
spec = json.dumps({
"swagger": "2.0",
"info": {
"description": "Autogenerated Royalnet API documentation",
"title": "Royalnet",
"version": f"{semantic}",
"paths": [star.swagger() for star in self.constellation.stars if isinstance(star, ApiStar)]
}
})
return HTMLResponse(
f"""
<html lang="en">
<head>
<title>Royalnet Docs</title>
<script src="https://unpkg.com/swagger-ui-dist@3/swagger-ui-bundle.js"></script>
</head>
<body>
<div id="docs"/>
<script>
const ui = SwaggerUIBundle({{
spec: {spec}
dom_id: '#docs',
presets: [
SwaggerUIBundle.presets.apis,
],
}})
</script>
</body>
</html>
"""
)

View file

@ -48,37 +48,27 @@ class ApiStar(PageStar, ABC):
raise NotImplementedError() raise NotImplementedError()
@classmethod @classmethod
def swagger(cls) -> str: def swagger(cls) -> ru.JSON:
"""Generate one or more swagger paths for this ApiStar.""" """Generate one or more swagger paths for this ApiStar."""
string = [f'{cls.path}:\n'] result = {}
for method in cls.methods: for method in cls.methods:
string.append( result[method.lower()] = {
f' {method.lower()}:\n' "summary": cls.summary,
f' summary: "{cls.summary}"\n' "description": cls.description,
f' description: "{cls.description}"\n' "produces": ["application/json"],
f' produces:\n' "responses": {
f' - "application/json"\n' "200": {"description": "Success"},
f' responses:\n' "400": {"description": "Bad request"},
f' 200:\n' "403": {"description": "Forbidden"},
f' description: "Success"\n' "404": {"description": "Not found"},
f' 400:\n' "500": {"description": "Serverside unhandled exception"},
f' description: "Bad request"\n' "501": {"description": "Not yet implemented"}
f' 403:\n' },
f' description: "Forbidden"\n' "paameters": [{
f' 404:\n' "name": parameter,
f' description: "Not found"\n' "in": "query",
f' 500:\n' "description": cls.parameters[parameter],
f' description: "Serverside unhandled exception"\n' "type": "string"
f' 501:\n' } for parameter in cls.parameters]
f' description: "Not yet implemented"\n' }
) return result
if len(cls.parameters) > 0:
string.append(f' parameters:\n')
for parameter in cls.parameters:
string.append(
f' - name: "{parameter}"\n'
f' in: "query"\n'
f' description: "{cls.parameters[parameter]}"\n'
f' type: "string"\n'
)
return "".join(string).rstrip("\n")

View file

@ -99,6 +99,9 @@ class Constellation:
self.starlette = starlette.applications.Starlette(debug=__debug__) self.starlette = starlette.applications.Starlette(debug=__debug__)
"""The :class:`~starlette.Starlette` app.""" """The :class:`~starlette.Starlette` app."""
self.stars: List[PageStar] = []
"""A list of all the :class:`PageStar` registered to this :class:`Constellation`."""
# Register Events # Register Events
for pack_name in packs: for pack_name in packs:
pack = packs[pack_name] pack = packs[pack_name]
@ -268,6 +271,7 @@ class Constellation:
f"{SelectedPageStar.__qualname__} - {e.__class__.__qualname__} in the initialization.") f"{SelectedPageStar.__qualname__} - {e.__class__.__qualname__} in the initialization.")
ru.sentry_exc(e) ru.sentry_exc(e)
continue continue
self.stars.append(page_star_instance)
self.starlette.add_route(*self._page_star_wrapper(page_star_instance)) self.starlette.add_route(*self._page_star_wrapper(page_star_instance))
def run_blocking(self): def run_blocking(self):

View file

@ -47,29 +47,6 @@ def run(config_filename, file_format):
for line in lines: for line in lines:
p(line) p(line)
elif file_format == "swagger":
p(
f'swagger: "2.0"\n'
f'info:\n'
f' description: "This is autogenerated Royalnet API documentation."\n'
f' title: "Royalnet"\n'
f' version: "{semantic}"\n'
f'paths:'
)
for pack_name in packs:
pack = packs[pack_name]
try:
page_stars = pack["stars"].available_page_stars
except AttributeError:
p(f"Pack `{pack}` does not have the `available_page_stars` attribute.", err=True)
continue
for page_star in page_stars:
try:
p(f' {page_star.swagger()}')
except AttributeError:
pass
else: else:
raise click.ClickException("Unknown format") raise click.ClickException("Unknown format")

View file

@ -1 +1 @@
semantic = "5.5" semantic = "5.6"