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/699#issuecomment-626945281,https://api.github.com/repos/simonw/datasette/issues/699,626945281,MDEyOklzc3VlQ29tbWVudDYyNjk0NTI4MQ==,9599,2020-05-11T20:32:33Z,2020-05-11T20:32:33Z,OWNER,"I did have a bit of trouble with this one-off plugin getting it to load in the correct order - since I need authentication to work if EITHER the one-off plugin spots a token or my `datasette-auth-github` plugin authenticates the user. That's why I want authentication as a core Datasette concept - so plugins like these can easily play together in a predictable manner.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",582526961, https://github.com/simonw/datasette/issues/699#issuecomment-626943809,https://api.github.com/repos/simonw/datasette/issues/699,626943809,MDEyOklzc3VlQ29tbWVudDYyNjk0MzgwOQ==,9599,2020-05-11T20:30:07Z,2020-05-11T20:31:18Z,OWNER,"I implemented bearer tokens in a private project of mine as a one-off plugin. I'm going to extract that out into a installable plugin soon. For the moment, my `plugins/token_auth.py` file looks like this: ```python from datasette import hookimpl import secrets class TokenAuth: def __init__( self, app, secret, auth, ): self.app = app self.secret = secret self.auth = auth async def __call__(self, scope, receive, send): if scope.get(""type"") != ""http"": return await self.app(scope, receive, send) authorization = dict(scope.get(""headers"") or {}).get(b""authorization"") or b"""" expected = ""Bearer {}"".format(self.secret).encode(""utf8"") if secrets.compare_digest(authorization, expected): scope = dict(scope, auth=self.auth) return await self.app(scope, receive, send) @hookimpl(trylast=True) def asgi_wrapper(datasette): config = datasette.plugin_config(""token-auth"") or {} secret = config.get(""secret"") auth = config.get(""auth"") def wrap_with_asgi_auth(app): return TokenAuth(app, secret=secret, auth=auth,) return wrap_with_asgi_auth ``` Then I have the following in `metadata.json`: ```json { ""plugins"": { ""token-auth"": { ""auth"": { ""name"": ""token-bot"" }, ""secret"": { ""$env"": ""TOKEN_SECRET"" } } } } ``` And a `TOKEN_SECRET` environment variable.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",582526961, https://github.com/simonw/sqlite-utils/issues/30#issuecomment-626903632,https://api.github.com/repos/simonw/sqlite-utils/issues/30,626903632,MDEyOklzc3VlQ29tbWVudDYyNjkwMzYzMg==,9599,2020-05-11T19:17:17Z,2020-05-11T19:17:17Z,OWNER,I don't think this is a useful feature.,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",461215118, https://github.com/simonw/datasette/issues/765#issuecomment-626874374,https://api.github.com/repos/simonw/datasette/issues/765,626874374,MDEyOklzc3VlQ29tbWVudDYyNjg3NDM3NA==,9599,2020-05-11T18:25:43Z,2020-05-11T18:25:43Z,OWNER,"Trickiness here is what tag to use. Do we use the tag of the installed copy of Datasette that is running `datasette publish`? That would mean you don't get the latest features in your deployed release. Could hit an API to figure out the most recent version? Bit odd. Could we output the version of Datasette that was deployed and tell people they can run `--latest` to force the most recent release?","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",616087149, https://github.com/simonw/datasette/issues/764#issuecomment-626813924,https://api.github.com/repos/simonw/datasette/issues/764,626813924,MDEyOklzc3VlQ29tbWVudDYyNjgxMzkyNA==,9599,2020-05-11T16:36:06Z,2020-05-11T16:36:06Z,OWNER,Made a TIL: https://github.com/simonw/til/blob/master/pypi/project-links.md,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",616012427, https://github.com/simonw/datasette/issues/764#issuecomment-626810129,https://api.github.com/repos/simonw/datasette/issues/764,626810129,MDEyOklzc3VlQ29tbWVudDYyNjgxMDEyOQ==,9599,2020-05-11T16:28:43Z,2020-05-11T16:28:43Z,OWNER,"For Datasette I'll go with: * Documentation * Changelog * Live demo * Source code * Issues * CI","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",616012427, https://github.com/simonw/datasette/issues/764#issuecomment-626808805,https://api.github.com/repos/simonw/datasette/issues/764,626808805,MDEyOklzc3VlQ29tbWVudDYyNjgwODgwNQ==,9599,2020-05-11T16:26:17Z,2020-05-11T16:27:27Z,OWNER,"The keys here can be anything: https://packaging.python.org/guides/distributing-packages-using-setuptools/#project-urls So where do the icons come from? Turns out the PyPI site has special case rules for the icons here: https://github.com/pypa/warehouse/blob/2f00f4a9f208546ff0ebb6a6e61439021ca60a43/warehouse/templates/packaging/detail.html#L16-L60","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",616012427, https://github.com/simonw/sqlite-utils/issues/111#issuecomment-626431562,https://api.github.com/repos/simonw/sqlite-utils/issues/111,626431562,MDEyOklzc3VlQ29tbWVudDYyNjQzMTU2Mg==,9599,2020-05-11T01:58:36Z,2020-05-11T01:58:36Z,OWNER,Released in 2.9 https://sqlite-utils.readthedocs.io/en/latest/changelog.html#v2-9,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",615477131, https://github.com/simonw/sqlite-utils/issues/110#issuecomment-626431484,https://api.github.com/repos/simonw/sqlite-utils/issues/110,626431484,MDEyOklzc3VlQ29tbWVudDYyNjQzMTQ4NA==,9599,2020-05-11T01:58:20Z,2020-05-11T01:58:20Z,OWNER,Released in 2.9 https://sqlite-utils.readthedocs.io/en/latest/changelog.html#v2-9,"{""total_count"": 1, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 1, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",613755043, https://github.com/simonw/sqlite-utils/issues/111#issuecomment-626417220,https://api.github.com/repos/simonw/sqlite-utils/issues/111,626417220,MDEyOklzc3VlQ29tbWVudDYyNjQxNzIyMA==,9599,2020-05-11T00:46:04Z,2020-05-11T00:46:04Z,OWNER,"Docs: * https://sqlite-utils.readthedocs.io/en/latest/cli.html#dropping-tables * https://sqlite-utils.readthedocs.io/en/latest/cli.html#dropping-views","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",615477131,