{"html_url": "https://github.com/simonw/datasette/issues/1958#issuecomment-1353977605", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1958", "id": 1353977605, "node_id": "IC_kwDOBm6k_c5QtA8F", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-12-16T00:38:23Z", "updated_at": "2022-12-16T00:38:23Z", "author_association": "OWNER", "body": "Confirmed, I just got the same result:\r\n```\r\n- % docker run datasetteproject/datasette pip install datasette-upload-csvs\r\n~ % docker commit $(docker ps -lq) datasette-with-plugins\r\nsha256:8cde4a6357b9221d6f9e15887a314f2b4d9d1b87b517764d207ccbaec7c0a69f\r\n~ % docker run -p 8001:8001 -v $(pwd):/mnt datasette-with-plugins datasette --root -p 8001 -h 0.0.0.0\r\nINFO: Started server process [1]\r\nINFO: Waiting for application startup.\r\nINFO: Application startup complete.\r\nINFO: Uvicorn running on http://0.0.0.0:8001 (Press CTRL+C to quit)\r\n\r\n\r\n\r\n^CINFO: Shutting down\r\nINFO: Waiting for application shutdown.\r\nINFO: Application shutdown complete.\r\nINFO: Finished server process [1]\r\nhttp://0.0.0.0:8001/-/auth-token?token=4bd70fdbca215ea55c874eaf889adf8c09f2a00231f7e5e6d0470f3176407a98\r\n```\r\nNote how the auth-token URL is only displayed after you hit `Ctrl+C`!", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1497909798, "label": "datasette --root running in Docker doesn't reliably show the magic URL"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1958#issuecomment-1354008688", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1958", "id": 1354008688, "node_id": "IC_kwDOBm6k_c5QtIhw", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-12-16T00:45:40Z", "updated_at": "2022-12-16T00:45:40Z", "author_association": "OWNER", "body": "The fix may just be to switch to `click.echo()`. https://click.palletsprojects.com/en/8.1.x/api/#click.echo", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1497909798, "label": "datasette --root running in Docker doesn't reliably show the magic URL"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1958#issuecomment-1354019543", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1958", "id": 1354019543, "node_id": "IC_kwDOBm6k_c5QtLLX", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-12-16T00:54:11Z", "updated_at": "2022-12-16T00:54:11Z", "author_association": "OWNER", "body": "To test the fix, I did a fresh checkout of `simonw/datasette` and edited `Dockerfile` to look like this:\r\n```dockerfile\r\nFROM python:3.11.0-slim-bullseye as build\r\n\r\nRUN apt-get update && \\\r\n apt-get install -y --no-install-recommends libsqlite3-mod-spatialite && \\\r\n apt clean && \\\r\n rm -rf /var/lib/apt && \\\r\n rm -rf /var/lib/dpkg/info/*\r\n\r\nRUN pip install https://github.com/simonw/datasette/archive/refs/heads/main.zip && \\\r\n find /usr/local/lib -name '__pycache__' | xargs rm -r && \\\r\n rm -rf /root/.cache/pip\r\n\r\nEXPOSE 8001\r\nCMD [\"datasette\"]\r\n```\r\nThen I built it like this:\r\n```\r\ndocker build -f Dockerfile -t datasette-pre-click .\r\n```\r\nAnd ran like this:\r\n```\r\ndocker run -p 8001:8001 -v $(pwd):/mnt datasette-pre-click datasette --root -p 8001 -h 0.0.0.0\r\n```\r\nThis exhibited the same problem.\r\n\r\nThen I pushed a changed to branch and changed the line to:\r\n```\r\nRUN pip install https://github.com/simonw/datasette/archive/refs/heads/click-echo-root.zip && \\\r\n```\r\nRan this:\r\n```\r\ndocker build -f Dockerfile -t datasette-post-click .\r\n```\r\nAnd this:\r\n```\r\ndocker run -p 8001:8001 -v $(pwd):/mnt datasette-post-click datasette --root -p 8001 -h 0.0.0.0\r\n```\r\nIt fixed the problem!\r\n```\r\ndatasette % docker run -p 8001:8001 -v $(pwd):/mnt datasette-post-click datasette --root -p 8001 -h 0.0.0.0\r\nhttp://0.0.0.0:8001/-/auth-token?token=6542dcf5c8f34f8d13f4af9ce728359c602469efb54029098562bd06c87ad26d\r\nINFO: Started server process [1]\r\nINFO: Waiting for application startup.\r\nINFO: Application startup complete.\r\nINFO: Uvicorn running on http://0.0.0.0:8001 (Press CTRL+C to quit)\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1497909798, "label": "datasette --root running in Docker doesn't reliably show the magic URL"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1958#issuecomment-1354023960", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1958", "id": 1354023960, "node_id": "IC_kwDOBm6k_c5QtMQY", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-12-16T00:58:14Z", "updated_at": "2022-12-16T00:58:19Z", "author_association": "OWNER", "body": "This is in the `0.63.x` branch now, ready to go out in a bug fix release.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1497909798, "label": "datasette --root running in Docker doesn't reliably show the magic URL"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/issues/1958#issuecomment-1354025319", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1958", "id": 1354025319, "node_id": "IC_kwDOBm6k_c5QtMln", "user": {"value": 11729897, "label": "davidhaley"}, "created_at": "2022-12-16T00:59:12Z", "updated_at": "2022-12-16T00:59:12Z", "author_association": "NONE", "body": "Awesome. Thank you @simonw.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1497909798, "label": "datasette --root running in Docker doesn't reliably show the magic URL"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/pull/1960#issuecomment-1354036967", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1960", "id": 1354036967, "node_id": "IC_kwDOBm6k_c5QtPbn", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-12-16T01:10:12Z", "updated_at": "2022-12-16T01:10:12Z", "author_association": "OWNER", "body": "If it does turn out that I can't use `scope=\"session\"` on this fixture it might not actually be a showstopper: I can take advantage of the fact that `memory_name=\"...\"` databases stay present in memory for the duration of the process, so I could have it such that each test that uses the `ds_client` fixture DOES construct a fresh `Datasette` instance, but doesn't need to populate the database since they can re-use the in-memory database from the previous object.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1499150951, "label": "Port as many tests as possible to async def tests against ds_client"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/pull/1960#issuecomment-1354046627", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1960", "id": 1354046627, "node_id": "IC_kwDOBm6k_c5QtRyj", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-12-16T01:23:21Z", "updated_at": "2022-12-16T01:23:21Z", "author_association": "OWNER", "body": "This does seem to help:\r\n```diff\r\ndiff --git a/tests/conftest.py b/tests/conftest.py\r\nindex 1306c407..af9c7696 100644\r\n--- a/tests/conftest.py\r\n+++ b/tests/conftest.py\r\n@@ -25,12 +25,7 @@ UNDOCUMENTED_PERMISSIONS = {\r\n }\r\n \r\n \r\n-@pytest.fixture(scope=\"session\")\r\n-def event_loop():\r\n- return asyncio.get_event_loop()\r\n-\r\n-\r\n-@pytest_asyncio.fixture(scope=\"session\")\r\n+@pytest_asyncio.fixture\r\n async def ds_client():\r\n from datasette.app import Datasette\r\n from .fixtures import METADATA, PLUGINS_DIR\r\n@@ -53,10 +48,11 @@ async def ds_client():\r\n db = ds.add_memory_database(\"fixtures\")\r\n \r\n def prepare(conn):\r\n- conn.executescript(TABLES)\r\n- for sql, params in TABLE_PARAMETERIZED_SQL:\r\n- with conn:\r\n- conn.execute(sql, params)\r\n+ if not conn.execute(\"select count(*) from sqlite_master\").fetchone()[0]:\r\n+ conn.executescript(TABLES)\r\n+ for sql, params in TABLE_PARAMETERIZED_SQL:\r\n+ with conn:\r\n+ conn.execute(sql, params)\r\n \r\n await db.execute_write_fn(prepare)\r\n return ds.client\r\ndiff --git a/tests/plugins/my_plugin_2.py b/tests/plugins/my_plugin_2.py\r\nindex 4f7bf08c..d588342c 100644\r\n--- a/tests/plugins/my_plugin_2.py\r\n+++ b/tests/plugins/my_plugin_2.py\r\n@@ -117,7 +117,12 @@ def actor_from_request(datasette, request):\r\n def permission_allowed(datasette, actor, action):\r\n # Testing asyncio version of permission_allowed\r\n async def inner():\r\n- assert 2 == (await datasette.get_database().execute(\"select 1 + 1\")).first()[0]\r\n+ assert (\r\n+ 2\r\n+ == (\r\n+ await datasette.get_database(\"_internal\").execute(\"select 1 + 1\")\r\n+ ).first()[0]\r\n+ )\r\n if action == \"this_is_allowed_async\":\r\n return True\r\n elif action == \"this_is_denied_async\":\r\n```\r\n`pytest -m ds_client` now passes 134 tests.\r\n\r\nNeed to get `pytest -n auto` passing too.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1499150951, "label": "Port as many tests as possible to async def tests against ds_client"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/pull/1960#issuecomment-1354053151", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1960", "id": 1354053151, "node_id": "IC_kwDOBm6k_c5QtTYf", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-12-16T01:33:22Z", "updated_at": "2022-12-16T01:33:22Z", "author_association": "OWNER", "body": "The thing with `Datasette(memory=False)` is tripping me up.\r\n\r\nThe problem is that the tests written against `app_client` - which I want to replace - all assume that there is no `_memory` database, because when you start Datasette with at least one database file it doesn't enable `_memory` unless you explicitly tell it to.\r\n\r\nBut the new `ds_client` fixture works by creating a named in-memory database called `fixtures`, which it does with a call to `ds.add_memory_database(\"fixtures\")` after the object has been instantiated.\r\n\r\nThis results in a datasette instance that DOES have a `_memory` database, when we didn't want one.\r\n\r\nMy initial solution attempt was a huge hack - I decided that if you pass `memory=False` to the `Datasette` constructor it should mean \"don't add a `_memory` database even though I didn't pass any files\". I set a the default `memory` argument to `None`.\r\n\r\nThis is weird and surprising (`memory=False` no does something different from `memory=None`?) and I found other tests that it broke, like this one:\r\n\r\n```python\r\ndef test_sql_errors_logged_to_stderr():\r\n runner = CliRunner(mix_stderr=False)\r\n result = runner.invoke(cli, [\"--get\", \"/_memory.json?sql=select+blah\"])\r\n assert result.exit_code == 1\r\n assert \"sql = 'select blah', params = {}: no such column: blah\\n\" in result.stderr\r\n```\r\nIt ended up with no `_memory` database because it turns out `datasette serve ...` passes `memory=False` without me realizing it.\r\n\r\nSo I'm going to undo that hack and teach the fixture to do this instead:\r\n\r\n```python\r\ndb = ds.add_memory_database(\"fixtures\")\r\nds.remove_database(\"_memory\")\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1499150951, "label": "Port as many tests as possible to async def tests against ds_client"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/pull/1960#issuecomment-1354061440", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1960", "id": 1354061440, "node_id": "IC_kwDOBm6k_c5QtVaA", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-12-16T01:45:38Z", "updated_at": "2022-12-16T01:45:38Z", "author_association": "OWNER", "body": "I'm going to do `test_table_html.py` next.\r\n\r\nCurrently: 68 passed in 17.20s\r\n\r\nWill this speed it up?", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1499150951, "label": "Port as many tests as possible to async def tests against ds_client"}, "performed_via_github_app": null}
{"html_url": "https://github.com/simonw/datasette/pull/1960#issuecomment-1354062939", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1960", "id": 1354062939, "node_id": "IC_kwDOBm6k_c5QtVxb", "user": {"value": 22429695, "label": "codecov[bot]"}, "created_at": "2022-12-16T01:48:06Z", "updated_at": "2022-12-17T21:40:43Z", "author_association": "NONE", "body": "# [Codecov](https://codecov.io/gh/simonw/datasette/pull/1960?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) Report\nBase: **92.19**% // Head: **92.05**% // Decreases project coverage by **`-0.13%`** :warning:\n> Coverage data is based on head [(`770879a`)](https://codecov.io/gh/simonw/datasette/pull/1960?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) compared to base [(`0b68996`)](https://codecov.io/gh/simonw/datasette/commit/0b68996cc511b3a801f0cd0157bd66332d75f46f?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison).\n> Patch coverage: 100.00% of modified lines in pull request are covered.\n\n> :exclamation: Current head 770879a differs from pull request most recent head f42bca8. Consider uploading reports for the commit f42bca8 to get more accurate results\n\nAdditional details and impacted files
\n\n\n```diff\n@@ Coverage Diff @@\n## main #1960 +/- ##\n==========================================\n- Coverage 92.19% 92.05% -0.14% \n==========================================\n Files 38 38 \n Lines 5521 5527 +6 \n==========================================\n- Hits 5090 5088 -2 \n- Misses 431 439 +8 \n```\n\n\n| [Impacted Files](https://codecov.io/gh/simonw/datasette/pull/1960?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) | Coverage \u0394 | |\n|---|---|---|\n| [datasette/app.py](https://codecov.io/gh/simonw/datasette/pull/1960/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-ZGF0YXNldHRlL2FwcC5weQ==) | `94.13% <100.00%> (-0.57%)` | :arrow_down: |\n| [datasette/utils/testing.py](https://codecov.io/gh/simonw/datasette/pull/1960/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-ZGF0YXNldHRlL3V0aWxzL3Rlc3RpbmcucHk=) | `95.83% <100.00%> (+0.24%)` | :arrow_up: |\n| [datasette/views/index.py](https://codecov.io/gh/simonw/datasette/pull/1960/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-ZGF0YXNldHRlL3ZpZXdzL2luZGV4LnB5) | `96.49% <0.00%> (-1.76%)` | :arrow_down: |\n| [datasette/database.py](https://codecov.io/gh/simonw/datasette/pull/1960/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-ZGF0YXNldHRlL2RhdGFiYXNlLnB5) | `94.57% <0.00%> (-0.61%)` | :arrow_down: |\n\nHelp us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison)\n\n