Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
    Penguin Master
    @PenguinMaster0226

    This is the code on the docs

    connected_websockets = set()
    
    def collect_websocket(func):
        @wraps(func)
        async def wrapper(*args, **kwargs):
            global connected_websockets
            queue = asyncio.Queue()
            connected_websockets.add(queue)
            try:
                return await func(queue, *args, **kwargs)
            finally:
                connected_websockets.remove(queue)
        return wrapper

    This creates an empty queue, and then adds it to the set, but the queue is completely empty.

    Phil Jones
    @pgjones
    @PenguinMaster0226 Could you provide a snippet that doesn't work - it is hard to say what is going on otherwise
    Penguin Master
    @PenguinMaster0226
    @pgjones the code I used was from the docs (https://pgjones.gitlab.io/quart/tutorials/websocket_tutorial.html#websocket-tutorial). Just to make sure I wasn't doing it wrong, I used the exact code, but it still didn't work. Like I said above, the queues are empty and I'm not sure how to fix that.
    Phil Jones
    @pgjones
    Ideally the queues are always empty, as this means the message passed through them has been broadcast. What is it that you are expecting to happen?
    Penguin Master
    @PenguinMaster0226
    @pgjones I'm trying to store multiple websocket connections so I can send to them later. Is this the wrong way to do it?
    Is there another way?
    Phil Jones
    @pgjones
    So the example stores a queue for each connection, allowing messages to be sent to that connection via the queue.
    I think this is the clearest way, and the len(connected_websockets) would indicate how many connected websockets you have
    Penguin Master
    @PenguinMaster0226
    OK, so I tried using await websocket.receive() instead of await queue.get(), but then when I try to use await queue.put_nowait, it says TypeError: object NoneType can't be used in 'await' expression. How should I fix this?
    Phil Jones
    @pgjones
    put_nowait is a synchronous function (no need to await it)
    Penguin Master
    @PenguinMaster0226
    @pgjones now it doesn't raise an error, but nothing happens. Will it send to the websockets as a normal message?
    Phil Jones
    @pgjones
    It is really hard for me to know without seeing your code
    tibs
    @7185
    Hello, is there a better way to use quart_auth with websockets? So far I'm doing:
     token = websocket.cookies['QUART_AUTH']
     serializer = _AuthSerializer('**changeme**', 'quart auth salt')
     user_id = serializer.loads(token)
    Basically I'm looking for a current_user in a websocket context
    Phil Jones
    @pgjones
    Not yet, see pgjones/quart-auth#9
    tibs
    @7185
    thank you!
    Penguin Master
    @PenguinMaster0226

    @pgjones sorry for the late reply, but here's my code:

    from quart import Quart, websocket
    from functools import wraps
    import asyncio
    
    app = Quart(__name__)
    
    connected_websockets = set()
    
    def collect_websocket(func):
        @wraps(func)
        async def wrapper(*args, **kwargs):
            global connected_websockets
            queue = asyncio.Queue()
            connected_websockets.add(queue)
            print(connected_websockets)
            try:
                return await func(queue, *args, **kwargs)
            finally:
                connected_websockets.remove(queue)
        return wrapper
    
    
    async def broadcast(message):
        for queue in connected_websockets:
            queue.put_nowait("New connection")
    
    
    @app.websocket('/')
    @collect_websocket
    async def ws(queue):
        while True:
            data = await websocket.receive()
            print(data)
            await broadcast(data)
    
    if __name__ == "__main__":
        app.run(host="0.0.0.0", port=8080)

    You can ignore the host="0.0.0.0", that's just there because it's on replit

    Phil Jones
    @pgjones
    In this code you receive data from the websocket connections and place "New connection" (ignoring the data) on a queue, but you never read the data from the queue. The connected_websockets set will contain a queue for each websocket connection though. What are you hoping will happen?
    Phil Jones
    @pgjones
    @7185 see pgjones/quart-auth@68b6786 - could you say if this solves your need?
    tibs
    @7185
    @pgjones yes, this is exactly what I wanted, thank you!
    povar81
    @povar81

    Hi, everyone.
    I've just started using quart for my tests, I'm using this simple code :

    def start_app():
        from keyboard import press
        import quart
        app = quart.Quart(__name__)
        @app.route("/api", methods=["POST"])
        async def json():
            return {"hello": "quart world"}
        app.run(host='myip',port=5000)
    start_app()

    and it's working fine, except that I always get these unwanted messages when it starts:

    • Serving Quart app 'main'
    • Environment: production
    • Please use an ASGI server (e.g. Hypercorn) directly in production
    • Debug mode: False
    • Running on http://myhost:5000 (CTRL + C to quit)
      [2021-04-05 18:19:07,784] Running on http://myhost:5000 (CTRL + C to quit).

    Can anyone please tell me how to disable them?
    I've tried

    logging.getLogger('werkzeug').setLevel(logging.CRITICAL)
    logging.getLogger('app.serving').setLevel(logging.CRITICAL)
    logging.getLogger('quart.serving').setLevel(logging.CRITICAL)
    
    logging.getLogger('app.serving').disabled = True
    logging.getLogger('quart.serving').disabled = True
    
    logging.getLogger('app.serving').propagate = False
    logging.getLogger('quart.serving').propagate = False

    nothing helps

    Phil Jones
    @pgjones
    Probably best for you to make use of the run_task method to fully control how quart runs
    povar81
    @povar81
    Thank you, I see there are some options for changing the look of the logging:
    config = HyperConfig()
    config.access_log_format = "%(h)s %(r)s %(s)s %(b)s %(D)s"
    config.accesslog = create_serving_logger()
    but how can I disable the logging entirely (temporarily)?
    Phil Jones
    @pgjones
    I think if you remove the accesslog line it will disable all loggers
    povar81
    @povar81

    thank you, it worked in combination with
    sys.stdout = open(os.devnull, 'w')
    sys.stderr = open(os.devnull, "w")

    but I actually wanted to start this function in background via this code:

    import multiprocess as mp
    proc = mp.Process(target=start_app, args=())
    proc.start()

    and that still doesn't work because besides those lines I'm also getting an empty line in console (the app waiting for the requests I guess).

    Is there a way to start/stop the quart app in background?

    Phil Jones
    @pgjones
    Yea, you can use asyncio.run(app.run_task(...)) in the start_app function
    povar81
    @povar81
    No, I mean I need the start_app function to be running in the background
    and then be able to stop it at certain point
    povar81
    @povar81
    I was able to run the start_app function in the background but only when I moved start_app function into a separate py file, imported and run it like this:
    import mock_service_app
    import multiprocessing as mp
    proc = mp.Process(target=mock_service_app.start_app, args=())
    proc.start()
    proc = mp.Process(target=start_app, args=(), initializer=mute)
    povar81
    @povar81
    are there any working examples of how to use startup/shutdown described in:
    https://pgjones.gitlab.io/quart/how_to_guides/startup_shutdown.html
    ?
    Phil Jones
    @pgjones
    There is an example here for my website
    povar81
    @povar81

    Thank you,
    I see
    @app.before_serving

    and
    app.run()

    is there also an example on how to shutdown it?

    Phil Jones
    @pgjones
    Something like this?
    Ernesto Ruge
    @the-infinity
    @povar81 I just pushed an project where I used before and after serving as a global extension: https://github.com/openbikebox/open-bike-box-connect/blob/master/webapp/common/amqp_queue.py . Perhaps this is an inspiration, too? :)
    András Mózes
    @mozesa
    @the-infinity Nice work! A great inspiration source :smile:
    Phil Jones
    @pgjones
    Nice!
    Phil Jones
    @pgjones
    @the-infinity Hopefully you don't need jsonify anymore (can just return a dict) e.g. here.
    Ernesto Ruge
    @the-infinity
    @pgjones thanks for the hint! The configure_error_handlers is somehow a standard block which is in all my Flask / Quart projects, but without jsonify it's even more beautiful. Does it respect the JSON encoder I set here without jsonify: https://github.com/openbikebox/connect/blob/master/webapp/common/filter.py#L13 ?
    povar81
    @povar81
    Thank you.
    I need a solution so that my start_app can be started in background in pytest in one case
    and then to be able to read data coming to the start_app in another case
    (and then stop it in yet another case - but that one I've already figured out via psutils)
    Phil Jones
    @pgjones
    @the-infinity it should do (bug if it doesn't)
    shantanoo
    @shantanoo:matrix.org
    [m]
    hi, how do i use sqlite3 or ORM like peewee (sqlite3) with quart?
    was looking @ https://aiosqlite.omnilib.dev/en/stable/ but couldn't find any example
    Phil Jones
    @pgjones
    Hi @shantanoo:matrix.org there isn't anything particularly special you need to do. Which aspects are you unsure about? Here is an sqlite example and pgjones/quart#35 is a good discussion.
    5 replies
    Montassar Ben Dhifallah
    @Momentum-TN
    hello everyone,
    I am new to quart.
    I want to get multiple files from a request. In flask, I used to use request.files.getlist("file")
    What is the equivalent in quart ?
    Phil Jones
    @pgjones
    (await request.files).getlist("file") should work
    shantanoo
    @shantanoo:matrix.org
    [m]
    but asyncpg seems nice
    Montassar Ben Dhifallah
    @Momentum-TN
    @pgjones thank you so much !
    tomgper
    @tomgper
    hi, I'm moving some code from flask to quart. In flask with gevent we had a way to obtain the port that was opened by the internal socket (configured with port 0 basically). Is there a way to do the same with quart (asyncio) + hypercorn? Thank you