fh-dev-utils


Namefh-dev-utils JSON
Version 0.0.2 PyPI version JSON
download
home_pagehttps://github.com/ExploringML/fh-dev-utils
SummaryUtility functions to help with the development of FastHTML applications.
upload_time2025-02-03 16:46:23
maintainerNone
docs_urlNone
authorDavid Gwyer
requires_python>=3.7
licenseApache Software License 2.0
keywords nbdev jupyter notebook python
VCS
bugtrack_url
requirements python-fasthtml pytailwindcss jupyterlab sqlite-web
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # FastHTML Developer Utils


<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->

## Why?

Here’s a brief outline of the benefits of using `fh-dev-utils`.

1.  Super-easy to dynamically build Tailwind styles!
2.  Compatible with [TailwindCSS
    v4](https://tailwindcss.com/blog/tailwindcss-v4).
3.  Cach buster to bypass browser styles during development.
4.  Run a Jupyter notebook server alongside your FastHTML app.
5.  Database browser to easily view/manage your apps db tables and
    records.
6.  TailwindCSS intellisense for a great developer experience.

It’s recommended by the authors of TailwindCSS uses a build step to
compile styles for published websites, rather than just add the CDN
version to the site header.

And if you like using Tailwind for your app styling then make sure you
[enable intellisense](#tailwind-intellisense). This is only available if
you dynamically build your styles. Being able to see inline color
information, all available tailwind classes, and what CSS a class will
be converted into is a game-changer!

A complete list of the benefits of compiling TailwindCSS styles can be
found [here](#tailwindcss-dynamic-build).

## Introduction

The `fh-dev-utils` package helps during the devlopment of FastHTML
applications by adding support for live TailwindCSS build, a Jupyter
notebook server, and an SQLite viewer/manager via the `serve_dev()`
function.

There is also a `cache_buster()` function available to help prevent
caching of CSS styles during development.

See [here](https://exploringml.github.io/fh-dev-utils/serve_dev.html)
for the full definition of `serve_dev()` and `cache_buster()` plus all
available parameters.

## Usage

Install the `fh-dev-utils` package from PyPi.

``` sh
$ pip install fh-dev-utils
```

Then import the `fh_dev_utils` package inside your FastHTML application.

`main.py`

``` python
from fasthtml.common import *
from fh_dev_utils.serve import *

app,rt = fast_app(live=True)

@rt('/')
def get(): return Div(P('Hello World!'))

#serve()
serve_dev()
```

Replace the default `serve()` function with `serve_dev()`. This performs
the same functionality as `serve()` but includes a few additional
enhancements, which make developing FastHTML applications a little
easier.

Currently `serve_dev()` offers three main features.

1.  TailwindCSS styles dynamic build process
2.  Jupyter notebook server
3.  SQLite database browser

Note: If you use `serve_dev()` without any options then it performs the
exact same function as `serve()`.

## 1. TailwindCSS Dynamic Build

Uses the TailwindCSS CLI to dynamically build styles as you edit your
apps source code.

Benefits include:

- Smaller CSS files size (only build what you have defined)
- Recommended best practice from the authors of TailwindCSS:
  - > The \[Play\] CDN is designed for development purposes only, and is
    > not intended for production.
- Use dynamic selectors such as `mb-[34px]`
- TailwindCSS intellisense support
- Custom configuration (e.g. plugins, and custom themes)

``` python
serve_dev(tw=True)
```

When you start a FastHTML app with the `tw` parameter enabled you’ll see
an additional link to open Jupyter Lab. By default the source
TailwindCSS file is assumed to be located in `./app.css` and the output
is saved to `./public/app.css`. Both these paths can be configured by
the `tw_src` and `tw_dist` parameters respectively.

``` sh
$ python main.py
Watching for Tailwind class changes...
Link: http://localhost:5001
INFO:     Will watch for changes in these directories: ['/home/david/fh-dev-utils-test']
INFO:     Uvicorn running on http://0.0.0.0:5001 (Press CTRL+C to quit)
INFO:     Started reloader process [1951725] using WatchFiles
INFO:     Started server process [1951759]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
```

### TailwindCSS Setup

The `serve_dev(tw=True)` function runs the TailwindCSS CLI to watch for
class name changes but you need to setup your FastHTML to be Tailwind
‘compatible’. This means adding a Tailwind source CSS file and a config
file.

In the root of your FastTML project add an `app.css` file:

``` css
@import "tailwindcss";
```

This is for TailwindCSS v4. If you’re using an older version then use
this format instead:

``` css
@tailwind base;
@tailwind components;
@tailwind utilities;
```

If your Tailwind CSS file is named something other then `app.css` or is
in a different location then you can use the `tw_src` parameter in
`serve_dev()` to change the name/path as required.

The last thing to do is add the generated Tailwind CSS file to the
header of your FastHTML site.

``` python
app,rt,todos,ToDo = fast_app(
    pico=False,
    live=True,
    hdrs=(
        Link(rel="stylesheet", href=f"/public/app.css{cache_buster() if DEV_MODE else ""}", type="text/css"),
    ),
)
```

This will add the necessary styles and will also bypass the browser CSS
cache via the `fh-dev-utils` `cache_buster()` function.

### Tailwind Intellisense

One of the advantages to building TailwindCSS styles dynamically is that
it enables support for auto-completion (intellisense) of Tailwind
classes as you type.

To get this working you need to be using VS Code and install the
[Tailwind CSS
IntelliSense](https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss)
extension.

You also need to edit the TailwindCSS VS Code settings so that
intellisense is auto-triggered as you edit your FastHTML app source
code.

Open the JSON user settings in VS Code and add the following settings to
the existing ones:

``` json
 {
  "tailwindCSS.includeLanguages": {
    "python": "html"
  },
  "tailwindCSS.experimental.classRegex": [
    "\\b[a-zA-Z_]+\\s*=\\s*[\"']([^\"']*)[\"']",
    "\"[^\"]+\"\\s*:\\s*\"([^\"]*)\"",
    "'[^']+'\\s*:\\s*'([^']*)'"
  ],
}
```

Once this is set up then you get full intellisense support.

<img src="https://raw.githubusercontent.com/ExploringML/fh-dev-utils/main/nbs/assets/tw-intellisense1.png" width="750" />

Plus, all colors are highlighted inline too, and you can hover over the
Tailwind class to see what the computed CSS will be when rendered!

<img src="https://raw.githubusercontent.com/ExploringML/fh-dev-utils/main/nbs/assets/tw-intellisense2.png" width="750" />

### Troubleshooting

If you don’t see a little color swatch next to the Tailwind color
classes then intellisense isn’t working. This is usually because the
TailwindCSS CLI is not running, or you don’t have a `tailwind.config.js`
added to the root of your FastHTML app.

Also, if you are using Linux under Windows (WSL) then make sure the
Tailwind CSS Intellisense VS Code extension is enabled for WSL.

## 2. Jupyter Notebook Server

It is often really useful to add one or more notebooks to your FastHTML
to enable quick exploration or research when developing you app. Use it
to test things out or as a scratch pad to try out ideas. You can then
transfer any code you want to incorporate into the FastHTML app.

The `serve_dev()` function makes this super-easy. Simply set the
`jupyter` argument to `True`:

``` python
serve_dev(jupyter=True)
```

When you start a FastHTML app with the `jupyter` parameter enabled
you’ll see an additional link to open Jupyter Lab. By default port 8036
will be used for the Jupyter lab server but this can be changed via the
`jupyter_port` parameter.

``` sh
$ python main.py
Jupyter Lab link: http://localhost:8036/lab
Link: http://localhost:5001
INFO:     Will watch for changes in these directories: ['/home/david/fh-dev-utils-test']
INFO:     Uvicorn running on http://0.0.0.0:5001 (Press CTRL+C to quit)
INFO:     Started reloader process [1951725] using WatchFiles
INFO:     Started server process [1951759]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
```

This will give you access to a full Jupyter Lab server that runs along
side your FastHTML app.

<img src="https://raw.githubusercontent.com/ExploringML/fh-dev-utils/main/nbs/assets/jupyter-1.png" width="750" />

A particularly useful way to use a notebook to complement your FastHTML
app is to view the schema for an SQLite database (only relevant if your
app includes a database).

<img src="https://raw.githubusercontent.com/ExploringML/fh-dev-utils/main/nbs/assets/jupyter-2.png" width="750" />

Note: The `fastlite` `diagram()` function requires
[`graphviz`](https://graphviz.org/) to be installed.

## 3. SQLite Database Browser

When working with an SQLite database in your FastHTML app it is often
useful to be able to easily view/edit database data. You can also do
this manually via a Jupyter Lab notebook too but it is very convenient
to have a dedicated app to be able to interect with your database.

We have included support for the
[`sqlite-web`](https://github.com/coleifer/sqlite-web) browser which is
written in Python.

``` python
serve_dev(db=True)
```

When you start a FastHTML app with the `db` parameter enabled you’ll see
an additional link to open sqlite-web database browser. By default port
8035 will be used for the SQLite browser but this can be changed via the
`sqlite_port` parameter. The database file can be configured via
`db_path`. By default it is set to `./data/app.db`.

``` sh
$ python main.py
SQLite link: http://localhost:8035
Link: http://localhost:5001
INFO:     Will watch for changes in these directories: ['/home/david/fh-dev-utils-test']
INFO:     Uvicorn running on http://0.0.0.0:5001 (Press CTRL+C to quit)
INFO:     Started reloader process [1988346] using WatchFiles
INFO:     Started server process [1988418]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
```

This will give you access to a full sqlite-web database server that runs
along side your FastHTML app.

<img src="https://raw.githubusercontent.com/ExploringML/fh-dev-utils/main/nbs/assets/sqlite-web-1.png" width="750" />

## Enabling All Options

If you enable TailwindCSS file watching, Jupyter Lab server, and
sqlite-web database browser altogether then the console output will look
like this when you first start a FastHTML app.

``` sh
$ python main.py
Watching for Tailwind class changes...
SQLite link: http://localhost:8035
Jupyter Lab link: http://localhost:8036/lab
Link: http://localhost:5001
INFO:     Will watch for changes in these directories: ['/home/david/fh-dev-utils-test']
INFO:     Uvicorn running on http://0.0.0.0:5001 (Press CTRL+C to quit)
INFO:     Started reloader process [1988346] using WatchFiles
INFO:     Started server process [1988418]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
```

All links are placed next to each other for convenience making it easy
to select which server (FastHTML, Jupyter, or sqlite-web) you want to
open in the browser.

## Example FastHTML Apps

Here are a couple of examples of full minimal FastHTML apps that
implement the `fh-dev-utils` package to make development easier.
Remember to include a config file if using TailwindCSS so that live
reload and auto-intellisense works properly.

In both examples a `DEV_MODE` variable is used to easily switch between
development and production. When `DEV_MODE` is enabled it uses CSS
browser cache busting, and uses the `serve_dev()` function. Otherwise,
in production, the CSS is cached and the FastHTML `serve()` function is
used.

This first one is very simple and doesn’t include a database:

``` python
from fasthtml.common import *
from fh_dev_utils.serve import *

DEV_MODE=True

app,rt = fast_app(
    pico=False,
    live=True,
    hdrs=(
        Link(rel="stylesheet", href=f"/public/app.css{cache_buster() if DEV_MODE else ""}", type="text/css"),
    )
)

@rt('/')
def get():
    return Div(
        P('Hello World!', cls="text-[#bada55] bg-gradient-to-r from-blue-400 to-purple-600 p-4 rounded-lg shadow-lg"),
        P('Blue Background', cls="bg-blue-500 text-white p-2 round"),
        P('Gradient Text', cls="bg-gradient-to-r from-pink-500 to-yellow-500 text-transparent bg-clip-text p-6"),
        cls="m-[41px] space-y-4"
    )

if DEV_MODE: serve_dev(tw=True, jupyter=True)
else: serve()
```

And here’s one that includes an SQLite database.

``` python
from fasthtml.common import *
from fh_dev_utils.serve import *

DEV_MODE=True

app,rt,todos,ToDo = fast_app('data/todos.db', id=int, title=str, pk='id', pico=True, live=True)

if not todos(): # Seed database if empty
    todos.insert_all([
        {"title": "Buy groceries"},
        {"title": "Finish blog post"},
        {"title": "Reply to emails"},
        {"title": "Plan weekend trip"},
        {"title": "Read AI research paper"}
    ]
)

def TodoRow(todo): return Li(todo.title, href=f'/todos/{todo.id}', id=f'todo-{todo.id}')

def home():
    add = Form(
            Group(
                Input(name="title", placeholder="New Todo"),
                Button("Add")
            ), action="/", method='post'
        )
    card = Card(
                Ul(*map(TodoRow, todos()), id='todo-list', style="padding:20px;"),
                header=add,
                footer=Div(id='current-todo')
            )
    return Titled('Todo list', card)

@rt("/")
def get(): return home()

@rt("/")
def post(todo:ToDo):
    todos.insert(todo)
    return home()

if DEV_MODE: serve_dev(db=True, db_path='data/todos.db')
else: serve()
```

This is a very minimal database app just as an illustrative example of
using `serve_dev()` to spin up a database browser. You can only add and
view todo items. However, using `sqlite-web` you can browse the database
and add/edit/remove items very easily!

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/ExploringML/fh-dev-utils",
    "name": "fh-dev-utils",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.7",
    "maintainer_email": null,
    "keywords": "nbdev jupyter notebook python",
    "author": "David Gwyer",
    "author_email": "d.v.gwyer@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/68/ad/4925c28a0dc215861a4475a3c80dd7e86f02dd6464f25fd00163dc4e7ffb/fh_dev_utils-0.0.2.tar.gz",
    "platform": null,
    "description": "# FastHTML Developer Utils\n\n\n<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->\n\n## Why?\n\nHere\u2019s a brief outline of the benefits of using `fh-dev-utils`.\n\n1.  Super-easy to dynamically build Tailwind styles!\n2.  Compatible with [TailwindCSS\n    v4](https://tailwindcss.com/blog/tailwindcss-v4).\n3.  Cach buster to bypass browser styles during development.\n4.  Run a Jupyter notebook server alongside your FastHTML app.\n5.  Database browser to easily view/manage your apps db tables and\n    records.\n6.  TailwindCSS intellisense for a great developer experience.\n\nIt\u2019s recommended by the authors of TailwindCSS uses a build step to\ncompile styles for published websites, rather than just add the CDN\nversion to the site header.\n\nAnd if you like using Tailwind for your app styling then make sure you\n[enable intellisense](#tailwind-intellisense). This is only available if\nyou dynamically build your styles. Being able to see inline color\ninformation, all available tailwind classes, and what CSS a class will\nbe converted into is a game-changer!\n\nA complete list of the benefits of compiling TailwindCSS styles can be\nfound [here](#tailwindcss-dynamic-build).\n\n## Introduction\n\nThe `fh-dev-utils` package helps during the devlopment of FastHTML\napplications by adding support for live TailwindCSS build, a Jupyter\nnotebook server, and an SQLite viewer/manager via the `serve_dev()`\nfunction.\n\nThere is also a `cache_buster()` function available to help prevent\ncaching of CSS styles during development.\n\nSee [here](https://exploringml.github.io/fh-dev-utils/serve_dev.html)\nfor the full definition of `serve_dev()` and `cache_buster()` plus all\navailable parameters.\n\n## Usage\n\nInstall the `fh-dev-utils` package from PyPi.\n\n``` sh\n$ pip install fh-dev-utils\n```\n\nThen import the `fh_dev_utils` package inside your FastHTML application.\n\n`main.py`\n\n``` python\nfrom fasthtml.common import *\nfrom fh_dev_utils.serve import *\n\napp,rt = fast_app(live=True)\n\n@rt('/')\ndef get(): return Div(P('Hello World!'))\n\n#serve()\nserve_dev()\n```\n\nReplace the default `serve()` function with `serve_dev()`. This performs\nthe same functionality as `serve()` but includes a few additional\nenhancements, which make developing FastHTML applications a little\neasier.\n\nCurrently `serve_dev()` offers three main features.\n\n1.  TailwindCSS styles dynamic build process\n2.  Jupyter notebook server\n3.  SQLite database browser\n\nNote: If you use `serve_dev()` without any options then it performs the\nexact same function as `serve()`.\n\n## 1. TailwindCSS Dynamic Build\n\nUses the TailwindCSS CLI to dynamically build styles as you edit your\napps source code.\n\nBenefits include:\n\n- Smaller CSS files size (only build what you have defined)\n- Recommended best practice from the authors of TailwindCSS:\n  - > The \\[Play\\] CDN is designed for development purposes only, and is\n    > not intended for production.\n- Use dynamic selectors such as `mb-[34px]`\n- TailwindCSS intellisense support\n- Custom configuration (e.g.\u00a0plugins, and custom themes)\n\n``` python\nserve_dev(tw=True)\n```\n\nWhen you start a FastHTML app with the `tw` parameter enabled you\u2019ll see\nan additional link to open Jupyter Lab. By default the source\nTailwindCSS file is assumed to be located in `./app.css` and the output\nis saved to `./public/app.css`. Both these paths can be configured by\nthe `tw_src` and `tw_dist` parameters respectively.\n\n``` sh\n$ python main.py\nWatching for Tailwind class changes...\nLink: http://localhost:5001\nINFO:     Will watch for changes in these directories: ['/home/david/fh-dev-utils-test']\nINFO:     Uvicorn running on http://0.0.0.0:5001 (Press CTRL+C to quit)\nINFO:     Started reloader process [1951725] using WatchFiles\nINFO:     Started server process [1951759]\nINFO:     Waiting for application startup.\nINFO:     Application startup complete.\n```\n\n### TailwindCSS Setup\n\nThe `serve_dev(tw=True)` function runs the TailwindCSS CLI to watch for\nclass name changes but you need to setup your FastHTML to be Tailwind\n\u2018compatible\u2019. This means adding a Tailwind source CSS file and a config\nfile.\n\nIn the root of your FastTML project add an `app.css` file:\n\n``` css\n@import \"tailwindcss\";\n```\n\nThis is for TailwindCSS v4. If you\u2019re using an older version then use\nthis format instead:\n\n``` css\n@tailwind base;\n@tailwind components;\n@tailwind utilities;\n```\n\nIf your Tailwind CSS file is named something other then `app.css` or is\nin a different location then you can use the `tw_src` parameter in\n`serve_dev()` to change the name/path as required.\n\nThe last thing to do is add the generated Tailwind CSS file to the\nheader of your FastHTML site.\n\n``` python\napp,rt,todos,ToDo = fast_app(\n    pico=False,\n    live=True,\n    hdrs=(\n        Link(rel=\"stylesheet\", href=f\"/public/app.css{cache_buster() if DEV_MODE else \"\"}\", type=\"text/css\"),\n    ),\n)\n```\n\nThis will add the necessary styles and will also bypass the browser CSS\ncache via the `fh-dev-utils` `cache_buster()` function.\n\n### Tailwind Intellisense\n\nOne of the advantages to building TailwindCSS styles dynamically is that\nit enables support for auto-completion (intellisense) of Tailwind\nclasses as you type.\n\nTo get this working you need to be using VS Code and install the\n[Tailwind CSS\nIntelliSense](https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss)\nextension.\n\nYou also need to edit the TailwindCSS VS Code settings so that\nintellisense is auto-triggered as you edit your FastHTML app source\ncode.\n\nOpen the JSON user settings in VS Code and add the following settings to\nthe existing ones:\n\n``` json\n {\n  \"tailwindCSS.includeLanguages\": {\n    \"python\": \"html\"\n  },\n  \"tailwindCSS.experimental.classRegex\": [\n    \"\\\\b[a-zA-Z_]+\\\\s*=\\\\s*[\\\"']([^\\\"']*)[\\\"']\",\n    \"\\\"[^\\\"]+\\\"\\\\s*:\\\\s*\\\"([^\\\"]*)\\\"\",\n    \"'[^']+'\\\\s*:\\\\s*'([^']*)'\"\n  ],\n}\n```\n\nOnce this is set up then you get full intellisense support.\n\n<img src=\"https://raw.githubusercontent.com/ExploringML/fh-dev-utils/main/nbs/assets/tw-intellisense1.png\" width=\"750\" />\n\nPlus, all colors are highlighted inline too, and you can hover over the\nTailwind class to see what the computed CSS will be when rendered!\n\n<img src=\"https://raw.githubusercontent.com/ExploringML/fh-dev-utils/main/nbs/assets/tw-intellisense2.png\" width=\"750\" />\n\n### Troubleshooting\n\nIf you don\u2019t see a little color swatch next to the Tailwind color\nclasses then intellisense isn\u2019t working. This is usually because the\nTailwindCSS CLI is not running, or you don\u2019t have a `tailwind.config.js`\nadded to the root of your FastHTML app.\n\nAlso, if you are using Linux under Windows (WSL) then make sure the\nTailwind CSS Intellisense VS Code extension is enabled for WSL.\n\n## 2. Jupyter Notebook Server\n\nIt is often really useful to add one or more notebooks to your FastHTML\nto enable quick exploration or research when developing you app. Use it\nto test things out or as a scratch pad to try out ideas. You can then\ntransfer any code you want to incorporate into the FastHTML app.\n\nThe `serve_dev()` function makes this super-easy. Simply set the\n`jupyter` argument to `True`:\n\n``` python\nserve_dev(jupyter=True)\n```\n\nWhen you start a FastHTML app with the `jupyter` parameter enabled\nyou\u2019ll see an additional link to open Jupyter Lab. By default port 8036\nwill be used for the Jupyter lab server but this can be changed via the\n`jupyter_port` parameter.\n\n``` sh\n$ python main.py\nJupyter Lab link: http://localhost:8036/lab\nLink: http://localhost:5001\nINFO:     Will watch for changes in these directories: ['/home/david/fh-dev-utils-test']\nINFO:     Uvicorn running on http://0.0.0.0:5001 (Press CTRL+C to quit)\nINFO:     Started reloader process [1951725] using WatchFiles\nINFO:     Started server process [1951759]\nINFO:     Waiting for application startup.\nINFO:     Application startup complete.\n```\n\nThis will give you access to a full Jupyter Lab server that runs along\nside your FastHTML app.\n\n<img src=\"https://raw.githubusercontent.com/ExploringML/fh-dev-utils/main/nbs/assets/jupyter-1.png\" width=\"750\" />\n\nA particularly useful way to use a notebook to complement your FastHTML\napp is to view the schema for an SQLite database (only relevant if your\napp includes a database).\n\n<img src=\"https://raw.githubusercontent.com/ExploringML/fh-dev-utils/main/nbs/assets/jupyter-2.png\" width=\"750\" />\n\nNote: The `fastlite` `diagram()` function requires\n[`graphviz`](https://graphviz.org/) to be installed.\n\n## 3. SQLite Database Browser\n\nWhen working with an SQLite database in your FastHTML app it is often\nuseful to be able to easily view/edit database data. You can also do\nthis manually via a Jupyter Lab notebook too but it is very convenient\nto have a dedicated app to be able to interect with your database.\n\nWe have included support for the\n[`sqlite-web`](https://github.com/coleifer/sqlite-web) browser which is\nwritten in Python.\n\n``` python\nserve_dev(db=True)\n```\n\nWhen you start a FastHTML app with the `db` parameter enabled you\u2019ll see\nan additional link to open sqlite-web database browser. By default port\n8035 will be used for the SQLite browser but this can be changed via the\n`sqlite_port` parameter. The database file can be configured via\n`db_path`. By default it is set to `./data/app.db`.\n\n``` sh\n$ python main.py\nSQLite link: http://localhost:8035\nLink: http://localhost:5001\nINFO:     Will watch for changes in these directories: ['/home/david/fh-dev-utils-test']\nINFO:     Uvicorn running on http://0.0.0.0:5001 (Press CTRL+C to quit)\nINFO:     Started reloader process [1988346] using WatchFiles\nINFO:     Started server process [1988418]\nINFO:     Waiting for application startup.\nINFO:     Application startup complete.\n```\n\nThis will give you access to a full sqlite-web database server that runs\nalong side your FastHTML app.\n\n<img src=\"https://raw.githubusercontent.com/ExploringML/fh-dev-utils/main/nbs/assets/sqlite-web-1.png\" width=\"750\" />\n\n## Enabling All Options\n\nIf you enable TailwindCSS file watching, Jupyter Lab server, and\nsqlite-web database browser altogether then the console output will look\nlike this when you first start a FastHTML app.\n\n``` sh\n$ python main.py\nWatching for Tailwind class changes...\nSQLite link: http://localhost:8035\nJupyter Lab link: http://localhost:8036/lab\nLink: http://localhost:5001\nINFO:     Will watch for changes in these directories: ['/home/david/fh-dev-utils-test']\nINFO:     Uvicorn running on http://0.0.0.0:5001 (Press CTRL+C to quit)\nINFO:     Started reloader process [1988346] using WatchFiles\nINFO:     Started server process [1988418]\nINFO:     Waiting for application startup.\nINFO:     Application startup complete.\n```\n\nAll links are placed next to each other for convenience making it easy\nto select which server (FastHTML, Jupyter, or sqlite-web) you want to\nopen in the browser.\n\n## Example FastHTML Apps\n\nHere are a couple of examples of full minimal FastHTML apps that\nimplement the `fh-dev-utils` package to make development easier.\nRemember to include a config file if using TailwindCSS so that live\nreload and auto-intellisense works properly.\n\nIn both examples a `DEV_MODE` variable is used to easily switch between\ndevelopment and production. When `DEV_MODE` is enabled it uses CSS\nbrowser cache busting, and uses the `serve_dev()` function. Otherwise,\nin production, the CSS is cached and the FastHTML `serve()` function is\nused.\n\nThis first one is very simple and doesn\u2019t include a database:\n\n``` python\nfrom fasthtml.common import *\nfrom fh_dev_utils.serve import *\n\nDEV_MODE=True\n\napp,rt = fast_app(\n    pico=False,\n    live=True,\n    hdrs=(\n        Link(rel=\"stylesheet\", href=f\"/public/app.css{cache_buster() if DEV_MODE else \"\"}\", type=\"text/css\"),\n    )\n)\n\n@rt('/')\ndef get():\n    return Div(\n        P('Hello World!', cls=\"text-[#bada55] bg-gradient-to-r from-blue-400 to-purple-600 p-4 rounded-lg shadow-lg\"),\n        P('Blue Background', cls=\"bg-blue-500 text-white p-2 round\"),\n        P('Gradient Text', cls=\"bg-gradient-to-r from-pink-500 to-yellow-500 text-transparent bg-clip-text p-6\"),\n        cls=\"m-[41px] space-y-4\"\n    )\n\nif DEV_MODE: serve_dev(tw=True, jupyter=True)\nelse: serve()\n```\n\nAnd here\u2019s one that includes an SQLite database.\n\n``` python\nfrom fasthtml.common import *\nfrom fh_dev_utils.serve import *\n\nDEV_MODE=True\n\napp,rt,todos,ToDo = fast_app('data/todos.db', id=int, title=str, pk='id', pico=True, live=True)\n\nif not todos(): # Seed database if empty\n    todos.insert_all([\n        {\"title\": \"Buy groceries\"},\n        {\"title\": \"Finish blog post\"},\n        {\"title\": \"Reply to emails\"},\n        {\"title\": \"Plan weekend trip\"},\n        {\"title\": \"Read AI research paper\"}\n    ]\n)\n\ndef TodoRow(todo): return Li(todo.title, href=f'/todos/{todo.id}', id=f'todo-{todo.id}')\n\ndef home():\n    add = Form(\n            Group(\n                Input(name=\"title\", placeholder=\"New Todo\"),\n                Button(\"Add\")\n            ), action=\"/\", method='post'\n        )\n    card = Card(\n                Ul(*map(TodoRow, todos()), id='todo-list', style=\"padding:20px;\"),\n                header=add,\n                footer=Div(id='current-todo')\n            )\n    return Titled('Todo list', card)\n\n@rt(\"/\")\ndef get(): return home()\n\n@rt(\"/\")\ndef post(todo:ToDo):\n    todos.insert(todo)\n    return home()\n\nif DEV_MODE: serve_dev(db=True, db_path='data/todos.db')\nelse: serve()\n```\n\nThis is a very minimal database app just as an illustrative example of\nusing `serve_dev()` to spin up a database browser. You can only add and\nview todo items. However, using `sqlite-web` you can browse the database\nand add/edit/remove items very easily!\n",
    "bugtrack_url": null,
    "license": "Apache Software License 2.0",
    "summary": "Utility functions to help with the development of FastHTML applications.",
    "version": "0.0.2",
    "project_urls": {
        "Homepage": "https://github.com/ExploringML/fh-dev-utils"
    },
    "split_keywords": [
        "nbdev",
        "jupyter",
        "notebook",
        "python"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "2451f54f514626c4e619c2817d2f4c7e926d596b2a44903c93e0377660e8946c",
                "md5": "857ad8d8138d7a4125b72f32d0f91f88",
                "sha256": "4f3b8b4b58f8ce1b3b430e7741611cb6e330a5375378ea084853ce3df5729dfc"
            },
            "downloads": -1,
            "filename": "fh_dev_utils-0.0.2-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "857ad8d8138d7a4125b72f32d0f91f88",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 12431,
            "upload_time": "2025-02-03T16:46:21",
            "upload_time_iso_8601": "2025-02-03T16:46:21.719433Z",
            "url": "https://files.pythonhosted.org/packages/24/51/f54f514626c4e619c2817d2f4c7e926d596b2a44903c93e0377660e8946c/fh_dev_utils-0.0.2-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "68ad4925c28a0dc215861a4475a3c80dd7e86f02dd6464f25fd00163dc4e7ffb",
                "md5": "6b344518d440e38ff5868e5b314f719f",
                "sha256": "cf0f843f09521520c4a6273f6ab0a06a009eaa4e4a99454e38e4c24e21079fc7"
            },
            "downloads": -1,
            "filename": "fh_dev_utils-0.0.2.tar.gz",
            "has_sig": false,
            "md5_digest": "6b344518d440e38ff5868e5b314f719f",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7",
            "size": 13696,
            "upload_time": "2025-02-03T16:46:23",
            "upload_time_iso_8601": "2025-02-03T16:46:23.168408Z",
            "url": "https://files.pythonhosted.org/packages/68/ad/4925c28a0dc215861a4475a3c80dd7e86f02dd6464f25fd00163dc4e7ffb/fh_dev_utils-0.0.2.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-02-03 16:46:23",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "ExploringML",
    "github_project": "fh-dev-utils",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [
        {
            "name": "python-fasthtml",
            "specs": []
        },
        {
            "name": "pytailwindcss",
            "specs": []
        },
        {
            "name": "jupyterlab",
            "specs": []
        },
        {
            "name": "sqlite-web",
            "specs": []
        }
    ],
    "lcname": "fh-dev-utils"
}
        
Elapsed time: 0.79716s