Skip to content

Commit

Permalink
Merge pull request #598 from AnswerDotAI/apirouter-refactor
Browse files Browse the repository at this point in the history
Made route functions accesible from an instance of APIRouter as well …
  • Loading branch information
jph00 authored Dec 12, 2024
2 parents 72dbc04 + 13b58d8 commit 6e7b2a4
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 10 deletions.
1 change: 1 addition & 0 deletions fasthtml/_modidx.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
'fasthtml.components.sse_message': ('api/components.html#sse_message', 'fasthtml/components.py')},
'fasthtml.core': { 'fasthtml.core.APIRouter': ('api/core.html#apirouter', 'fasthtml/core.py'),
'fasthtml.core.APIRouter.__call__': ('api/core.html#apirouter.__call__', 'fasthtml/core.py'),
'fasthtml.core.APIRouter.__getattr__': ('api/core.html#apirouter.__getattr__', 'fasthtml/core.py'),
'fasthtml.core.APIRouter.__init__': ('api/core.html#apirouter.__init__', 'fasthtml/core.py'),
'fasthtml.core.APIRouter._wrap_func': ('api/core.html#apirouter._wrap_func', 'fasthtml/core.py'),
'fasthtml.core.APIRouter.to_app': ('api/core.html#apirouter.to_app', 'fasthtml/core.py'),
Expand Down
9 changes: 7 additions & 2 deletions fasthtml/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -658,8 +658,9 @@ class RouteFuncs:
def __init__(self): super().__setattr__('_funcs', {})
def __setattr__(self, name, value): self._funcs[name] = value
def __getattr__(self, name):
if name in all_meths: raise KeyError("Route functions with HTTP Names are not accessible here")
return self._funcs[name]
if name in all_meths: raise AttributeError("Route functions with HTTP Names are not accessible here")
try: return self._funcs[name]
except KeyError: raise AttributeError(f"No route named {name} found in route functions")
def __dir__(self): return list(self._funcs.keys())

# %% ../nbs/api/00_core.ipynb
Expand All @@ -686,6 +687,10 @@ def f(func):
self.routes.append((func, p, methods, name, include_in_schema, body_wrap))
return wrapped
return f(path) if callable(path) else f

def __getattr__(self, name):
try: return getattr(self.rt_funcs, name)
except AttributeError: return super().__getattr__(self, name)

def to_app(self, app):
"Add routes to `app`"
Expand Down
32 changes: 24 additions & 8 deletions nbs/api/00_core.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@
{
"data": {
"text/plain": [
"datetime.datetime(2024, 12, 4, 14, 0)"
"datetime.datetime(2024, 12, 10, 14, 0)"
]
},
"execution_count": null,
Expand Down Expand Up @@ -2423,13 +2423,13 @@
"name": "stdout",
"output_type": "stream",
"text": [
"Set to 2024-12-04 09:20:09.428221\n"
"Set to 2024-12-10 09:54:42.331681\n"
]
},
{
"data": {
"text/plain": [
"'Session time: 2024-12-04 09:20:09.428221'"
"'Session time: 2024-12-10 09:54:42.331681'"
]
},
"execution_count": null,
Expand Down Expand Up @@ -2620,8 +2620,9 @@
" def __init__(self): super().__setattr__('_funcs', {})\n",
" def __setattr__(self, name, value): self._funcs[name] = value\n",
" def __getattr__(self, name): \n",
" if name in all_meths: raise KeyError(\"Route functions with HTTP Names are not accessible here\")\n",
" return self._funcs[name]\n",
" if name in all_meths: raise AttributeError(\"Route functions with HTTP Names are not accessible here\")\n",
" try: return self._funcs[name]\n",
" except KeyError: raise AttributeError(f\"No route named {name} found in route functions\")\n",
" def __dir__(self): return list(self._funcs.keys())"
]
},
Expand Down Expand Up @@ -2656,6 +2657,10 @@
" self.routes.append((func, p, methods, name, include_in_schema, body_wrap))\n",
" return wrapped\n",
" return f(path) if callable(path) else f\n",
" \n",
" def __getattr__(self, name):\n",
" try: return getattr(self.rt_funcs, name)\n",
" except AttributeError: return super().__getattr__(self, name)\n",
"\n",
" def to_app(self, app):\n",
" \"Add routes to `app`\"\n",
Expand Down Expand Up @@ -2720,8 +2725,14 @@
"metadata": {},
"outputs": [],
"source": [
"assert str(ar.rt_funcs.index) == '/'\n",
"assert str(yoyo) == '/yoyo'\n",
"# ensure route functions are properly discoverable on `APIRouter` and `APIRouter.rt_funcs`\n",
"assert ar.prefix == ''\n",
"assert str(ar.rt_funcs.index) == '/'\n",
"assert str(ar.index) == '/'\n",
"with ExceptionExpected(): ar.blah()\n",
"with ExceptionExpected(): ar.rt_funcs.blah()\n",
"# ensure any route functions named using an HTTPMethod are not discoverable via `rt_funcs`\n",
"assert \"get\" not in ar.rt_funcs._funcs.keys()"
]
},
Expand Down Expand Up @@ -2806,8 +2817,13 @@
"metadata": {},
"outputs": [],
"source": [
"assert str(ar2.rt_funcs.index) == '/products/'\n",
"assert str(yoyo) == '/products/yoyo'\n",
"assert ar2.prefix == '/products'\n",
"assert str(ar2.rt_funcs.index) == '/products/'\n",
"assert str(ar2.index) == '/products/'\n",
"assert str(ar.index) == '/'\n",
"with ExceptionExpected(): ar2.blah()\n",
"with ExceptionExpected(): ar2.rt_funcs.blah()\n",
"assert \"get\" not in ar2.rt_funcs._funcs.keys()"
]
},
Expand Down Expand Up @@ -2933,7 +2949,7 @@
{
"data": {
"text/plain": [
"'Cookie was set at time 09:20:09.542569'"
"'Cookie was set at time 09:54:43.255286'"
]
},
"execution_count": null,
Expand Down

0 comments on commit 6e7b2a4

Please sign in to comment.