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/2168#issuecomment-1701823609,https://api.github.com/repos/simonw/datasette/issues/2168,1701823609,IC_kwDOBm6k_c5lb8R5,9599,2023-08-31T21:43:06Z,2023-08-31T21:44:13Z,OWNER,"Not sure what to call this. Maybe `app_wrapper()`?
Or perhaps it's simpler than that, something like this:
```python
@hookspec
def process_response(datasette, request, response):
""""""Last chance to modify the response before it is returned to the client""""""
```","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1876353656,
https://github.com/simonw/datasette/issues/2168#issuecomment-1701826521,https://api.github.com/repos/simonw/datasette/issues/2168,1701826521,IC_kwDOBm6k_c5lb8_Z,9599,2023-08-31T21:46:13Z,2023-08-31T21:46:13Z,OWNER,"This could even be a pair of hooks - `process_request()` and `process_response()`.
Or could take a leaf from Django, which redesigned middleware to use this pattern instead:
```python
def simple_middleware(get_response):
# One-time configuration and initialization.
def middleware(request):
# Code to be executed for each request before
# the view (and later middleware) are called.
response = get_response(request)
# Code to be executed for each request/response after
# the view is called.
return response
return middleware
```
Or even borrow an idea from `pytest` where fixtures can `yield` in the middle, like this:
```python
@pytest.fixture
def sending_user(mail_admin):
user = mail_admin.create_user()
yield user
mail_admin.delete_user(user)
```","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1876353656,
https://github.com/simonw/datasette/issues/2168#issuecomment-1701828197,https://api.github.com/repos/simonw/datasette/issues/2168,1701828197,IC_kwDOBm6k_c5lb9Zl,9599,2023-08-31T21:48:00Z,2023-08-31T21:48:57Z,OWNER,"A pattern like this could be interesting:
```python
async def my_middleware(datasette, request, get_response):
# Mess with request here if neccessary
response = await get_response(request)
# mess with response
return response
```
The Django pattern is more complicated but does have that mechanism for running one-time configuration prior to defining the `middleware()` function, which is neat.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1876353656,
https://github.com/simonw/datasette/issues/2168#issuecomment-1701830241,https://api.github.com/repos/simonw/datasette/issues/2168,1701830241,IC_kwDOBm6k_c5lb95h,9599,2023-08-31T21:50:18Z,2023-08-31T21:50:18Z,OWNER,"The hook could be called `register_middleware()` and could work like `register_routes()` and `register_commands()`:
```python
@hookspec
def register_middleware(datasette):
""""""Register middleware: returns a list of async def middleware functions""""""
```","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1876353656,
https://github.com/simonw/datasette/issues/2168#issuecomment-1701831013,https://api.github.com/repos/simonw/datasette/issues/2168,1701831013,IC_kwDOBm6k_c5lb-Fl,9599,2023-08-31T21:51:12Z,2023-08-31T21:52:15Z,OWNER,"Need to make sure the design of this takes streaming responses into account. Those could be pretty tricky here.
I nice thing about `asgi_wrapper()` is that it handles those already.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1876353656,
https://github.com/simonw/datasette/issues/1765#issuecomment-1701894468,https://api.github.com/repos/simonw/datasette/issues/1765,1701894468,IC_kwDOBm6k_c5lcNlE,9599,2023-08-31T23:08:24Z,2023-08-31T23:08:24Z,OWNER,https://docs.datasette.io/en/latest/writing_plugins.html#plugins-that-define-new-plugin-hooks,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1292370469,
https://github.com/simonw/datasette/issues/2157#issuecomment-1700291967,https://api.github.com/repos/simonw/datasette/issues/2157,1700291967,IC_kwDOBm6k_c5lWGV_,15178711,2023-08-31T02:45:56Z,2023-08-31T02:45:56Z,CONTRIBUTOR,"@simonw what do you think about adding a `DATASETTE_INTERNAL_DB_PATH` env variable, where when defined, is the default location of the internal DB? This means when the `--internal` flag is NOT provided, Datasette would check to see if `DATASETTE_INTERNAL_DB_PATH` exists, and if so, uses that as the internal database (and would fallback to an ephemeral memory database)
My rationale: some plugins may require, or strongly encourage, a persistent internal database (`datasette-comments`, `datasette-bookmarks`, `datasette-link-shortener`, etc.). However, for users that have a global installation of Datasette (say from `brew install` or a global `pip install`), it would be annoying having to specify `--internal` every time. So instead, they can just add `export DATASETTE_INTERNAL_DB_PATH=""/path/to/internal.db""` to their bashrc/zshrc/whereever to not have to worry about `--internal`","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1865869205,