from IPython import display
+from enum import Enum
+from pprint import pprint
+
+from starlette.testclient import TestClient
FastHTML
+# if 'HX-Request' not in request.headers:
+# resp = wrap_root(resp, self.headtags)
+ +
date
++++date (s)
+ +
snake2hyphens
++++snake2hyphens (s)
+ +
RouteX
++++RouteX (path, endpoint, *args, **kw)
Initialize self. See help(type(self)) for accurate signature.
++ +
FastHTML
++++FastHTML ()
Initialize self. See help(type(self)) for accurate signature.
+Demo
+def todict(req): return {k:str(v) for k,v in req.items()}
= FastHTML()
+ app
+@app.get("/")
+def root(req): return todict(req.scope)
+
+@app.get('/user/{nm}')
+def get_nm(nm:str): return f"Good day to you, {nm}!"
= TestClient(app)
+ client = client.get('/')
+ r print(r.text)
{"type":"http","http_version":"1.1","method":"GET","path":"/","raw_path":"b'/'","root_path":"","scheme":"http","query_string":"b''","headers":"[(b'host', b'testserver'), (b'accept', b'*/*'), (b'accept-encoding', b'gzip, deflate, br'), (b'connection', b'keep-alive'), (b'user-agent', b'testclient')]","client":"['testclient', 50000]","server":"['testserver', 80]","extensions":"{'http.response.debug': {}}","state":"{}","app":"<starlette.applications.Starlette object>","starlette.exception_handlers":"({<class 'starlette.exceptions.HTTPException'>: <bound method ExceptionMiddleware.http_exception of <starlette.middleware.exceptions.ExceptionMiddleware object>>, <class 'starlette.exceptions.WebSocketException'>: <bound method ExceptionMiddleware.websocket_exception of <starlette.middleware.exceptions.ExceptionMiddleware object>>}, {})","router":"<starlette.routing.Router object>","endpoint":"<function _wrap_ep.<locals>._f>","path_params":"{}"}
+'/user/jph').text client.get(
'Good day to you, jph!'
+@app.get('/html/{idx}')
+async def get_html(idx:int):
+return Body(
+ "Wow look here"),
+ H4(f'It looks like you are visitor {idx}! Next is {idx+1}.')
+ P( )
'/html/1').text) display.HTML(client.get(
+Wow look here +
++It looks like you are visitor 1! Next is 2. +
+ += str_enum('ModelName', "alexnet", "resnet", "lenet")
+ ModelName
+= FastHTML()
+ app @app.get("/models/{nm}")
+def model(nm:ModelName): return nm
+
+@app.get("/files/{path}")
+async def txt(path: Path): return path.with_suffix('.txt')
print(TestClient(app).get('/models/alexnet').text)
alexnet
+print(TestClient(app).get('/files/foo').text)
foo.txt
+= [{"name": "Foo"}, {"name": "Bar"}]
+ fake_db
+@app.get("/items/")
+def read_item(idx:int|None = 0): return fake_db[idx]
print(TestClient(app).get('/items/?idx=1').text)
{"name":"Bar"}
+print(TestClient(app).get('/items/').text)
{"name":"Foo"}
+@app.get("/booly/")
+def booly(coming:bool=True): return 'Coming' if coming else 'Not coming'
= TestClient(app)
+ cli print(cli.get('/booly/?coming=true').text)
Coming
+print(cli.get('/booly/?coming=no').text)
Not coming
+@app.get("/datie/")
+def datie(d:date): return d
= TestClient(app)
+ cli = "17th of May, 2024, 2p"
+ date_str print(cli.get(f'/datie/?d={date_str}').text)
2024-05-17 14:00:00
+@dataclass
+class Bodie:
+int;b:str a:
@app.post("/bodie/{nm}/")
+async def bodie(nm:str, data:Bodie):
+= asdict(data)
+ res 'nm'] = nm
+ res[return res
'/bodie/me', data=dict(a=1, b='foo')).text cli.post(
'{"a":1,"b":"foo","nm":"me"}'
+@app.get("/setcookie")
+async def setc(req):
+= datetime.now()
+ now = Response(f'Set to {now}')
+ res 'now', str(now))
+ res.set_cookie(return res
'/setcookie').text cli.get(
'Set to 2024-05-17 15:23:30.099808'
+@app.get("/getcookie")
+async def getc(now:date): return f'Cookie was set at time {now.time()}'
'/getcookie').text cli.get(
'Cookie was set at time 15:23:30.099808'
+@app.get("/ua")
+async def ua(user_agent:str): return user_agent
'/ua', headers={'User-Agent':'FastHTML'}).text cli.get(
'FastHTML'
+