python-fasthtml 0.12.29__tar.gz → 0.12.30__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.29/python_fasthtml.egg-info → python_fasthtml-0.12.30}/PKG-INFO +1 -1
- python_fasthtml-0.12.30/fasthtml/__init__.py +2 -0
- {python_fasthtml-0.12.29 → python_fasthtml-0.12.30}/fasthtml/_modidx.py +9 -0
- {python_fasthtml-0.12.29 → python_fasthtml-0.12.30}/fasthtml/oauth.py +3 -1
- {python_fasthtml-0.12.29 → python_fasthtml-0.12.30}/fasthtml/xtend.py +92 -10
- {python_fasthtml-0.12.29 → python_fasthtml-0.12.30/python_fasthtml.egg-info}/PKG-INFO +1 -1
- {python_fasthtml-0.12.29 → python_fasthtml-0.12.30}/settings.ini +1 -1
- python_fasthtml-0.12.29/fasthtml/__init__.py +0 -2
- {python_fasthtml-0.12.29 → python_fasthtml-0.12.30}/CONTRIBUTING.md +0 -0
- {python_fasthtml-0.12.29 → python_fasthtml-0.12.30}/LICENSE +0 -0
- {python_fasthtml-0.12.29 → python_fasthtml-0.12.30}/MANIFEST.in +0 -0
- {python_fasthtml-0.12.29 → python_fasthtml-0.12.30}/README.md +0 -0
- {python_fasthtml-0.12.29 → python_fasthtml-0.12.30}/fasthtml/authmw.py +0 -0
- {python_fasthtml-0.12.29 → python_fasthtml-0.12.30}/fasthtml/basics.py +0 -0
- {python_fasthtml-0.12.29 → python_fasthtml-0.12.30}/fasthtml/cli.py +0 -0
- {python_fasthtml-0.12.29 → python_fasthtml-0.12.30}/fasthtml/common.py +0 -0
- {python_fasthtml-0.12.29 → python_fasthtml-0.12.30}/fasthtml/components.py +0 -0
- {python_fasthtml-0.12.29 → python_fasthtml-0.12.30}/fasthtml/components.pyi +0 -0
- {python_fasthtml-0.12.29 → python_fasthtml-0.12.30}/fasthtml/core.py +0 -0
- {python_fasthtml-0.12.29 → python_fasthtml-0.12.30}/fasthtml/core.pyi +0 -0
- {python_fasthtml-0.12.29 → python_fasthtml-0.12.30}/fasthtml/fastapp.py +0 -0
- {python_fasthtml-0.12.29 → python_fasthtml-0.12.30}/fasthtml/ft.py +0 -0
- {python_fasthtml-0.12.29 → python_fasthtml-0.12.30}/fasthtml/js.py +0 -0
- {python_fasthtml-0.12.29 → python_fasthtml-0.12.30}/fasthtml/jupyter.py +0 -0
- {python_fasthtml-0.12.29 → python_fasthtml-0.12.30}/fasthtml/katex.js +0 -0
- {python_fasthtml-0.12.29 → python_fasthtml-0.12.30}/fasthtml/live_reload.py +0 -0
- {python_fasthtml-0.12.29 → python_fasthtml-0.12.30}/fasthtml/pico.py +0 -0
- {python_fasthtml-0.12.29 → python_fasthtml-0.12.30}/fasthtml/starlette.py +0 -0
- {python_fasthtml-0.12.29 → python_fasthtml-0.12.30}/fasthtml/stripe_otp.py +0 -0
- {python_fasthtml-0.12.29 → python_fasthtml-0.12.30}/fasthtml/svg.py +0 -0
- {python_fasthtml-0.12.29 → python_fasthtml-0.12.30}/fasthtml/toaster.py +0 -0
- {python_fasthtml-0.12.29 → python_fasthtml-0.12.30}/fasthtml/xtend.pyi +0 -0
- {python_fasthtml-0.12.29 → python_fasthtml-0.12.30}/pyproject.toml +0 -0
- {python_fasthtml-0.12.29 → python_fasthtml-0.12.30}/python_fasthtml.egg-info/SOURCES.txt +0 -0
- {python_fasthtml-0.12.29 → python_fasthtml-0.12.30}/python_fasthtml.egg-info/dependency_links.txt +0 -0
- {python_fasthtml-0.12.29 → python_fasthtml-0.12.30}/python_fasthtml.egg-info/entry_points.txt +0 -0
- {python_fasthtml-0.12.29 → python_fasthtml-0.12.30}/python_fasthtml.egg-info/not-zip-safe +0 -0
- {python_fasthtml-0.12.29 → python_fasthtml-0.12.30}/python_fasthtml.egg-info/requires.txt +0 -0
- {python_fasthtml-0.12.29 → python_fasthtml-0.12.30}/python_fasthtml.egg-info/top_level.txt +0 -0
- {python_fasthtml-0.12.29 → python_fasthtml-0.12.30}/setup.cfg +0 -0
- {python_fasthtml-0.12.29 → python_fasthtml-0.12.30}/setup.py +0 -0
- {python_fasthtml-0.12.29 → python_fasthtml-0.12.30}/tests/test_toaster.py +0 -0
|
@@ -263,6 +263,12 @@ d = { 'settings': { 'branch': 'main',
|
|
|
263
263
|
'fasthtml.xtend.Fragment.__init__': ('api/xtend.html#fragment.__init__', 'fasthtml/xtend.py'),
|
|
264
264
|
'fasthtml.xtend.Hidden': ('api/xtend.html#hidden', 'fasthtml/xtend.py'),
|
|
265
265
|
'fasthtml.xtend.HtmxOn': ('api/xtend.html#htmxon', 'fasthtml/xtend.py'),
|
|
266
|
+
'fasthtml.xtend.LdContactPoint': ('api/xtend.html#ldcontactpoint', 'fasthtml/xtend.py'),
|
|
267
|
+
'fasthtml.xtend.LdCourse': ('api/xtend.html#ldcourse', 'fasthtml/xtend.py'),
|
|
268
|
+
'fasthtml.xtend.LdCourseInstance': ('api/xtend.html#ldcourseinstance', 'fasthtml/xtend.py'),
|
|
269
|
+
'fasthtml.xtend.LdJson': ('api/xtend.html#ldjson', 'fasthtml/xtend.py'),
|
|
270
|
+
'fasthtml.xtend.LdOrg': ('api/xtend.html#ldorg', 'fasthtml/xtend.py'),
|
|
271
|
+
'fasthtml.xtend.LdWebsite': ('api/xtend.html#ldwebsite', 'fasthtml/xtend.py'),
|
|
266
272
|
'fasthtml.xtend.Nbsp': ('api/xtend.html#nbsp', 'fasthtml/xtend.py'),
|
|
267
273
|
'fasthtml.xtend.Now': ('api/xtend.html#now', 'fasthtml/xtend.py'),
|
|
268
274
|
'fasthtml.xtend.On': ('api/xtend.html#on', 'fasthtml/xtend.py'),
|
|
@@ -280,6 +286,9 @@ d = { 'settings': { 'branch': 'main',
|
|
|
280
286
|
'fasthtml.xtend.jsd': ('api/xtend.html#jsd', 'fasthtml/xtend.py'),
|
|
281
287
|
'fasthtml.xtend.loose_format': ('api/xtend.html#loose_format', 'fasthtml/xtend.py'),
|
|
282
288
|
'fasthtml.xtend.replace_css_vars': ('api/xtend.html#replace_css_vars', 'fasthtml/xtend.py'),
|
|
289
|
+
'fasthtml.xtend.robots_txt': ('api/xtend.html#robots_txt', 'fasthtml/xtend.py'),
|
|
283
290
|
'fasthtml.xtend.run_js': ('api/xtend.html#run_js', 'fasthtml/xtend.py'),
|
|
291
|
+
'fasthtml.xtend.sitemap_url': ('api/xtend.html#sitemap_url', 'fasthtml/xtend.py'),
|
|
292
|
+
'fasthtml.xtend.sitemap_xml': ('api/xtend.html#sitemap_xml', 'fasthtml/xtend.py'),
|
|
284
293
|
'fasthtml.xtend.undouble_braces': ('api/xtend.html#undouble_braces', 'fasthtml/xtend.py'),
|
|
285
294
|
'fasthtml.xtend.with_sid': ('api/xtend.html#with_sid', 'fasthtml/xtend.py')}}}
|
|
@@ -184,7 +184,9 @@ class OAuth:
|
|
|
184
184
|
|
|
185
185
|
@app.get(redir_path)
|
|
186
186
|
def redirect(req, session, code:str=None, error:str=None, state:str=None):
|
|
187
|
-
if not code:
|
|
187
|
+
if not code:
|
|
188
|
+
session['oauth_error']=error
|
|
189
|
+
return RedirectResponse(self.error_path, status_code=303)
|
|
188
190
|
scheme = 'http' if url_match(req,self.http_patterns) or not self.https else 'https'
|
|
189
191
|
base_url = f"{scheme}://{get_host(req)}"
|
|
190
192
|
info = AttrDictDefault(cli.retr_info(code, base_url+redir_path))
|
|
@@ -5,7 +5,9 @@
|
|
|
5
5
|
# %% auto 0
|
|
6
6
|
__all__ = ['sid_scr', 'A', 'AX', 'Form', 'Hidden', 'CheckboxX', 'Script', 'Style', 'double_braces', 'undouble_braces',
|
|
7
7
|
'loose_format', 'ScriptX', 'replace_css_vars', 'StyleX', 'Nbsp', 'Surreal', 'On', 'Prev', 'Now', 'AnyNow',
|
|
8
|
-
'run_js', 'HtmxOn', 'jsd', 'Fragment', 'Titled', 'Socials', 'YouTubeEmbed', 'Favicon', 'clear', 'with_sid'
|
|
8
|
+
'run_js', 'HtmxOn', 'jsd', 'Fragment', 'Titled', 'Socials', 'YouTubeEmbed', 'Favicon', 'clear', 'with_sid',
|
|
9
|
+
'LdJson', 'LdContactPoint', 'LdOrg', 'LdWebsite', 'LdCourseInstance', 'LdCourse', 'robots_txt',
|
|
10
|
+
'sitemap_url', 'sitemap_xml']
|
|
9
11
|
|
|
10
12
|
# %% ../nbs/api/02_xtend.ipynb
|
|
11
13
|
from dataclasses import dataclass, asdict
|
|
@@ -224,18 +226,13 @@ def YouTubeEmbed(video_id:str, *, width:int=560, height:int=315, start_time:int=
|
|
|
224
226
|
print(f"https://www.youtube.com/embed/{video_id}{query_string}")
|
|
225
227
|
return Div(
|
|
226
228
|
Iframe(
|
|
227
|
-
width=width,
|
|
228
|
-
height=height,
|
|
229
|
+
width=width, height=height,
|
|
229
230
|
src=f"https://www.youtube.com/embed/{video_id}{query_string}",
|
|
230
|
-
title=title,
|
|
231
|
-
frameborder="0",
|
|
231
|
+
title=title, frameborder="0",
|
|
232
232
|
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share",
|
|
233
|
-
referrerpolicy="strict-origin-when-cross-origin",
|
|
234
|
-
allowfullscreen='',
|
|
233
|
+
referrerpolicy="strict-origin-when-cross-origin", allowfullscreen='',
|
|
235
234
|
**kwargs
|
|
236
|
-
),
|
|
237
|
-
cls=cls
|
|
238
|
-
)
|
|
235
|
+
), cls=cls)
|
|
239
236
|
|
|
240
237
|
# %% ../nbs/api/02_xtend.ipynb
|
|
241
238
|
def Favicon(light_icon, dark_icon):
|
|
@@ -268,3 +265,88 @@ htmx.on("htmx:configRequest", (e) => {
|
|
|
268
265
|
def with_sid(app, dest, path='/'):
|
|
269
266
|
@app.route(path)
|
|
270
267
|
def get(): return Div(hx_get=dest, hx_trigger=f'load delay:0.001s', hx_swap='outerHTML')
|
|
268
|
+
|
|
269
|
+
# %% ../nbs/api/02_xtend.ipynb
|
|
270
|
+
def LdJson(typ, data:dict, script=False, extra=None, **kwargs)->FT:
|
|
271
|
+
"A script tag containing JSON-LD structured data"
|
|
272
|
+
cts = {'@type':typ, "@context": "https://schema.org"} | data | (extra or {})
|
|
273
|
+
if not script: return cts
|
|
274
|
+
return Script(dumps(cts, indent=1), type="application/ld+json", **kwargs)
|
|
275
|
+
|
|
276
|
+
# %% ../nbs/api/02_xtend.ipynb
|
|
277
|
+
def LdContactPoint(contact_type:str, email:str=None, phone:str=None, script=False, **extra)->dict:
|
|
278
|
+
"Create a ContactPoint for JSON-LD"
|
|
279
|
+
data = {"contactType": contact_type}
|
|
280
|
+
if email: data["email"] = email
|
|
281
|
+
if phone: data["telephone"] = phone
|
|
282
|
+
return LdJson("ContactPoint", data, extra=extra, script=script)
|
|
283
|
+
|
|
284
|
+
# %% ../nbs/api/02_xtend.ipynb
|
|
285
|
+
def LdOrg(name:str, url:str=None, logo:str=None, alt_name:str=None,
|
|
286
|
+
same_as:list=None, contact_points:list=None, script=False, **extra)->dict:
|
|
287
|
+
"JSON-LD Organization structured data"
|
|
288
|
+
data = {"name": name}
|
|
289
|
+
if alt_name: data["alternateName"] = alt_name
|
|
290
|
+
if url: data["url"] = url
|
|
291
|
+
if logo: data["logo"] = logo
|
|
292
|
+
if same_as: data["sameAs"] = same_as
|
|
293
|
+
if contact_points: data["contactPoint"] = contact_points
|
|
294
|
+
return LdJson("Organization", data, extra=extra, script=script)
|
|
295
|
+
|
|
296
|
+
# %% ../nbs/api/02_xtend.ipynb
|
|
297
|
+
def LdWebsite(name:str, url:str, script=False, **extra)->dict:
|
|
298
|
+
"Create JSON-LD WebSite structured data"
|
|
299
|
+
data = {"name": name, "url": url}
|
|
300
|
+
return LdJson("WebSite", data, extra=extra, script=script)
|
|
301
|
+
|
|
302
|
+
# %% ../nbs/api/02_xtend.ipynb
|
|
303
|
+
def LdCourseInstance(course_mode:str="Online", start_date:str=None, end_date:str=None,
|
|
304
|
+
location:dict=None, instructor:dict=None, script=False, **extra)->dict:
|
|
305
|
+
"Create a CourseInstance for JSON-LD"
|
|
306
|
+
data = {"courseMode": course_mode}
|
|
307
|
+
if start_date: data["startDate"] = start_date
|
|
308
|
+
if end_date: data["endDate"] = end_date
|
|
309
|
+
if location: data["location"] = location
|
|
310
|
+
if instructor: data["instructor"] = instructor
|
|
311
|
+
return LdJson("CourseInstance", data, extra=extra, script=script)
|
|
312
|
+
|
|
313
|
+
# %% ../nbs/api/02_xtend.ipynb
|
|
314
|
+
def LdCourse(name:str, description:str, provider:dict, course_instance:dict=None, script=False, **extra)->dict:
|
|
315
|
+
"Create JSON-LD Course structured data"
|
|
316
|
+
data = { "name": name, "description": description, "provider": provider }
|
|
317
|
+
if course_instance: data["hasCourseInstance"] = course_instance
|
|
318
|
+
return LdJson("Course", data, extra=extra, script=script)
|
|
319
|
+
|
|
320
|
+
# %% ../nbs/api/02_xtend.ipynb
|
|
321
|
+
def robots_txt(app, allow_all=True, disallow_paths=None, sitemap_url=None, crawl_delay=None):
|
|
322
|
+
"Add a /robots.txt route to the app"
|
|
323
|
+
@app.route("/robots.txt")
|
|
324
|
+
def get():
|
|
325
|
+
lines = ["User-agent: *"]
|
|
326
|
+
if allow_all and not disallow_paths: lines.append("Allow: /")
|
|
327
|
+
elif disallow_paths: lines.extend(f"Disallow: {path}" for path in disallow_paths)
|
|
328
|
+
else: lines.append("Disallow: /")
|
|
329
|
+
if crawl_delay: lines.append(f"Crawl-delay: {crawl_delay}")
|
|
330
|
+
if sitemap_url: lines.append(f"Sitemap: {sitemap_url}")
|
|
331
|
+
return "\n".join(lines)
|
|
332
|
+
|
|
333
|
+
# %% ../nbs/api/02_xtend.ipynb
|
|
334
|
+
from fastcore.xml import Url,Loc,Lastmod,Changefreq,Priority,Urlset
|
|
335
|
+
|
|
336
|
+
# %% ../nbs/api/02_xtend.ipynb
|
|
337
|
+
def sitemap_url(url_info, loc_base=""):
|
|
338
|
+
"Create a sitemap URL element from url_info (string or dict)"
|
|
339
|
+
if isinstance(url_info, str): return Url(Loc(loc_base + url_info))
|
|
340
|
+
loc = loc_base + url_info['loc']
|
|
341
|
+
url_elem = [Loc(loc)]
|
|
342
|
+
if 'lastmod' in url_info: url_elem.append(Lastmod(url_info['lastmod']))
|
|
343
|
+
if 'changefreq' in url_info: url_elem.append(Changefreq(url_info['changefreq']))
|
|
344
|
+
if 'priority' in url_info: url_elem.append(Priority(str(url_info['priority'])))
|
|
345
|
+
return Url(*url_elem)
|
|
346
|
+
|
|
347
|
+
def sitemap_xml(app, urls, loc_base=""):
|
|
348
|
+
"Add a /sitemap.xml route to the app with list of URLs"
|
|
349
|
+
@app.route("/sitemap.xml")
|
|
350
|
+
def get():
|
|
351
|
+
urlset = [sitemap_url(url_info, loc_base) for url_info in urls]
|
|
352
|
+
return Urlset(*urlset, xmlns="http://www.sitemaps.org/schemas/sitemap/0.9")
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
[DEFAULT]
|
|
2
2
|
repo = fasthtml
|
|
3
3
|
lib_name = python-fasthtml
|
|
4
|
-
version = 0.12.
|
|
4
|
+
version = 0.12.30
|
|
5
5
|
min_python = 3.10
|
|
6
6
|
license = apache2
|
|
7
7
|
requirements = fastcore>=1.8.1 python-dateutil starlette>0.33 oauthlib itsdangerous uvicorn[standard]>=0.30 httpx fastlite>=0.1.1 python-multipart beautifulsoup4
|
|
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.29 → python_fasthtml-0.12.30}/python_fasthtml.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{python_fasthtml-0.12.29 → python_fasthtml-0.12.30}/python_fasthtml.egg-info/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|