Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 48 additions & 6 deletions chancy/plugins/api/__init__.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
__all__ = ("Api", "AuthBackend", "SimpleAuthBackend")
import json
import os
import secrets
from pathlib import Path
from functools import partial
from pathlib import Path
from typing import Type

import uvicorn
from starlette.applications import Starlette
from starlette.middleware import Middleware
from starlette.middleware.authentication import AuthenticationMiddleware
from starlette.middleware.cors import CORSMiddleware
from starlette.responses import Response
from starlette.staticfiles import StaticFiles

from chancy import Worker, Chancy
from chancy import Chancy, Worker
from chancy.plugin import Plugin
from chancy.plugins.api.auth import (
AuthBackend,
Expand Down Expand Up @@ -103,6 +105,7 @@ class Api(Plugin):
:param host: The host to listen on.
:param debug: Whether to run the server in debug mode.
:param allow_origins: A list of origins that are allowed to access the API.
:param path_prefix: Optional URL prefix when mounting under another ASGI app.
"""

def __init__(
Expand All @@ -114,6 +117,7 @@ def __init__(
allow_origins: list[str] | None = None,
secret_key: str | None = None,
authentication_backend: AuthBackend,
path_prefix: str | None = None,
):
super().__init__()
self.port = port
Expand All @@ -124,15 +128,22 @@ def __init__(
self.plugins: set[Type[ApiPlugin]] = {CoreApiPlugin}
self.authentication_backend = authentication_backend
self.secret_key = secret_key or secrets.token_urlsafe(32)
path_prefix = path_prefix or ""
path_prefix = path_prefix.strip("/")
self.path_prefix = f"/{path_prefix}" if path_prefix else ""
self._app: Starlette | None = None

@staticmethod
def get_identifier() -> str:
return "chancy.api"

async def run(self, worker: Worker, chancy: Chancy):
def build_starlette_app(self, worker: Worker, chancy: Chancy) -> Starlette:
"""
Start the web server.
Build (or return) the Starlette app that powers the API and dashboard.
"""
if self._app is not None:
return self._app

Comment on lines +140 to +146
for plug in chancy.plugins.values():
api_plugin = plug.api_plugin()
if api_plugin is None:
Expand Down Expand Up @@ -167,6 +178,7 @@ def _r(f):
),
],
)
app.state.path_prefix = self.path_prefix

web_plugins = []
# Look through all the enabled plugins for any that implement the
Expand All @@ -192,6 +204,19 @@ def _r(f):
name=route["name"],
)

async def prefix_config(request):

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems reasonable overall. We should probably pass the port through as well.

return Response(
f"window.__CHANCY_BASE_PATH__ = {json.dumps(self.path_prefix)};",
media_type="application/javascript",
)

app.add_route(
"/chancy-config.js",
prefix_config,
methods=["GET"],
name="chancy_config",
)

# Add the wildcard route to the end of the list so that it doesn't
# override any other routes and serves anything that should be handled
# by the UI SPA.
Expand All @@ -204,15 +229,32 @@ def _r(f):
name="ui",
)

self._app = app
return app

async def run(self, worker: Worker, chancy: Chancy):
"""
Start the web server.
"""
app = self.build_starlette_app(worker, chancy)
root_app: Starlette = app

if self.path_prefix:
root_app = Starlette()
root_app.mount(self.path_prefix, app)

server = uvicorn.Server(
config=uvicorn.Config(
app=app,
app=root_app,
host=self.host,
port=self.port,
log_level="error",
)
)

chancy.log.info(f"Dashboard running at http://{self.host}:{self.port}")
suffix = self.path_prefix or ""
chancy.log.info(
f"Dashboard running at http://{self.host}:{self.port}{suffix}"
)

await server.serve()
1 change: 1 addition & 0 deletions chancy/plugins/api/ui/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
</head>
<body>
<div id="root"></div>
<script src="./chancy-config.js"></script>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
Loading
Loading