|
|
|
|
|
|
|
|
|
import os |
|
import tempfile |
|
from pathlib import Path |
|
|
|
import marimo |
|
import requests |
|
from fastapi import FastAPI, Request |
|
from fastapi.templating import Jinja2Templates |
|
|
|
GITHUB_REPO = os.environ.get("GITHUB_REPO", "marimo-team/marimo") |
|
ROOT_DIR = os.environ.get("GITHUB_ROOT_DIR", "examples/ui") |
|
|
|
|
|
def download_github_files(repo: str, path: str = "") -> list[tuple[str, str]]: |
|
"""Download files from GitHub repo, returns list of (file_path, content)""" |
|
api_url = f"https://api.github.com/repos/{repo}/contents/{path}" |
|
response = requests.get(api_url) |
|
response.raise_for_status() |
|
|
|
files: list[tuple[str, str]] = [] |
|
for item in response.json(): |
|
if item["type"] == "file" and item["name"].endswith(".py"): |
|
content_response = requests.get(item["download_url"]) |
|
files.append((Path(path) / item["name"], content_response.text)) |
|
elif item["type"] == "dir": |
|
files.extend(download_github_files(repo, str(Path(path) / item["name"]))) |
|
return files |
|
|
|
|
|
files = download_github_files(GITHUB_REPO, ROOT_DIR) |
|
|
|
server = marimo.create_asgi_app() |
|
tmp_dir = tempfile.TemporaryDirectory() |
|
app_names: list[str] = [] |
|
|
|
for file_path, content in files: |
|
app_name = Path(file_path).stem |
|
local_path = Path(tmp_dir.name) / file_path |
|
|
|
|
|
local_path.parent.mkdir(parents=True, exist_ok=True) |
|
|
|
|
|
local_path.write_text(content) |
|
|
|
|
|
print(f"Adding app: {app_name}") |
|
server = server.with_app(path=f"/{app_name}", root=str(local_path)) |
|
app_names.append(app_name) |
|
|
|
app = FastAPI() |
|
templates = Jinja2Templates(directory=Path(__file__).parent / "templates") |
|
|
|
|
|
@app.get("/") |
|
async def home(request: Request): |
|
return templates.TemplateResponse( |
|
"home.html", {"request": request, "app_names": app_names} |
|
) |
|
|
|
|
|
|
|
app.mount("/", server.build()) |
|
|
|
if __name__ == "__main__": |
|
import uvicorn |
|
|
|
uvicorn.run(app, host="0.0.0.0", port=7860, log_level="info") |
|
|