view.py icon indicating copy to clipboard operation
view.py copied to clipboard

Yielded Responses

Open ZeroIntensity opened this issue 1 year ago • 1 comments

Feature description

As a means of making things easier for the developer, View could support using yield as a means of returning a partial response. For example, the user could yield a status code early on, and then return the body at the end of the function. Likewise, they can do the inverse and yield the response, and then finally return the status code.

Multiple yields of the same data (such as a int, indicating a status code, followed by another int, once again indicating a status code) should do what they can to merge. For example, two strings yielded would result in them being concatenated, and two dictionaries would result in them being merged (PyDict_Merge in C, but dict.update in Python). Integers should probably just overwrite each other, so 200 followed by 400 would result in 400.

This should try to be as asynchronous as possible. I'm not too sure about the semantics, but I'm assuming the generator can just be exhausted after receiving it from the PyAwaitable callback. If that's so, there shouldn't be too much view.py has to do, but if not, then there might be some chaos in terms of sending generators back and forth between PyAwaitable.

As a final note, if we're going to be messing with the PyAwaitable anyway, something similar to Starlette's background tasks could be integrated, allowing the user to yield coroutines to be executed later by the event loop.

Feature example API

from view import new_app

app = new_app()

@app.get("/")
async def index():
    yield {"hello": "world"}
    
    if "foo" != "bar":
        yield {"foo_is_not": "bar"}

    yield 201
    
    if "something":
        yield some_funny_coro()
    return "Hello, view.py!"

app.run()

Anything else?

No response

ZeroIntensity avatar Jan 29 '24 15:01 ZeroIntensity

Note that this should stream the response incrementally as well.

ZeroIntensity avatar May 15 '24 15:05 ZeroIntensity