Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dude, Where's My bool? #583

Closed
miklevin opened this issue Nov 20, 2024 · 4 comments
Closed

Dude, Where's My bool? #583

miklevin opened this issue Nov 20, 2024 · 4 comments
Assignees
Labels
bug Something isn't working

Comments

@miklevin
Copy link

Describe the bug

Auto create-table fails on bool fields. System thinks field name is bool value (True)

(bool broke)

Debugging table schemas:

task schema:
id: <class 'int'> (<class 'type'>)
title: <class 'str'> (<class 'type'>)
done: <class 'bool'> (<class 'type'>)
priority: <class 'int'> (<class 'type'>)
profile_id: <class 'int'> (<class 'type'>)
pk: id (<class 'str'>)
Traceback (most recent call last):
File "/home/mike/repos/botifython/botifymograph.py", line 2147, in
app, rt, (tasks, Task) = debug_fast_app(
^^^^^^^^^^^^^^^
File "/home/mike/repos/botifython/botifymograph.py", line 2142, in debug_fast_app
result = fast_app(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/mike/repos/botifython/.venv/lib/python3.11/site-packages/fasthtml/fastapp.py", line 84, in fast_app
dbtbls = [_get_tbl(db.t, k, v) for k,v in tbls.items()]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/mike/repos/botifython/.venv/lib/python3.11/site-packages/fasthtml/fastapp.py", line 84, in
dbtbls = [_get_tbl(db.t, k, v) for k,v in tbls.items()]
^^^^^^^^^^^^^^^^^^^^
File "/home/mike/repos/botifython/.venv/lib/python3.11/site-packages/fasthtml/fastapp.py", line 16, in _get_tbl
if tbl not in dt: tbl.create(**schema)
^^^^^^^^^^^^^^^^^^^^
File "/home/mike/repos/botifython/.venv/lib/python3.11/site-packages/fastlite/kw.py", line 80, in create
return self._orig_create(
^^^^^^^^^^^^^^^^^^
File "/home/mike/repos/botifython/.venv/lib/python3.11/site-packages/sqlite_minutils/db.py", line 1645, in create
self.db.create_table(
File "/home/mike/repos/botifython/.venv/lib/python3.11/site-packages/sqlite_minutils/db.py", line 997, in create_table
sql = self.create_table_sql(
^^^^^^^^^^^^^^^^^^^^^^
File "/home/mike/repos/botifython/.venv/lib/python3.11/site-packages/sqlite_minutils/db.py", line 876, in create_table_sql
column_type=COLUMN_TYPE_MAPPING[column_type],
~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^
KeyError: True

Minimal Reproducible Example

# Debug wrapper
def debug_fast_app(*args, **kwargs):
    print("\nDebugging table schemas:")
    for k, v in kwargs.items():
        if isinstance(v, dict) and 'pk' in v:  # This identifies our table schemas
            print(f"\n{k} schema:")
            for field, type_ in v.items():
                print(f"  {field}: {type_} ({type(type_)})")
    
    result = fast_app(*args, **kwargs)
    return result


app, rt, (tasks, Task) = debug_fast_app(
    "data/data.db",
    live=True,
    task={
        "id": int,
        "title": str,
        "done": bool,
        "priority": int,
        "profile_id": int,
        "pk": "id"
    }
)

Expected behavior
Table to be created

Environment Information
FAILS ON FASTHTML VERSIONS 0.7.0 to 0.10.0

Name: fastlite
Version: 0.0.13

Name: fastcore
Version: 1.7.20

Name: python-fasthtml
Version: 0.10.0

THE VERSION IT WORKS UNDER <-- Pinning to 0.6.14 (at the latest) fixes

Name: fastlite
Version: 0.0.13

Name: fastcore
Version: 1.7.20

Name: python-fasthtml
Version: 0.6.14

Confirmation
Please confirm the following:

  • [ yes siree ] I have read the FAQ (https://docs.fastht.ml/explains/faq.html)
  • [ todo... done! ] I have provided a minimal reproducible example
  • [ meticulously, including cutoff where it broke ] I have included the versions of fastlite, fastcore, and fasthtml
  • [ and I thank you profusely ] I understand that this is a volunteer open source project with no commercial support.

Additional context
Impossible to believe I'm the only one encounterng / reporting as it is THE use case example.

@miklevin miklevin added the bug Something isn't working label Nov 20, 2024
@jph00
Copy link
Contributor

jph00 commented Nov 22, 2024

@pydanny @audreyfeldroy would you like to look at this one?

@pydanny
Copy link
Collaborator

pydanny commented Dec 28, 2024

Hey @miklevin, I know it's been a while but I just dug into your reported bug. I can't replicate your challenge. See some of my efforts to do so here: https://gist.github.com/pydanny/3bc248038542565ae8151397159f267b

FWIW, we've replaced sqlite-minutils with apswutils. Which uses a different Sqlite3 wrapper than what is provided in core python. That may explain why I can't replicate your bug.

Can you try replicating the bug yourself? Perhaps I'm missing something.

@jph00 jph00 closed this as completed Dec 28, 2024
@miklevin
Copy link
Author

miklevin commented Dec 30, 2024

TLDR: can't delete this. It ws a breaking change I didn't keep up with: ws_hdr=True was being interpreted as a automatic table creation by **kwargs splatting. I've got to follow the breaking changes!

Okay, here's my requirements.txt before:

autopep8
isort
vulture

aiohttp
beautifulsoup4
loguru
pyfiglet
python_fasthtml==0.6.14  # bool broke beyond this version
Requests
rich
watchdog

jupyterlab
jupyterlab-spellchecker
jupytext
nb-clean
itables
pandas

tiktoken

Alll is working. I make this edit:

python_fasthtml

which unpins the 0.6.14 version.

I force an update of my pip installed packages.

pip install -r requirements.txt --upgrade --force-reinstall

I delete my fasthtml-created .db file.

I start my app.

Traceback (most recent call last):
  File "/home/mike/repos/botifython/botifython.py", line 3609, in <module>
    app, rt, (store, Store), (tasks, Task), (clients, Client), (pipeline, Pipeline) = fast_app(
                                                                                      ^^^^^^^^^
  File "/home/mike/repos/botifython/.venv/lib/python3.11/site-packages/fasthtml/fastapp.py", line 84, in fast_app
    dbtbls = [_get_tbl(db.t, k, v) for k,v in tbls.items()]
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mike/repos/botifython/.venv/lib/python3.11/site-packages/fasthtml/fastapp.py", line 84, in <listcomp>
    dbtbls = [_get_tbl(db.t, k, v) for k,v in tbls.items()]
              ^^^^^^^^^^^^^^^^^^^^
  File "/home/mike/repos/botifython/.venv/lib/python3.11/site-packages/fasthtml/fastapp.py", line 16, in _get_tbl
    if tbl not in dt: tbl.create(**schema)
                      ^^^^^^^^^^^^^^^^^^^^
  File "/home/mike/repos/botifython/.venv/lib/python3.11/site-packages/fastlite/kw.py", line 90, in create
    return self._orig_create(
           ^^^^^^^^^^^^^^^^^^
  File "/home/mike/repos/botifython/.venv/lib/python3.11/site-packages/apswutils/db.py", line 1660, in create
    self.db.create_table(
  File "/home/mike/repos/botifython/.venv/lib/python3.11/site-packages/apswutils/db.py", line 1001, in create_table
    sql = self.create_table_sql(
          ^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mike/repos/botifython/.venv/lib/python3.11/site-packages/apswutils/db.py", line 879, in create_table_sql
    column_type=COLUMN_TYPE_MAPPING[column_type],
                ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^
KeyError: True

I re-pin to fasthtml version 0.6.14

I force the re-install of all my pip packages.

Database gets created seamlessly. App working.

nixos-version
25.05beta724962.d70bd19e0a38 (Warbler)

uname -m
x86_64

uname -r
6.6.66

nix-channel --list
nixos https://nixos.org/channels/nixos-unstable

python --version
Python 3.11.10

And the code it's choking on, in all locations where a bool is used, it's trying to use a bool value as the field name. Let me know anything else I can provide.

# Configure app by unpacking the returned glboal scope (table, Dataclass) tuple pairs (singular, Plural)
app, rt, (store, Store), (tasks, Task), (clients, Client), (pipeline, Pipeline) = fast_app(
    "data/data.db",
    ws_hdr=True,  # Turns on WebSockets for 2-way chat
    live=True,    # Make edit, check page, make edit, check page... this is how.
    default_hdrs=False,  # See all that hdrs stuff immediately below I want to control deliberately? Needs this.
    hdrs=(
        Meta(charset='utf-8'),              # Best to let your browser know your encoding sooner rather than later
        Link(rel='stylesheet', href='/static/pico.css'),  # We load our dependencies statically around here
        Script(src='/static/htmx.min.js'),  # htmx is the backbone of the UI
        Script(src='/static/fasthtml.js'),  # FastHTML is not FastAPI. I can't emphasize this enough.
        Script(src='/static/surreal.js'),   # Enables dynamic updates to the user interface without requiring full page reloads. How to describe it? It's just...
        Script(src='/static/script.js'),    # A not-so-descriptive name for a file that cleverly scopes styles and keeps your CSS drama-free!
        Script(src='/static/Sortable.js'),  # Got a UL with LI's and want to make them drag-and-drop sortable? This is how.
        create_chat_scripts('.sortable'),   # All the early pageload JavaScript not part of above.
        Script(type='module')               # Because FastHTML has a bug and I need to include this to force the correct JS import pattern.
    ),
    store={            # server-side DictLikeDB store used for persistence
        "key": str,    # Key is the primary key
        "value": str,  # Value is the value of the key
        "pk": "key"    # Never twice the same key (updates override)
    },
    task={                  # Exposed to user as "task" endpoint but hardwired to "todo" in the wiring. New instances will have to accomodate in their render_item() method.
        "id": int,          # We lean into the strengths of SQLite. Auto-increment primary key work well.
        "name": str,        # Changed from "title" to "name"
        "done": bool,       # Done is a boolean flag to indicate if the task is completed
        "priority": int,    # Integrates beautifully with Sortable.js to sort tasks by priority
        "profile_id": int,  # Foreign key to profile for use with MiniDataAPI Spec .xtra() extract filter to filter TodoApp by profile
        "pk": "id"          # A task by any other name is still a todo item or generic linked-list CRUD app
    },
    client={               # "client" exposed to user as endpoint but hardwired to "profile" in the wiring of plugin element IDs in Web UI
        "id": int,         # To be defined as a SQLite auto-increment primary key via MiniDataAPI Spec
        "name": str,       # Name is actually hidden on the menu so real client names are never exposed unless in client (profile) list app
        "menu_name": str,  # Menu name is exposed on the menu so user can switch profiles in front of client without showing other client names
        "address": str,    # Address is actually used for website domain to control other apps like gap analysis
        "code": str,       # Code is actually country code used to control data-pull filters in API integrations like SEMRush
        "active": bool,    # Active lets you toggle the profile on and off in the menu
        "priority": int,   # Controls the sort order of the profile in the menu
        "pk": "id"         # Default SQLite auto-increment primary key so name and menu_name can be freely changed
    },
    pipeline={           # To "pipulate" is use this for a Unix pipe-like "pipeline" workflow: Card 1 | Card 2 | Card 3
        "url": str,      # A url must be used on Card 1 to initiate a job, and can be plugged in later to from last complete Card step
        "data": str,     # All jobs get just 1 pipulate record and use a JSON blob to track state for the entire workflow. The JSON blog contains the args and results of each Card for interruptionless pattern
        "created": str,  # ISO timestamp of first insert
        "updated": str,  # ISO timestamp of last update
        "pk": "url"      # URL is the primary key and can always be plugged into Card 1 to continue a job, jumping to where it left off (the same behavior as any step of workflow processing)
    }                    # A FastHTML-friendly querystring-like path can be used to jump to any Card in the workflow: /endpoint/card3

@miklevin
Copy link
Author

Oops, ws_hdr and cts_hdr both removed from FastHTML and fast_app; replaced with exts, which takes a list of extension names (e.g. exts='ws')

Breaking changes. I got it. Thanks for the investigation anyway. Interesting to have tracked down ws_hdr now gets interpreted as a splat table create!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants