spec-first / connexion

Connexion is a modern Python web framework that makes spec-first and api-first development easy.
https://connexion.readthedocs.io/en/latest/
Apache License 2.0
4.5k stars 766 forks source link

Flask Streaming Contents Generator won’t close when clients disconnects. #1822

Open tobiaswer opened 1 year ago

tobiaswer commented 1 year ago

Description

I'm using the FlaskApp and a Flask Streaming Contents Generator to stream a video (image/jpeg) to a client as long as the client is connected. When the client disconnects the Generator won't exit but continue to stream data. Using just Flask without Connexion this works fine. Uvicorn does send out a message = {"type": "http.disconnect"}. Do I miss something in the configuration or is this an issue with the ASGI stack? Thank you!

Expected behaviour

The Generator should exit when the client disconnects.

Actual behaviour

The Generator will continue to generate Data. If the API is called again it will start another Generator and so on.

Steps to reproduce

  1. Start a Response Generator using the FlaskApp.
  2. Connect with a client and disconnect.
  3. The Generator will still continue to run.

Additional info:

Output of the commands:

RobbeSneyders commented 1 year ago

Hi @tobiaswer. Please provide a minimal reproducible example.

tobiaswer commented 12 months ago

app.py

from pathlib import Path
import connexion
import time

def stream():
    def generate():
        count = 0
        try:
            while True:
                time.sleep(1)
                foobar = f"foobar {count}"
                print(foobar)
                yield f"{foobar} <br>"
                count += 1
        except GeneratorExit:
            print('closed')

    return generate()

app = connexion.FlaskApp(__name__, specification_dir="spec/")
app.add_api("openapi.yaml", arguments={"title": "stream Example"})

if __name__ == "__main__":
    app.run(f"{Path(__file__).stem}:app", port=8080)

openapi.yaml

openapi: "3.0.0"

info:
  title: Stream test
  version: "1.0"
servers:
  - url: /openapi

paths:
  /stream:
    get:
      operationId: hello.stream
      responses:
        '200':
          description: stream test
          content:
            text/html: { }

When opening http://127.0.0.1:8080/openapi/stream the server starts streaming and will continue even after you closed the page.

tobiaswer commented 8 months ago

Were you able to take a look at it @RobbeSneyders ?