7
7
'charset' , 'cors_allow' , 'iframe_scr' , 'all_meths' , 'devtools_loc' , 'parsed_date' , 'snake2hyphens' ,
8
8
'HtmxHeaders' , 'HttpHeader' , 'HtmxResponseHeaders' , 'form2dict' , 'parse_form' , 'JSONResponse' , 'flat_xt' ,
9
9
'Beforeware' , 'EventStream' , 'signal_shutdown' , 'uri' , 'decode_uri' , 'flat_tuple' , 'noop_body' , 'respond' ,
10
- 'Redirect' , 'get_key' , 'qp' , 'def_hdrs' , 'FastHTML' , 'nested_name' , 'serve' , 'Client' , 'RouteFuncs ' ,
11
- 'APIRouter' , 'cookie' , 'reg_re_param' , 'MiddlewareBase' , 'FtResponse' , 'unqid' , 'setup_ws' ]
10
+ 'is_full_page' , ' Redirect' , 'get_key' , 'qp' , 'def_hdrs' , 'FastHTML' , 'nested_name' , 'serve' , 'Client' ,
11
+ 'RouteFuncs' , ' APIRouter' , 'cookie' , 'reg_re_param' , 'MiddlewareBase' , 'FtResponse' , 'unqid' , 'setup_ws' ]
12
12
13
13
# %% ../nbs/api/00_core.ipynb
14
14
import json ,uuid ,inspect ,types ,signal ,asyncio ,threading ,inspect
@@ -389,25 +389,35 @@ def respond(req, heads, bdy):
389
389
return Html (Head (* heads , * flat_xt (req .hdrs )), body , ** req .htmlkw )
390
390
391
391
# %% ../nbs/api/00_core.ipynb
392
- def _xt_cts (req , resp ):
392
+ def is_full_page (req , resp ):
393
+ is_frag = 'hx-request' in req .headers and 'hx-history-restore-request' not in req .headers
394
+ return (resp and not is_frag and not any (getattr (o , 'tag' , '' )== 'html' for o in resp ))
395
+
396
+ # %% ../nbs/api/00_core.ipynb
397
+ def _part_resp (req , resp ):
393
398
resp = flat_tuple (resp )
394
399
resp = resp + tuple (getattr (req , 'injects' , ()))
395
400
http_hdrs ,resp = partition (resp , risinstance (HttpHeader ))
396
- http_hdrs = {o .k :str (o .v ) for o in http_hdrs }
397
401
tasks ,resp = partition (resp , risinstance (BackgroundTask ))
398
- ts = BackgroundTasks ()
399
- for t in tasks : ts .tasks .append (t )
402
+ kw = {"headers" : {"vary" : "HX-Request, HX-History-Restore-Request" }}
403
+ if http_hdrs : kw ['headers' ] |= {o .k :str (o .v ) for o in http_hdrs }
404
+ if tasks :
405
+ ts = BackgroundTasks ()
406
+ for t in tasks : ts .tasks .append (t )
407
+ kw ['background' ] = ts
408
+ resp = tuple (resp )
409
+ if len (resp )== 1 : resp = resp [0 ]
410
+ return resp ,kw
411
+
412
+ # %% ../nbs/api/00_core.ipynb
413
+ def _xt_cts (req , resp ):
400
414
hdr_tags = 'title' ,'meta' ,'link' ,'style' ,'base'
415
+ resp = tuplify (resp )
401
416
heads ,bdy = partition (resp , lambda o : getattr (o , 'tag' , '' ) in hdr_tags )
402
- if resp and 'hx-request' not in req . headers and not any ( getattr ( o , 'tag' , '' ) == 'html' for o in resp ):
417
+ if is_full_page ( req , resp ):
403
418
title = [] if any (getattr (o , 'tag' , '' )== 'title' for o in heads ) else [Title (req .app .title )]
404
419
resp = respond (req , [* heads , * title ], bdy )
405
- return _to_xml (req , resp , indent = fh_cfg .indent ), http_hdrs , ts
406
-
407
- # %% ../nbs/api/00_core.ipynb
408
- def _xt_resp (req , resp , status_code ):
409
- cts ,http_hdrs ,tasks = _xt_cts (req , resp )
410
- return HTMLResponse (cts , status_code = status_code , headers = http_hdrs , background = tasks )
420
+ return _to_xml (req , resp , indent = fh_cfg .indent )
411
421
412
422
# %% ../nbs/api/00_core.ipynb
413
423
def _is_ft_resp (resp ): return isinstance (resp , _iter_typs + (HttpHeader ,FT )) or hasattr (resp , '__ft__' )
@@ -418,15 +428,18 @@ def _resp(req, resp, cls=empty, status_code=200):
418
428
if hasattr (resp , '__response__' ): resp = resp .__response__ (req )
419
429
if cls in (Any ,FT ): cls = empty
420
430
if isinstance (resp , FileResponse ) and not os .path .exists (resp .path ): raise HTTPException (404 , resp .path )
421
- if cls is not empty : return cls (resp , status_code = status_code )
422
- if isinstance (resp , Response ): return resp # respect manually set status_code
423
- if _is_ft_resp (resp ): return _xt_resp (req , resp , status_code )
431
+ resp ,kw = _part_resp (req , resp )
432
+ if cls is not empty : return cls (resp , status_code = status_code , ** kw )
433
+ if isinstance (resp , Response ): return resp
434
+ if _is_ft_resp (resp ):
435
+ cts = _xt_cts (req , resp )
436
+ return HTMLResponse (cts , status_code = status_code , ** kw )
424
437
if isinstance (resp , str ): cls = HTMLResponse
425
438
elif isinstance (resp , Mapping ): cls = JSONResponse
426
439
else :
427
440
resp = str (resp )
428
441
cls = HTMLResponse
429
- return cls (resp , status_code = status_code )
442
+ return cls (resp , status_code = status_code , ** kw )
430
443
431
444
# %% ../nbs/api/00_core.ipynb
432
445
class Redirect :
@@ -788,8 +801,10 @@ def __init__(self, content, status_code:int=200, headers=None, cls=HTMLResponse,
788
801
self .cls ,self .media_type ,self .background = cls ,media_type ,background
789
802
790
803
def __response__ (self , req ):
791
- cts ,httphdrs ,tasks = _xt_cts (req , self .content )
792
- if not tasks .tasks : tasks = self .background
804
+ resp ,kw = _part_resp (req , self .content )
805
+ cts = _xt_cts (req , resp )
806
+ tasks ,httphdrs = kw .get ('background' ),kw .get ('headers' )
807
+ if not tasks : tasks = self .background
793
808
headers = {** (self .headers or {}), ** httphdrs }
794
809
return self .cls (cts , status_code = self .status_code , headers = headers , media_type = self .media_type , background = tasks )
795
810
0 commit comments