diff --git a/examples/09_advanced/custom_endpoint/.dockerignore b/examples/09_advanced/custom_endpoint/.dockerignore new file mode 100644 index 00000000..6b7b5403 --- /dev/null +++ b/examples/09_advanced/custom_endpoint/.dockerignore @@ -0,0 +1,2 @@ +Dockerfile +README.md diff --git a/examples/09_advanced/custom_endpoint/Dockerfile b/examples/09_advanced/custom_endpoint/Dockerfile new file mode 100644 index 00000000..1a8bb878 --- /dev/null +++ b/examples/09_advanced/custom_endpoint/Dockerfile @@ -0,0 +1,6 @@ +FROM kitware/trame:py3.9 + +COPY --chown=trame-user:trame-user . /deploy + +ENV TRAME_CLIENT_TYPE=vue3 +RUN /opt/trame/entrypoint.sh build diff --git a/examples/09_advanced/custom_endpoint/README.md b/examples/09_advanced/custom_endpoint/README.md new file mode 100644 index 00000000..06d7486e --- /dev/null +++ b/examples/09_advanced/custom_endpoint/README.md @@ -0,0 +1,22 @@ +# Trame app with custom endpoint + +This allow you to register special HTTP endpoint for your app. +While it works by default locally, when using docker bundling, you need to add special handling. + +## Run locally without docker + +```bash +python ./app.py +``` + +## Build the image + +```bash +docker build -t trame-app-api . +``` + +## Run the image on port 8080 + +```bash +docker run -it --rm -p 8080:80 trame-app-api +``` diff --git a/examples/09_advanced/custom_endpoint/app.py b/examples/09_advanced/custom_endpoint/app.py new file mode 100644 index 00000000..1b0482ba --- /dev/null +++ b/examples/09_advanced/custom_endpoint/app.py @@ -0,0 +1,65 @@ +from trame.app import get_server +from trame.ui.vuetify3 import SinglePageLayout +from trame.widgets import vuetify3 as v3, html +from trame.decorators import TrameApp, controller + +import time +from pathlib import Path +from aiohttp import web + + +@TrameApp() +class App: + def __init__(self, server=None): + self.server = get_server(server, client_type="vue3") + self.server.cli.add_argument("--session") + self._build_ui() + + # Use CLI to know when used inside docker + args, _ = self.server.cli.parse_known_args() + session = args.session + + # simple default state + self.state.response = {} + self.state.session = session + self.state.url = "/trame-endpoint" + + # Need to adjust URL when within docker + if session: + self.state.url = f"/api/{session}/trame-endpoint" + + @property + def state(self): + return self.server.state + + @controller.add("on_server_bind") + def _bind_routes(self, wslink_server): + wslink_server.app.add_routes( + [web.get("/trame-endpoint", self.on_trame_endpoint)] + ) + + def on_trame_endpoint(self, request): + return web.json_response({"url": self.state.url, "time": time.time()}) + + def _build_ui(self): + with SinglePageLayout(self.server) as layout: + with layout.toolbar: + v3.VSpacer() + v3.VBtn( + "Make request", + click="utils.get('fetch')(url).then(v => v.json()).then(v => (response = v))", + ) + with layout.content: + html.Div("URL: {{ url }}") + html.Div("Session: {{ session }}") + html.Div("Response") + html.Pre("{{ JSON.stringify(response, null, 2) }}") + + +def main(): + app = App() + app.server.start() + + +if __name__ == "__main__": + main() diff --git a/examples/09_advanced/custom_endpoint/setup/apps.yml b/examples/09_advanced/custom_endpoint/setup/apps.yml new file mode 100644 index 00000000..361310af --- /dev/null +++ b/examples/09_advanced/custom_endpoint/setup/apps.yml @@ -0,0 +1,13 @@ +trame: + cmd: + - python + - /deploy/app.py + - --host + - ${host} + - --port + - ${port} + - --authKey + - ${secret} + - --server + - --session + - ${id} \ No newline at end of file diff --git a/examples/09_advanced/custom_endpoint/setup/requirements.txt b/examples/09_advanced/custom_endpoint/setup/requirements.txt new file mode 100644 index 00000000..9bdf51a8 --- /dev/null +++ b/examples/09_advanced/custom_endpoint/setup/requirements.txt @@ -0,0 +1,2 @@ +trame +trame-vuetify