{"html_url": "https://github.com/simonw/datasette/issues/2157#issuecomment-1700291967", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/2157", "id": 1700291967, "node_id": "IC_kwDOBm6k_c5lWGV_", "user": {"value": 15178711, "label": "asg017"}, "created_at": "2023-08-31T02:45:56Z", "updated_at": "2023-08-31T02:45:56Z", "author_association": "CONTRIBUTOR", "body": "@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)\r\n\r\nMy 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`", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1865869205, "label": "Proposal: Make the `_internal` database persistent, customizable, and hidden"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/2166#issuecomment-1701045404", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/2166", "id": 1701045404, "node_id": "IC_kwDOBm6k_c5lY-Sc", "user": {"value": 22429695, "label": "codecov[bot]"}, "created_at": "2023-08-31T13:31:15Z", "updated_at": "2023-09-06T13:25:17Z", "author_association": "NONE", "body": "## [Codecov](https://app.codecov.io/gh/simonw/datasette/pull/2166?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) Report\nPatch and project coverage have no change.\n> Comparison is base [(`05707aa`)](https://app.codecov.io/gh/simonw/datasette/commit/05707aa16b5c6c39fbe48b3176b85a8ffe493938?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) 92.68% compared to head [(`7c9df6e`)](https://app.codecov.io/gh/simonw/datasette/pull/2166?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) 92.68%.\n\n
Additional details and impacted files\n\n\n```diff\n@@ Coverage Diff @@\n## main #2166 +/- ##\n=======================================\n Coverage 92.68% 92.68% \n=======================================\n Files 40 40 \n Lines 6012 6012 \n=======================================\n Hits 5572 5572 \n Misses 440 440 \n```\n\n\n\n\n
\n\n[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/simonw/datasette/pull/2166?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison). \n:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison).\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1875519316, "label": "Bump the python-packages group with 1 update"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/2168#issuecomment-1701823609", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/2168", "id": 1701823609, "node_id": "IC_kwDOBm6k_c5lb8R5", "user": {"value": 9599, "label": "simonw"}, "created_at": "2023-08-31T21:43:06Z", "updated_at": "2023-08-31T21:44:13Z", "author_association": "OWNER", "body": "Not sure what to call this. Maybe `app_wrapper()`?\r\n\r\nOr perhaps it's simpler than that, something like this:\r\n\r\n```python\r\n@hookspec\r\ndef process_response(datasette, request, response):\r\n \"\"\"Last chance to modify the response before it is returned to the client\"\"\"\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1876353656, "label": "Consider a request/response wrapping hook slightly higher level than asgi_wrapper()"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/2168#issuecomment-1701826521", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/2168", "id": 1701826521, "node_id": "IC_kwDOBm6k_c5lb8_Z", "user": {"value": 9599, "label": "simonw"}, "created_at": "2023-08-31T21:46:13Z", "updated_at": "2023-08-31T21:46:13Z", "author_association": "OWNER", "body": "This could even be a pair of hooks - `process_request()` and `process_response()`.\r\n\r\nOr could take a leaf from Django, which redesigned middleware to use this pattern instead:\r\n\r\n```python\r\ndef simple_middleware(get_response):\r\n # One-time configuration and initialization.\r\n def middleware(request):\r\n # Code to be executed for each request before\r\n # the view (and later middleware) are called.\r\n response = get_response(request)\r\n # Code to be executed for each request/response after\r\n # the view is called.\r\n return response\r\n return middleware\r\n```\r\nOr even borrow an idea from `pytest` where fixtures can `yield` in the middle, like this:\r\n```python\r\n@pytest.fixture\r\ndef sending_user(mail_admin):\r\n user = mail_admin.create_user()\r\n yield user\r\n mail_admin.delete_user(user)\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1876353656, "label": "Consider a request/response wrapping hook slightly higher level than asgi_wrapper()"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/2168#issuecomment-1701828197", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/2168", "id": 1701828197, "node_id": "IC_kwDOBm6k_c5lb9Zl", "user": {"value": 9599, "label": "simonw"}, "created_at": "2023-08-31T21:48:00Z", "updated_at": "2023-08-31T21:48:57Z", "author_association": "OWNER", "body": "A pattern like this could be interesting:\r\n```python\r\nasync def my_middleware(datasette, request, get_response):\r\n # Mess with request here if neccessary\r\n response = await get_response(request)\r\n # mess with response\r\n return response\r\n```\r\nThe Django pattern is more complicated but does have that mechanism for running one-time configuration prior to defining the `middleware()` function, which is neat.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1876353656, "label": "Consider a request/response wrapping hook slightly higher level than asgi_wrapper()"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/2168#issuecomment-1701830241", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/2168", "id": 1701830241, "node_id": "IC_kwDOBm6k_c5lb95h", "user": {"value": 9599, "label": "simonw"}, "created_at": "2023-08-31T21:50:18Z", "updated_at": "2023-08-31T21:50:18Z", "author_association": "OWNER", "body": "The hook could be called `register_middleware()` and could work like `register_routes()` and `register_commands()`:\r\n\r\n```python\r\n@hookspec\r\ndef register_middleware(datasette):\r\n \"\"\"Register middleware: returns a list of async def middleware functions\"\"\"\r\n\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1876353656, "label": "Consider a request/response wrapping hook slightly higher level than asgi_wrapper()"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/2168#issuecomment-1701831013", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/2168", "id": 1701831013, "node_id": "IC_kwDOBm6k_c5lb-Fl", "user": {"value": 9599, "label": "simonw"}, "created_at": "2023-08-31T21:51:12Z", "updated_at": "2023-08-31T21:52:15Z", "author_association": "OWNER", "body": "Need to make sure the design of this takes streaming responses into account. Those could be pretty tricky here.\r\n\r\nI nice thing about `asgi_wrapper()` is that it handles those already.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1876353656, "label": "Consider a request/response wrapping hook slightly higher level than asgi_wrapper()"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1765#issuecomment-1701894468", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1765", "id": 1701894468, "node_id": "IC_kwDOBm6k_c5lcNlE", "user": {"value": 9599, "label": "simonw"}, "created_at": "2023-08-31T23:08:24Z", "updated_at": "2023-08-31T23:08:24Z", "author_association": "OWNER", "body": "https://docs.datasette.io/en/latest/writing_plugins.html#plugins-that-define-new-plugin-hooks", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1292370469, "label": "Document plugins providing new plugin hook-"}, "performed_via_github_app": null}