im going to provide you my current road map for a project with some detailed steps. Then after that i will provide you detailed docs the underlying framework used to build the UI

Can you help me curate the docs to synthesis the key parts of them that an LLM would need to have context and all the information it would need to build out the roadmap?

here is the current roadmap first The docs will follow after the road map:

Updated Roadmap:
```
✅ Implement basic UI layout
✅ Create file browser functionality
✅ Implement file viewing with syntax highlighting
✅ Add dark/light mode toggle
CLI Tool Integration:
Connect to the CLI tool
Use selected files and entered prompt to generate responses
Implement error handling for CLI interactions
Enhance Conversation History:
Implement storage of conversation history
Add scrolling functionality for past interactions
Improve display of user and system messages
Improve Code Output:
Implement diff view for proposed changes
Add user approval system for changes
Implement Streaming Functionality:
Set up real-time streaming of responses from CLI tool
Develop Preview Functionality:
Create a preview of how prompts will be processed
Add File Editing Capabilities (if desired):
Implement in-browser file editing
Add save functionality for edited files
Create Project Management System:
Implement saving and loading of different projects
Add project metadata management
Optimize Performance and User Experience:
Conduct thorough testing and bug fixing
Implement performance optimizations
Implement Advanced Features:
Add variable embedding functionality
Implement any additional features specific to your CLI tool
Thank you for providing the main.py file of your CLI tool. This gives us a clear picture of how to integrate it with our web UI. Here's a high-level strategy for integration:

Adapt CLI Functions for Web Use:
Convert the main async function into smaller, modular functions that can be called from our FastHTML routes.
Create separate functions for chat, model switching, context management, and file operations.
State Management:
Utilize FastHTML's session management to maintain conversation history and app state.
Adapt the AppState class to work with web sessions.
File Context Integration:
Modify the file context system to work with the files selected in our web UI's file browser.
Implement a method to update file context when files are selected or deselected.
Model Switching:
Create a route to handle model switching, updating the current model in the session.
Chat Functionality:
Implement a route that calls the chat_with_model function, passing the user input and current model.
Return the assistant's response to be displayed in the web UI.
Special Commands:
Implement routes for special commands like 'reset', 'view context', and 'smart_edit'.
Create UI elements (buttons or commands) to trigger these actions.
Code Extraction:
Implement the code extraction feature as a separate route, allowing users to save extracted code.
Token Usage Display:
Adapt the token usage display for web presentation, possibly as a real-time update in the UI.
Error Handling:
Implement robust error handling in all routes, returning appropriate error messages to the UI.
Asynchronous Operations:
Utilize FastHTML's support for asynchronous operations to handle long-running tasks without blocking the UI.
Rich Output Adaptation:
Convert Rich console output to HTML for web display, preserving formatting and styles.
Integration Approach:

Create a new Python file (e.g., cli_integration.py) to house the adapted CLI functions.
In app.py, import the necessary functions from cli_integration.py.
Implement new routes in app.py for each major CLI function (chat, model switching, context management, etc.).
Update the frontend JavaScript to make appropriate fetch calls to these new routes.
Modify the UI to include new elements for CLI-specific features (model selection dropdown, context view button, etc.).
Implement WebSocket connection for real-time updates (token usage, streaming responses).
Next steps:

Create cli_integration.py and start adapting CLI functions for web use.
Implement the chat route in app.py, connecting it to the adapted chat_with_model function.
Update the frontend to send chat requests and display responses.
Gradually implement other CLI features, testing each step of the way.
This approach will allow us to maintain the core functionality of your CLI tool while adapting it for web use through our FastHTML interface. We'll need to carefully manage state and ensure proper error handling throughout the integration process.


The console-based UI elements in the main.py can indeed be adapted and enhanced for our web interface. This "porting" process will not only maintain the functionality but also allow us to leverage the strengths of a web-based UI. Here's how we can approach this:

Console Output to Web UI:
Replace Rich console prints with HTML/CSS formatted output.
Use JavaScript to dynamically update the UI with this formatted content.
Panels and Markdown:
Convert Rich panels to styled div elements in HTML.
Use a JavaScript Markdown parser (like marked.js) to render Markdown content in the browser.
Token Usage Display:
Create a dedicated area in the UI for real-time token usage updates.
Use WebSockets to push updates to the client without page reloads.
User Approvals:
Implement modal dialogs or inline confirmation buttons for user approvals.
Use JavaScript to handle user interactions and send approval/rejection back to the server.
Prompt Caching:
Implement a client-side cache using localStorage or IndexedDB for frequently used prompts.
Create a UI element to display and select from cached prompts.
Model Switching:
Replace the console-based model selection with a dropdown menu in the web UI.
Implement real-time model switching without interrupting the conversation flow.
File Context Summary:
Create a collapsible section in the UI to display the current file context summary.
Update this dynamically as files are selected or deselected in the file browser.
Error Messages:
Design a toast notification system for displaying errors and warnings.
Use different colors and icons to distinguish between error types.
Code Extraction:
Implement a button next to code blocks that allows for one-click extraction and saving.
Provide a preview of the extracted code before saving.
Conversation Context:
Create a visual representation of the conversation context, possibly as a tree or graph.
Allow users to expand/collapse parts of the context for easier navigation.
Smart Edit Feature:
Implement a split-view diff editor for the smart edit feature.
Show original file content on one side and proposed changes on the other.
Progress Indicators:
Add loading spinners or progress bars for long-running operations.
Provide cancel options for operations that might take a while.
Implementation Strategy:

Start with a basic port of each console UI element to a web equivalent.
Gradually enhance each element with web-specific features (interactivity, real-time updates).
Implement responsive design to ensure the UI works well on different screen sizes.
Use CSS transitions and animations to make the UI feel more dynamic and responsive.
Implement keyboard shortcuts for power users, mirroring the CLI experience.
By taking this approach, we can create a web UI that not only replicates the functionality of the CLI tool but also enhances it with the interactivity and visual richness possible in a web environment. This will provide users with a familiar yet more powerful interface, combining the best of both the CLI and web worlds.

As we implement these features, we can prioritize them based on their importance to the core functionality and the value they add to the user experience. We can start with the most critical elements (like chat functionality and token usage display) and then progressively add the more advanced features.
```

