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/2189#issuecomment-1724084199,https://api.github.com/repos/simonw/datasette/issues/2189,1724084199,IC_kwDOBm6k_c5mw2_n,9599,2023-09-18T17:47:01Z,2023-09-18T17:47:01Z,OWNER,I managed to trigger it by loading `http://127.0.0.1:8045/airtable_refs/airtable_refs` - which worked - and then hitting refresh on that page a bunch of times until it hung.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1901416155,
https://github.com/simonw/datasette/issues/2189#issuecomment-1724083324,https://api.github.com/repos/simonw/datasette/issues/2189,1724083324,IC_kwDOBm6k_c5mw2x8,9599,2023-09-18T17:46:21Z,2023-09-18T17:46:21Z,OWNER,"Sometimes it takes a few clicks for the bug to occur, but it does seem to always be within the in-memory database.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1901416155,
https://github.com/simonw/datasette/issues/2189#issuecomment-1724081909,https://api.github.com/repos/simonw/datasette/issues/2189,1724081909,IC_kwDOBm6k_c5mw2b1,9599,2023-09-18T17:45:27Z,2023-09-18T17:45:27Z,OWNER,Maybe it's not related to faceting - I just got it on a hit to `http://127.0.0.1:8045/airtable_refs/airtable_refs` instead.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1901416155,
https://github.com/simonw/datasette/issues/2189#issuecomment-1724072390,https://api.github.com/repos/simonw/datasette/issues/2189,1724072390,IC_kwDOBm6k_c5mw0HG,9599,2023-09-18T17:39:06Z,2023-09-18T17:39:06Z,OWNER,Landing a version of that test anyway.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1901416155,
https://github.com/simonw/datasette/issues/2189#issuecomment-1724064440,https://api.github.com/repos/simonw/datasette/issues/2189,1724064440,IC_kwDOBm6k_c5mwyK4,9599,2023-09-18T17:36:00Z,2023-09-18T17:36:00Z,OWNER,"I wrote this test, but it passes:
```python
@pytest.mark.asyncio
async def test_facet_against_in_memory_database():
ds = Datasette()
db = ds.add_memory_database(""mem"")
await db.execute_write(""create table t (id integer primary key, name text)"")
await db.execute_write_many(
""insert into t (name) values (?)"", [[""one""], [""one""], [""two""]]
)
response1 = await ds.client.get(""/mem/t.json"")
assert response1.status_code == 200
response2 = await ds.client.get(""/mem/t.json?_facet=name"")
assert response2.status_code == 200
assert response2.json() == {
""ok"": True,
""next"": None,
""facet_results"": {
""results"": {
""name"": {
""name"": ""name"",
""type"": ""column"",
""hideable"": True,
""toggle_url"": ""/mem/t.json"",
""results"": [
{
""value"": ""one"",
""label"": ""one"",
""count"": 2,
""toggle_url"": ""http://localhost/mem/t.json?_facet=name&name=one"",
""selected"": False,
},
{
""value"": ""two"",
""label"": ""two"",
""count"": 1,
""toggle_url"": ""http://localhost/mem/t.json?_facet=name&name=two"",
""selected"": False,
},
],
""truncated"": False,
}
},
""timed_out"": [],
},
""rows"": [
{""id"": 1, ""name"": ""one""},
{""id"": 2, ""name"": ""one""},
{""id"": 3, ""name"": ""two""},
],
""truncated"": False,
}
```","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1901416155,
https://github.com/simonw/datasette/issues/2189#issuecomment-1724055823,https://api.github.com/repos/simonw/datasette/issues/2189,1724055823,IC_kwDOBm6k_c5mwwEP,9599,2023-09-18T17:31:10Z,2023-09-18T17:31:10Z,OWNER,That line was added in https://github.com/simonw/datasette/commit/942411ef946e9a34a2094944d3423cddad27efd3 which first shipped in 0.62a0.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1901416155,
https://github.com/simonw/datasette/issues/2189#issuecomment-1724051886,https://api.github.com/repos/simonw/datasette/issues/2189,1724051886,IC_kwDOBm6k_c5mwvGu,9599,2023-09-18T17:28:20Z,2023-09-18T17:30:30Z,OWNER,"The bug exhibits when I try to add a facet. I think it's caused by the parallel query execution I added to facets at some point.
http://127.0.0.1:8045/airtable_refs/airtable_refs - no error
http://127.0.0.1:8045/airtable_refs/airtable_refs?_facet=table_name#facet-table_name - hangs the server
Crucial line in the traceback:
```
await gather(execute_facets(), execute_suggested_facets())
```
From here: https://github.com/simonw/datasette/blob/917272c864ad7b8a00c48c77f5c2944093babb4e/datasette/views/table.py#L568","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1901416155,
https://github.com/simonw/datasette/issues/2189#issuecomment-1724049538,https://api.github.com/repos/simonw/datasette/issues/2189,1724049538,IC_kwDOBm6k_c5mwuiC,9599,2023-09-18T17:26:44Z,2023-09-18T17:26:44Z,OWNER,"Just managed to get this exception trace:
```
return await self.route_path(scope, receive, send, path)
File ""/Users/simon/.local/share/virtualenvs/airtable-export-Ca4U-3qk/lib/python3.8/site-packages/datasette/app.py"", line 1354, in route_path
response = await view(request, send)
File ""/Users/simon/.local/share/virtualenvs/airtable-export-Ca4U-3qk/lib/python3.8/site-packages/datasette/views/base.py"", line 134, in view
return await self.dispatch_request(request)
File ""/Users/simon/.local/share/virtualenvs/airtable-export-Ca4U-3qk/lib/python3.8/site-packages/datasette/views/base.py"", line 91, in dispatch_request
return await handler(request)
File ""/Users/simon/.local/share/virtualenvs/airtable-export-Ca4U-3qk/lib/python3.8/site-packages/datasette/views/base.py"", line 361, in get
response_or_template_contexts = await self.data(request, **data_kwargs)
File ""/Users/simon/.local/share/virtualenvs/airtable-export-Ca4U-3qk/lib/python3.8/site-packages/datasette/views/table.py"", line 158, in data
return await self._data_traced(request, default_labels, _next, _size)
File ""/Users/simon/.local/share/virtualenvs/airtable-export-Ca4U-3qk/lib/python3.8/site-packages/datasette/views/table.py"", line 568, in _data_traced
await gather(execute_facets(), execute_suggested_facets())
File ""/Users/simon/.local/share/virtualenvs/airtable-export-Ca4U-3qk/lib/python3.8/site-packages/datasette/views/table.py"", line 177, in _gather_parallel
return await asyncio.gather(*args)
asyncio.exceptions.CancelledError
INFO: 127.0.0.1:64109 - ""GET /airtable_refs/airtable_refs?_facet=table_name&table_name=Sessions HTTP/1.1"" 500 Internal Server Error
^CError in atexit._run_exitfuncs:
Traceback (most recent call last):
File ""/Users/simon/.pyenv/versions/3.8.17/lib/python3.8/concurrent/futures/thread.py"", line 40, in _python_exit
t.join()
File ""/Users/simon/.pyenv/versions/3.8.17/lib/python3.8/threading.py"", line 1011, in join
self._wait_for_tstate_lock()
File ""/Users/simon/.pyenv/versions/3.8.17/lib/python3.8/threading.py"", line 1027, in _wait_for_tstate_lock
elif lock.acquire(block, timeout):
KeyboardInterrupt
```","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1901416155,
https://github.com/simonw/datasette/issues/2189#issuecomment-1724048314,https://api.github.com/repos/simonw/datasette/issues/2189,1724048314,IC_kwDOBm6k_c5mwuO6,9599,2023-09-18T17:25:55Z,2023-09-18T17:25:55Z,OWNER,"The good news is that this bug is currently unlikely to affect most users since named in-memory databases (created using `datasette.add_memory_database(""airtable_refs"")` ([docs](https://docs.datasette.io/en/stable/internals.html#add-memory-database-name)) are a pretty obscure feature, only available to plugins.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1901416155,
https://github.com/simonw/datasette/issues/2189#issuecomment-1724045748,https://api.github.com/repos/simonw/datasette/issues/2189,1724045748,IC_kwDOBm6k_c5mwtm0,9599,2023-09-18T17:24:07Z,2023-09-18T17:24:07Z,OWNER,"I need reliable steps to reproduce, then I can bisect and figure out which exact version of Datasette introduced the problem.
I have a hunch that it relates to changes made to the `datasette/database.py` module, maybe one of these changes here: https://github.com/simonw/datasette/compare/0.61...0.63.1#diff-4e20309c969326a0008dc9237f6807f48d55783315fbfc1e7dfa480b550e16f9","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1901416155,
https://github.com/simonw/datasette/issues/2123#issuecomment-1723362847,https://api.github.com/repos/simonw/datasette/issues/2123,1723362847,IC_kwDOBm6k_c5muG4f,6523121,2023-09-18T13:02:46Z,2023-09-18T13:02:46Z,NONE,"Can confirm that this bug can be reproduced as follows:
```
docker run datasetteproject/datasette datasette serve --reload
```
which produces the following output:
> Starting monitor for PID 10.
> Error: Invalid value for '[FILES]...': Path 'serve' does not exist.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1825007061,
https://github.com/simonw/datasette/pull/2052#issuecomment-1722943484,https://api.github.com/repos/simonw/datasette/issues/2052,1722943484,IC_kwDOBm6k_c5msgf8,30934,2023-09-18T08:14:47Z,2023-09-18T08:14:47Z,NONE,This is such a well thought out contribution. I don't think I've seen such a thoroughly considered PR on any project in recent memory.,"{""total_count"": 1, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 1, ""rocket"": 0, ""eyes"": 0}",1651082214,
https://github.com/simonw/datasette/issues/2188#issuecomment-1722848454,https://api.github.com/repos/simonw/datasette/issues/2188,1722848454,IC_kwDOBm6k_c5msJTG,15178711,2023-09-18T06:58:53Z,2023-09-18T06:58:53Z,CONTRIBUTOR,"Thinking about this more, here a list of things I imagine a ""compile-to-sql"" plugin would want to do:
1. Attach itself to the SQL code editor (switch from SQL -> PRQL/Logica, additional syntax highlighting)
2. Add ""Query using PRQL"" buttons in various parts of Datasette's UI, like `/dbname` page
3. Use `$LANGUAGE=` instead of `sql=` in the JSON API and the SQL results pages
4. Have their own dedicated code editor page
1) and 2) would be difficult to do with current plugin hooks, unless we add the concept of ""slots"" and get the JS plugin support in. 3) could maybe be done with the [`asgi_wrapper(datasette)`](https://docs.datasette.io/en/stable/plugin_hooks.html#asgi-wrapper-datasette) hook? And 4) ca n be done easily with the `register_routes()` hooks.
So it really only sounds like extending the SQL editor will be the hard part. In #2094 I want to add JavaScript plugin hooks for extending the SQL editor, which may work here.
If I get the time/motivation, I might try out a `datasette-prql` extension, just because I like playing with it. It'd be really cool if I can get the `asgi_wrapper()` hook to work right there...","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1900026059,
https://github.com/simonw/datasette/issues/1191#issuecomment-1722845490,https://api.github.com/repos/simonw/datasette/issues/1191,1722845490,IC_kwDOBm6k_c5msIky,15178711,2023-09-18T06:55:52Z,2023-09-18T06:55:52Z,CONTRIBUTOR,"One note here: this feature could be called ""slots"", similar to [Layout Slots](https://vitepress.dev/guide/extending-default-theme#layout-slots) in Vitepress.
In Vitepress, you can add custom components/widget/gadgets into determined named ""slots"", like so:
```
doc-top
doc-bottom
doc-footer-before
doc-before
doc-after
...
```
Would be great to do in both Python and Javascript, with the upcoming JavaScript API #2052. In `datasette-write-ui`, all we do is add a few ""Insert row"" and ""edit this row"" buttons and that required completely capturing the `table.html` template, which isn't great for other plugins. But having ""slots"" like `table-footer-before` or `table-row-id` or something would be great to work with.
","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",787098345,
https://github.com/simonw/datasette/issues/2188#issuecomment-1722662413,https://api.github.com/repos/simonw/datasette/issues/2188,1722662413,IC_kwDOBm6k_c5mrb4N,9599,2023-09-18T02:01:34Z,2023-09-18T02:01:34Z,OWNER,"I'm not interested in these in Datasette core itself, but I think they have a ton of potential for plugins.
I wonder what the best way to handle that would be?
Right now it's possible to write a plugin that [adds extra routes](https://docs.datasette.io/en/stable/plugin_hooks.html#register-routes-datasette), so someone could build a `/dbname/-/prql?query=xxx` endpoint.
If this could return JSON, they could add JavaScript to the `/dbname` page that provided a UI for kicking off one of those queries.
Something that could make that more ergonomic might be the plugin hook that allows plugins to add extra HTML to different core database pages - e.g. adding a ""Query this database using PRQL"" button or link or even a full form at the top of that database page. That's this issue here:
- #1191","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1900026059,
https://github.com/simonw/datasette/issues/2057#issuecomment-1722323967,https://api.github.com/repos/simonw/datasette/issues/2057,1722323967,IC_kwDOBm6k_c5mqJP_,9599,2023-09-16T21:54:33Z,2023-09-16T21:54:33Z,OWNER,Just found this migration guide: https://importlib-metadata.readthedocs.io/en/latest/migration.html,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1662951875,
https://github.com/simonw/datasette/issues/2057#issuecomment-1722266942,https://api.github.com/repos/simonw/datasette/issues/2057,1722266942,IC_kwDOBm6k_c5mp7U-,9599,2023-09-16T16:38:27Z,2023-09-16T16:38:27Z,OWNER,"The `importlib.metadata.entry_points()` function is pretty interesting:
```pycon
>>> import importlib.metadata
>>> from pprint import pprint
>>> pprint(importlib.metadata.entry_points())
{'babel.checkers': [EntryPoint(name='num_plurals', value='babel.messages.checkers:num_plurals', group='babel.checkers'),
EntryPoint(name='python_format', value='babel.messages.checkers:python_format', group='babel.checkers')],
'babel.extractors': [EntryPoint(name='jinja2', value='jinja2.ext:babel_extract[i18n]', group='babel.extractors'),
EntryPoint(name='ignore', value='babel.messages.extract:extract_nothing', group='babel.extractors'),
EntryPoint(name='javascript', value='babel.messages.extract:extract_javascript', group='babel.extractors'),
EntryPoint(name='python', value='babel.messages.extract:extract_python', group='babel.extractors')],
'console_scripts': [EntryPoint(name='datasette', value='datasette.cli:cli', group='console_scripts'),
EntryPoint(name='normalizer', value='charset_normalizer.cli.normalizer:cli_detect', group='console_scripts'),
EntryPoint(name='pypprint', value='pprintpp:console', group='console_scripts'),
EntryPoint(name='cog', value='cogapp:main', group='console_scripts'),
EntryPoint(name='icdiff', value='icdiff:start', group='console_scripts'),
EntryPoint(name='pycodestyle', value='pycodestyle:_main', group='console_scripts'),
EntryPoint(name='sphinx-autobuild', value='sphinx_autobuild.__main__:main', group='console_scripts'),
EntryPoint(name='sphinx-apidoc', value='sphinx.ext.apidoc:main', group='console_scripts'),
EntryPoint(name='sphinx-autogen', value='sphinx.ext.autosummary.generate:main', group='console_scripts'),
EntryPoint(name='sphinx-build', value='sphinx.cmd.build:main', group='console_scripts'),
EntryPoint(name='sphinx-quickstart', value='sphinx.cmd.quickstart:main', group='console_scripts'),
EntryPoint(name='sphinx-to-sqlite', value='sphinx_to_sqlite.cli:cli', group='console_scripts'),
EntryPoint(name='pybabel', value='babel.messages.frontend:main', group='console_scripts'),
EntryPoint(name='docutils', value='docutils.__main__:main', group='console_scripts'),
EntryPoint(name='isort', value='isort.main:main', group='console_scripts'),
EntryPoint(name='isort-identify-imports', value='isort.main:identify_imports_main', group='console_scripts'),
EntryPoint(name='hupper', value='hupper.cli:main', group='console_scripts'),
EntryPoint(name='sqlite-utils', value='sqlite_utils.cli:cli', group='console_scripts'),
EntryPoint(name='py.test', value='pytest:console_main', group='console_scripts'),
EntryPoint(name='pytest', value='pytest:console_main', group='console_scripts'),
EntryPoint(name='pyflakes', value='pyflakes.api:main', group='console_scripts'),
EntryPoint(name='livereload', value='livereload.cli:main', group='console_scripts'),
EntryPoint(name='uvicorn', value='uvicorn.main:main', group='console_scripts'),
EntryPoint(name='httpx', value='httpx:main', group='console_scripts'),
EntryPoint(name='flake8', value='flake8.main.cli:main', group='console_scripts'),
EntryPoint(name='blacken-docs', value='blacken_docs:main', group='console_scripts'),
EntryPoint(name='pip', value='pip._internal.cli.main:main', group='console_scripts'),
EntryPoint(name='pip3', value='pip._internal.cli.main:main', group='console_scripts'),
EntryPoint(name='pip3.10', value='pip._internal.cli.main:main', group='console_scripts'),
EntryPoint(name='wheel', value='wheel.cli:main', group='console_scripts'),
EntryPoint(name='pygmentize', value='pygments.cmdline:main', group='console_scripts'),
EntryPoint(name='black', value='black:patched_main', group='console_scripts'),
EntryPoint(name='blackd', value='blackd:patched_main [d]', group='console_scripts'),
EntryPoint(name='codespell', value='codespell_lib:_script_main', group='console_scripts'),
EntryPoint(name='tabulate', value='tabulate:_main', group='console_scripts')],
'datasette': [EntryPoint(name='debug_permissions', value='datasette_debug_permissions', group='datasette'),
EntryPoint(name='codespaces', value='datasette_codespaces', group='datasette'),
EntryPoint(name='vega', value='datasette_vega', group='datasette'),
EntryPoint(name='x_forwarded_host', value='datasette_x_forwarded_host', group='datasette'),
EntryPoint(name='json_html', value='datasette_json_html', group='datasette'),
EntryPoint(name='datasette_write_ui', value='datasette_write_ui', group='datasette'),
EntryPoint(name='pretty_json', value='datasette_pretty_json', group='datasette'),
EntryPoint(name='graphql', value='datasette_graphql', group='datasette')],
'distutils.commands': [EntryPoint(name='compile_catalog', value='babel.messages.frontend:compile_catalog', group='distutils.commands'),
EntryPoint(name='extract_messages', value='babel.messages.frontend:extract_messages', group='distutils.commands'),
EntryPoint(name='init_catalog', value='babel.messages.frontend:init_catalog', group='distutils.commands'),
EntryPoint(name='update_catalog', value='babel.messages.frontend:update_catalog', group='distutils.commands'),
EntryPoint(name='isort', value='isort.setuptools_commands:ISortCommand', group='distutils.commands'),
EntryPoint(name='alias', value='setuptools.command.alias:alias', group='distutils.commands'),
EntryPoint(name='bdist_egg', value='setuptools.command.bdist_egg:bdist_egg', group='distutils.commands'),
EntryPoint(name='bdist_rpm', value='setuptools.command.bdist_rpm:bdist_rpm', group='distutils.commands'),
EntryPoint(name='build', value='setuptools.command.build:build', group='distutils.commands'),
EntryPoint(name='build_clib', value='setuptools.command.build_clib:build_clib', group='distutils.commands'),
EntryPoint(name='build_ext', value='setuptools.command.build_ext:build_ext', group='distutils.commands'),
EntryPoint(name='build_py', value='setuptools.command.build_py:build_py', group='distutils.commands'),
EntryPoint(name='develop', value='setuptools.command.develop:develop', group='distutils.commands'),
EntryPoint(name='dist_info', value='setuptools.command.dist_info:dist_info', group='distutils.commands'),
EntryPoint(name='easy_install', value='setuptools.command.easy_install:easy_install', group='distutils.commands'),
EntryPoint(name='editable_wheel', value='setuptools.command.editable_wheel:editable_wheel', group='distutils.commands'),
EntryPoint(name='egg_info', value='setuptools.command.egg_info:egg_info', group='distutils.commands'),
EntryPoint(name='install', value='setuptools.command.install:install', group='distutils.commands'),
EntryPoint(name='install_egg_info', value='setuptools.command.install_egg_info:install_egg_info', group='distutils.commands'),
EntryPoint(name='install_lib', value='setuptools.command.install_lib:install_lib', group='distutils.commands'),
EntryPoint(name='install_scripts', value='setuptools.command.install_scripts:install_scripts', group='distutils.commands'),
EntryPoint(name='rotate', value='setuptools.command.rotate:rotate', group='distutils.commands'),
EntryPoint(name='saveopts', value='setuptools.command.saveopts:saveopts', group='distutils.commands'),
EntryPoint(name='sdist', value='setuptools.command.sdist:sdist', group='distutils.commands'),
EntryPoint(name='setopt', value='setuptools.command.setopt:setopt', group='distutils.commands'),
EntryPoint(name='test', value='setuptools.command.test:test', group='distutils.commands'),
EntryPoint(name='upload_docs', value='setuptools.command.upload_docs:upload_docs', group='distutils.commands'),
EntryPoint(name='bdist_wheel', value='wheel.bdist_wheel:bdist_wheel', group='distutils.commands')],
'distutils.setup_keywords': [EntryPoint(name='message_extractors', value='babel.messages.frontend:check_message_extractors', group='distutils.setup_keywords'),
EntryPoint(name='cffi_modules', value='cffi.setuptools_ext:cffi_modules', group='distutils.setup_keywords'),
EntryPoint(name='dependency_links', value='setuptools.dist:assert_string_list', group='distutils.setup_keywords'),
EntryPoint(name='eager_resources', value='setuptools.dist:assert_string_list', group='distutils.setup_keywords'),
EntryPoint(name='entry_points', value='setuptools.dist:check_entry_points', group='distutils.setup_keywords'),
EntryPoint(name='exclude_package_data', value='setuptools.dist:check_package_data', group='distutils.setup_keywords'),
EntryPoint(name='extras_require', value='setuptools.dist:check_extras', group='distutils.setup_keywords'),
EntryPoint(name='include_package_data', value='setuptools.dist:assert_bool', group='distutils.setup_keywords'),
EntryPoint(name='install_requires', value='setuptools.dist:check_requirements', group='distutils.setup_keywords'),
EntryPoint(name='namespace_packages', value='setuptools.dist:check_nsp', group='distutils.setup_keywords'),
EntryPoint(name='package_data', value='setuptools.dist:check_package_data', group='distutils.setup_keywords'),
EntryPoint(name='packages', value='setuptools.dist:check_packages', group='distutils.setup_keywords'),
EntryPoint(name='python_requires', value='setuptools.dist:check_specifier', group='distutils.setup_keywords'),
EntryPoint(name='setup_requires', value='setuptools.dist:check_requirements', group='distutils.setup_keywords'),
EntryPoint(name='test_loader', value='setuptools.dist:check_importable', group='distutils.setup_keywords'),
EntryPoint(name='test_runner', value='setuptools.dist:check_importable', group='distutils.setup_keywords'),
EntryPoint(name='test_suite', value='setuptools.dist:check_test_suite', group='distutils.setup_keywords'),
EntryPoint(name='tests_require', value='setuptools.dist:check_requirements', group='distutils.setup_keywords'),
EntryPoint(name='use_2to3', value='setuptools.dist:invalid_unless_false', group='distutils.setup_keywords'),
EntryPoint(name='zip_safe', value='setuptools.dist:assert_bool', group='distutils.setup_keywords')],
'egg_info.writers': [EntryPoint(name='PKG-INFO', value='setuptools.command.egg_info:write_pkg_info', group='egg_info.writers'),
EntryPoint(name='dependency_links.txt', value='setuptools.command.egg_info:overwrite_arg', group='egg_info.writers'),
EntryPoint(name='depends.txt', value='setuptools.command.egg_info:warn_depends_obsolete', group='egg_info.writers'),
EntryPoint(name='eager_resources.txt', value='setuptools.command.egg_info:overwrite_arg', group='egg_info.writers'),
EntryPoint(name='entry_points.txt', value='setuptools.command.egg_info:write_entries', group='egg_info.writers'),
EntryPoint(name='namespace_packages.txt', value='setuptools.command.egg_info:overwrite_arg', group='egg_info.writers'),
EntryPoint(name='requires.txt', value='setuptools.command.egg_info:write_requirements', group='egg_info.writers'),
EntryPoint(name='top_level.txt', value='setuptools.command.egg_info:write_toplevel_names', group='egg_info.writers')],
'flake8.extension': [EntryPoint(name='C90', value='mccabe:McCabeChecker', group='flake8.extension'),
EntryPoint(name='E', value='flake8.plugins.pycodestyle:pycodestyle_logical', group='flake8.extension'),
EntryPoint(name='F', value='flake8.plugins.pyflakes:FlakesChecker', group='flake8.extension'),
EntryPoint(name='W', value='flake8.plugins.pycodestyle:pycodestyle_physical', group='flake8.extension')],
'flake8.report': [EntryPoint(name='default', value='flake8.formatting.default:Default', group='flake8.report'),
EntryPoint(name='pylint', value='flake8.formatting.default:Pylint', group='flake8.report'),
EntryPoint(name='quiet-filename', value='flake8.formatting.default:FilenameOnly', group='flake8.report'),
EntryPoint(name='quiet-nothing', value='flake8.formatting.default:Nothing', group='flake8.report')],
'pylama.linter': [EntryPoint(name='isort', value='isort.pylama_isort:Linter', group='pylama.linter')],
'pytest11': [EntryPoint(name='icdiff', value='pytest_icdiff', group='pytest11'),
EntryPoint(name='asyncio', value='pytest_asyncio.plugin', group='pytest11'),
EntryPoint(name='xdist', value='xdist.plugin', group='pytest11'),
EntryPoint(name='xdist.looponfail', value='xdist.looponfail', group='pytest11'),
EntryPoint(name='timeout', value='pytest_timeout', group='pytest11'),
EntryPoint(name='anyio', value='anyio.pytest_plugin', group='pytest11')],
'setuptools.finalize_distribution_options': [EntryPoint(name='keywords', value='setuptools.dist:Distribution._finalize_setup_keywords', group='setuptools.finalize_distribution_options'),
EntryPoint(name='parent_finalize', value='setuptools.dist:_Distribution.finalize_options', group='setuptools.finalize_distribution_options')],
'sphinx.html_themes': [EntryPoint(name='alabaster', value='alabaster', group='sphinx.html_themes'),
EntryPoint(name='basic-ng', value='sphinx_basic_ng', group='sphinx.html_themes'),
EntryPoint(name='furo', value='furo', group='sphinx.html_themes')],
'sqlite_utils': [EntryPoint(name='hello_world', value='sqlite_utils_hello_world', group='sqlite_utils')]}
```","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1662951875,
https://github.com/simonw/datasette/issues/2057#issuecomment-1722266513,https://api.github.com/repos/simonw/datasette/issues/2057,1722266513,IC_kwDOBm6k_c5mp7OR,9599,2023-09-16T16:36:09Z,2023-09-16T16:36:09Z,OWNER,"Now I need to switch out `pkg_resources` in `plugins.py`:
https://github.com/simonw/datasette/blob/852f5014853943fa27f43ddaa2d442545b3259fb/datasette/plugins.py#L33-L74","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1662951875,
https://github.com/simonw/datasette/issues/2057#issuecomment-1722265848,https://api.github.com/repos/simonw/datasette/issues/2057,1722265848,IC_kwDOBm6k_c5mp7D4,9599,2023-09-16T16:32:42Z,2023-09-16T16:32:42Z,OWNER,"Here's the exception it uses:
```pycon
>>> importlib.metadata.version(""datasette"")
'1.0a6'
>>> importlib.metadata.version(""datasette2"")
Traceback (most recent call last):
File """", line 1, in
File ""/opt/homebrew/Caskroom/miniconda/base/lib/python3.10/importlib/metadata/__init__.py"", line 996, in version
return distribution(distribution_name).version
File ""/opt/homebrew/Caskroom/miniconda/base/lib/python3.10/importlib/metadata/__init__.py"", line 969, in distribution
return Distribution.from_name(distribution_name)
File ""/opt/homebrew/Caskroom/miniconda/base/lib/python3.10/importlib/metadata/__init__.py"", line 548, in from_name
raise PackageNotFoundError(name)
importlib.metadata.PackageNotFoundError: No package metadata was found for datasette2
```","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1662951875,
https://github.com/simonw/datasette/issues/2057#issuecomment-1722258980,https://api.github.com/repos/simonw/datasette/issues/2057,1722258980,IC_kwDOBm6k_c5mp5Yk,9599,2023-09-16T15:56:45Z,2023-09-16T15:56:45Z,OWNER,"Weird, I still can't get the warning to show even with this:
```python
@pytest.mark.asyncio
async def test_plugin_is_installed():
datasette = Datasette(memory=True)
class DummyPlugin:
__name__ = ""DummyPlugin""
@hookimpl
def actors_from_ids(self, datasette, actor_ids):
return {}
try:
pm.register(DummyPlugin(), name=""DummyPlugin"")
response = await datasette.client.get(""/-/plugins.json"")
assert response.status_code == 200
installed_plugins = {p[""name""] for p in response.json()}
assert ""DummyPlugin"" in installed_plugins
finally:
pm.unregister(name=""ReturnNothingPlugin"")
```","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1662951875,
https://github.com/simonw/datasette/issues/2057#issuecomment-1722257328,https://api.github.com/repos/simonw/datasette/issues/2057,1722257328,IC_kwDOBm6k_c5mp4-w,9599,2023-09-16T15:47:32Z,2023-09-16T15:47:32Z,OWNER,"Frustrating that this warning doesn't show up in the Datasette test suite itself. It shows up in plugin test suites that run this test:
```python
@pytest.mark.asyncio
async def test_plugin_is_installed():
datasette = Datasette(memory=True)
response = await datasette.client.get(""/-/plugins.json"")
assert response.status_code == 200
installed_plugins = {p[""name""] for p in response.json()}
assert ""datasette-chronicle"" in installed_plugins
```
If you run that test inside Datasette core `installed_plugins` is an empty set, which presumably is why the warning doesn't get triggered there.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1662951875,
https://github.com/simonw/datasette/issues/2186#issuecomment-1721742055,https://api.github.com/repos/simonw/datasette/issues/2186,1721742055,IC_kwDOBm6k_c5mn7Ln,9599,2023-09-15T19:27:59Z,2023-09-15T19:27:59Z,OWNER,This feels like it might be quite a nice pattern generally - providing optional arguments to plugins and views that can be `await get_x()` called to run an extra calculation.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1898927976,
https://github.com/simonw/datasette/issues/2186#issuecomment-1721740872,https://api.github.com/repos/simonw/datasette/issues/2186,1721740872,IC_kwDOBm6k_c5mn65I,9599,2023-09-15T19:26:51Z,2023-09-15T19:27:19Z,OWNER,"Here's where it's called at the moment: https://github.com/simonw/datasette/blob/16f0b6d8222d06682a31b904d0a402c391ae1c1c/datasette/views/base.py#L297-L313
And the docs: https://github.com/simonw/datasette/blob/1.0a6/docs/plugin_hooks.rst#register-output-renderer-datasette
I'm tempted to add a `get_count` argument which, when awaited, returns the full count. Then plugins could do this:
```python
async def render_notebook(datasette, request, get_count, rows):
count = await get_count()
# ...
```","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1898927976,
https://github.com/simonw/datasette/pull/2182#issuecomment-1719451803,https://api.github.com/repos/simonw/datasette/issues/2182,1719451803,IC_kwDOBm6k_c5mfMCb,49699333,2023-09-14T13:27:26Z,2023-09-14T13:27:26Z,CONTRIBUTOR,"Looks like these dependencies are updatable in another way, so this is no longer needed.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1890593563,
https://github.com/simonw/datasette/pull/2183#issuecomment-1718316733,https://api.github.com/repos/simonw/datasette/issues/2183,1718316733,IC_kwDOBm6k_c5ma269,9599,2023-09-13T21:05:36Z,2023-09-13T21:05:36Z,OWNER,I'm going to land this and make any further documentation tweaks on `main`.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1891212159,
https://github.com/simonw/datasette/pull/2183#issuecomment-1714544153,https://api.github.com/repos/simonw/datasette/issues/2183,1714544153,IC_kwDOBm6k_c5mMd4Z,22429695,2023-09-11T20:37:52Z,2023-09-13T20:58:51Z,NONE,"## [Codecov](https://app.codecov.io/gh/simonw/datasette/pull/2183?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) Report
Patch coverage: **`95.00%`** and project coverage change: **`-0.04%`** :warning:
> Comparison is base [(`a4c96d0`)](https://app.codecov.io/gh/simonw/datasette/commit/a4c96d01b27ce7cd06662a024da3547132a7c412?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) 92.69% compared to head [(`659dcbd`)](https://app.codecov.io/gh/simonw/datasette/pull/2183?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) 92.66%.
> :exclamation: Current head 659dcbd differs from pull request most recent head acca338. Consider uploading reports for the commit acca338 to get more accurate results
Additional details and impacted files
```diff
@@ Coverage Diff @@
## main #2183 +/- ##
==========================================
- Coverage 92.69% 92.66% -0.04%
==========================================
Files 40 40
Lines 6025 6039 +14
==========================================
+ Hits 5585 5596 +11
- Misses 440 443 +3
```
| [Files Changed](https://app.codecov.io/gh/simonw/datasette/pull/2183?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) | Coverage Δ | |
|---|---|---|
| [datasette/app.py](https://app.codecov.io/gh/simonw/datasette/pull/2183?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-ZGF0YXNldHRlL2FwcC5weQ==) | `94.19% <95.00%> (-0.24%)` | :arrow_down: |
[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/simonw/datasette/pull/2183?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison).
: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).
","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1891212159,
https://github.com/simonw/datasette/pull/2183#issuecomment-1716801971,https://api.github.com/repos/simonw/datasette/issues/2183,1716801971,IC_kwDOBm6k_c5mVFGz,15178711,2023-09-13T01:34:01Z,2023-09-13T01:34:01Z,CONTRIBUTOR,"@simonw docs are finished, this is ready for review!
One thing: I added ""Configuration"" as a top-level item in the documentation site, at the very bottom. Not sure if this is the best, maybe it can be named ""datasette.yaml Configuration"" or something similar?
Mostly because ""Configuration"" by itself can mean many things, but adding ""datasette.yaml"" would make it pretty clear it's about that specific file, and is easier to scan. I'd also be fine with using ""datasette.yaml"" instead of ""datasette.json"", since writing in YAML is much more forgiving (and advanced users will know JSON is also supported)
Also, maybe this is a chance to consolidate the docs a bit? I think ""Settings"", ""Configuration"", ""Metadata"", and ""Authentication and permissions"" should possibly be under the same section. Maybe even consolidate the different Plugin pages that exist?
","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1891212159,
https://github.com/simonw/sqlite-utils/issues/594#issuecomment-1714920708,https://api.github.com/repos/simonw/sqlite-utils/issues/594,1714920708,IC_kwDOCGYnMM5mN50E,9599,2023-09-12T03:51:13Z,2023-09-12T03:51:13Z,OWNER,"Changing this without breaking backwards compatibility (and forcing a 4.0 release) will be tricky, because `ForeignKey()` is a `namedtuple`:
https://github.com/simonw/sqlite-utils/blob/622c3a5a7dd53a09c029e2af40c2643fe7579340/sqlite_utils/db.py#L148-L150
I could swap it out for a `dataclass` and add those extra columns, but I need to make sure that code like this still works:
```python
for table, column, other_table, other_column in table.foreign_keys:
# ...
```","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1891614971,
https://github.com/simonw/sqlite-utils/issues/594#issuecomment-1714919806,https://api.github.com/repos/simonw/sqlite-utils/issues/594,1714919806,IC_kwDOCGYnMM5mN5l-,9599,2023-09-12T03:49:41Z,2023-09-12T03:49:41Z,OWNER,"Digging in a bit more:
```pycon
>>> pprint(list(db.query('PRAGMA foreign_key_list(courses)')))
[{'from': 'campus_name',
'id': 0,
'match': 'NONE',
'on_delete': 'NO ACTION',
'on_update': 'NO ACTION',
'seq': 0,
'table': 'departments',
'to': 'campus_name'},
{'from': 'dept_code',
'id': 0,
'match': 'NONE',
'on_delete': 'NO ACTION',
'on_update': 'NO ACTION',
'seq': 1,
'table': 'departments',
'to': 'dept_code'}]
```
I think the way you tell it's a compound foreign key is that both of those have the same `id` value - of `0` - but they then have two different `seq` values of `0` and `1`.
Right now I ignore those columns entirely: https://github.com/simonw/sqlite-utils/blob/622c3a5a7dd53a09c029e2af40c2643fe7579340/sqlite_utils/db.py#L1523-L1540","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1891614971,
https://github.com/simonw/datasette/pull/2183#issuecomment-1714699724,https://api.github.com/repos/simonw/datasette/issues/2183,1714699724,IC_kwDOBm6k_c5mND3M,9599,2023-09-11T23:01:36Z,2023-09-11T23:02:30Z,OWNER,"On thinking about this further, I'm fine releasing it as another alpha provided it causes Datasette to error loudly with an explanatory message if you attempt to load `-m metadata.json` at a metadata file that includes `""plugins""` configuration.
Something like this:
```bash
datasette -m metadata.json
```
Outputs:
> Datasette no longer accepts plugin configuration in --metadata. Move your `""plugins""` configuration blocks to a separate file - we suggest calling that `datasette.yaml` - and start Datasette with `datasette -c datasette.yaml`.
For added usability points, let's have it suggest `datasette.json` if they used `metadata.json` and `datasette.yaml` if they tried to use `metadata.yaml`.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1891212159,
https://github.com/simonw/datasette/issues/2168#issuecomment-1712897194,https://api.github.com/repos/simonw/datasette/issues/2168,1712897194,IC_kwDOBm6k_c5mGLyq,9599,2023-09-10T17:54:07Z,2023-09-10T17:54:07Z,OWNER,"This looks relevant:
https://pluggy.readthedocs.io/en/stable/#wrappers
> A *hookimpl* can be marked with the `""wrapper""` option, which indicates that the function will be called to *wrap* (or surround) all other normal *hookimpl* calls. A *hook wrapper* can thus execute some code ahead and after the execution of all corresponding non-wrappper *hookimpls*.
This could be the perfect mechanism for implementing this hook, although I still need to figure out how it interacts with streaming.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1876353656,
https://github.com/simonw/sqlite-utils/issues/592#issuecomment-1712895580,https://api.github.com/repos/simonw/sqlite-utils/issues/592,1712895580,IC_kwDOCGYnMM5mGLZc,9599,2023-09-10T17:46:41Z,2023-09-10T17:46:41Z,OWNER,"In working on this I learned that `rowid` values in SQLite are way less stable than I had thought - in particular, they are often entirely rewritten on a `VACUUM`:
https://www.sqlite.org/lang_vacuum.html#how_vacuum_works
> The VACUUM command may change the [ROWIDs](https://www.sqlite.org/lang_createtable.html#rowid) of entries in any tables that do not have an explicit [INTEGER PRIMARY KEY](https://www.sqlite.org/lang_createtable.html#rowid).
So this fix wasn't as valuable as I thought. I need to move away from ever assuming that a `rowid` is a useful foreign key for anything.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1886771493,
https://github.com/simonw/datasette/issues/2180#issuecomment-1712895084,https://api.github.com/repos/simonw/datasette/issues/2180,1712895084,IC_kwDOBm6k_c5mGLRs,9599,2023-09-10T17:44:14Z,2023-09-10T17:44:14Z,OWNER,Used by `datasette-short-links` here: https://github.com/datasette/datasette-short-links/blob/468c3e25dbe06a8dcba8edda59bc16a18e126a51/datasette_short_links/__init__.py#L108-L115,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1886791100,
https://github.com/simonw/sqlite-utils/pull/593#issuecomment-1710939868,https://api.github.com/repos/simonw/sqlite-utils/issues/593,1710939868,IC_kwDOCGYnMM5l-t7c,22429695,2023-09-08T01:03:40Z,2023-09-09T00:44:52Z,NONE,"## [Codecov](https://app.codecov.io/gh/simonw/sqlite-utils/pull/593?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) Report
Patch coverage: **`100.00%`** and no project coverage change.
> Comparison is base [(`5d123f0`)](https://app.codecov.io/gh/simonw/sqlite-utils/commit/5d123f031fc4fadc98f508e0ef6b7b6671e86155?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) 95.77% compared to head [(`b86374f`)](https://app.codecov.io/gh/simonw/sqlite-utils/pull/593?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) 95.77%.
Additional details and impacted files
```diff
@@ Coverage Diff @@
## main #593 +/- ##
=======================================
Coverage 95.77% 95.77%
=======================================
Files 8 8
Lines 2837 2840 +3
=======================================
+ Hits 2717 2720 +3
Misses 120 120
```
| [Files Changed](https://app.codecov.io/gh/simonw/sqlite-utils/pull/593?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) | Coverage Δ | |
|---|---|---|
| [sqlite\_utils/db.py](https://app.codecov.io/gh/simonw/sqlite-utils/pull/593?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-c3FsaXRlX3V0aWxzL2RiLnB5) | `97.22% <100.00%> (+<0.01%)` | :arrow_up: |
[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/simonw/sqlite-utils/pull/593?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison).
: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).
","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1886783150,
https://github.com/simonw/datasette/issues/2180#issuecomment-1711057080,https://api.github.com/repos/simonw/datasette/issues/2180,1711057080,IC_kwDOBm6k_c5l_Ki4,9599,2023-09-08T04:28:03Z,2023-09-08T04:28:03Z,OWNER,"Landed:
- https://docs.datasette.io/en/latest/plugin_hooks.html#actors-from-ids-datasette-actor-ids
- https://docs.datasette.io/en/latest/internals.html#await-actors-from-ids-actor-ids","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1886791100,
https://github.com/simonw/datasette/pull/2181#issuecomment-1711054840,https://api.github.com/repos/simonw/datasette/issues/2181,1711054840,IC_kwDOBm6k_c5l_J_4,9599,2023-09-08T04:23:47Z,2023-09-08T04:23:47Z,OWNER,"I've implemented this hook once now in:
- https://github.com/datasette/datasette-remote-actors
And built and tested a debug tool for it in:
- https://github.com/datasette/datasette-debug-actors-from-ids
I'm now confident in the design of this plugin hook, I'm going to land it.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1886812002,
https://github.com/simonw/datasette/issues/2180#issuecomment-1711054624,https://api.github.com/repos/simonw/datasette/issues/2180,1711054624,IC_kwDOBm6k_c5l_J8g,9599,2023-09-08T04:23:23Z,2023-09-08T04:23:23Z,OWNER,"I've implemented this hook once now in:
- https://github.com/datasette/datasette-remote-actors
And built and tested a debug tool for it in:
- https://github.com/datasette/datasette-debug-actors-from-ids
I'm now confident in the design of this plugin hook, I'm going to land it.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1886791100,
https://github.com/simonw/datasette/pull/2181#issuecomment-1710972324,https://api.github.com/repos/simonw/datasette/issues/2181,1710972324,IC_kwDOBm6k_c5l-12k,22429695,2023-09-08T01:58:44Z,2023-09-08T03:43:43Z,NONE,"## [Codecov](https://app.codecov.io/gh/simonw/datasette/pull/2181?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) Report
Patch coverage: **`100.00%`** and no project coverage change.
> Comparison is base [(`c263704`)](https://app.codecov.io/gh/simonw/datasette/commit/c26370485a4fd4bf130da051be9163d92c57f24f?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) 92.68% compared to head [(`e1c5a9d`)](https://app.codecov.io/gh/simonw/datasette/pull/2181?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) 92.69%.
Additional details and impacted files
```diff
@@ Coverage Diff @@
## main #2181 +/- ##
=======================================
Coverage 92.68% 92.69%
=======================================
Files 40 40
Lines 6017 6025 +8
=======================================
+ Hits 5577 5585 +8
Misses 440 440
```
| [Files Changed](https://app.codecov.io/gh/simonw/datasette/pull/2181?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) | Coverage Δ | |
|---|---|---|
| [datasette/app.py](https://app.codecov.io/gh/simonw/datasette/pull/2181?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-ZGF0YXNldHRlL2FwcC5weQ==) | `94.43% <100.00%> (+0.03%)` | :arrow_up: |
| [datasette/hookspecs.py](https://app.codecov.io/gh/simonw/datasette/pull/2181?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-ZGF0YXNldHRlL2hvb2tzcGVjcy5weQ==) | `100.00% <100.00%> (ø)` | |
[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/simonw/datasette/pull/2181?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison).
: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).","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1886812002,
https://github.com/simonw/datasette/issues/2180#issuecomment-1711028355,https://api.github.com/repos/simonw/datasette/issues/2180,1711028355,IC_kwDOBm6k_c5l_DiD,9599,2023-09-08T03:36:02Z,2023-09-08T03:36:02Z,OWNER,"I shipped the first version of
- https://github.com/datasette/datasette-remote-actors/issues/1
When I land this plugin in a Datasette release I need to update that repo to depend on the new alpha.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1886791100,
https://github.com/simonw/datasette/pull/2181#issuecomment-1710969448,https://api.github.com/repos/simonw/datasette/issues/2181,1710969448,IC_kwDOBm6k_c5l-1Jo,9599,2023-09-08T01:53:27Z,2023-09-08T01:53:27Z,OWNER,"Documentation preview:
- https://datasette--2181.org.readthedocs.build/en/2181/internals.html#await-actors-from-ids-actor-ids
- https://datasette--2181.org.readthedocs.build/en/2181/plugin_hooks.html#plugin-hook-actors-from-ids","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1886812002,
https://github.com/simonw/datasette/issues/2180#issuecomment-1710969339,https://api.github.com/repos/simonw/datasette/issues/2180,1710969339,IC_kwDOBm6k_c5l-1H7,9599,2023-09-08T01:53:16Z,2023-09-08T01:53:16Z,OWNER,"Documentation preview:
- https://datasette--2181.org.readthedocs.build/en/2181/internals.html#await-actors-from-ids-actor-ids
- https://datasette--2181.org.readthedocs.build/en/2181/plugin_hooks.html#plugin-hook-actors-from-ids","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1886791100,
https://github.com/dogsheep/google-takeout-to-sqlite/pull/8#issuecomment-1710950671,https://api.github.com/repos/dogsheep/google-takeout-to-sqlite/issues/8,1710950671,IC_kwDODFE5qs5l-wkP,150855,2023-09-08T01:22:49Z,2023-09-08T01:22:49Z,NONE,"Makes sense, thanks for explaining!","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",954546309,
https://github.com/simonw/datasette/issues/2180#issuecomment-1710947637,https://api.github.com/repos/simonw/datasette/issues/2180,1710947637,IC_kwDOBm6k_c5l-v01,9599,2023-09-08T01:17:28Z,2023-09-08T01:17:28Z,OWNER,I think this is both a plugin hook and a `await datasette.actors_from_ids(actor_ids)` internal API function that calls it.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1886791100,
https://github.com/simonw/sqlite-utils/issues/592#issuecomment-1710935270,https://api.github.com/repos/simonw/sqlite-utils/issues/592,1710935270,IC_kwDOCGYnMM5l-szm,9599,2023-09-08T00:55:30Z,2023-09-08T00:55:30Z,OWNER,"Yes! That recreated the bug:
```
> assert previous_rows == next_rows
E AssertionError: assert equals failed
E [ [
E (1, '1', 'Paris'), (1, '1', 'Paris'),
E (3, '3', 'New York'), (2, '3', 'New York'),
E (4, '4', 'London'), (3, '4', 'London'),
E ] ...
E
```","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1886771493,
https://github.com/simonw/sqlite-utils/issues/592#issuecomment-1710934448,https://api.github.com/repos/simonw/sqlite-utils/issues/592,1710934448,IC_kwDOCGYnMM5l-smw,9599,2023-09-08T00:54:03Z,2023-09-08T00:54:03Z,OWNER,"Oh! Maybe the row ID preservation here is a coincidence because the tables are created from scratch and count 1, 2, 3.
If I delete a row from the table and then insert some more - breaking the `rowid` sequence - it might show the bug.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1886771493,
https://github.com/simonw/sqlite-utils/issues/592#issuecomment-1710933716,https://api.github.com/repos/simonw/sqlite-utils/issues/592,1710933716,IC_kwDOCGYnMM5l-sbU,9599,2023-09-08T00:52:42Z,2023-09-08T00:52:42Z,OWNER,"I just noticed that the table where I encountered this bug wasn't actually a `rowid` table after all - it had an `id` column that was a text primary key.
The reason the `rowid` was important is that's how the FTS mechanism in Datasette relates FTS entries to their rows.
But I tried this test and it passed, too:
```python
def test_transform_preserves_rowids(fresh_db):
fresh_db[""places""].insert_all(
[
{""id"": ""1"", ""name"": ""Paris"", ""country"": ""France""},
{""id"": ""2"", ""name"": ""London"", ""country"": ""UK""},
{""id"": ""3"", ""name"": ""New York"", ""country"": ""USA""},
],
pk=""id"",
)
previous_rows = list(
tuple(row) for row in fresh_db.execute(""select rowid, id, name from places"")
)
# Transform it
fresh_db[""places""].transform(column_order=(""country"", ""name""))
# Should be the same
next_rows = list(
tuple(row) for row in fresh_db.execute(""select rowid, id, name from places"")
)
assert previous_rows == next_rows
```","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1886771493,
https://github.com/simonw/sqlite-utils/issues/592#issuecomment-1710931605,https://api.github.com/repos/simonw/sqlite-utils/issues/592,1710931605,IC_kwDOCGYnMM5l-r6V,9599,2023-09-08T00:49:02Z,2023-09-08T00:49:02Z,OWNER,"I tried bumping that up to 10,000 rows instead of just 3 but the test still passed.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1886771493,
https://github.com/simonw/sqlite-utils/issues/592#issuecomment-1710930934,https://api.github.com/repos/simonw/sqlite-utils/issues/592,1710930934,IC_kwDOCGYnMM5l-rv2,9599,2023-09-08T00:47:57Z,2023-09-08T00:47:57Z,OWNER,"That's odd, I wrote a test for this just now and it passes already:
```python
def test_transform_preserves_rowids(fresh_db):
# Create a rowid table
fresh_db[""places""].insert_all(
(
{""name"": ""Paris"", ""country"": ""France""},
{""name"": ""London"", ""country"": ""UK""},
{""name"": ""New York"", ""country"": ""USA""},
),
)
assert fresh_db[""places""].use_rowid
previous_rows = list(
tuple(row) for row in fresh_db.execute(""select rowid, name from places"")
)
# Transform it
fresh_db[""places""].transform(column_order=(""country"", ""name""))
# Should be the same
next_rows = list(
tuple(row) for row in fresh_db.execute(""select rowid, name from places"")
)
assert previous_rows == next_rows
```
So maybe I'm wrong about the cause of that bug?","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1886771493,
https://github.com/simonw/datasette/pull/2174#issuecomment-1708699926,https://api.github.com/repos/simonw/datasette/issues/2174,1708699926,IC_kwDOBm6k_c5l2LEW,22429695,2023-09-06T16:18:13Z,2023-09-08T00:46:13Z,NONE,"## [Codecov](https://app.codecov.io/gh/simonw/datasette/pull/2174?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) Report
Patch and project coverage have no change.
> 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 [(`d75b519`)](https://app.codecov.io/gh/simonw/datasette/pull/2174?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) 92.68%.
> Report is 7 commits behind head on main.
Additional details and impacted files
```diff
@@ Coverage Diff @@
## main #2174 +/- ##
=======================================
Coverage 92.68% 92.68%
=======================================
Files 40 40
Lines 6012 6017 +5
=======================================
+ Hits 5572 5577 +5
Misses 440 440
```
| [Files Changed](https://app.codecov.io/gh/simonw/datasette/pull/2174?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) | Coverage Δ | |
|---|---|---|
| [datasette/cli.py](https://app.codecov.io/gh/simonw/datasette/pull/2174?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-ZGF0YXNldHRlL2NsaS5weQ==) | `82.53% <ø> (ø)` | |
... and [1 file with indirect coverage changes](https://app.codecov.io/gh/simonw/datasette/pull/2174/indirect-changes?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison)
[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/simonw/datasette/pull/2174?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison).
: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).","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1884330740,
https://github.com/simonw/datasette/pull/2174#issuecomment-1708727204,https://api.github.com/repos/simonw/datasette/issues/2174,1708727204,IC_kwDOBm6k_c5l2Ruk,9599,2023-09-06T16:35:39Z,2023-09-07T23:45:42Z,OWNER,"We can use this here: https://click.palletsprojects.com/en/8.1.x/options/#values-from-environment-variables
```python
@click.option(..., envvar=""DATASETTE_INTERNAL"")
```","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1884330740,
https://github.com/simonw/datasette/issues/2178#issuecomment-1710879239,https://api.github.com/repos/simonw/datasette/issues/2178,1710879239,IC_kwDOBm6k_c5l-fIH,9599,2023-09-07T23:20:32Z,2023-09-07T23:20:32Z,OWNER,"To test that locally, use this YAML instead:
```yaml
databases:
content:
allow:
id: root
tables:
releases:
allow: true
```
And:
```yaml
allow:
id: root
databases:
content:
tables:
releases:
allow: true","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1886350562,
https://github.com/simonw/datasette/issues/2178#issuecomment-1710878391,https://api.github.com/repos/simonw/datasette/issues/2178,1710878391,IC_kwDOBm6k_c5l-e63,9599,2023-09-07T23:19:05Z,2023-09-07T23:19:05Z,OWNER,"This fix didn't work on Datasette Cloud. I used `/-/permissions` to debug it and saw this:
![image](https://github.com/simonw/datasette/assets/9599/61d2bc5f-1f96-41ea-8658-91dfbcb6610c)
Only checking `view-table` is not enough: for my instance on Datasette Cloud the view permission check that should have failed was for the database or instance.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1886350562,
https://github.com/simonw/datasette/issues/2178#issuecomment-1710871095,https://api.github.com/repos/simonw/datasette/issues/2178,1710871095,IC_kwDOBm6k_c5l-dI3,9599,2023-09-07T23:07:16Z,2023-09-07T23:07:16Z,OWNER,"I ran this:
datasette content.db -p 8043 -m fk-auth.yml --root
Against this YAML:
```yaml
databases:
content:
tables:
users:
allow:
id: root
```
And it worked as it should - here's a screenshot of an anonymous user and a root user viewing the same page:
![CleanShot 2023-09-07 at 16 05 34@2x](https://github.com/simonw/datasette/assets/9599/3e91da08-107c-421c-8a00-aa650b960c58)
","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1886350562,
https://github.com/simonw/datasette/issues/2178#issuecomment-1710567329,https://api.github.com/repos/simonw/datasette/issues/2178,1710567329,IC_kwDOBm6k_c5l9S-h,9599,2023-09-07T17:59:59Z,2023-09-07T17:59:59Z,OWNER,Should I put the permission check in that undocumented `datasette.expand_foreign_keys()` method? I think so - it should accept `request.actor` as one of its arguments.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1886350562,
https://github.com/simonw/datasette/issues/2178#issuecomment-1710565268,https://api.github.com/repos/simonw/datasette/issues/2178,1710565268,IC_kwDOBm6k_c5l9SeU,9599,2023-09-07T17:58:04Z,2023-09-07T17:59:06Z,OWNER,"Relevant code: https://github.com/simonw/datasette/blob/fbcb103c0cb6668018ace539a01a6a1f156e8d6a/datasette/views/table.py#L1132-L1149
Which calls this undocumented method:
https://github.com/simonw/datasette/blob/fbcb103c0cb6668018ace539a01a6a1f156e8d6a/datasette/app.py#L938-L973","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1886350562,
https://github.com/dogsheep/google-takeout-to-sqlite/pull/8#issuecomment-1710380941,https://api.github.com/repos/dogsheep/google-takeout-to-sqlite/issues/8,1710380941,IC_kwDODFE5qs5l8leN,28565,2023-09-07T15:39:59Z,2023-09-07T15:39:59Z,NONE,"> @maxhawkins curious why you didn't use the stdlib `mailbox` to parse the `mbox` files?
Mailbox parses the entire mbox into memory. Using the lower level library lets us stream the emails in one at a time to support larger archives. Both libraries are in the stdlib.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",954546309,
https://github.com/simonw/datasette/issues/1479#issuecomment-1709373304,https://api.github.com/repos/simonw/datasette/issues/1479,1709373304,IC_kwDOBm6k_c5l4vd4,363004,2023-09-07T02:14:15Z,2023-09-07T02:14:15Z,NONE,"I ran into the same issue on Windows using
`datasette publish cloudrun mydatabase.db --service=my-database`
do do a [google cloud publish](https://docs.datasette.io/en/stable/publish.html).
@Rik-de-Kort your fix worked perfectly! Thanks!
I can always go back and delete the temp directories myself :)
","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1010112818,
https://github.com/dogsheep/google-takeout-to-sqlite/pull/8#issuecomment-1708945716,https://api.github.com/repos/dogsheep/google-takeout-to-sqlite/issues/8,1708945716,IC_kwDODFE5qs5l3HE0,150855,2023-09-06T19:12:33Z,2023-09-06T19:12:33Z,NONE,@maxhawkins curious why you didn't use the stdlib `mailbox` to parse the `mbox` files?,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",954546309,
https://github.com/simonw/datasette/issues/2177#issuecomment-1708777964,https://api.github.com/repos/simonw/datasette/issues/2177,1708777964,IC_kwDOBm6k_c5l2eHs,9599,2023-09-06T17:04:30Z,2023-09-06T17:04:30Z,OWNER,"Here's the thinking: setting the`DATASETTE_INTERNAL` environment variable for your entire machine will cause any time you run `datasette x.db` to result in a process that shares the same `internal.db` database as other instances.
You might run more than one instance at once (I often have 4 or 5 going). This would currently break, because they would over-write each other's catalog tables:
https://github.com/simonw/datasette/blob/e4abae3fd7a828625d00c35c316852ffbaa5ef2f/datasette/utils/internal_db.py#L5-L62
The breaking wouldn't be obvious because the catalog tables aren't used by any features yet, but it's still bad.
This convinced us that actually we should move those `catalog_` tables OUT of `internal.db`. The `_internal` database will be reserved for plugins that want to use it for caching, storing progress, etc.
I think we move them to an in-memory `_catalog` database which is excluded from `ds.databases` (like `_internal` is ) but can be accessed using `datasette.get_catalog_database()` - similar to `datasette.get_internal_database()`.
So each instance of Datasette gets its own truly private `_catalog`, which is in-memory and so gets cleared at the end of each process.
An interesting thing that came up about a shared `_internal` database is that it provides opportunities for things like a notes plugin which allows you to attach notes to any row in any table in a database... where those notes become available to multiple Datasette instances that you might launch on the same laptop.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1884408624,
https://github.com/simonw/datasette/pull/2174#issuecomment-1708728926,https://api.github.com/repos/simonw/datasette/issues/2174,1708728926,IC_kwDOBm6k_c5l2SJe,9599,2023-09-06T16:36:56Z,2023-09-06T16:36:56Z,OWNER,`DATASETTE_INTERNAL` would be more consistent with `DATASETTE_SECRET`.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1884330740,
https://github.com/simonw/sqlite-utils/pull/591#issuecomment-1708695907,https://api.github.com/repos/simonw/sqlite-utils/issues/591,1708695907,IC_kwDOCGYnMM5l2KFj,9599,2023-09-06T16:15:59Z,2023-09-06T16:19:14Z,OWNER,"The test failure was while installing `numpy`, relating to importing `distutils` - maybe relevant:
- https://github.com/pypa/setuptools/issues/3661
```
25h Installing build dependencies: started
Installing build dependencies: finished with status 'done'
Getting requirements to build wheel: started
Getting requirements to build wheel: finished with status 'done'
ERROR: Exception:
Traceback (most recent call last):
...
File ""/opt/hostedtoolcache/Python/3.12.0-rc.2/x64/lib/python3.12/site-packages/pip/_internal/utils/misc.py"", line 697, in get_requires_for_build_wheel
return super().get_requires_for_build_wheel(config_settings=cs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File ""/opt/hostedtoolcache/Python/3.12.0-rc.2/x64/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_impl.py"", line 166, in get_requires_for_build_wheel
return self._call_hook('get_requires_for_build_wheel', {
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File ""/opt/hostedtoolcache/Python/3.12.0-rc.2/x64/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_impl.py"", line 321, in _call_hook
raise BackendUnavailable(data.get('traceback', ''))
pip._vendor.pyproject_hooks._impl.BackendUnavailable: Traceback (most recent call last):
File ""/opt/hostedtoolcache/Python/3.12.0-rc.2/x64/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py"", line 77, in _build_backend
obj = import_module(mod_path)
^^^^^^^^^^^^^^^^^^^^^^^
File ""/opt/hostedtoolcache/Python/3.12.0-rc.2/x64/lib/python3.12/importlib/__init__.py"", line 90, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File """", line 1381, in _gcd_import
File """", line 1354, in _find_and_load
File """", line 1304, in _find_and_load_unlocked
File """", line 488, in _call_with_frames_removed
File """", line 1381, in _gcd_import
File """", line 1354, in _find_and_load
File """", line 1325, in _find_and_load_unlocked
File """", line 929, in _load_unlocked
File """", line 994, in exec_module
File """", line 488, in _call_with_frames_removed
File ""/tmp/pip-build-env-x9nyg3kd/overlay/lib/python3.12/site-packages/setuptools/__init__.py"", line 10, in
import distutils.core
ModuleNotFoundError: No module named 'distutils'
```","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1884335789,
https://github.com/simonw/datasette/pull/2166#issuecomment-1701045404,https://api.github.com/repos/simonw/datasette/issues/2166,1701045404,IC_kwDOBm6k_c5lY-Sc,22429695,2023-08-31T13:31:15Z,2023-09-06T13:25:17Z,NONE,"## [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
Patch and project coverage have no change.
> 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%.
Additional details and impacted files
```diff
@@ Coverage Diff @@
## main #2166 +/- ##
=======================================
Coverage 92.68% 92.68%
=======================================
Files 40 40
Lines 6012 6012
=======================================
Hits 5572 5572
Misses 440 440
```
[: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).
: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).
","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1875519316,
https://github.com/simonw/datasette/pull/2173#issuecomment-1707570044,https://api.github.com/repos/simonw/datasette/issues/2173,1707570044,IC_kwDOBm6k_c5lx3N8,22429695,2023-09-06T02:39:59Z,2023-09-06T02:49:01Z,NONE,"## [Codecov](https://app.codecov.io/gh/simonw/datasette/pull/2173?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) Report
Patch and project coverage have no change.
> Comparison is base [(`fd083e3`)](https://app.codecov.io/gh/simonw/datasette/commit/fd083e37ec53e7e625111168d324a572344a3b19?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) 92.68% compared to head [(`a481ebd`)](https://app.codecov.io/gh/simonw/datasette/pull/2173?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) 92.68%.
> Report is 1 commits behind head on main.
Additional details and impacted files
```diff
@@ Coverage Diff @@
## main #2173 +/- ##
=======================================
Coverage 92.68% 92.68%
=======================================
Files 40 40
Lines 6012 6012
=======================================
Hits 5572 5572
Misses 440 440
```
[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/simonw/datasette/pull/2173?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison).
: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).
","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1883055640,
https://github.com/simonw/datasette/pull/2173#issuecomment-1707570378,https://api.github.com/repos/simonw/datasette/issues/2173,1707570378,IC_kwDOBm6k_c5lx3TK,9599,2023-09-06T02:40:31Z,2023-09-06T02:40:31Z,OWNER,"Surprising error:
```
blacken-docs -l 60 docs/*.rst
shell: /usr/bin/bash -e {0}
env:
pythonLocation: /opt/hostedtoolcache/Python/3.11.4/x64
PKG_CONFIG_PATH: /opt/hostedtoolcache/Python/3.11.4/x64/lib/pkgconfig
Python_ROOT_DIR: /opt/hostedtoolcache/Python/3.11.4/x64
Python2_ROOT_DIR: /opt/hostedtoolcache/Python/3.11.4/x64
Python3_ROOT_DIR: /opt/hostedtoolcache/Python/3.11.4/x64
LD_LIBRARY_PATH: /opt/hostedtoolcache/Python/3.11.4/x64/lib
docs/writing_plugins.rst:365: code block parse error Cannot parse: 8:0:
```","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1883055640,
https://github.com/simonw/datasette/pull/2173#issuecomment-1707565495,https://api.github.com/repos/simonw/datasette/issues/2173,1707565495,IC_kwDOBm6k_c5lx2G3,9599,2023-09-06T02:33:56Z,2023-09-06T02:33:56Z,OWNER,Running tests to see if Pyodide works - that was the reason I switched to my `click-default-group-wheel` package originally.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1883055640,
https://github.com/simonw/datasette/issues/328#issuecomment-1706701195,https://api.github.com/repos/simonw/datasette/issues/328,1706701195,IC_kwDOBm6k_c5lujGL,7983005,2023-09-05T14:10:39Z,2023-09-05T14:10:39Z,NONE,"Hey @simonw I hit the same issue as mentionned by @chmaynard on a fresh install, ""/mnt/fixtures.db"" doesn't seem to exist in the docker image","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",336464733,
https://github.com/simonw/sqlite-utils/issues/590#issuecomment-1704387161,https://api.github.com/repos/simonw/sqlite-utils/issues/590,1704387161,IC_kwDOCGYnMM5lluJZ,9599,2023-09-03T19:50:36Z,2023-09-03T19:50:36Z,OWNER,"Maybe just populate `db.memory: bool` and `db.memory_name: Optional[str]` for this, then document them.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1879214365,
https://github.com/simonw/sqlite-utils/issues/589#issuecomment-1704384393,https://api.github.com/repos/simonw/sqlite-utils/issues/589,1704384393,IC_kwDOCGYnMM5llteJ,9599,2023-09-03T19:36:34Z,2023-09-03T19:36:34Z,OWNER,"Here's a prototype: https://github.com/simonw/sqlite-utils/commit/62f673835c4a66f87cf6f949eaff43c8b014619b
Still needs tests and documentation (and some more thought to make sure it's doing the right thing).","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1879209560,
https://github.com/simonw/sqlite-utils/issues/589#issuecomment-1704384111,https://api.github.com/repos/simonw/sqlite-utils/issues/589,1704384111,IC_kwDOCGYnMM5lltZv,9599,2023-09-03T19:35:03Z,2023-09-03T19:35:03Z,OWNER,"Normally in Python/`sqlite3` you de-register a function by passing `None` to it.
You can't do that with `db.register_function()` at the moment because a `fn` of `None` does something else:
https://github.com/simonw/sqlite-utils/blob/1260bdc7bfe31c36c272572c6389125f8de6ef71/sqlite_utils/db.py#L461-L464","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1879209560,
https://github.com/simonw/sqlite-utils/issues/589#issuecomment-1704383901,https://api.github.com/repos/simonw/sqlite-utils/issues/589,1704383901,IC_kwDOCGYnMM5lltWd,9599,2023-09-03T19:34:05Z,2023-09-03T19:34:05Z,OWNER,"For that particular case I realized I'd quite like to have a mechanism for applying functions for a block of code and then de-registering them at the end - a context manager.
I played with this idea a bit:
```python
with db.register_functions(md5, md5_random):
db.query(...)
```
","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1879209560,
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/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/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-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-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-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/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,
https://github.com/simonw/datasette/issues/1092#issuecomment-1699926384,https://api.github.com/repos/simonw/datasette/issues/1092,1699926384,IC_kwDOBm6k_c5lUtFw,9599,2023-08-30T22:17:42Z,2023-08-30T22:17:42Z,OWNER,"This is implemented now:
- https://docs.datasette.io/en/stable/internals.html#await-ensure-permissions-actor-permissions","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",742041667,
https://github.com/simonw/datasette/issues/1190#issuecomment-1699925224,https://api.github.com/repos/simonw/datasette/issues/1190,1699925224,IC_kwDOBm6k_c5lUszo,9599,2023-08-30T22:16:38Z,2023-08-30T22:16:38Z,OWNER,"This is going to happen in this tool instead:
- https://github.com/simonw/dclient","{""total_count"": 1, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 1, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",787098146,
https://github.com/simonw/datasette/pull/2165#issuecomment-1699910555,https://api.github.com/repos/simonw/datasette/issues/2165,1699910555,IC_kwDOBm6k_c5lUpOb,9599,2023-08-30T22:05:14Z,2023-08-30T22:05:14Z,OWNER,Documentation preview: https://github.com/simonw/datasette/blob/6321c9c055a640ed6ea98e231dc5813dcde1f773/docs/plugins.rst#controlling-which-plugins-are-loaded,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1874327336,
https://github.com/simonw/datasette/pull/2165#issuecomment-1699812599,https://api.github.com/repos/simonw/datasette/issues/2165,1699812599,IC_kwDOBm6k_c5lURT3,22429695,2023-08-30T20:43:19Z,2023-08-30T22:05:05Z,NONE,"## [Codecov](https://app.codecov.io/gh/simonw/datasette/pull/2165?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) Report
Patch coverage: **`26.66%`** and project coverage change: **`-0.17%`** :warning:
> Comparison is base [(`30b28c8`)](https://app.codecov.io/gh/simonw/datasette/commit/30b28c8367a9c6870386ea10a202705b40862457?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) 92.84% compared to head [(`5eddf34`)](https://app.codecov.io/gh/simonw/datasette/pull/2165?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) 92.68%.
> :exclamation: Current head 5eddf34 differs from pull request most recent head 6321c9c. Consider uploading reports for the commit 6321c9c to get more accurate results
Additional details and impacted files
```diff
@@ Coverage Diff @@
## main #2165 +/- ##
==========================================
- Coverage 92.84% 92.68% -0.17%
==========================================
Files 40 40
Lines 5998 6012 +14
==========================================
+ Hits 5569 5572 +3
- Misses 429 440 +11
```
| [Files Changed](https://app.codecov.io/gh/simonw/datasette/pull/2165?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) | Coverage Δ | |
|---|---|---|
| [datasette/plugins.py](https://app.codecov.io/gh/simonw/datasette/pull/2165?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-ZGF0YXNldHRlL3BsdWdpbnMucHk=) | `64.58% <26.66%> (-17.77%)` | :arrow_down: |
[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/simonw/datasette/pull/2165?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison).
: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).
","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1874327336,
https://github.com/simonw/datasette/pull/2165#issuecomment-1699884314,https://api.github.com/repos/simonw/datasette/issues/2165,1699884314,IC_kwDOBm6k_c5lUi0a,9599,2023-08-30T21:38:29Z,2023-08-30T21:39:51Z,OWNER,"Here's the reason for that name disparity:
https://github.com/simonw/datasette/blob/30b28c8367a9c6870386ea10a202705b40862457/datasette/plugins.py#L54-L65
Note how the `distinfo.project_name` name is used when available. That seems to work for regularly installed plugins but not for plugins loaded via `DATASETTE_LOAD_PLUGINS`.
And that's looking things up in `plugin_to_distinfo` which is populated here:
https://github.com/simonw/datasette/blob/30b28c8367a9c6870386ea10a202705b40862457/datasette/plugins.py#L37","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1874327336,
https://github.com/simonw/datasette/pull/2165#issuecomment-1699811810,https://api.github.com/repos/simonw/datasette/issues/2165,1699811810,IC_kwDOBm6k_c5lURHi,9599,2023-08-30T20:42:41Z,2023-08-30T20:42:41Z,OWNER,"The `load_setuptools_entrypoints()` function in Pluggy [does this](https://github.com/pytest-dev/pluggy/blob/0b41c9766508a46ae666cf281684df3164b3e2a9/src/pluggy/_manager.py#L376):
```python
for ep in dist.entry_points:
if (
ep.group != group
or (name is not None and ep.name != name)
# already registered
or self.get_plugin(ep.name)
or self.is_blocked(ep.name)
):
continue
plugin = ep.load()
self.register(plugin, name=ep.name)
```","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1874327336,
https://github.com/simonw/datasette/pull/2165#issuecomment-1699809688,https://api.github.com/repos/simonw/datasette/issues/2165,1699809688,IC_kwDOBm6k_c5lUQmY,9599,2023-08-30T20:41:06Z,2023-08-30T20:41:06Z,OWNER,"Slight weirdness: I noticed that the output from the `datasette plugins` command looks like this for plugins loaded with the new environment variable:
```json
{
""name"": ""datasette_pretty_json"",
""static"": false,
""templates"": false,
""version"": null,
""hooks"": [
""render_cell""
]
},
```
That should ideally be `datasette-pretty-json`, not `datasette_pretty_json`.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1874327336,
https://github.com/simonw/datasette/pull/2165#issuecomment-1699802028,https://api.github.com/repos/simonw/datasette/issues/2165,1699802028,IC_kwDOBm6k_c5lUOus,9599,2023-08-30T20:35:02Z,2023-08-30T20:35:02Z,OWNER,"Testing this is going to be a bit of a pain.
I think I'll add a whole separate test block to CI which installs a couple of plugins and then exercises this feature using `datasette plugins`.
I'll use `datasette-init` and `datasette-json-html` just because they are small and simple.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1874327336,
https://github.com/simonw/datasette/issues/2164#issuecomment-1699728102,https://api.github.com/repos/simonw/datasette/issues/2164,1699728102,IC_kwDOBm6k_c5lT8rm,9599,2023-08-30T19:35:32Z,2023-08-30T19:35:47Z,OWNER,"Figured this out so far with the help of GPT-4: https://chat.openai.com/share/0e785865-621b-4fb3-ba05-7449e57c8496
Now this works:
```bash
DATASETTE_LOAD_PLUGINS=datasette-write-ui datasette plugins
```
```json
[
{
""name"": ""datasette_write_ui"",
""static"": true,
""templates"": true,
""version"": null,
""hooks"": [
""extra_template_vars"",
""register_routes""
]
}
]
```
Or multiple plugins:
```bash
DATASETTE_LOAD_PLUGINS=datasette-write-ui,datasette-pretty-json datasette plugins
```
Outputs:
```json
[
{
""name"": ""datasette_pretty_json"",
""static"": false,
""templates"": false,
""version"": null,
""hooks"": [
""render_cell""
]
},
{
""name"": ""datasette_write_ui"",
""static"": true,
""templates"": true,
""version"": null,
""hooks"": [
""extra_template_vars"",
""register_routes""
]
}
]
```","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1874255116,
https://github.com/simonw/datasette/issues/2163#issuecomment-1697818917,https://api.github.com/repos/simonw/datasette/issues/2163,1697818917,IC_kwDOBm6k_c5lMqkl,9599,2023-08-29T16:56:20Z,2023-08-29T16:56:20Z,OWNER,https://github.com/simonw/datasette/blob/50da908213a0fc405ecd7a40090dfea7a2e7395c/datasette/utils/internal_db.py#L8-L62,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1872043170,
https://github.com/simonw/datasette/pull/2154#issuecomment-1691798722,https://api.github.com/repos/simonw/datasette/issues/2154,1691798722,IC_kwDOBm6k_c5k1szC,22429695,2023-08-24T14:31:42Z,2023-08-29T16:15:12Z,NONE,"## [Codecov](https://app.codecov.io/gh/simonw/datasette/pull/2154?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) Report
Patch coverage: **`100.00%`** and project coverage change: **`+0.03%`** :tada:
> Comparison is base [(`2e28258`)](https://app.codecov.io/gh/simonw/datasette/commit/2e2825869fc2655b5fcadc743f6f9dec7a49bc65?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) 92.82% compared to head [(`3e49fd3`)](https://app.codecov.io/gh/simonw/datasette/pull/2154?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) 92.85%.
> Report is 3 commits behind head on main.
Additional details and impacted files
```diff
@@ Coverage Diff @@
## main #2154 +/- ##
==========================================
+ Coverage 92.82% 92.85% +0.03%
==========================================
Files 40 40
Lines 5948 6008 +60
==========================================
+ Hits 5521 5579 +58
- Misses 427 429 +2
```
| [Files Changed](https://app.codecov.io/gh/simonw/datasette/pull/2154?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) | Coverage Δ | |
|---|---|---|
| [datasette/views/special.py](https://app.codecov.io/gh/simonw/datasette/pull/2154?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-ZGF0YXNldHRlL3ZpZXdzL3NwZWNpYWwucHk=) | `94.06% <ø> (-0.85%)` | :arrow_down: |
| [datasette/app.py](https://app.codecov.io/gh/simonw/datasette/pull/2154?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-ZGF0YXNldHRlL2FwcC5weQ==) | `94.37% <100.00%> (+0.07%)` | :arrow_up: |
| [datasette/default\_permissions.py](https://app.codecov.io/gh/simonw/datasette/pull/2154?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-ZGF0YXNldHRlL2RlZmF1bHRfcGVybWlzc2lvbnMucHk=) | `97.48% <100.00%> (+0.57%)` | :arrow_up: |
| [datasette/permissions.py](https://app.codecov.io/gh/simonw/datasette/pull/2154?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-ZGF0YXNldHRlL3Blcm1pc3Npb25zLnB5) | `100.00% <100.00%> (ø)` | |
... and [3 files with indirect coverage changes](https://app.codecov.io/gh/simonw/datasette/pull/2154/indirect-changes?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison)
[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/simonw/datasette/pull/2154?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison).
: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).
","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1865281760,
https://github.com/simonw/datasette/pull/2154#issuecomment-1697725150,https://api.github.com/repos/simonw/datasette/issues/2154,1697725150,IC_kwDOBm6k_c5lMTre,9599,2023-08-29T15:54:12Z,2023-08-29T15:54:12Z,OWNER,"In that last commit I also upgraded `Permission` from a named tuple to a dataclass, and added a `implies_can_view=True` private (not documented) option to it.
Last step is to refactor the code to use that new property.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1865281760,
https://github.com/simonw/datasette/pull/2154#issuecomment-1697612168,https://api.github.com/repos/simonw/datasette/issues/2154,1697612168,IC_kwDOBm6k_c5lL4GI,9599,2023-08-29T14:57:54Z,2023-08-29T14:57:54Z,OWNER,"The code to refactor is this: https://github.com/simonw/datasette/blob/d64a9896f743f87b673d58859a0ec16685594e79/datasette/default_permissions.py#L181-L280
I'm going to turn that into a more general `restrictions_allow_action` function.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1865281760,
https://github.com/simonw/datasette/pull/2162#issuecomment-1696710911,https://api.github.com/repos/simonw/datasette/issues/2162,1696710911,IC_kwDOBm6k_c5lIcD_,9599,2023-08-29T03:23:44Z,2023-08-29T03:23:44Z,OWNER,I'm going to merge this so we can see how it feels.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1870672704,
https://github.com/simonw/datasette/pull/2162#issuecomment-1696709110,https://api.github.com/repos/simonw/datasette/issues/2162,1696709110,IC_kwDOBm6k_c5lIbn2,9599,2023-08-29T03:20:40Z,2023-08-29T03:22:47Z,OWNER,"> However, one important notes about those new `core_` tables: If a `--internal` DB is passed in, that means those `core_` tables will persist across multiple Datasette instances. This wasn't the case before, since `_internal` was always an in-memory database created from scratch.
I'm completely happy for the `core_*` tables (or `datasette_*` or some other name) to live in the persisted-to-disk `internal.db` database, even though they're effectively meant to be an in-memory cache.
I don't think it causes any harm, and it could even be quite useful to have them visible on disk - other applications could read the `internal.db` database while Datasette itself is running, should they have some weird reason to want to do that!
Having those tables stick around in `internal.db` after Datasette shuts down could be useful for other debugging activities as well.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1870672704,
https://github.com/simonw/datasette/pull/2162#issuecomment-1696594855,https://api.github.com/repos/simonw/datasette/issues/2162,1696594855,IC_kwDOBm6k_c5lH_un,22429695,2023-08-29T00:19:29Z,2023-08-29T03:22:21Z,NONE,"## [Codecov](https://app.codecov.io/gh/simonw/datasette/pull/2162?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) Report
Patch coverage: **`100.00%`** and project coverage change: **`-0.03%`** :warning:
> Comparison is base [(`2e28258`)](https://app.codecov.io/gh/simonw/datasette/commit/2e2825869fc2655b5fcadc743f6f9dec7a49bc65?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) 92.82% compared to head [(`73489ca`)](https://app.codecov.io/gh/simonw/datasette/pull/2162?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) 92.79%.
> Report is 1 commits behind head on main.
Additional details and impacted files
```diff
@@ Coverage Diff @@
## main #2162 +/- ##
==========================================
- Coverage 92.82% 92.79% -0.03%
==========================================
Files 40 40
Lines 5948 5953 +5
==========================================
+ Hits 5521 5524 +3
- Misses 427 429 +2
```
| [Files Changed](https://app.codecov.io/gh/simonw/datasette/pull/2162?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) | Coverage Δ | |
|---|---|---|
| [datasette/default\_permissions.py](https://app.codecov.io/gh/simonw/datasette/pull/2162?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-ZGF0YXNldHRlL2RlZmF1bHRfcGVybWlzc2lvbnMucHk=) | `96.87% <ø> (-0.04%)` | :arrow_down: |
| [datasette/app.py](https://app.codecov.io/gh/simonw/datasette/pull/2162?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-ZGF0YXNldHRlL2FwcC5weQ==) | `94.32% <100.00%> (+0.03%)` | :arrow_up: |
| [datasette/cli.py](https://app.codecov.io/gh/simonw/datasette/pull/2162?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-ZGF0YXNldHRlL2NsaS5weQ==) | `82.53% <100.00%> (-0.06%)` | :arrow_down: |
| [datasette/database.py](https://app.codecov.io/gh/simonw/datasette/pull/2162?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-ZGF0YXNldHRlL2RhdGFiYXNlLnB5) | `94.72% <100.00%> (+0.04%)` | :arrow_up: |
| [datasette/utils/internal\_db.py](https://app.codecov.io/gh/simonw/datasette/pull/2162?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-ZGF0YXNldHRlL3V0aWxzL2ludGVybmFsX2RiLnB5) | `100.00% <100.00%> (ø)` | |
| [datasette/views/database.py](https://app.codecov.io/gh/simonw/datasette/pull/2162?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-ZGF0YXNldHRlL3ZpZXdzL2RhdGFiYXNlLnB5) | `95.45% <100.00%> (ø)` | |
| [datasette/views/special.py](https://app.codecov.io/gh/simonw/datasette/pull/2162?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-ZGF0YXNldHRlL3ZpZXdzL3NwZWNpYWwucHk=) | `94.06% <100.00%> (-0.85%)` | :arrow_down: |
[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/simonw/datasette/pull/2162?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison).
: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).
","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1870672704,
https://github.com/simonw/datasette/pull/2162#issuecomment-1696707458,https://api.github.com/repos/simonw/datasette/issues/2162,1696707458,IC_kwDOBm6k_c5lIbOC,9599,2023-08-29T03:17:54Z,2023-08-29T03:17:54Z,OWNER,Documentation preview: https://datasette--2162.org.readthedocs.build/en/2162/internals.html#datasette-s-internal-database,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1870672704,
https://github.com/simonw/datasette/pull/2154#issuecomment-1696644066,https://api.github.com/repos/simonw/datasette/issues/2154,1696644066,IC_kwDOBm6k_c5lILvi,9599,2023-08-29T01:37:47Z,2023-08-29T03:00:25Z,OWNER,"Code for this might be cleaner with a `Restrictions()` class that takes a `""_r""` dictionary to the constructor and can then answer questions like `.any_resource_has_permission(""view-table"")` - where it can resolve aliases etc as well.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1865281760,
https://github.com/simonw/datasette/pull/2154#issuecomment-1696642671,https://api.github.com/repos/simonw/datasette/issues/2154,1696642671,IC_kwDOBm6k_c5lILZv,9599,2023-08-29T01:35:37Z,2023-08-29T01:35:37Z,OWNER,"Reminder that I also need to confirm that `insert-row` works if you have it at the instance level, the database level or the resource level in `_r`.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1865281760,
https://github.com/simonw/datasette/pull/2154#issuecomment-1696618784,https://api.github.com/repos/simonw/datasette/issues/2154,1696618784,IC_kwDOBm6k_c5lIFkg,9599,2023-08-29T00:58:34Z,2023-08-29T00:58:34Z,OWNER,Should this have `implies_can_view=True` too? Probably: https://github.com/simonw/datasette/blob/d64a9896f743f87b673d58859a0ec16685594e79/datasette/default_permissions.py#L20-L22,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1865281760,
https://github.com/simonw/datasette/pull/2160#issuecomment-1695754277,https://api.github.com/repos/simonw/datasette/issues/2160,1695754277,IC_kwDOBm6k_c5lEygl,22429695,2023-08-28T14:00:17Z,2023-08-29T00:32:52Z,NONE,"## [Codecov](https://app.codecov.io/gh/simonw/datasette/pull/2160?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) Report
Patch and project coverage have no change.
> Comparison is base [(`2e28258`)](https://app.codecov.io/gh/simonw/datasette/commit/2e2825869fc2655b5fcadc743f6f9dec7a49bc65?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) 92.82% compared to head [(`c81b024`)](https://app.codecov.io/gh/simonw/datasette/pull/2160?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) 92.82%.
> :exclamation: Current head c81b024 differs from pull request most recent head 3529c9c. Consider uploading reports for the commit 3529c9c to get more accurate results
Additional details and impacted files
```diff
@@ Coverage Diff @@
## main #2160 +/- ##
=======================================
Coverage 92.82% 92.82%
=======================================
Files 40 40
Lines 5948 5948
=======================================
Hits 5521 5521
Misses 427 427
```
[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/simonw/datasette/pull/2160?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison).
: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).
","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1869807874,
https://github.com/simonw/datasette/pull/2160#issuecomment-1696595326,https://api.github.com/repos/simonw/datasette/issues/2160,1696595326,IC_kwDOBm6k_c5lH_1-,9599,2023-08-29T00:20:08Z,2023-08-29T00:20:08Z,OWNER,Cog failed!,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1869807874,
https://github.com/simonw/datasette/pull/2160#issuecomment-1696592763,https://api.github.com/repos/simonw/datasette/issues/2160,1696592763,IC_kwDOBm6k_c5lH_N7,9599,2023-08-29T00:16:38Z,2023-08-29T00:16:38Z,OWNER,"Since this bumps Sphinx I'm manually reviewing the ReadTheDocs preview a bit, looks good to me: https://datasette--2160.org.readthedocs.build/en/2160/","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1869807874,
https://github.com/simonw/datasette/pull/2148#issuecomment-1696591957,https://api.github.com/repos/simonw/datasette/issues/2148,1696591957,IC_kwDOBm6k_c5lH_BV,49699333,2023-08-29T00:15:29Z,2023-08-29T00:15:29Z,CONTRIBUTOR,This pull request was built based on a group rule. Closing it will not ignore any of these versions in future pull requests.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",1859415334,