{"html_url": "https://github.com/simonw/datasette/issues/1809#issuecomment-1249990033", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1809", "id": 1249990033, "node_id": "IC_kwDOBm6k_c5KgVWR", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-09-17T03:39:05Z", "updated_at": "2022-09-17T03:39:05Z", "author_association": "OWNER", "body": "New docs section on the need to call `await ds.invoke_startup()`: https://github.com/simonw/datasette/blob/ddc999ad1296e8c69cffede3e367dda059b8adad/docs/testing_plugins.rst#setting-up-a-datasette-test-instance", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1373595927, "label": "`prepare_jinja2_environment()` hook should take `datasette` argument"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1809#issuecomment-1249987643", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1809", "id": 1249987643, "node_id": "IC_kwDOBm6k_c5KgUw7", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-09-17T03:19:24Z", "updated_at": "2022-09-17T03:19:24Z", "author_association": "OWNER", "body": "In looking at the documentation on [writing tests](https://docs.datasette.io/en/latest/testing_plugins.html), there are a lot of examples like this:\r\n```python\r\n def test_that_opens_the_debugger_or_errors():\r\n ds = Datasette([db_path], pdb=True)\r\n response = await ds.client.get(\"/\")\r\n```\r\nI really don't like having to tell people to add `await ds.invoke_startup()` to every test that might look like this.\r\n\r\nSince it's safe to call that function multiple times, I'm going to have `ds.client.get()` and friends call it for you too - so if you forget in a plugin test it won't matter.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1373595927, "label": "`prepare_jinja2_environment()` hook should take `datasette` argument"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1809#issuecomment-1249986079", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1809", "id": 1249986079, "node_id": "IC_kwDOBm6k_c5KgUYf", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-09-17T03:07:24Z", "updated_at": "2022-09-17T03:07:24Z", "author_association": "OWNER", "body": "Datasette's own tests started to break because calls to the `TestClient` were performed without awaiting that method. I fixed that by adding this to `_request()` inside that class:\r\n\r\n```python\r\n async def _request(\r\n self,\r\n path,\r\n follow_redirects=True,\r\n redirect_count=0,\r\n method=\"GET\",\r\n cookies=None,\r\n headers=None,\r\n post_body=None,\r\n content_type=None,\r\n if_none_match=None,\r\n ):\r\n if not self.ds._startup_invoked:\r\n await self.ds.invoke_startup()\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1373595927, "label": "`prepare_jinja2_environment()` hook should take `datasette` argument"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1809#issuecomment-1249985971", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1809", "id": 1249985971, "node_id": "IC_kwDOBm6k_c5KgUWz", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-09-17T03:06:32Z", "updated_at": "2022-09-17T03:06:32Z", "author_association": "OWNER", "body": "This is likely going to cause some tests in plugins to break, but I'm OK with that - I'll fix them as I find them once this release is out.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1373595927, "label": "`prepare_jinja2_environment()` hook should take `datasette` argument"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1809#issuecomment-1249985741", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1809", "id": 1249985741, "node_id": "IC_kwDOBm6k_c5KgUTN", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-09-17T03:04:51Z", "updated_at": "2022-09-17T03:04:51Z", "author_association": "OWNER", "body": "I'm going to throw an error in `ds.render_template()` if you haven't previously called `await ds.invoke_startup()`.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1373595927, "label": "`prepare_jinja2_environment()` hook should take `datasette` argument"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1809#issuecomment-1247317941", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1809", "id": 1247317941, "node_id": "IC_kwDOBm6k_c5KWI-1", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-09-14T21:24:43Z", "updated_at": "2022-09-14T21:24:43Z", "author_association": "OWNER", "body": "It looks like Datasette Lite does NOT invoke that method, which is likely a bug: https://github.com/simonw/datasette-lite/blob/e7ccaf621b3cdf613ebaf544304d387f2af32edf/webworker.js#L103-L110", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1373595927, "label": "`prepare_jinja2_environment()` hook should take `datasette` argument"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1809#issuecomment-1247316715", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1809", "id": 1247316715, "node_id": "IC_kwDOBm6k_c5KWIrr", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-09-14T21:23:10Z", "updated_at": "2022-09-14T21:23:10Z", "author_association": "OWNER", "body": "It might be good to have Datasette LOUDLY fail if you attempt to use it without calling `await ds.invoke_startup()`.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1373595927, "label": "`prepare_jinja2_environment()` hook should take `datasette` argument"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1809#issuecomment-1247316097", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1809", "id": 1247316097, "node_id": "IC_kwDOBm6k_c5KWIiB", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-09-14T21:22:24Z", "updated_at": "2022-09-14T21:22:24Z", "author_association": "OWNER", "body": "It looks like this is the only place that calls `invoke_startup()`: https://github.com/simonw/datasette/blob/1d64c9a8dac45b9a3452acf8e76dfadea2b0bc49/datasette/cli.py#L590-L591\r\n\r\n`datasette-publish-vercel` is the one deployment mechanism that skips running Uvicorn, and it calls that method separately here: https://github.com/simonw/datasette-publish-vercel/blob/1559d979b4e3b1f2f83c51c3c0c10192ff9a6d0c/datasette_publish_vercel/__init__.py#L42-L52\r\n\r\n```python\r\nds = Datasette(\r\n [],\r\n {database_files},\r\n static_mounts=static_mounts,\r\n metadata=metadata{extras},\r\n secret=secret,\r\n cors=True,\r\n settings={settings}{crossdb}\r\n)\r\nasyncio.run(ds.invoke_startup())\r\napp = ds.app()\r\n```\r\nSo preparing the Jinja environment inside that function would work fine.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1373595927, "label": "`prepare_jinja2_environment()` hook should take `datasette` argument"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1809#issuecomment-1247314352", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1809", "id": 1247314352, "node_id": "IC_kwDOBm6k_c5KWIGw", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-09-14T21:20:12Z", "updated_at": "2022-09-14T21:20:12Z", "author_association": "OWNER", "body": "The reason to support `await_me_maybe` is in case a hook wants to execute a SQL query as part of configuring the Jinja template loader.\r\n\r\nThat's exactly what `datasette-edit-templates` needs to do, though it's currently achieving that in a `startup()` hook instead: https://github.com/simonw/datasette-edit-templates/blob/087f6a6cabc20020f2b0524f11aa3a7836320848/datasette_edit_templates/__init__.py#L32-L48\r\n\r\n```python\r\n@hookimpl\r\ndef startup(datasette):\r\n datasette._edit_templates = {}\r\n\r\n async def inner():\r\n db = get_database(datasette)\r\n # Does the table exist?\r\n if not await db.table_exists(TABLE):\r\n for sql in CREATE_TABLE:\r\n await db.execute_write(sql, block=True)\r\n else:\r\n # Load all templates from that table\r\n rows = await db.execute(\"select template, body FROM {}\".format(TABLE))\r\n for name, content in rows:\r\n datasette._edit_templates[name] = content\r\n\r\n return inner\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1373595927, "label": "`prepare_jinja2_environment()` hook should take `datasette` argument"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1809#issuecomment-1247313134", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1809", "id": 1247313134, "node_id": "IC_kwDOBm6k_c5KWHzu", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-09-14T21:18:46Z", "updated_at": "2022-09-14T21:18:46Z", "author_association": "OWNER", "body": "`await_me_maybe` might be tricky though, because the only place that hook is executed is here:\r\n\r\nhttps://github.com/simonw/datasette/blob/8430c3bc7dd22b173c1a8c6cd7180e3b31240cd1/datasette/app.py#L348\r\n\r\nWhich is inside the `Datasette.__init__` method.\r\n\r\nTo implement an `await` on that would need to move it somewhere else - probably here: https://github.com/simonw/datasette/blob/8430c3bc7dd22b173c1a8c6cd7180e3b31240cd1/datasette/app.py#L391-L393\r\n\r\nBut I'm not 100% confident that is always executed at the right time to ensure the Jinja environment is properly configured? I think it is, but would need to make sure.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1373595927, "label": "`prepare_jinja2_environment()` hook should take `datasette` argument"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1809#issuecomment-1247311275", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1809", "id": 1247311275, "node_id": "IC_kwDOBm6k_c5KWHWr", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-09-14T21:16:32Z", "updated_at": "2022-09-14T21:16:32Z", "author_association": "OWNER", "body": "It should also implement the `await_me_maybe` pattern so you can return an `async` function from it.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1373595927, "label": "`prepare_jinja2_environment()` hook should take `datasette` argument"}, "performed_via_github_app": null}