DOCUMENTATION TO SYNTHESIS:

```

8k tokens docs
<project title="FastHTML" summary='FastHTML is a python library which brings together Starlette, Uvicorn, HTMX, and fastcore&#39;s `FT` "FastTags" into a library for creating server-rendered hypermedia applications. The `FastHTML` class itself inherits from `Starlette`, and adds decorator-based routing with many additions, Beforeware, automatic `FT` to HTML rendering, and much more.'>
Things to remember when writing FastHTML apps:

- Although parts of its API are inspired by FastAPI, it is *not* compatible with FastAPI syntax and is not targeted at creating API services
- FastHTML includes support for Pico CSS and the fastlite sqlite library, although using both are optional; sqlalchemy can be used directly or via the fastsql library, and any CSS framework can be used. Support for the Surreal and css-scope-inline libraries are also included, but both are optional
- FastHTML is compatible with JS-native web components and any vanilla JS library, but not with React, Vue, or Svelte
- Use `serve()` for running uvicorn (`if __name__ == "__main__"` is not needed since it's automatic)
- When a title is needed with a response, use `Titled`; note that that already wraps children in `Container`, and already includes both the meta title as well as the H1 element.
  <docs>
    <doc title="FastHTML quick start" desc="A brief overview of many FastHTML features"># Web Devs Quickstart



## Installation

``` bash
pip install python-fasthtml
```

## A Minimal Application

A minimal FastHTML application looks something like this:

<div class="code-with-filename">

**main.py**

``` python
from fasthtml.common import *

app, rt = fast_app()

@rt("/")
def get():
    return Titled("FastHTML", P("Let's do this!"))

