python-fasthtml 0.12.41__tar.gz → 0.12.43__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {python_fasthtml-0.12.41/python_fasthtml.egg-info → python_fasthtml-0.12.43}/PKG-INFO +1 -1
- python_fasthtml-0.12.43/fasthtml/__init__.py +2 -0
- {python_fasthtml-0.12.41 → python_fasthtml-0.12.43}/fasthtml/_modidx.py +4 -0
- {python_fasthtml-0.12.41 → python_fasthtml-0.12.43}/fasthtml/core.py +22 -13
- {python_fasthtml-0.12.41 → python_fasthtml-0.12.43}/fasthtml/oauth.py +10 -4
- {python_fasthtml-0.12.41 → python_fasthtml-0.12.43/python_fasthtml.egg-info}/PKG-INFO +1 -1
- python_fasthtml-0.12.41/fasthtml/__init__.py +0 -2
- {python_fasthtml-0.12.41 → python_fasthtml-0.12.43}/CONTRIBUTING.md +0 -0
- {python_fasthtml-0.12.41 → python_fasthtml-0.12.43}/LICENSE +0 -0
- {python_fasthtml-0.12.41 → python_fasthtml-0.12.43}/MANIFEST.in +0 -0
- {python_fasthtml-0.12.41 → python_fasthtml-0.12.43}/README.md +0 -0
- {python_fasthtml-0.12.41 → python_fasthtml-0.12.43}/fasthtml/authmw.py +0 -0
- {python_fasthtml-0.12.41 → python_fasthtml-0.12.43}/fasthtml/basics.py +0 -0
- {python_fasthtml-0.12.41 → python_fasthtml-0.12.43}/fasthtml/cli.py +0 -0
- {python_fasthtml-0.12.41 → python_fasthtml-0.12.43}/fasthtml/common.py +0 -0
- {python_fasthtml-0.12.41 → python_fasthtml-0.12.43}/fasthtml/components.py +0 -0
- {python_fasthtml-0.12.41 → python_fasthtml-0.12.43}/fasthtml/components.pyi +0 -0
- {python_fasthtml-0.12.41 → python_fasthtml-0.12.43}/fasthtml/core.pyi +0 -0
- {python_fasthtml-0.12.41 → python_fasthtml-0.12.43}/fasthtml/fastapp.py +0 -0
- {python_fasthtml-0.12.41 → python_fasthtml-0.12.43}/fasthtml/ft.py +0 -0
- {python_fasthtml-0.12.41 → python_fasthtml-0.12.43}/fasthtml/js.py +0 -0
- {python_fasthtml-0.12.41 → python_fasthtml-0.12.43}/fasthtml/jupyter.py +0 -0
- {python_fasthtml-0.12.41 → python_fasthtml-0.12.43}/fasthtml/katex.js +0 -0
- {python_fasthtml-0.12.41 → python_fasthtml-0.12.43}/fasthtml/live_reload.py +0 -0
- {python_fasthtml-0.12.41 → python_fasthtml-0.12.43}/fasthtml/pico.py +0 -0
- {python_fasthtml-0.12.41 → python_fasthtml-0.12.43}/fasthtml/starlette.py +0 -0
- {python_fasthtml-0.12.41 → python_fasthtml-0.12.43}/fasthtml/stripe_otp.py +0 -0
- {python_fasthtml-0.12.41 → python_fasthtml-0.12.43}/fasthtml/svg.py +0 -0
- {python_fasthtml-0.12.41 → python_fasthtml-0.12.43}/fasthtml/toaster.py +0 -0
- {python_fasthtml-0.12.41 → python_fasthtml-0.12.43}/fasthtml/xtend.py +0 -0
- {python_fasthtml-0.12.41 → python_fasthtml-0.12.43}/fasthtml/xtend.pyi +0 -0
- {python_fasthtml-0.12.41 → python_fasthtml-0.12.43}/pyproject.toml +0 -0
- {python_fasthtml-0.12.41 → python_fasthtml-0.12.43}/python_fasthtml.egg-info/SOURCES.txt +0 -0
- {python_fasthtml-0.12.41 → python_fasthtml-0.12.43}/python_fasthtml.egg-info/dependency_links.txt +0 -0
- {python_fasthtml-0.12.41 → python_fasthtml-0.12.43}/python_fasthtml.egg-info/entry_points.txt +0 -0
- {python_fasthtml-0.12.41 → python_fasthtml-0.12.43}/python_fasthtml.egg-info/requires.txt +0 -0
- {python_fasthtml-0.12.41 → python_fasthtml-0.12.43}/python_fasthtml.egg-info/top_level.txt +0 -0
- {python_fasthtml-0.12.41 → python_fasthtml-0.12.43}/setup.cfg +0 -0
- {python_fasthtml-0.12.41 → python_fasthtml-0.12.43}/tests/test_toaster.py +0 -0
|
@@ -33,6 +33,10 @@ d = { 'settings': { 'branch': 'main',
|
|
|
33
33
|
'fasthtml.core.APIRouter._wrap_func': ('api/core.html#apirouter._wrap_func', 'fasthtml/core.py'),
|
|
34
34
|
'fasthtml.core.APIRouter.to_app': ('api/core.html#apirouter.to_app', 'fasthtml/core.py'),
|
|
35
35
|
'fasthtml.core.APIRouter.ws': ('api/core.html#apirouter.ws', 'fasthtml/core.py'),
|
|
36
|
+
'fasthtml.core.ApiReturn': ('api/core.html#apireturn', 'fasthtml/core.py'),
|
|
37
|
+
'fasthtml.core.ApiReturn.__call__': ('api/core.html#apireturn.__call__', 'fasthtml/core.py'),
|
|
38
|
+
'fasthtml.core.ApiReturn.__from_request__': ('api/core.html#apireturn.__from_request__', 'fasthtml/core.py'),
|
|
39
|
+
'fasthtml.core.ApiReturn.__init__': ('api/core.html#apireturn.__init__', 'fasthtml/core.py'),
|
|
36
40
|
'fasthtml.core.Beforeware': ('api/core.html#beforeware', 'fasthtml/core.py'),
|
|
37
41
|
'fasthtml.core.Beforeware.__init__': ('api/core.html#beforeware.__init__', 'fasthtml/core.py'),
|
|
38
42
|
'fasthtml.core.Client': ('api/core.html#client', 'fasthtml/core.py'),
|
|
@@ -5,18 +5,19 @@
|
|
|
5
5
|
# %% auto #0
|
|
6
6
|
__all__ = ['empty', 'htmx_hdrs', 'fh_cfg', 'htmx_resps', 'htmx_exts', 'htmxsrc', 'fhjsscr', 'surrsrc', 'scopesrc', 'viewport',
|
|
7
7
|
'charset', 'cors_allow', 'iframe_scr', 'all_meths', 'devtools_loc', 'parsed_date', 'snake2hyphens',
|
|
8
|
-
'HtmxHeaders', 'HttpHeader', 'HtmxResponseHeaders', 'form2dict', 'parse_form', '
|
|
9
|
-
'Beforeware', 'EventStream', 'signal_shutdown', 'uri', 'decode_uri', 'flat_tuple', 'noop_body',
|
|
10
|
-
'is_full_page', 'Redirect', 'get_key', 'qp', 'def_hdrs', 'FastHTML', 'nested_name', 'serve',
|
|
11
|
-
'RouteFuncs', 'APIRouter', 'cookie', 'reg_re_param', 'StaticNoCache', 'MiddlewareBase',
|
|
12
|
-
'unqid']
|
|
8
|
+
'HtmxHeaders', 'HttpHeader', 'HtmxResponseHeaders', 'form2dict', 'parse_form', 'ApiReturn', 'JSONResponse',
|
|
9
|
+
'flat_xt', 'Beforeware', 'EventStream', 'signal_shutdown', 'uri', 'decode_uri', 'flat_tuple', 'noop_body',
|
|
10
|
+
'respond', 'is_full_page', 'Redirect', 'get_key', 'qp', 'def_hdrs', 'FastHTML', 'nested_name', 'serve',
|
|
11
|
+
'Client', 'RouteFuncs', 'APIRouter', 'cookie', 'reg_re_param', 'StaticNoCache', 'MiddlewareBase',
|
|
12
|
+
'FtResponse', 'unqid']
|
|
13
13
|
|
|
14
14
|
# %% ../nbs/api/00_core.ipynb #23503b9e
|
|
15
|
-
import json,uuid,inspect,types,signal,asyncio,threading,inspect,random,contextlib,httpx,itsdangerous
|
|
15
|
+
import json,uuid,inspect,types,signal,asyncio,threading,inspect,random,contextlib,httpx,itsdangerous,uvicorn
|
|
16
16
|
|
|
17
17
|
from fastcore.utils import *
|
|
18
18
|
from fastcore.xml import *
|
|
19
|
-
from fastcore.meta import use_kwargs_dict
|
|
19
|
+
from fastcore.meta import use_kwargs_dict,delegates
|
|
20
|
+
from fastcore.style import S
|
|
20
21
|
|
|
21
22
|
from types import UnionType, SimpleNamespace as ns, GenericAlias
|
|
22
23
|
from typing import Optional, get_type_hints, get_args, get_origin, Union, Mapping, TypedDict, List, Any
|
|
@@ -165,6 +166,13 @@ async def _from_body(req, p):
|
|
|
165
166
|
cargs = {k: _form_arg(k, v, d) for k, v in data.items() if not d or k in d}
|
|
166
167
|
return anno(**cargs)
|
|
167
168
|
|
|
169
|
+
# %% ../nbs/api/00_core.ipynb #88b6da3f
|
|
170
|
+
class ApiReturn:
|
|
171
|
+
@classmethod
|
|
172
|
+
async def __from_request__(cls, data, req): return cls(req.headers.get('accept')=='application/json')
|
|
173
|
+
def __init__(self, isapi=False): self.isapi = isapi
|
|
174
|
+
def __call__(self, norm, **kw): return kw if self.isapi else norm
|
|
175
|
+
|
|
168
176
|
# %% ../nbs/api/00_core.ipynb #7cc39ba9
|
|
169
177
|
class JSONResponse(JSONResponseOrig):
|
|
170
178
|
"Same as starlette's version, but auto-stringifies non serializable types"
|
|
@@ -195,6 +203,7 @@ async def _find_p(req, arg:str, p:Parameter):
|
|
|
195
203
|
if arg.lower()=='app': return req.scope['app']
|
|
196
204
|
if arg.lower()=='body': return (await req.body()).decode()
|
|
197
205
|
if arg.lower()=='state': return req.scope['app'].state
|
|
206
|
+
if arg.lower()=='api': return ApiReturn(req.headers.get('accept')=='application/json')
|
|
198
207
|
if arg.lower() in ('hdrs','ftrs','bodykw','htmlkw'): return getattr(req, arg.lower())
|
|
199
208
|
if arg!='resp': warn(f"`{arg} has no type annotation and is not a recognised special name, so is ignored.")
|
|
200
209
|
return None
|
|
@@ -702,15 +711,15 @@ def set_lifespan(self:FastHTML, value):
|
|
|
702
711
|
self.router.lifespan_context = value
|
|
703
712
|
|
|
704
713
|
# %% ../nbs/api/00_core.ipynb #3a348474
|
|
714
|
+
@delegates(uvicorn.run)
|
|
705
715
|
def serve(
|
|
706
716
|
appname=None, # Name of the module
|
|
707
717
|
app='app', # App instance to be served
|
|
708
718
|
host='0.0.0.0', # If host is 0.0.0.0 will convert to localhost
|
|
709
719
|
port=None, # If port is None it will default to 5001 or the PORT environment variable
|
|
710
720
|
reload=True, # Default is to reload the app upon code changes
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
):
|
|
721
|
+
**kwargs
|
|
722
|
+
):
|
|
714
723
|
"Run the app in an async server, with live reload set as the default."
|
|
715
724
|
bk = inspect.currentframe().f_back
|
|
716
725
|
glb = bk.f_globals
|
|
@@ -718,11 +727,11 @@ def serve(
|
|
|
718
727
|
if not appname:
|
|
719
728
|
if glb.get('__name__')=='__main__': appname = Path(glb.get('__file__', '')).stem
|
|
720
729
|
elif code.co_name=='main' and bk.f_back.f_globals.get('__name__')=='__main__': appname = inspect.getmodule(bk).__name__
|
|
721
|
-
import uvicorn
|
|
722
730
|
if appname:
|
|
723
731
|
if not port: port=int(os.getenv("PORT", default=5001))
|
|
724
|
-
|
|
725
|
-
|
|
732
|
+
link = f'http://{"localhost" if host=="0.0.0.0" else host}:{port}'
|
|
733
|
+
print('Link: '+ S.light_red.bold(link))
|
|
734
|
+
uvicorn.run(f'{appname}:{app}', host=host, port=port, reload=reload, **kwargs)
|
|
726
735
|
|
|
727
736
|
# %% ../nbs/api/00_core.ipynb #8121968a
|
|
728
737
|
class Client:
|
|
@@ -3,14 +3,17 @@
|
|
|
3
3
|
# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/api/08_oauth.ipynb.
|
|
4
4
|
|
|
5
5
|
# %% auto #0
|
|
6
|
-
__all__ = ['http_patterns', 'GoogleAppClient', 'GitHubAppClient', 'HuggingFaceClient', 'DiscordAppClient',
|
|
7
|
-
'AppleAppClient', 'get_host', 'redir_url', 'url_match', 'OAuth', 'load_creds']
|
|
6
|
+
__all__ = ['log', 'http_patterns', 'GoogleAppClient', 'GitHubAppClient', 'HuggingFaceClient', 'DiscordAppClient',
|
|
7
|
+
'Auth0AppClient', 'AppleAppClient', 'get_host', 'redir_url', 'url_match', 'OAuth', 'load_creds']
|
|
8
8
|
|
|
9
9
|
# %% ../nbs/api/08_oauth.ipynb #793722f2
|
|
10
10
|
from .common import *
|
|
11
11
|
from oauthlib.oauth2 import WebApplicationClient
|
|
12
12
|
from urllib.parse import urlparse, urlencode, parse_qs, quote, unquote
|
|
13
|
-
import secrets, httpx, time, asyncio
|
|
13
|
+
import secrets, httpx, time, asyncio, logging
|
|
14
|
+
|
|
15
|
+
# %% ../nbs/api/08_oauth.ipynb #44aa4a88
|
|
16
|
+
log = logging.getLogger(__name__)
|
|
14
17
|
|
|
15
18
|
# %% ../nbs/api/08_oauth.ipynb #0a078133
|
|
16
19
|
class _AppClient(WebApplicationClient):
|
|
@@ -186,8 +189,11 @@ async def parse_response_async(self:_AppClient, code, redirect_uri):
|
|
|
186
189
|
"Get the token from the oauth2 server response"
|
|
187
190
|
payload = dict(code=code, redirect_uri=redirect_uri, client_id=self.client_id,
|
|
188
191
|
client_secret=self.client_secret, grant_type='authorization_code')
|
|
192
|
+
log.debug(f"OAuth token request: redirect_uri={redirect_uri}, code={code[:20]}...")
|
|
189
193
|
async with httpx.AsyncClient() as c:
|
|
190
|
-
r = (await c.post(self.token_url, data=payload))
|
|
194
|
+
r = (await c.post(self.token_url, data=payload))
|
|
195
|
+
log.debug(f"OAuth response: {r.status_code} - {r.text}")
|
|
196
|
+
r.raise_for_status()
|
|
191
197
|
self.parse_request_body_response(r.text)
|
|
192
198
|
|
|
193
199
|
@patch
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_fasthtml-0.12.41 → python_fasthtml-0.12.43}/python_fasthtml.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{python_fasthtml-0.12.41 → python_fasthtml-0.12.43}/python_fasthtml.egg-info/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|