question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

New pattern for views that return either JSON or HTML, available for plugins

See original GitHub issue

Can be part of #870 - refactoring existing views to use register_routes().

I’m going to put the new check_permissions() method on BaseView as well. If I want that method to be available to plugins I can do so by turning that BaseView class into a documented API that plugins are encouraged to use themselves. _Originally posted by @simonw in https://github.com/simonw/datasette/issues/832#issuecomment-651995453_

Issue Analytics

  • State:open
  • Created 3 years ago
  • Comments:26 (25 by maintainers)

github_iconTop GitHub Comments

1reaction
simonwcommented, Mar 20, 2021

I came up with a slightly wild idea for this that would involve pytest-style dependency injection.

Prototype here: https://gist.github.com/simonw/496b24fdad44f6f8b7237fe394a0ced7

Copying from my private notes:

Use the lazy evaluated DI mechanism to break up table view into different pieces eg for faceting

Use that to solve JSON vs HTML views

Oh here’s an idea: what if the various components of the table view were each defined as async functions… and then executed using asyncio.gather in order to run the SQL queries in parallel? Then try benchmarking with different numbers of threads?

The async_call_with_arguments function could do this automatically for any awaitable dependencies

This would give me massively parallel dependency injection

(I could build an entire framework around this and call it c64)

Idea: arguments called eg “count” are executed and the result passed to the function. If called count_fn then a reference to the not-yet-called function is passed instead

I’m not going to completely combine the views mechanism and the render hooks. Instead, the core view will define a bunch of functions used to compose the page and the render hook will have conditional access to those functions - which will otherwise be asyncio.gather executed directly by the HTML page version

Using asyncio.gather to execute facets and suggest facets in parallel would be VERY interesting

suggest facets should be VERY cachable - doesn’t matter if it’s wrong unlike actual facets themselves

What if all Datasette views were defined in terms of dependency injection - and those dependency functions could themselves depend on others just like pytest fixtures. Everything would become composable and async stuff could execute in parallel

FURTHER IDEA: use this for the ?_extra= mechanism as well.

Any view in Datasette can be defined as a collection of named keys. Each of those keys maps to a function or an async function that accepts as input other named keys, using DI to handle them.

The HTML view is a defined function. So are the other outputs.

Default original inputs include “request” and “datasette”.

So… maybe a view function is a class methods that use DI. One of those methods as an .html() method used for the default page.

Output formats are a bit more complicated because they are supposed to be defined separately in plugins. They are unified across query, row and table though.

I’m going to try breaking up the TableView to see what happens.

0reactions
simonwcommented, Mar 19, 2022

On revisiting https://gist.github.com/simonw/281eac9c73b062c3469607ad86470eb2 a few months later I’m having second thoughts about using @inject on the main() method.

But I still like the pattern as a way to resolve more complex cases like “to generate GeoJSON of the expanded view with labels, the label expansion code needs to run once at some before the GeoJSON formatting code does”.

So I’m going to stick with it a tiny bit longer, but maybe try to make it a lot more explicit when it’s going to happen rather than having the main view methods themselves also use async DI.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Internals for plugins — Datasette documentation
If neither metadata.json nor any of the plugins provide an answer to the permission query the default argument will be returned.
Read more >
Connect REST Interface - Confluent Documentation
Currently the REST API only supports application/json as both the request ... Create a new connector, returning the current connector info if successful....
Read more >
Views and templates — Phoenix v1.6.15 - HexDocs
Views are about data presentation. Given a bag of data, the view's purpose is to present that in a meaningful way given some...
Read more >
JSON - Smartling Help Center
Content Parsing. JSON files are based on name and value pairs. For example, in this basic JSON file, “button1” is the name and...
Read more >
10 REST 5.2.5 - The Grails Framework
Simply by adding the Resource transformation and specifying a URI, your domain class will automatically be available as a REST resource in either...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found