html_url,issue_url,id,node_id,user,created_at,updated_at,author_association,body,reactions,issue,performed_via_github_app https://github.com/simonw/datasette/issues/1739#issuecomment-1117662420,https://api.github.com/repos/simonw/datasette/issues/1739,1117662420,IC_kwDOBm6k_c5CnizU,9599,2022-05-04T18:21:18Z,2022-05-04T18:21:18Z,OWNER,That prototype is now public: https://github.com/simonw/datasette-lite,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1223699280, https://github.com/simonw/datasette/issues/1739#issuecomment-1116215371,https://api.github.com/repos/simonw/datasette/issues/1739,1116215371,IC_kwDOBm6k_c5CiBhL,9599,2022-05-03T15:12:16Z,2022-05-03T15:12:16Z,OWNER,"That worked - both DBs are 304 for me now on a subsequent load of the page: ","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1223699280, https://github.com/simonw/datasette/issues/1739#issuecomment-1116183369,https://api.github.com/repos/simonw/datasette/issues/1739,1116183369,IC_kwDOBm6k_c5Ch5tJ,9599,2022-05-03T14:43:14Z,2022-05-03T14:43:14Z,OWNER,Relevant tests start here: https://github.com/simonw/datasette/blob/d60f163528f466b1127b2935c3b6869c34fd6545/tests/test_html.py#L395,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1223699280, https://github.com/simonw/datasette/issues/1739#issuecomment-1116180599,https://api.github.com/repos/simonw/datasette/issues/1739,1116180599,IC_kwDOBm6k_c5Ch5B3,9599,2022-05-03T14:40:32Z,2022-05-03T14:40:32Z,OWNER,"Database downloads are served here: https://github.com/simonw/datasette/blob/d60f163528f466b1127b2935c3b6869c34fd6545/datasette/views/database.py#L186-L192 Here's `AsgiFileDownload`: https://github.com/simonw/datasette/blob/d60f163528f466b1127b2935c3b6869c34fd6545/datasette/utils/asgi.py#L410-L430 I can add an `etag=` parameter to that and populate it with `db.hash`, if it is populated (which it always should be for immutable databases that can be downloaded).","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1223699280, https://github.com/simonw/datasette/issues/1739#issuecomment-1116178727,https://api.github.com/repos/simonw/datasette/issues/1739,1116178727,IC_kwDOBm6k_c5Ch4kn,9599,2022-05-03T14:38:46Z,2022-05-03T14:38:46Z,OWNER,"Reminded myself how this works by reviewing `conditional-get`: https://github.com/simonw/conditional-get/blob/db6dfec0a296080aaf68fcd80e55fb3f0714e738/conditional_get/cli.py#L33-L52 Simply add a `If-None-Match: last-known-etag` header to the request and check that the response is a status 304 with an empty body.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1223699280, https://github.com/simonw/datasette/issues/1739#issuecomment-1115760104,https://api.github.com/repos/simonw/datasette/issues/1739,1115760104,IC_kwDOBm6k_c5CgSXo,9599,2022-05-03T05:50:19Z,2022-05-03T05:50:19Z,OWNER,Here's how Starlette does it: https://github.com/encode/starlette/blob/830f3486537916bae6b46948ff922adc14a22b7c/starlette/staticfiles.py#L213,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1223699280,