Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
    McSinyx
    @McSinyx:matrix.org
    [m]
    quart-trio-twice is a temporary fork of quart-trio 0.6 (3 times 2 is 6) with some patches added: we haven't found the time to migrate to quart 0.14+ / quart-trio 0.7+
    there is some issues with mypy and inheritance iirc but I haven't looked into it for quite a while
    Dario
    @91DarioDev

    hello, i was trying to figure out how the config files should be done in hypercorn, but i found 0 examples unfortunately. as far i as i got reading the documentation i have to insert the parameters in config.py as global variables. anyways hypercorn is ignoring those variables

    i post the example file i wrote

    import asyncio
    from quart import Quart
    from hypercorn.asyncio import serve
    
    from hypercorn.config import Config
    
    
    app = Quart(__name__)
    
    @app.route('/')
    async def hello():
        return 'hello'
    
    if __name__ == '__main__':
        config = Config()
        config.from_pyfile("config.py")
        asyncio.run(serve(app, config))

    this is my config.py

    bind = '0.0.0.0:3068'

    anyways issuing python3.7 main.py it starts it [INFO] Running on http://127.0.0.1:8000

    i think the config.py should not be written this way if getting ignored.
    can someone give me a hint? thank you and sorry to bother you

    Dario
    @91DarioDev
    ok i solved in a different way using from_mapping :)
    Phil Jones
    @pgjones
    Ah, It should be config = Config.from_pyfile("config.py")
    As from_pyfile returns a config instance
    pgjones/hypercorn#178 (I welcome a MR)
    Dario
    @91DarioDev

    running hypercorn on production i get this error that i don't get in development

    Traceback (most recent call last):
      File "/home/chatincognitobot/.local/lib/python3.7/site-packages/quart/app.py", line 1862, in handle_request
        return await self.full_dispatch_request(request_context)
      File "/home/chatincognitobot/.local/lib/python3.7/site-packages/quart/app.py", line 1887, in full_dispatch_request
        result = await self.handle_user_exception(error)
      File "/home/chatincognitobot/.local/lib/python3.7/site-packages/quart/app.py", line 1100, in handle_user_exception
        return await self.handle_http_exception(error)
      File "/home/chatincognitobot/.local/lib/python3.7/site-packages/quart/app.py", line 1080, in handle_http_exception
        return await handler(error)
      File "/home/chatincognitobot/bot/web_server.py", line 64, in page_not_found_handler
        return await web_server_code.pages.page_not_found_handler(request, e)
      File "/home/chatincognitobot/bot/web_server_code/pages.py", line 29, in page_not_found_handler
        page_not_found=await web_server_code.locale.get_string('page_not_found', browser_language)
      File "/home/chatincognitobot/.local/lib/python3.7/site-packages/quart/templating.py", line 90, in render_template
        template = current_app.jinja_env.get_or_select_template(template_name_or_list)
      File "/home/chatincognitobot/.local/lib/python3.7/site-packages/quart/local.py", line 118, in getattr
        return getattr(self._get_current_object(), name)
      File "/home/chatincognitobot/.local/lib/python3.7/site-packages/quart/app.py", line 337, in jinja_env
        self._jinja_env = self.create_jinja_environment()
      File "/home/chatincognitobot/.local/lib/python3.7/site-packages/quart/app.py", line 429, in create_jinja_environment
        jinja_env = self.jinja_environment(self, **options)
      File "/home/chatincognitobot/.local/lib/python3.7/site-packages/quart/templating.py", line 32, in init
        super().__init__(**options)
    TypeError: __init__() got an unexpected keyword argument 'enable_async'

    i think it should be something related to async but i don't get waht

    1 reply
    Dario
    @91DarioDev
    more details: i have both python3 (old version) and python3.7 and i'm calling the script with python3.7 main.py
    McSinyx
    @McSinyx:matrix.org
    [m]
    which version of hypercorn and quart are you using?
    Dario
    @91DarioDev

    Name: Hypercorn
    Version: 0.11.2

    Name: Quart
    Version: 0.14.1

    Dario
    @91DarioDev
    the problem is just jinja because calling an endpoint not using templates it works perfectly.
    Dario
    @91DarioDev
    ok finally I got it working updating jinja2 with python3.7 -m pip install -U jinja2
    Augusto Zanellato
    @augustozanellato
    Have anybody tried to integrate certbot and hypercorn?
    I'm working on dockerizing a project which uses quart and hypercorn
    McSinyx
    @McSinyx:matrix.org
    [m]
    what do you mean by integrating
    Augusto Zanellato
    @augustozanellato
    Setting up certbot in such a way that it "restarts" or reloads hypercorn after cert renewal (if such a thing is needed)
    McSinyx
    @McSinyx:matrix.org
    [m]
    i think you can use systemd for hypercorn and use systemctl for such task
    Augusto Zanellato
    @augustozanellato
    everything will be inside an alpine linux docker container so I won't have systemd available inside
    Last resort would be using Caddy as a reverse proxy, but that would mean adding more (not essential) complexity
    McSinyx
    @McSinyx:matrix.org
    [m]
    with openrc it's not much different: https://wiki.alpinelinux.org/wiki/Alpine_Linux_Init_System
    using the init system will ensure stop is done cleanly and it restarts upon crash etc.
    Augusto Zanellato
    @augustozanellato
    for ensuring restart on crash I was using --restart unless-stopped, regarding the clean stops I'm 99% sure that docker sends a sigterm to the process when a container stop is requested so that's not an issue
    What about adding a file watcher on ssl cert/key and somehow updating hypercorn ssl context on changes? cc @pgjones
    (maybe this feature should be disabled by default and enabled using a cli flag)
    McSinyx
    @McSinyx:matrix.org
    [m]

    This message is replying to a Matrix event but we were unable to find associated bridged Gitter message to put it in the appropriate threaded conversation.

    if you run the certbot renew using cron you can stop and start the server before and after the renewal

    Dario
    @91DarioDev
    Adding a file watcher for certificates would be geat 🤩 I just deployed in production yesterday and used nginx as reverse proxy to handle this, but it was unnecessary
    Phil Jones
    @pgjones
    @augustozanellato I think Hypercorn needs to accept a signal to reload like Gunicorn does (HUP)
    luna
    @lun-4
    I'm trying out the new APIs for files cited in pgjones/quart#375 on my test suite, and even though I'm sending a file via make_test_body_with_headers (I get a non-empty body), await request.files returns an empty dict inside my webapp code. I think this is related with the multipart header value not containing the boundary?
    luna
    @lun-4
    Yeah, I patched it with the correct boundary and my tests now fail for a different reason (need to learn how to fetch the files now), making an MR now
    Phil Jones
    @pgjones
    :+1:
    Phil Jones
    @pgjones
    Merged the MR - thanks for testing
    luna
    @lun-4

    Was able to make the new API work somewhat (there's some missing refactors on my side to make full use of it), but I'm hitting a different kind of error.

    Are there any Quart rules regarding routes such as /a/b returning a HTTP 308 redirection to /a/b/? Maybe I'm missing something...

    luna
    @lun-4
    One of my blueprints has an url_prefix of /api/shorten, and one of the routes is just declared as @bp.route("", methods=["POST"]) since I want to just expose POST /api/shorten, but that gives a redirection to /api/shorten/...
    Phil Jones
    @pgjones
    luna
    @lun-4
    Oh! Thank you!
    Phil Jones
    @pgjones

    I've written about how to use postgres with Quart, specifying my preferred libraries (Databases & asyncpg) and how to convert types automatically,
    https://pgjones.dev/blog/quart-postgres-2021/

    Would be good to know if you think this is better as an extension

    Jorge Escobar
    @esfoobar

    Hi @pgjones I am stumped with the following. I'm trying to pass a cursor_id to a websocket view, like so:

    @home_app.websocket("/ws")
    @login_required
    async def ws():
        dbc = current_app.dbc
        cursor_id = int(request.args.get("cursor_id"))

    But when I try to read the argument I get the error: "Attempt to access request outside of a relevant context". How can I pass that value from the template to the websocket endpoint?

    Phil Jones
    @pgjones
    If you switch request to websocket it should work (given this runs in a websocket context).
    You can also do,
    cursor_id = websocket.args.get("cursor_id", type=int)
    luna
    @lun-4
    Is there something planned to account for FileStorage.stream not being an asyncio object, or would we be locked waiting for the (currently) 16KB chunks of data on every iteration? I think those would probably be fine considering the kernel can cache possible future file reads, but I'm not sure.
    Phil Jones
    @pgjones
    It is something I've been wondering as well (along with the intermediate stream when parsing the form request body). I'm not sure what is best - do you have a suggestion?
    luna
    @lun-4
    I was thinking that an async for file in request.files:-like API to fetch files (instead of await request.files) would enable us to provide async reading of them, but I don't know how possible that is, considering werkzeug
    Jorge Escobar
    @esfoobar

    If you switch request to websocket it should work (given this runs in a websocket context).
    You can also do,

    cursor_id = websocket.args.get("cursor_id", type=int)

    That worked @pgjones, thanks!

    Penguin Master
    @PenguinMaster0226
    Hello, @pgjones, I need some help with Quart's websockets.
    How do I recieve multiple websocket client connections?
    Penguin Master
    @PenguinMaster0226
    I tried using the broadcast function shown on the docs, but when I ran queue.put(), it didn't send.
    I'm not sure why though
    queue.get() also never worked
    Ernesto Ruge
    @the-infinity
    @PenguinMaster0226 usually this happens if something at your code blocks the loop. put would be a good candidat because it awaits the get, so usually put_nowait is the way to go.
    Penguin Master
    @PenguinMaster0226
    @the-infinity I tried that, and then I figured out the issue. I believe it's because the queues are empty. When I used queue.get_nowait, it raised an asyncio.QueueEmpty error. How do I add the websocket to the queue?
    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