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/943#issuecomment-693003652 | https://api.github.com/repos/simonw/datasette/issues/943 | 693003652 | MDEyOklzc3VlQ29tbWVudDY5MzAwMzY1Mg== | 9599 | 2020-09-15T22:03:08Z | 2020-09-15T22:03:08Z | OWNER | I'm not going to mess around with formats - you'll get back the exact response that a web client would receive. Question: what should the response object look like? e.g. if you do: response = await datasette.get("/db/table.json") What should `response` be? I could reuse the Datasette `Response` class from `datasette.utils.asgi`. This would work well for regular responses which just have a status code, some headers and a response body. It wouldn't be great for streaming responses though such as you get back from `?_stream=1` CSV exports. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
681375466 | |
https://github.com/simonw/datasette/issues/943#issuecomment-693004296 | https://api.github.com/repos/simonw/datasette/issues/943 | 693004296 | MDEyOklzc3VlQ29tbWVudDY5MzAwNDI5Ng== | 9599 | 2020-09-15T22:04:54Z | 2020-09-15T22:04:54Z | OWNER | So what should I do about streaming responses? I could deliberately ignore them - through an exception if you attempt to run `await datasette.get(...)` against a streaming URL. I could load the entire response into memory and return it as a wrapped object. I could support some kind of asynchronous iterator mechanism. This would be pretty elegant if I could decide the right syntax for it - it would allow plugins to take advantage of other internal URLs that return streaming content without needing to load that content entirely into memory in order to process it. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
681375466 | |
https://github.com/simonw/datasette/issues/943#issuecomment-693004572 | https://api.github.com/repos/simonw/datasette/issues/943 | 693004572 | MDEyOklzc3VlQ29tbWVudDY5MzAwNDU3Mg== | 9599 | 2020-09-15T22:05:39Z | 2020-09-15T22:05:39Z | OWNER | Maybe these methods become the way most Datasette tests are written, replacing the existing `TestClient` mechanism? | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
681375466 | |
https://github.com/simonw/datasette/issues/943#issuecomment-693004770 | https://api.github.com/repos/simonw/datasette/issues/943 | 693004770 | MDEyOklzc3VlQ29tbWVudDY5MzAwNDc3MA== | 9599 | 2020-09-15T22:06:13Z | 2020-09-15T22:06:13Z | OWNER | I'm tempted to create a `await datasette.request()` method which can take any HTTP verb - then have `datasette.get()` and `datasette.post()` as thin wrappers around it. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
681375466 | |
https://github.com/simonw/datasette/issues/943#issuecomment-693005033 | https://api.github.com/repos/simonw/datasette/issues/943 | 693005033 | MDEyOklzc3VlQ29tbWVudDY5MzAwNTAzMw== | 9599 | 2020-09-15T22:06:58Z | 2020-09-15T22:10:58Z | OWNER | What if `datasette.get()` was an alias for `httpx.get()`, pre-configured to route to the correct application? And with some sugar that added `http://localhost/` to the beginning of the path if it was missing? This would make `httpx` a dependency of core Datasette, which I think is OK. It would also solve the return type problem: I would return whatever `httpx` returns. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
681375466 | |
https://github.com/simonw/datasette/issues/943#issuecomment-693007512 | https://api.github.com/repos/simonw/datasette/issues/943 | 693007512 | MDEyOklzc3VlQ29tbWVudDY5MzAwNzUxMg== | 9599 | 2020-09-15T22:13:30Z | 2020-09-15T22:13:30Z | OWNER | I could solve streaming using something like this: ```python async with datasette.stream("GET", "/fixtures/compound_three_primary_keys.csv?_stream=on&_size=max") as response: async for chunk in response.aiter_bytes(): print(chunk) ``` Which would be a wrapper around `AsyncClient.stream(method, url, ...)` from https://www.python-httpx.org/async/#streaming-responses | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
681375466 | |
https://github.com/simonw/datasette/issues/943#issuecomment-693008540 | https://api.github.com/repos/simonw/datasette/issues/943 | 693008540 | MDEyOklzc3VlQ29tbWVudDY5MzAwODU0MA== | 9599 | 2020-09-15T22:16:07Z | 2020-09-15T22:16:07Z | OWNER | I think I can use `async with httpx.AsyncClient(base_url="http://localhost/") as client:` to ensure I don't need to use `http://localhost/` on every call. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
681375466 | |
https://github.com/simonw/datasette/issues/943#issuecomment-693009048 | https://api.github.com/repos/simonw/datasette/issues/943 | 693009048 | MDEyOklzc3VlQ29tbWVudDY5MzAwOTA0OA== | 9599 | 2020-09-15T22:17:30Z | 2020-09-22T14:37:00Z | OWNER | Maybe instead of implementing `datasette.get()` and `datasette.post()` and `datasette.request()` and `datasette.stream()` I could instead have a nested object called `datasette.client` which is a preconfigured `AsyncClient` instance. ```python response = await datasette.client.get("/") ``` Or perhaps this should be a method in case I ever need to be able to `await` it: ```python response = await (await datasette.client()).get("/") ``` This is a bit cosmetically ugly though, I'd rather avoid that if possible. Maybe I could get this working by returning an object from `.client()` which provides a `await obj.get()` method: ```python response = await datasette.client().get("/") ``` I don't think there's any benefit to that over `await datasette.client.get()` though. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
681375466 | |
https://github.com/simonw/datasette/issues/943#issuecomment-693010291 | https://api.github.com/repos/simonw/datasette/issues/943 | 693010291 | MDEyOklzc3VlQ29tbWVudDY5MzAxMDI5MQ== | 9599 | 2020-09-15T22:20:55Z | 2020-09-15T22:20:55Z | OWNER | Should I instantiate a single `Client` and reuse it for all internal requests, or can I instantiate a new `Client` for each request? https://www.python-httpx.org/advanced/#why-use-a-client says that the main benefit of a Client instance is HTTP connection pooling - which isn't an issue for these internal requests since they won't be using the HTTP protocol at all, they'll be calling the ASGI application directly. So I'm leaning towards instantiating a fresh client for every internal request. I'll run a microbenchmark to check that this doesn't have any unpleasant performance implications. | { "total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0 } |
681375466 |