nbdev icon indicating copy to clipboard operation
nbdev copied to clipboard

nbdev with fasthtml

Open michela opened this issue 11 months ago • 1 comments

Should there be a way to use nbdev to develop a package that uses fasthtml?

I'm trying to port the fasthtml 3d-component example to run in nbdev to understand the framework but getting stuck on paths and importers

This is related to my bigger issue which is I can't figure out how to reference static files so that they resolve in Jupyter, exported python package and docs.

I can resolve Jupyter and exported python package, using the following to use .parent in the exported python file and .cwd in Jupyter but can't find any docs on how to rewrite file_path to support nbdev_docs (which crashes not being able to resolve this file).

try:
    file_path = Path(__file__).parent/f"../nbs/static/data/csv/Mandarin vocab lists - hsk{config['hsk_level']}.csv"
except NameError:
    file_path = Path.cwd()/f"static/data/csv/Mandarin vocab lists - hsk{config['hsk_level']}.csv"

vocab = pd.read_csv(file_path)

I'm suspecting that nbdev & fasthtml (or any ASGI service) aren't compatible because I can happily run exported files in my editable package

 python -m hao.flashcards

but the ported 3d-components one (renamed https://github.com/AnswerDotAI/fasthtml-example/blob/main/3d-component/main.py to component.py) will start and then complain about the module as below

$ uv run python -m hao.component
Link: http://localhost:5001
INFO:     Will watch for changes in these directories: ['/home/XXX/src/hao']
INFO:     Uvicorn running on http://0.0.0.0:5001 (Press CTRL+C to quit)
INFO:     Started reloader process [10395] using WatchFiles
ERROR:    Error loading ASGI app. Could not import module "component".

Any advice?

michela avatar Mar 01 '25 09:03 michela

Worked out a few things which seem a bit convoluted. Hope there's a better way of doing this.

Resolving static file references

Root level "static" folder can be referenced as such from the ASGI server (not "/static") Path needs to be constructed differently for python package and Jupyter contexts to resolve file paths Neither works with nbdev_docs but you can catch error and modify Path yet again

try:
    # use in python package context
    file_path = Path(__file__).parent/f"../static/data/csv/Mandarin vocab lists - hsk{config['hsk_level']}.csv"
except NameError:
    # used in Jupyter context
    file_path = Path.cwd()/f"../static/data/csv/Mandarin vocab lists - hsk{config['hsk_level']}.csv"

try:
    vocab = pd.read_csv(file_path)
except FileNotFoundError as e:
    # use in nbdev_docs context
    logger.error(e)
    file_path = Path.cwd()/f"static/data/csv/Mandarin vocab lists - hsk{config['hsk_level']}.csv"
    vocab = pd.read_csv(file_path)

Is there a cleaner way to set up static files for referencing in all these contexts?

Running package as a module

I still can't run as a module as above but calling the script directly works. My package is 'hao'

e.g.

uv run python hao/flashcards.py

nbdev_export stripping out needed package name in import statements

python package only working with additional imports if you hack in the package name as used in Jupyter. Not sure why these are being stripped out

Was able to run the 3d component example by hacking the generator python file to add the package name to import.

e.g. the generator is stripping out the package name "hao" even though it's in the nb

from .playingcard import playing_card
from .card3d import card_3d

If I hack the autogen files like this, the ported example 3d-component works

from hao.playingcard import playing_card
from hao.card3d import card_3d

michela avatar Mar 02 '25 11:03 michela