serve()
```

</div>

Line 1  
We import what we need for rapid development! A carefully-curated set of
FastHTML functions and other Python objects is brought into our global
namespace for convenience.

Line 3  
We instantiate a FastHTML app with the `fast_app()` utility function.
This provides a number of really useful defaults that we’ll take
advantage of later in the tutorial.

Line 5  
We use the `rt()` decorator to tell FastHTML what to return when a user
visits `/` in their browser.

Line 6  
We connect this route to HTTP GET requests by defining a view function
called `get()`.

Line 7  
A tree of Python function calls that return all the HTML required to
write a properly formed web page. You’ll soon see the power of this
approach.

Line 9  
The `serve()` utility configures and runs FastHTML using a library
called `uvicorn`.

Run the code:

``` bash
python main.py
```

The terminal will look like this:

``` bash
INFO:     Uvicorn running on http://0.0.0.0:5001 (Press CTRL+C to quit)
INFO:     Started reloader process [58058] using WatchFiles
INFO:     Started server process [58060]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
```

Confirm FastHTML is running by opening your web browser to
[127.0.0.1:5001](http://127.0.0.1:5001). You should see something like
the image below:

![](quickstart-web-dev/quickstart-fasthtml.png)

<div>

> **Note**
>
> While some linters and developers will complain about the wildcard
> import, it is by design here and perfectly safe. FastHTML is very
> deliberate about the objects it exports in `fasthtml.common`. If it
> bothers you, you can import the objects you need individually, though
> it will make the code more verbose and less readable.
>
> If you want to learn more about how FastHTML handles imports, we cover
> that [here](https://docs.fastht.ml/explains/faq.html#why-use-import).

</div>


# CSS Files and Inline Styles

Here we modify default headers to demonstrate how to use the [Sakura CSS
microframework](https://github.com/oxalorg/sakura) instead of FastHTML’s
default of Pico CSS.

<div class="code-with-filename">

**main.py**

``` python
from fasthtml.common import * 

app, rt = fast_app(
    pico=False,
    hdrs=(
        Link(rel='stylesheet', href='assets/normalize.min.css', type='text/css'),
        Link(rel='stylesheet', href='assets/sakura.css', type='text/css'),
        Style("p {color: red;}")
))

@app.get("/")
def home():
    return Titled("FastHTML",
        P("Let's do this!"),
    )

serve()
```

</div>

Line 4  
By setting `pico` to `False`, FastHTML will not include `pico.min.css`.

Line 7  
This will generate an HTML `<link>` tag for sourcing the css for Sakura.

Line 8  
If you want an inline styles, the `Style()` function will put the result
into the HTML.

### Dataclasses as ft components

While functions are easy to read, for more complex components some might
find it easier to use a dataclass.

``` python
from dataclasses import dataclass

@dataclass
class Hero:
    title: str
    statement: str
    
    def __ft__(self):
        """ The __ft__ method renders the dataclass at runtime."""
        return Div(H1(self.title),P(self.statement), cls="hero")
    
# usage example
Main(
    Hero("Hello World", "This is a hero statement")
)
```

``` html
<main>
  <div class="hero">
    <h1>Hello World</h1>
    <p>This is a hero statement</p>
  </div>
</main>
```


## Forms

To validate data coming from users, first define a dataclass
representing the data you want to check. Here’s an example representing
a signup form.

``` python
from dataclasses import dataclass

@dataclass
class Profile: email:str; phone:str; age:int
```

Create an FT component representing an empty version of that form. Don’t
pass in any value to fill the form, that gets handled later.

``` python
profile_form = Form(method="post", action="/profile")(
        Fieldset(
            Label('Email', Input(name="email")),
            Label("Phone", Input(name="phone")),
            Label("Age", Input(name="age")),
        ),
        Button("Save", type="submit"),
    )
profile_form
```

``` html
<form enctype="multipart/form-data" method="post" action="/profile">
  <fieldset>
    <label>
Email
      <input name="email">
    </label>
    <label>
Phone
      <input name="phone">
    </label>
    <label>
Age
      <input name="age">
    </label>
  </fieldset>
  <button type="submit">Save</button>
