ZeroIntensity / view.py

The Batteries-Detachable Web Framework
https://view.zintensity.dev
MIT License
206 stars 15 forks source link

Yielded Responses #142

Open ZeroIntensity opened 5 months ago

ZeroIntensity commented 5 months ago

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 commented 1 month ago

Note that this should stream the response incrementally as well.