### Install Dependencies and Run Source: https://github.com/answerdotai/fasthtml-example/blob/main/e_commerce/README.md Commands to install project dependencies and run the FastHTML application. ```bash pip install -r requirements.txt python main.py ``` -------------------------------- ### Install requirements Source: https://github.com/answerdotai/fasthtml-example/blob/main/code_editor/README.md Install the requirements using pip. ```bash pip install -r requirements.txt ``` -------------------------------- ### Install Dependencies Source: https://github.com/answerdotai/fasthtml-example/blob/main/chess_app/chess_app.ipynb Installs the necessary chess and stockfish libraries using uv pip. ```shell ! uv pip install chess stockfish ``` -------------------------------- ### Start the server Source: https://github.com/answerdotai/fasthtml-example/blob/main/cli_oauth_example/README.md This command starts the server component that handles OAuth redirects and token management. ```bash python server.py ``` -------------------------------- ### App Setup and Database Integration (manual setup) Source: https://github.com/answerdotai/fasthtml-example/blob/main/01_todo_app/README.md Manually sets up the app and database connection using the standard FastHTML class and database function from fastlite. ```python app = FastHTML(hdrs=[Style(':root { --pico-font-size: 100%; }')]) rt = app.route db = database('todos.db') if 'Todo' not in db.t: db.t['Todo'].create(id=int, title=str, done=bool, pk='id') Todo = db.t['Todo'].dataclass() ``` -------------------------------- ### Run Server Source: https://github.com/answerdotai/fasthtml-example/blob/main/chess_app/README.md Starts the Python web server for the chess application. ```bash python chess_app.py ``` -------------------------------- ### Run the server Source: https://github.com/answerdotai/fasthtml-example/blob/main/code_editor/README.md Run the server to start the code editor. ```bash python code_editor.py ``` -------------------------------- ### Run Application Source: https://github.com/answerdotai/fasthtml-example/blob/main/xtermjs/README.md Starts the FastHTML web application. ```bash python main.py ``` -------------------------------- ### FastHTML App Setup Source: https://github.com/answerdotai/fasthtml-example/blob/main/chess_app/chess_app.ipynb Initializes the FastHTML app, including necessary CSS and JavaScript for the chess board and websockets. ```python #| export from fasthtml.common import * from fastcore.utils import * from fastcore.xml import to_xml from starlette.endpoints import WebSocketEndpoint from starlette.routing import WebSocketRoute import chess import chess.svg cboard = chess.Board() # move e2e4 cboard.push_san('e4') cboard.push_san('e5') css = Style( '''\ #chess-board { display: grid; grid-template-columns: repeat(8, 64px); grid-template-rows: repeat(8, 64px);gap: 1px; } .board-cell { width: 64px; height: 64px; border: 1px solid black; } .black { background-color: grey; } .white { background-color: white; } .active { background-color: green; } ''' ) # Flexbox CSS (http://flexboxgrid.com/) gridlink = Link(rel="stylesheet", href="https://cdnjs.cloudflare.com/ajax/libs/flexboxgrid/6.3.1/flexboxgrid.min.css", type="text/css") htmx_ws = Script(src="https://unpkg.com/htmx-ext-ws@2.0.0/ws.js") app = FastHTML(hdrs=(gridlink, css, htmx_ws,)) rt = app.route ``` -------------------------------- ### App Setup and Database Integration (using fast_app) Source: https://github.com/answerdotai/fasthtml-example/blob/main/01_todo_app/README.md Sets up the app, routing, database connection, and Todo data model using the fast_app function. ```python app,rt,todos,Todo = fast_app( 'data/todos.db', hdrs=[Style(':root { --pico-font-size: 100%; }')], id=int, title=str, done=bool, pk='id') ``` -------------------------------- ### Environment Variables and Running minimal.py Source: https://github.com/answerdotai/fasthtml-example/blob/main/oauth_example/README.md Sets the required environment variables for OAuth and runs the minimal.py example. ```bash export AUTH_CLIENT_ID=your_client_id export AUTH_CLIENT_SECRET=your_client_secret python minimal.py ``` -------------------------------- ### Python Imports and Setup Source: https://github.com/answerdotai/fasthtml-example/blob/main/code_editor/code_editor.ipynb Imports necessary modules from fasthtml and sets up external scripts and CSS for the code editor. ```python #| export from fasthtml.fastapp import * # Ace Editor (https://ace.c9.io/) ace_editor = Script(src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.35.0/ace.min.js") # Flexbox CSS (http://flexboxgrid.com/) gridlink = Link(rel="stylesheet", href="https://cdnjs.cloudflare.com/ajax/libs/flexboxgrid/6.3.1/flexboxgrid.min.css", type="text/css") css = Style('''\ .sidebar { background-color: #f4f4f4; overflow-y: auto; padding: 10px; box-shadow: 2px 0 5px rgba(0,0,0,0.1); height: calc(100vh - 40px); } #editor-container { flex: 1; height: calc(100vh - 40px); } #editor { height: 100%; width: 100%; } .box-row { border: 1px solid #ccc; } ''') app,rt,files, File = fast_app('data/files.db', hdrs=(ace_editor, gridlink, css), id=int, filename=str, content=str, pk='id') id_curr = 'current-file' id_list = 'file-list' ``` -------------------------------- ### Root Route Source: https://github.com/answerdotai/fasthtml-example/blob/main/chess_app/chess_app.ipynb Defines the HTTP GET route for the root path, returning the Home page. ```python #| export @rt("/") def get(): return Home() ``` -------------------------------- ### Environment Variables Source: https://github.com/answerdotai/fasthtml-example/blob/main/e_commerce/README.md Environment variables required for Google OAuth and Stripe integration. ```bash export GOOGLE_CLIENT_ID=your_google_client_id export GOOGLE_CLIENT_SECRET=your_google_client_secret export STRIPE_SECRET_KEY=your_stripe_secret_key export STRIPE_WEBHOOK_SECRET=your_stripe_webhook_secret ``` -------------------------------- ### Running the app Source: https://github.com/answerdotai/fasthtml-example/blob/main/03_pictionary/README.md Export the Anthropic API key and run the Python application. ```bash export ANTHROPIC_API_KEY=your_api_key python app.py ``` -------------------------------- ### Export Notebook Source: https://github.com/answerdotai/fasthtml-example/blob/main/chess_app/chess_app.ipynb Command to export the notebook to a Python script. ```python #| eval: false #| hide from nbdev.export import nb_export nb_export('chess_app.ipynb', '.') ``` -------------------------------- ### Run the client to authenticate Source: https://github.com/answerdotai/fasthtml-example/blob/main/cli_oauth_example/README.md This command initiates the login process for the client component and saves the authentication token. ```bash python client-login.py ``` -------------------------------- ### Secured Endpoint Example Source: https://github.com/answerdotai/fasthtml-example/blob/main/cli_oauth_example/README.md An example of a secured endpoint on the server that retrieves the authenticated user's ID from the session. ```python # From server.py - the secured endpoint @rt async def secured(sess): return sess['auth'] ``` -------------------------------- ### Inserting Initial File Source: https://github.com/answerdotai/fasthtml-example/blob/main/code_editor/code_editor.ipynb Inserts a default file named 'file1.txt' with 'Hello, World!' content into the files database. ```python files.insert(File(filename='file1.txt', content='Hello, World!')) ``` -------------------------------- ### JavaScript for Ace Editor Source: https://github.com/answerdotai/fasthtml-example/blob/main/code_editor/code_editor.ipynb JavaScript code to initialize and manage the Ace Editor instance, including rendering and getting content. ```javascript //| export js_code = """ function renderEditor() { var editor = ace.edit("editor"); editor.setTheme("ace/theme/monokai"); editor.session.setMode("ace/mode/javascript"); } function getFileContent() { var editor = ace.edit("editor"); return editor.getValue(); } renderEditor(); """ example_code = """ function foo(items) { var x = "All this is syntax highlighted"; return x; } """ ``` -------------------------------- ### Select Piece Route Source: https://github.com/answerdotai/fasthtml-example/blob/main/chess_app/chess_app.ipynb Handles the '/select' POST request to determine and highlight legal moves for a selected piece. ```python #| export @rt('/select') async def post(col: str, row: str): global cboards lmoves = [] for m in cboard.legal_moves: if str(m).startswith(f'{col}{row}'): lmoves.append(str(m)[2:]) return Board(lmoves=lmoves, selected=f'{col}{row}') ``` -------------------------------- ### Manual Image Handling Source: https://github.com/answerdotai/fasthtml-example/blob/main/image_classification_app/readme.md Example of how to get an image from a request manually in a POST endpoint. ```python @app.post("/classify") async def handle_classify(request): data = await request.form() image = data["image"] ... ``` -------------------------------- ### Gallery HTML Structure Source: https://github.com/answerdotai/fasthtml-example/blob/main/story/demo.html Example HTML structure for a gallery component. ```html ``` -------------------------------- ### Chess Board Rendering Source: https://github.com/answerdotai/fasthtml-example/blob/main/chess_app/chess_app.ipynb Generates the HTML representation of the chess board, highlighting legal moves and selected pieces. ```python #| export ROWS = '87654321' COLS = 'abcdefgh' def Board(lmoves: list[str] = [], selected: str = ''): board = [] for row in ROWS: board_row = [] for col in COLS: pos = f"{col}{row}" cell_color = "black" if (ROWS.index(row) + COLS.index(col)) % 2 == 0 else "white" cell_color = 'active' if pos in lmoves else cell_color cell_cls = f'board-cell {cell_color}' if pos == selected: cell_cls += ' selected' piece = cboard.piece_at(chess.parse_square(pos)) if piece: piece = NotStr(chess.svg.piece(piece)) board_row.append( Div( piece, id=pos, cls=cell_cls, hx_post="/select", hx_vals={'col': col, 'row': row}, hx_swap='outerHTML', hx_target='#chess-board', hx_trigger='click' ) ) else: cell = Div(id=pos, cls=cell_cls) if selected != '': move = f'{selected}{pos}' print(move) if chess.Move.from_uci(move) in cboard.legal_moves: cell = Div(id=pos, cls=cell_cls, hx_put="/move", hx_vals={'move': move}, hx_swap='outerHTML', hx_target='#chess-board', hx_trigger='click' ) board_row.append(cell) board.append(Div(*board_row, cls="board-row")) return Div(*board, id="chess-board") ``` -------------------------------- ### Home Page Source: https://github.com/answerdotai/fasthtml-example/blob/main/chess_app/chess_app.ipynb Defines the main page of the chess application, including the board and websocket connection. ```python #| export def Home(): return Div( Div('Hello, still waiting on an opponent!', id='user-message'), Board(), hx_ext="ws", ws_connect="/chess" ) ``` -------------------------------- ### Make authenticated API calls Source: https://github.com/answerdotai/fasthtml-example/blob/main/cli_oauth_example/README.md This command demonstrates how to make authenticated API calls using the saved session token. ```bash python client-do.py ``` -------------------------------- ### File Content Route Handler Source: https://github.com/answerdotai/fasthtml-example/blob/main/code_editor/code_editor.ipynb Defines the route ('/files/{id}') to fetch and display the content of a specific file in the editor. ```python #| export @rt("/files/{id}") def get(id:int): return Div(files[id].content, id="editor", cls="ace_editor ace-tm")#, hx_on="htmx:afterSwap: renderEditor()",), ``` -------------------------------- ### Access Application Source: https://github.com/answerdotai/fasthtml-example/blob/main/xtermjs/README.md The URL to access the running terminal application in a web browser. ```bash http://localhost:5001 ``` -------------------------------- ### Sidebar Component Source: https://github.com/answerdotai/fasthtml-example/blob/main/code_editor/code_editor.ipynb Defines the HTML structure for the sidebar, which displays the list of files. ```python #| export def Sidebar(): return Div( Div( Ul(*map(FileRow, files()), id=id_list), cls="sidebar" ), cls="col-xs-12 col-sm-3" ) ``` -------------------------------- ### Root Route Handler Source: https://github.com/answerdotai/fasthtml-example/blob/main/code_editor/code_editor.ipynb Defines the root route ('/') that returns the main CodeEditor component. ```python #| export @rt("/") def get(): return CodeEditor() ``` -------------------------------- ### Sorting Algorithm Example Source: https://github.com/answerdotai/fasthtml-example/blob/main/story/demo.html A simple while loop that shuffles a deck of cards until it is in order, printing the number of iterations. ```javascript i = 0; while (!deck.isInOrder()) { print 'Iteration ' + i; deck.shuffle(); i++; } print 'It took ' + i + ' iterations to sort the deck.'; ``` -------------------------------- ### Server Communication: Login URL Generation Source: https://github.com/answerdotai/fasthtml-example/blob/main/cli_oauth_example/README.md Constructs the login URL that includes the paircode, which the client will open in the browser. ```python # From client-login.py url = f'http://{host}/cli_login?paircode={paircode}' login_url = httpx.get(url).text ``` ```python # From server.py @rt async def cli_login(request, paircode:str): pc_store[paircode] = None return cli.login_link(redir_url(request, redir_path), state=paircode) ``` -------------------------------- ### WebSocket Endpoint Source: https://github.com/answerdotai/fasthtml-example/blob/main/chess_app/chess_app.ipynb Defines the WebSocket endpoint for handling player connections, disconnections, and messages. ```python #| export from fasthtml.common import * from fastcore.utils import * from fastcore.xml import to_xml from starlette.endpoints import WebSocketEndpoint from starlette.routing import WebSocketRoute import chess import chess.svg cboard = chess.Board() # move e2e4 cboard.push_san('e4') cboard.push_san('e5') css = Style( '''\ #chess-board { display: grid; grid-template-columns: repeat(8, 64px); grid-template-rows: repeat(8, 64px);gap: 1px; } .board-cell { width: 64px; height: 64px; border: 1px solid black; } .black { background-color: grey; } .white { background-color: white; } .active { background-color: green; } ''' ) # Flexbox CSS (http://flexboxgrid.com/) gridlink = Link(rel="stylesheet", href="https://cdnjs.cloudflare.com/ajax/libs/flexboxgrid/6.3.1/flexboxgrid.min.css", type="text/css") htmx_ws = Script(src="https://unpkg.com/htmx-ext-ws@2.0.0/ws.js") app = FastHTML(hdrs=(gridlink, css, htmx_ws,)) rt = app.route player_queue = [] class WS(WebSocketEndpoint): encoding = 'text' async def on_connect(self, websocket): global player_queue player_queue.append(websocket) await websocket.accept() print(f'There are {len(player_queue)} players in the queue') await websocket.send_text("
Hello, you connected!
") if len(player_queue) == 2: await player_queue[0].send_text("
Opponent joined! Let the game begin!
") await player_queue[1].send_text("
You joined! Let the game begin!
") async def on_receive(self, websocket, data): await websocket.send_text("hi") async def on_disconnect(self, websocket, close_code): global player_queue player_queue.remove(websocket) for player in player_queue: await player.send_text("
Opponent disconnected!
") app.routes.append(WebSocketRoute('/chess', WS)) ``` -------------------------------- ### Using Authentication: Client with Session Cookies Source: https://github.com/answerdotai/fasthtml-example/blob/main/cli_oauth_example/README.md Loads saved session cookies and applies them to HTTP requests to authenticate with the server. ```python # From client-do.py def get_client(cookie_file): client = httpx.Client() cookies = Path(cookie_file).read_json() client.cookies.update(cookies) return client client = get_client(token_file) url = f'http://{host}/secured' res = client.get(url).text print(res) ``` -------------------------------- ### Save File Route Handler Source: https://github.com/answerdotai/fasthtml-example/blob/main/code_editor/code_editor.ipynb Defines the POST route ('/save') to handle saving file content, creating a new file if it doesn't exist. ```python #| export @rt("/save") def post(filename: str, content: str): file = File(filename=filename, content=content, id=len(files()) + 1) files.insert(file) return FileRow(file) ``` -------------------------------- ### Notebook Export Source: https://github.com/answerdotai/fasthtml-example/blob/main/code_editor/code_editor.ipynb A commented-out cell for exporting the notebook, typically used in nbdev projects. ```python #| eval: false #| hide from nbdev.export import nb_export nb_export('code_editor.ipynb', '.') ``` -------------------------------- ### App Setup and Database Integration Source: https://github.com/answerdotai/fasthtml-example/blob/main/annotate_text/README.md This code snippet shows how to set up the FastHTML application, including routing, database connection, and data model initialization in a single line. ```python app, rt, texts_db, Item = fast_app('texts.db', hdrs=(tlink, dlink, picolink, MarkdownJS(), HighlightJS()), live=True, id=int, messages=list, feedback=bool, notes=str, pk='id', render=render) ``` -------------------------------- ### Deleting Todos Route Source: https://github.com/answerdotai/fasthtml-example/blob/main/01_todo_app/README.md Handles deleting a todo item using the delete method. ```python @rt("/todos/{id}") def delete(id:int): todos.delete(id) return clear(id_curr) ``` -------------------------------- ### Session Creation: Polling for Token and Saving Cookies Source: https://github.com/answerdotai/fasthtml-example/blob/main/cli_oauth_example/README.md The client polls the server for the authentication token and saves the received session cookies to a file. ```python # From client-login.py def poll_token(paircode, host, interval=1, timeout=180): "Poll server for token until received or timeout" start = time() client = httpx.Client() while time()-start < timeout: resp = client.get(f"http://{host}/token?paircode={paircode}").raise_for_status() if resp.text.strip(): return dict(client.cookies) sleep(interval) # Save the session cookies cookies = poll_token(paircode, host) if cookies: with open(token_file, 'w') as f: json.dump(cookies, f) print(f"Token saved to {token_file}") ``` -------------------------------- ### Client Initialization: Paircode Generation Source: https://github.com/answerdotai/fasthtml-example/blob/main/cli_oauth_example/README.md Generates a random paircode to uniquely identify the authentication session between the CLI and the browser flow. ```python # From client-login.py paircode = secrets.token_urlsafe(16) ``` -------------------------------- ### WebSocket Form Submission Source: https://github.com/answerdotai/fasthtml-example/blob/main/02_chatbot/README.md Example of configuring a form to use WebSockets for submission and specifying the connection route. ```python Form(Group(ChatInput(), Button("Send", cls="btn btn-primary")), ws_send="", hx_ext="ws", ws_connect="/wscon") ``` -------------------------------- ### Move Piece Route Source: https://github.com/answerdotai/fasthtml-example/blob/main/chess_app/chess_app.ipynb Handles the '/move' PUT request to process a move, update the board, and notify players via websockets. ```python #| export @rt('/move') async def put(move: str): global cboards cboard.push_san(move) for player in player_queue: await player.send_text(to_xml(Board())) ``` -------------------------------- ### JavaScript for sending canvas data Source: https://github.com/answerdotai/fasthtml-example/blob/main/03_pictionary/README.md Custom JavaScript to set up the drawing canvas and send drawing data to the server. ```javascript function sendCanvasData() { canvas.toBlob((blob) => { const formData = new FormData(); formData.append('image', blob, 'canvas.png'); fetch('/process-canvas', { method: 'POST', body: formData, }).then(response => response.json()) .then(data => { document.getElementById('caption').innerHTML = data.caption; console.log(data);}) .catch(error => console.error('Error:', error)); }); } ``` -------------------------------- ### Code Editor Main Component Source: https://github.com/answerdotai/fasthtml-example/blob/main/code_editor/code_editor.ipynb Assembles the toolbar, sidebar, and editor container into the main code editor interface. ```python #| export def CodeEditor(): toolbar = Toolbar() main = Div( Sidebar(), Div( Div(example_code, id="editor"), id="editor-container", cls="col-xs-12 col-sm-9", hx_on="htmx:afterSwap: renderEditor()" ), cls="row" ) return Title("Code Editor",), Div(toolbar, main, cls="container-fluid"), Script(NotStr(js_code)) ``` -------------------------------- ### Session Creation: Token Endpoint Source: https://github.com/answerdotai/fasthtml-example/blob/main/cli_oauth_example/README.md The server's token endpoint, which the client polls to retrieve the authentication session after user approval. ```python # From server.py @rt async def token(paircode:str, sess): if pc_store.get(paircode, ''): auth = pc_store.pop(paircode) sess['auth'] = auth return auth ``` -------------------------------- ### Todo Item Rendering Source: https://github.com/answerdotai/fasthtml-example/blob/main/01_todo_app/README.md Defines how each Todo object is displayed, including its title, completion status, and edit link, using monkey patching. ```python @patch def __ft__(self:Todo): show = AX(self.title, f'/todos/{self.id}', id_curr) edit = AX('edit', f'/edit/{self.id}' , id_curr) dt = ' ✅' if self.done else '' return Li(show, dt, ' | ', edit, id=tid(self.id)) ``` -------------------------------- ### User Authentication: Opening Login URL Source: https://github.com/answerdotai/fasthtml-example/blob/main/cli_oauth_example/README.md Opens the generated login URL in the user's default web browser to initiate the OAuth provider authentication. ```python # From client-login.py webbrowser.open(login_url) ``` -------------------------------- ### Python server-side processing Source: https://github.com/answerdotai/fasthtml-example/blob/main/03_pictionary/README.md Python code to receive image data, process it with the Anthropic model, and return a caption. ```python @app.post("/process-canvas") async def process_canvas(image: str): image_bytes = await image.read() image_base64 = base64.b64encode(image_bytes).decode('utf-8') message = client.messages.create( model="claude-3-haiku-20240307", max_tokens=100, temperature=0.5, messages=[ {"role": "user", "content": [ {"type": "image", "source": {"type": "base64","media_type": "image/png", "data": image_base64}}, {"type": "text", "text": "Write a haiku about this drawing, respond with only that."} ]}] ) caption = message.content[0].text.replace("\n", "
") return JSONResponse({"caption": caption}) ``` -------------------------------- ### Editing Todos Route Source: https://github.com/answerdotai/fasthtml-example/blob/main/01_todo_app/README.md Handles editing a todo item by dynamically filling a form with the todo's current data. ```python @rt("/edit/{id}") def get(id:int): res = Form(Group(Input(id="title"), Button("Save")), Hidden(id="id"), CheckboxX(id="done", label='Done'), hx_put="/", hx_swap="outerHTML", target_id=tid(id), id="edit") return fill_form(res, todos.get(id)) ``` -------------------------------- ### File Row Component Source: https://github.com/answerdotai/fasthtml-example/blob/main/code_editor/code_editor.ipynb Defines the HTML structure for a single row in the file list, which links to load the file content into the editor. ```python #| export def FileRow(file: File): return Li( A( file.filename, hx_get=f'/files/{file.id}', target_id="editor-container", hx_swap="innerHTML", hx_on="htmx:afterSwap: renderEditor()", ), id=f'file-{file.id}' ) ``` -------------------------------- ### WebSocket Handler Source: https://github.com/answerdotai/fasthtml-example/blob/main/02_chatbot/README.md Example of a WebSocket handler that processes incoming messages, sends UI updates, and streams responses from a chat model. ```python @app.ws('/wscon') async def ws(msg:str, send): # Send the user message to the user (updates the UI right away) messages.append({"role":"user", "content":msg}) await send(Div(ChatMessage(messages[-1]), hx_swap_oob='beforeend', id="chatlist")) # Send the clear input field command to the user await send(ChatInput()) # Get and send the model response r = cli(messages, sp=sp) messages.append({"role":"assistant", "content":contents(r)}) await send(Div(ChatMessage(messages[-1]), hx_swap_oob='beforeend', id="chatlist")) ``` -------------------------------- ### Save File Form and Toolbar Source: https://github.com/answerdotai/fasthtml-example/blob/main/code_editor/code_editor.ipynb Defines the HTML structure for the save file form and the main toolbar, including language selection and save button. ```python #| export def SaveFile(): return Form( Input(type="text", id="filename", name="filename", placeholder="Filename", required=True), Button("Save", type="submit", hx_post="/save", target_id=id_list, hx_swap="beforeend", hx_vals="js:{content: getFileContent(), filename: filename.value}"), cls="col-xs-12" ) ... def Toolbar(): return Div( Div( Select( Option("JavaScript", value="javascript"), Option("Python", value="python"), Option("HTML", value="html"), Option("CSS", value="css"), Option("Markdown", value="markdown"), id="language" ), Button("Run", id="run"), SaveFile(), cls="col-xs-12 toolbar" ), cls="row" ) ``` -------------------------------- ### Adding New Todos Form Source: https://github.com/answerdotai/fasthtml-example/blob/main/01_todo_app/README.md Creates an input field and 'Add' button, which uses HTMX to post new todos without a page reload. ```python def mk_input(**kw): return Input(id="new-title", name="title", placeholder="New Todo", **kw) @rt("/") def get(): add = Form(Group(mk_input(), Button("Add")), hx_post="/", target_id='todo-list', hx_swap="beforeend") card = Card(Ul(*todos(), id='todo-list'), header=add, footer=Div(id=id_curr)), title = 'Todo list' return Title(title), Main(H1(title), card, cls='container') ``` -------------------------------- ### Authentication Processing: Handling Authorization Code Source: https://github.com/answerdotai/fasthtml-example/blob/main/cli_oauth_example/README.md The server receives the authorization code and state (paircode), exchanges the code for authentication info, and associates it with the paircode. ```python # From server.py @rt(redir_path) async def redirect(request, code:str, state:str=None): redir = redir_url(request, redir_path) auth = cli.retr_id(code, redir) if state and state in pc_store: pc_store[state] = auth if auth not in users: users.insert(User(auth=auth)) return 'complete' else: return f"Failed to find {state} in {pc_store}" ``` -------------------------------- ### Streaming Chat Message Updates Source: https://github.com/answerdotai/fasthtml-example/blob/main/02_chatbot/README.md Example of how to incrementally update a chat message by appending chunks of new content, preserving user selections. ```python for chunk in r: messages[-1]["content"] += chunk await send(Span(chunk, id=f"chat-content-{len(messages)-1}", hx_swap_oob="beforeend")) ``` -------------------------------- ### Pollinations API Image Generation Source: https://github.com/answerdotai/fasthtml-example/blob/main/image_app_simple/README.md Python code to generate a URL for image generation using the Pollinations API and a function to download and save the generated image. ```python # URL (for image generation) def get_url(prompt): return f"https://image.pollinations.ai/prompt/{prompt.replace(' ', '%20')}?model=flux&width=1024&height=1024&seed=42&nologo=true&enhance=true" ... @threaded def generate_and_save(prompt, id, folder): full_url = get_url(prompt) Image.open(requests.get(full_url, stream=True).raw).save(f"{folder}/{id}.png") return True ``` -------------------------------- ### Wrapper HTML Structure Source: https://github.com/answerdotai/fasthtml-example/blob/main/story/demo.html Example HTML structure for a wrapper element that can contain content and apply optional modifiers for color scheme inversion or specific background colors. ```html
(content)
``` -------------------------------- ### Gallery Style 2 HTML Structure Source: https://github.com/answerdotai/fasthtml-example/blob/main/story/demo.html Example HTML structure for a carousel of thumbnails with optional lightbox support. Demonstrates the use of 'style(N)' and various size/behavior modifiers. ```html
(content)
(content)
(content)
(content)
...
``` -------------------------------- ### Basic Chatbot POST Handler Source: https://github.com/answerdotai/fasthtml-example/blob/main/02_chatbot/README.md Handles incoming user messages, appends them to the message list, gets a response from the chat model, appends the response, and returns the new messages and a cleared input field. ```python @app.post("/") def post(msg:str): messages.append({"role":"user", "content":msg}) r = cli(messages, sp=sp) # get response from chat model messages.append({"role":"assistant", "content":contents(r)}) return (ChatMessage(messages[-2]), # The user's message ChatMessage(messages[-1]), # The chatbot's response ChatInput()) # And clear the input field via an OOB swap ``` -------------------------------- ### Adding DaisyUI and Tailwind CSS links Source: https://github.com/answerdotai/fasthtml-example/blob/main/02_chatbot/README.md This snippet shows how to include the necessary CSS and JavaScript links for Tailwind CSS and DaisyUI in the HTML head of a FastHTML application. ```python tlink = Script(src="https://cdn.tailwindcss.com"), dlink = Link(rel="stylesheet", href="https://cdn.jsdelivr.net/npm/daisyui@4.11.1/dist/full.min.css") app = FastHTML(hdrs=(tlink, dlink, picolink)) ``` -------------------------------- ### Spotlight HTML Structure Source: https://github.com/answerdotai/fasthtml-example/blob/main/story/demo.html Basic HTML structure for a spotlight component. ```html
(content)
Alternate text
``` -------------------------------- ### Main Page Layout Source: https://github.com/answerdotai/fasthtml-example/blob/main/02_chatbot/README.md Defines the main page structure for the chatbot, including a title, a chat display area, and a form for user input. ```python @app.route("/") def get(): page = Body(H1('Chatbot Demo'), Div(*[ChatMessage(msg) for msg in messages], id="chatlist", cls="chat-box h-[73vh] overflow-y-auto"), Form(Group(ChatInput(), Button("Send", cls="btn btn-primary")), hx_post="/", hx_target="#chatlist", hx_swap="beforeend", cls="flex space-x-2 mt-2", ), cls="p-4 max-w-lg mx-auto") return Title('Chatbot Demo'), page ``` -------------------------------- ### Form with Chunked Transfer Extension Source: https://github.com/answerdotai/fasthtml-example/blob/main/02_chatbot/README.md This Python code snippet shows how to configure a FastHTML Form to use the chunked transfer extension. ```python Form(hx_post=send, hx_target="#chatlist", hx_swap="beforeend", hx_ext="chunked-transfer", hx_disabled_elt="#msg-group") ```