</form>
```

Once the dataclass and form function are completed, we can add data to
the form. To do that, instantiate the profile dataclass:

``` python
profile = Profile(email='john@example.com', phone='123456789', age=5)
profile
```

    Profile(email='john@example.com', phone='123456789', age=5)

Then add that data to the `profile_form` using FastHTML’s
[`fill_form`](https://AnswerDotAI.github.io/fasthtml/api/components.html#fill_form)
class:

``` python
fill_form(profile_form, profile)
```

``` html
<form enctype="multipart/form-data" method="post" action="/profile">
  <fieldset>
    <label>
Email
      <input name="email" value="john@example.com">
    </label>
    <label>
Phone
      <input name="phone" value="123456789">
    </label>
    <label>
Age
      <input name="age" value="5">
    </label>
  </fieldset>
  <button type="submit">Save</button>
</form>
```
Defining new ft components
We can build our own ft components and combine them with other components. The simplest method is defining them as a function.
from fasthtml.common import *

Python
def hero(title, statement):
    return Div(H1(title),P(statement), cls="hero")

# usage example
Main(
    hero("Hello World", "This is a hero statement")
)


Python
<main>
  <div class="hero">
    <h1>Hello World</h1>
    <p>This is a hero statement</p>
  </div>
</main>

Html
Pass through components
For when we need to define a new component that allows zero-to-many components to be nested within them, we lean on Python’s *args and **kwargs mechanism. Useful for creating page layout controls.
def layout(*args, **kwargs):
    """Dashboard layout for all our dashboard views"""
    return Main(
        H1("Dashboard"),
        Div(*args, **kwargs),
        cls="dashboard",
    )

# usage example
layout(
    Ul(*[Li(o) for o in range(3)]),
    P("Some content", cls="description"),
)

Python
<main class="dashboard">
  <h1>Dashboard</h1>
  <div>
    <ul>
      <li>0</li>
      <li>1</li>
      <li>2</li>
    </ul>
    <p class="description">Some content</p>
  </div>
</main>


Html
Dataclasses as ft components
While functions are easy to read, for more complex components some might find it easier to use a dataclass.
from dataclasses import dataclass

@dataclass
class Hero:
    title: str
    statement: str
    
    def __ft__(self):
        """ The __ft__ method renders the dataclass at runtime."""
        return Div(H1(self.title),P(self.statement), cls="hero")
    
# usage example
Main(
    Hero("Hello World", "This is a hero statement")
)


Python
<main>
  <div class="hero">
    <h1>Hello World</h1>
    <p>This is a hero statement</p>
  </div>
</main>


### Forms with views

The usefulness of FastHTML forms becomes more apparent when they are
combined with FastHTML views. We’ll show how this works by using the
test client from above. First, let’s create a SQlite database:

``` python
db = Database("profiles.db")
profiles = db.create(Profile, pk="email")
```

Now we insert a record into the database:

``` python
profiles.insert(profile)
```

    Profile(email='john@example.com', phone='123456789', age=5)

And we can then demonstrate in the code that form is filled and
displayed to the user.

``` python
@rt("/profile/{email}")
def profile(email:str):
    profile = profiles[email]
    filled_profile_form = fill_form(profile_form, profile)
    return Titled(f'Profile for {profile.email}', filled_profile_form)

print(client.get(f"/profile/john@example.com").text)
```

Line 3  
Fetch the profile using the profile table’s `email` primary key

Line 4  
Fill the form for display.


     <!doctype html>

     <html>
       <head>
         <title>Profile for john@example.com</title>
       </head>
       <body>
         <main class="container">
           <h1>Profile for john@example.com</h1>
           <form enctype="multipart/form-data" method="post" action="/profile">
             <fieldset>
               <label>
    Email
                 <input name="email" value="john@example.com">
               </label>
               <label>
    Phone
                 <input name="phone" value="123456789">
               </label>
               <label>
    Age
                 <input name="age" value="5">
               </label>
             </fieldset>
             <button type="submit">Save</button>
           </form>
         </main>
       </body>
     </html>

And now let’s demonstrate making a change to the data.

``` python
@rt("/profile")
def post(profile: Profile):
    profiles.update(profile)
    return RedirectResponse(url=f"/profile/{profile.email}")

