github
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/1072#issuecomment-719955491 | https://api.github.com/repos/simonw/datasette/issues/1072 | 719955491 | MDEyOklzc3VlQ29tbWVudDcxOTk1NTQ5MQ== | 9599 | 2020-10-31T16:20:58Z | 2020-10-31T16:20:58Z | OWNER | Here's the proof of concept `FunctionLoader` that showed me that this wasn't going to work: ```diff diff --git a/datasette/app.py b/datasette/app.py index 4b28e71..b076be7 100644 --- a/datasette/app.py +++ b/datasette/app.py @@ -21,7 +21,7 @@ from pathlib import Path from markupsafe import Markup from itsdangerous import URLSafeSerializer import jinja2 -from jinja2 import ChoiceLoader, Environment, FileSystemLoader, PrefixLoader +from jinja2 import ChoiceLoader, Environment, FileSystemLoader, FunctionLoader, PrefixLoader from jinja2.environment import Template from jinja2.exceptions import TemplateNotFound import uvicorn @@ -300,6 +300,7 @@ class Datasette: template_paths.append(default_templates) template_loader = ChoiceLoader( [ + FunctionLoader(self._load_template_from_plugins), FileSystemLoader(template_paths), # Support {% extends "default:table.html" %}: PrefixLoader( @@ -322,6 +323,17 @@ class Datasette: self._root_token = secrets.token_hex(32) self.client = DatasetteClient(self) + def _load_template_from_plugins(self, template): + # "If auto reloading is enabled it’s called to check if the template changed" + uptodatefunc = lambda: True + source = pm.hook.load_template( + template=template, + datasette=self, + ) + if source is None: + return None + return source, template, uptodatefunc + @property def urls(self): return Urls(self) @@ -719,35 +731,7 @@ class Datasette: else: if isinstance(templates, str): templates = [templates] - - # Give plugins first chance at loading the template - break_outer = False - plugin_template_source = None - plugin_template_name = None - template_name = None - for template_name in templates: - … | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
733499930 | |
https://github.com/simonw/datasette/issues/1070#issuecomment-719955724 | https://api.github.com/repos/simonw/datasette/issues/1070 | 719955724 | MDEyOklzc3VlQ29tbWVudDcxOTk1NTcyNA== | 9599 | 2020-10-31T16:22:45Z | 2020-10-31T16:22:45Z | OWNER | I've removed this plugin hook in #1073. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
733390884 | |
https://github.com/simonw/datasette/issues/1067#issuecomment-719956184 | https://api.github.com/repos/simonw/datasette/issues/1067 | 719956184 | MDEyOklzc3VlQ29tbWVudDcxOTk1NjE4NA== | 9599 | 2020-10-31T16:26:09Z | 2020-10-31T16:26:09Z | OWNER | Should the hook provide an indication that it's running on a different type of page? I think yes for queries. Not sure about views - they behave very much like tables, and the plugin can always introspect to see if something is a view if it needs to. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
732905360 | |
https://github.com/simonw/datasette/issues/1067#issuecomment-719959419 | https://api.github.com/repos/simonw/datasette/issues/1067 | 719959419 | MDEyOklzc3VlQ29tbWVudDcxOTk1OTQxOQ== | 9599 | 2020-10-31T16:53:42Z | 2020-10-31T16:53:42Z | OWNER | For the 0.51 release I'm going to add tests that show this works on view pages. I won't implement it for query pages. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
732905360 | |
https://github.com/simonw/datasette/issues/1026#issuecomment-719959754 | https://api.github.com/repos/simonw/datasette/issues/1026 | 719959754 | MDEyOklzc3VlQ29tbWVudDcxOTk1OTc1NA== | 9599 | 2020-10-31T16:56:35Z | 2020-10-31T16:56:35Z | OWNER | #1041 can also benefit from the string subclass that shows that `base_url` has been added. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
722738988 | |
https://github.com/simonw/datasette/issues/1067#issuecomment-719961701 | https://api.github.com/repos/simonw/datasette/issues/1067 | 719961701 | MDEyOklzc3VlQ29tbWVudDcxOTk2MTcwMQ== | 9599 | 2020-10-31T17:11:59Z | 2020-10-31T17:11:59Z | OWNER | It bothers me that these aren't visible in any public demos. Maybe `latest.datasette.io` should include the `my_plugins.py` and `my_plugins2.py` plugins? | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
732905360 | |
https://github.com/simonw/datasette/issues/1074#issuecomment-719963074 | https://api.github.com/repos/simonw/datasette/issues/1074 | 719963074 | MDEyOklzc3VlQ29tbWVudDcxOTk2MzA3NA== | 9599 | 2020-10-31T17:23:48Z | 2020-10-31T17:23:48Z | OWNER | Needs a way to login as root, seeing as several plugins only show extra content if the user is logged in as root. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
733768037 | |
https://github.com/simonw/datasette/issues/1074#issuecomment-719965426 | https://api.github.com/repos/simonw/datasette/issues/1074 | 719965426 | MDEyOklzc3VlQ29tbWVudDcxOTk2NTQyNg== | 9599 | 2020-10-31T17:45:00Z | 2020-10-31T17:45:00Z | OWNER | This is working. Go to https://latest.datasette.io/login-as-root and click the button, then visit this page to see extra content added by plugins: https://latest.datasette.io/fixtures/compound_three_primary_keys ![latest-plugins](https://user-images.githubusercontent.com/9599/97786052-19e53d00-1b66-11eb-8268-b452e08965e3.gif) | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
733768037 | |
https://github.com/simonw/datasette/issues/1067#issuecomment-719966176 | https://api.github.com/repos/simonw/datasette/issues/1067 | 719966176 | MDEyOklzc3VlQ29tbWVudDcxOTk2NjE3Ng== | 9599 | 2020-10-31T17:51:31Z | 2020-10-31T17:51:31Z | OWNER | Demo: - https://latest.datasette.io/fixtures/facetable?_bot=1 - https://latest.datasette.io/fixtures/simple_view?_bot=1 | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
732905360 | |
https://github.com/simonw/datasette/issues/1074#issuecomment-719977864 | https://api.github.com/repos/simonw/datasette/issues/1074 | 719977864 | MDEyOklzc3VlQ29tbWVudDcxOTk3Nzg2NA== | 9599 | 2020-10-31T19:35:01Z | 2020-10-31T19:35:01Z | OWNER | These plugins were not designed to be actually hosted online, so they do some nasty things like linking to the made-up `plugin-example.com` domain. I should fix that. <img width="853" alt="Datasette_Fixtures__fixtures" src="https://user-images.githubusercontent.com/9599/97788348-7b60d800-1b75-11eb-8519-a58e52108841.png"> | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
733768037 | |
https://github.com/simonw/datasette/issues/1075#issuecomment-719980742 | https://api.github.com/repos/simonw/datasette/issues/1075 | 719980742 | MDEyOklzc3VlQ29tbWVudDcxOTk4MDc0Mg== | 9599 | 2020-10-31T19:58:57Z | 2020-10-31T19:58:57Z | OWNER | Sample traceback: ``` <link rel="stylesheet" href="{{ urls.static('app.css') }}?{{ app_css_hash }}"> /opt/hostedtoolcache/Python/3.7.9/x64/lib/python3.7/site-packages/jinja2/asyncsupport.py:173: in auto_await if inspect.isawaitable(value): /opt/hostedtoolcache/Python/3.7.9/x64/lib/python3.7/inspect.py:226: in isawaitable isinstance(object, collections.abc.Awaitable)) /opt/hostedtoolcache/Python/3.7.9/x64/lib/python3.7/abc.py:139: in __instancecheck__ return _abc_instancecheck(cls, instance) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ cls = <class 'collections.abc.Awaitable'> subclass = <bound method PrefixedUrlString.__getattribute__.<locals>.method of '/-/static/app.css'> def __subclasscheck__(cls, subclass): """Override for issubclass(subclass, cls).""" > return _abc_subclasscheck(cls, subclass) E TypeError: issubclass() arg 1 must be a class ``` This is within Jinja. It looks like Jinja really doesn't like methods that return non-string objects like `PrefixedUrlString`. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
733796942 | |
https://github.com/simonw/datasette/issues/1075#issuecomment-719981173 | https://api.github.com/repos/simonw/datasette/issues/1075 | 719981173 | MDEyOklzc3VlQ29tbWVudDcxOTk4MTE3Mw== | 9599 | 2020-10-31T20:02:30Z | 2020-10-31T20:03:45Z | OWNER | I wonder how Jinja's `Markup()` class works? It uses https://pypi.org/project/MarkupSafe/ It's a subclass of `str`, defined here: https://github.com/pallets/markupsafe/blob/master/src/markupsafe/__init__.py | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
733796942 | |
https://github.com/simonw/datasette/issues/1075#issuecomment-719983240 | https://api.github.com/repos/simonw/datasette/issues/1075 | 719983240 | MDEyOklzc3VlQ29tbWVudDcxOTk4MzI0MA== | 9599 | 2020-10-31T20:18:49Z | 2020-10-31T20:18:49Z | OWNER | Here's the core problem: ``` (Pdb) isinstance('bob', collections.abc.Awaitable) False (Pdb) isinstance(PrefixedUrlString('bob'), collections.abc.Awaitable) *** TypeError: issubclass() arg 1 must be a class ``` For some reason `isinstance()` does not like being handed an instance of PrefixedUrlString. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
733796942 | |
https://github.com/simonw/datasette/issues/1075#issuecomment-719983484 | https://api.github.com/repos/simonw/datasette/issues/1075 | 719983484 | MDEyOklzc3VlQ29tbWVudDcxOTk4MzQ4NA== | 9599 | 2020-10-31T20:20:28Z | 2020-10-31T20:20:28Z | OWNER | It looks like this is specific to the way `PrefixedUrlString` is built. ``` (Pdb) class Weird(str): pass (Pdb) isinstance(Weird('bob'), collections.abc.Awaitable) False ``` So subclassing strings doesn't trigger this bug, but something about `PrefixedUrlString` causes the problem. Here's the current `PrefixedUrlString` implementation: https://github.com/simonw/datasette/blob/bf18b9ba175a7b25fb8b765847397dd6efb8bb7b/datasette/utils/__init__.py#L1015-L1035 | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
733796942 | |
https://github.com/simonw/datasette/issues/1075#issuecomment-719983565 | https://api.github.com/repos/simonw/datasette/issues/1075 | 719983565 | MDEyOklzc3VlQ29tbWVudDcxOTk4MzU2NQ== | 9599 | 2020-10-31T20:21:03Z | 2020-10-31T20:21:03Z | OWNER | Here's the output of `dir(str)`: `['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isascii', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']` | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
733796942 | |
https://github.com/simonw/datasette/issues/1075#issuecomment-719983750 | https://api.github.com/repos/simonw/datasette/issues/1075 | 719983750 | MDEyOklzc3VlQ29tbWVudDcxOTk4Mzc1MA== | 9599 | 2020-10-31T20:22:29Z | 2020-10-31T20:22:29Z | OWNER | I bet this is because I'm mucking around with one of those `__` methods. I'll try just doing the non-underscore methods instead. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
733796942 | |
https://github.com/simonw/datasette/issues/1072#issuecomment-719986698 | https://api.github.com/repos/simonw/datasette/issues/1072 | 719986698 | MDEyOklzc3VlQ29tbWVudDcxOTk4NjY5OA== | 9599 | 2020-10-31T20:48:17Z | 2020-10-31T20:48:17Z | OWNER | Here's the `datasette-edit-templates` plugin WIP I had before removing the hook: https://github.com/simonw/datasette-edit-templates/tree/82855c2612b84bc09c48fca885f831633a0d1552 | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
733499930 | |
https://github.com/simonw/datasette/issues/1041#issuecomment-719986800 | https://api.github.com/repos/simonw/datasette/issues/1041 | 719986800 | MDEyOklzc3VlQ29tbWVudDcxOTk4NjgwMA== | 9599 | 2020-10-31T20:49:28Z | 2020-10-31T20:49:28Z | OWNER | Implemented in a4ca26a2659d21779adf625183061d8879954c15 | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
727627923 | |
https://github.com/simonw/datasette/issues/838#issuecomment-719986904 | https://api.github.com/repos/simonw/datasette/issues/838 | 719986904 | MDEyOklzc3VlQ29tbWVudDcxOTk4NjkwNA== | 9599 | 2020-10-31T20:50:41Z | 2020-10-31T20:50:41Z | OWNER | OK, this should be working now. You can use the `datasette.urls.static_plugins()` method to generate the correct URLs in the `extra_css_urls` plugin hook: https://docs.datasette.io/en/latest/internals.html#datasette-urls | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
637395097 | |
https://github.com/simonw/datasette/issues/1023#issuecomment-719986922 | https://api.github.com/repos/simonw/datasette/issues/1023 | 719986922 | MDEyOklzc3VlQ29tbWVudDcxOTk4NjkyMg== | 9599 | 2020-10-31T20:51:01Z | 2020-10-31T20:51:01Z | OWNER | This should all be working correctly now. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
722673818 | |
https://github.com/simonw/datasette/issues/1027#issuecomment-719988113 | https://api.github.com/repos/simonw/datasette/issues/1027 | 719988113 | MDEyOklzc3VlQ29tbWVudDcxOTk4ODExMw== | 9599 | 2020-10-31T21:03:37Z | 2020-10-31T21:03:37Z | OWNER | On my Mac, I run: datasette . -p 8009 --config base_url:/datasette-prefix/ Then I edited `/usr/local/etc/httpd/httpd.conf` and add this section: ``` LoadModule proxy_module lib/httpd/modules/mod_proxy.so LoadModule proxy_http_module lib/httpd/modules/mod_proxy_http.so ProxyPass /datasette-prefix/ http://localhost:8009/datasette-prefix/ ``` I ran Apache in the foreground like so: apachectl -X Now hitting http://localhost:8081/datasette-prefix/fixtures/compound_three_primary_keys worked! | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
722758132 | |
https://github.com/simonw/datasette/issues/1047#issuecomment-719994676 | https://api.github.com/repos/simonw/datasette/issues/1047 | 719994676 | MDEyOklzc3VlQ29tbWVudDcxOTk5NDY3Ng== | 9599 | 2020-10-31T22:11:25Z | 2020-10-31T22:11:25Z | OWNER | https://docs.datasette.io/en/latest/binary_data.html | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
728895233 | |
https://github.com/simonw/datasette/issues/1077#issuecomment-720003026 | https://api.github.com/repos/simonw/datasette/issues/1077 | 720003026 | MDEyOklzc3VlQ29tbWVudDcyMDAwMzAyNg== | 9599 | 2020-10-31T23:48:21Z | 2020-10-31T23:50:07Z | OWNER | Needed by https://github.com/simonw/datasette-backup/issues/6 | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
733829385 |