new_data = dict(email='john@example.com', phone='7654321', age=25)
print(client.post("/profile", data=new_data).text)
```

Line 2  
We use the `Profile` dataclass definition to set the type for the
incoming `profile` content. This validates the field types for the
incoming data

Line 3  
Taking our validated data, we updated the profiles table

Line 4  
We redirect the user back to their profile view

Line 7  
The display is of the profile form view showing the changes in data.


     <!doctype html>

     <html>
       <head>
         <title>Profile for john@example.com</title>
       </head>
       <body>
         <main class="container">
           <h1>Profile for john@example.com</h1>
           <form enctype="multipart/form-data" method="post" action="/profile">
             <fieldset>
               <label>
    Email
                 <input name="email" value="john@example.com">
               </label>
               <label>
    Phone
                 <input name="phone" value="7654321">
               </label>
               <label>
    Age
                 <input name="age" value="25">
               </label>
             </fieldset>
             <button type="submit">Save</button>
           </form>
         </main>
       </body>
     </html>


## HTTP Methods

FastHTML matches function names to HTTP methods. So far the URL routes
we’ve defined have been for HTTP GET methods, the most common method for
web pages.

Form submissions often are sent as HTTP POST. When dealing with more
dynamic web page designs, also known as Single Page Apps (SPA for
short), the need can arise for other methods such as HTTP PUT and HTTP
DELETE. The way FastHTML handles this is by changing the function name.

<div class="code-with-filename">

**main.py**

``` python
from fasthtml.common import * 

app, rt = fast_app()

@rt("/")  
def get():
  return Titled("HTTP GET", P("Handle GET"))

@rt("/")  
def post():
  return Titled("HTTP POST", P("Handle POST"))

serve()
```

</div>

Line 6  
On line 6 because the `get()` function name is used, this will handle
HTTP GETs going to the `/` URI.

Line 10  
On line 10 because the `post()` function name is used, this will handle
HTTP POSTs going to the `/` URI.


## Code highlighting

Here’s how to highlight code without any markdown configuration.

``` python
from fasthtml.common import *

# Add the HighlightJS built-in header
hdrs = (HighlightJS(langs=['python', 'javascript', 'html', 'css']),)

app, rt = fast_app(hdrs=hdrs)

code_example = """
import datetime
import time

for i in range(10):
    print(f"{datetime.datetime.now()}")
    time.sleep(1)
"""

@rt('/')
def get(req):
    return Titled("Markdown rendering example",
        Div(
            # The code example needs to be surrounded by
            # Pre & Code elements
            Pre(Code(code_example))
    ))

serve()
```
Websockets application

from asyncio import sleep
from fasthtml.common import *

app = FastHTML(ws_hdr=True)
rt = app.route

def mk_inp(): return Input(id='msg')
nid = 'notifications'

@rt('/')
async def get():
    cts = Div(
        Div(id=nid),
        Form(mk_inp(), id='form', ws_send=True),
        hx_ext='ws', ws_connect='/ws')
    return Titled('Websocket Test', cts)

async def on_connect(send): await send(Div('Hello, you have connected', id=nid))
async def on_disconnect( ): print('Disconnected!')

@app.ws('/ws', conn=on_connect, disconn=on_disconnect)
async def ws(msg:str, send):
    await send(Div('Hello ' + msg, id=nid))
    await sleep(2)
    return Div('Goodbye ' + msg, id=nid), mk_inp()

serve()


Explanation:
* ws_hdr=True: Tells FastHTML to include the Javascript header for WebSockets functionality.
* mk_inp(): A helper function to create an input field with the ID 'msg'.
* nid = 'notifications': Defines an ID for the element that will display messages.
* @rt('/'): The route handler for the main page.
* hx_ext='ws', ws_connect='/ws': These attributes on the Div establish the WebSocket connection to the /ws endpoint.
* ws_send=True: On the Form, this attribute indicates that form submissions should be sent via the WebSocket.
* @app.ws('/ws', ...): The decorator defines a WebSocket endpoint handler.
    * conn=on_connect: Specifies a function to run when a client connects.
    * disconn=on_disconnect: Specifies a function to run when a client disconnects.
* async def ws(msg:str, send): The WebSocket handler function.
    * It receives messages (msg) from the client and uses the send function to send messages back.
This example demonstrates a basic implementation of WebSockets with FastHTML, showcasing how to handle client connections, send and receive messages, and update the UI in real time.

## Strings and conversion order

The general rules for rendering are: - `__ft__` method will be called
(for default components like `P`, `H2`, etc. or if you define your own
components) - If you pass a string, it will be escaped - On other python
objects, `str()` will be called

As a consequence, if you want to include plain HTML tags directly into
e.g. a `Div()` they will get escaped by default (as a security measure
to avoid code injections). This can be avoided by using `NotStr()`, a
convenient way to reuse python code that returns already HTML. If you
use pandas, you can use `pandas.DataFrame.to_html()` to get a nice
table. To include the output a FastHTML, wrap it in `NotStr()`, like
`Div(NotStr(df.to_html()))`.

Above we saw how a dataclass behaves with the `__ft__` method defined.
On a plain dataclass, `str()` will be called (but not escaped).

``` python
from dataclasses import dataclass

@dataclass
class Hero:
    title: str
    statement: str
        
# rendering the dataclass with the default method
Main(
    Hero("<h1>Hello World</h1>", "This is a hero statement")
)
```

``` html
<main>Hero(title='<h1>Hello World</h1>', statement='This is a hero statement')</main>
```

``` python
# This will display the HTML as text on your page
Div("Let's include some HTML here: <div>Some HTML</div>")
```

``` html
<div>Let&#x27;s include some HTML here: &lt;div&gt;Some HTML&lt;/div&gt;</div>
```

``` python
# Keep the string untouched, will be rendered on the page
Div(NotStr("<div><h1>Some HTML</h1></div>"))
```

``` html
<div><div><h1>Some HTML</h1></div></div>
```

## Sessions

For convenience and security, FastHTML has a mechanism for storing small
amounts of data in the user’s browser. We can do this by adding a
`session` argument to routes. FastHTML sessions are Python dictionaries,
and we can leverage to our benefit. The example below shows how to
concisely set and get sessions.

``` python
@rt('/adder/{num}')
def get(session, num: int):
    session.setdefault('sum', 0)
    session['sum'] = session.get('sum') + num
    return Response(f'The sum is {session["sum"]}.')
```

## Toasts (also known as Messages)

Toasts, sometimes called “Messages” are small notifications usually in
colored boxes used to notify users that something has happened. Toasts
can be of four types:

- info
- success
- warning
- error

Examples toasts might include:

- “Payment accepted”
- “Data submitted”
- “Request approved”

Toasts require the use of the `setup_toasts()` function plus every view
needs these two features:

- The session argument
- Must return FT components

``` python
setup_toasts(app)

@rt('/toasting')
def get(session):
    # Normally one toast is enough, this allows us to see
    # different toast types in action.
    add_toast(session, f"Toast is being cooked", "info")
    add_toast(session, f"Toast is ready", "success")
    add_toast(session, f"Toast is getting a bit crispy", "warning")
    add_toast(session, f"Toast is burning!", "error")
    return Titled("I like toast")
```

Line 1  
`setup_toasts` is a helper function that adds toast dependencies.
Usually this would be declared right after `fast_app()`

Line 4  
Toasts require sessions

Line 11  
Views with Toasts must return FT components.

## Authentication and authorization

In FastHTML the tasks of authentication and authorization are handled
with Beforeware. Beforeware are functions that run before the route
handler is called. They are useful for global tasks like ensuring users
are authenticated or have permissions to access a view.

First, we write a function that accepts a request and session arguments:

``` python
# Status code 303 is a redirect that can change POST to GET,
# so it's appropriate for a login page.
login_redir = RedirectResponse('/login', status_code=303)

def user_auth_before(req, sess):
    # The `auth` key in the request scope is automatically provided
    # to any handler which requests it, and can not be injected
    # by the user using query params, cookies, etc, so it should
    # be secure to use.    
    auth = req.scope['auth'] = sess.get('auth', None)
    # If the session key is not there, it redirects to the login page.
    if not auth: return login_redir
```

Now we pass our `user_auth_before` function as the first argument into a
[`Beforeware`](https://AnswerDotAI.github.io/fasthtml/api/core.html#beforeware)
class. We also pass a list of regular expressions to the `skip`
argument, designed to allow users to still get to the home and login
pages.

``` python
beforeware = Beforeware(
    user_auth_before,
    skip=[r'/favicon\.ico', r'/static/.*', r'.*\.css', r'.*\.js', '/login', '/']
)

app, rt = fast_app(before=beforeware)
```


## Testing views in notebooks

Because of the ASGI event loop it is currently impossible to run
FastHTML inside a notebook. However, we can still test the output of our
views. To do this, we leverage Starlette, an ASGI toolkit that FastHTML
uses.

``` python
# First we instantiate our app, in this case we remove the
# default headers to reduce the size of the output.
app, rt = fast_app(default_hdrs=False)

# Setting up the Starlette test client
from starlette.testclient import TestClient
client = TestClient(app)

# Usage example
@rt("/")
def get():
    return Titled("FastHTML is awesome", 
        P("The fastest way to create web apps in Python"))

print(client.get("/").text)
```

     <!doctype html>

     <html>
       <head>
         <title>FastHTML is awesome</title>
       </head>
       <body>
         <main class="container">
           <h1>FastHTML is awesome</h1>
           <p>The fastest way to create web apps in Python</p>
         </main>
       </body>
     </html>


## Other Static Media File Locations

As you saw,
[`Script`](https://AnswerDotAI.github.io/fasthtml/api/xtend.html#script)
and `Link` are specific to the most common static media use cases in web
apps: including JavaScript, CSS, and images. But it also works with
videos and other static media files. The default behavior is to look for
these files in the root directory - typically we don’t do anything
special to include them. We can change the default directory that is
looked in for files by adding the `static_path` parameter to the
[`fast_app`](https://AnswerDotAI.github.io/fasthtml/api/fastapp.html#fast_app)
function.

``` python
app, rt = fast_app(static_path='public')
```

FastHTML also allows us to define a route that uses `FileResponse` to
serve the file at a specified path. This is useful for serving images,
videos, and other media files from a different directory without having
to change the paths of many files. So if we move the directory
containing the media files, we only need to change the path in one
place. In the example below, we call images from a directory called
`public`.

``` python
@rt("/{fname:path}.{ext:static}")
async def get(fname:str, ext:str): 
    return FileResponse(f'public/{fname}.{ext}')
```

## Rendering Markdown

``` python
from fasthtml.common import *

hdrs = (MarkdownJS(), HighlightJS(langs=['python', 'javascript', 'html', 'css']), )

app, rt = fast_app(hdrs=hdrs)

content = """
Here are some _markdown_ elements.

- This is a list item
- This is another list item
- And this is a third list item

**Fenced code blocks work here.**
"""

@rt('/')
def get(req):
    return Titled("Markdown rendering example", Div(content,cls="marked"))

serve()
```

## Server-sent events (SSE)

With [server-sent
events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events),
it’s possible for a server to send new data to a web page at any time,
by pushing messages to the web page. Unlike WebSockets, SSE can only go
in one direction: server to client. SSE is also part of the HTTP
specification unlike WebSockets which uses its own specification.

FastHTML introduces several tools for working with SSE which are covered
in the example below. While concise, there’s a lot going on in this
function so we’ve annotated it quite a bit.

``` python
import random
from asyncio import sleep
from fasthtml.common import *

hdrs=(Script(src="https://unpkg.com/htmx-ext-sse@2.2.1/sse.js"),)
app,rt = fast_app(hdrs=hdrs)

@rt
def index():
    return Titled("SSE Random Number Generator",
        P("Generate pairs of random numbers, as the list grows scroll downwards."),
        Div(hx_ext="sse",
            sse_connect="/number-stream",
            hx_swap="beforeend show:bottom",
            sse_swap="message"))

shutdown_event = signal_shutdown()

async def number_generator():
    while not shutdown_event.is_set():
        data = Article(random.randint(1, 100))
        yield sse_message(data)
        await sleep(1)

@rt("/number-stream")
async def get(): return EventStream(number_generator())
```

Line 5  
Import the HTMX SSE extension

Line 12  
Tell HTMX to load the SSE extension

Line 13  
Look at the `/number-stream` endpoint for SSE content

Line 14  
When new items come in from the SSE endpoint, add them at the end of the
current content within the div. If they go beyond the screen, scroll
downwards

Line 15  
Specify the name of the event. FastHTML’s default event name is
“message”. Only change if you have more than one call to SSE endpoints
within a view

Line 17  
Set up the asyncio event loop

Line 19  
Don’t forget to make this an `async` function!

Line 20  
Iterate through the asyncio event loop

Line 22  
We yield the data. Data ideally should be comprised of FT components as
that plugs nicely into HTMX in the browser

Line 26  
The endpoint view needs to be an async function that returns a
[`EventStream`](https://AnswerDotAI.github.io/fasthtml/api/core.html#eventstream)

<div>

> **New content as of September 1, 2024**
>
> - [Forms](../tutorials/quickstart_for_web_devs.html#forms)
> - [Server-side Events
>   (SSE)](../tutorials/quickstart_for_web_devs.html#server-sent-events-sse)
>
> We’re going to be adding more to this document, so check back
> frequently for updates.

</div>


🗿 Surreal
Tiny jQuery alternative for plain Javascript with inline Locality of Behavior!


Why does this exist?
For devs who love ergonomics! You may appreciate Surreal if:
* You want to stay as close as possible to Vanilla JS.
* Hate typing document.querySelector over.. and over..
* Hate typing addEventListener over.. and over..
* Really wish document.querySelectorAll had Array functions..
* Really wish this would work in any inline <script> tag
* Enjoyed using jQuery selector syntax.
* Animations, timelines, tweens with no extra libraries.
* Only 320 lines. No build step. No dependencies.
* Pairs well with htmx
* Want fewer layers, less complexity. Are aware of the cargo cult. ✈️
✨ What does it add to Javascript?
* ⚡️ Locality of Behavior (LoB) Use me() inside <script>
    * No .class or #id needed! Get an element without creating a unique name.
    * this but much more flexible!
    * Want me in your CSS <style> tags, too? See our companion script
* 🔗 Call chaining, jQuery style.
* ♻️ Functions work seamlessly on 1 element or arrays of elements!
    * All functions can use: me(), any(), NodeList, HTMLElement (..or arrays of these!)
    * Get 1 element: me()
    * ..or many elements: any()
    * me() or any() can chain with any Surreal function.
        * me() can be used directly as a single element (like querySelector() or $())
        * any() can use: for / forEach / filter / map (like querySelectorAll() or $())
* 🌗 No forced style. Use: classAdd or class_add or addClass or add_class
    * Use camelCase (Javascript) or snake_case (Python, Rust, PHP, Ruby, SQL, CSS).
🤔 Why use me() / any() instead of $()
* 💡 Solves the classic jQuery bloat problem: Am I getting 1 element or an array of elements?
    * me() is guaranteed to return 1 element (or first found, or null).
    * any() is guaranteed to return an array (or empty array).
    * No more checks = write less code. Bonus: Reads more like self-documenting english.
Key Points:
* Surreal is a small Javascript library that offers a streamlined way to interact with the DOM (Document Object Model), similar to jQuery.
* It emphasizes Locality of Behavior using the me() function to easily access elements within inline <script> tags without relying on IDs or classes.
* It provides convenient functions for common tasks like adding/removing classes, handling events, and manipulating styles.
* It's designed to be lightweight, easy to use, and complementary to HTMX.
```