cancel
Showing results for 
Search instead for 
Did you mean: 
SOLVED

Python Snap with Flask and Gunicorn

Python Snap with Flask and Gunicorn

rlilla
Established Member

Hello,

I´m trying to test an app with Python and Flask and Gunicorn as wsgi. If I configure Gunicorn to bind the address with port (0.0.0.0:5001), I can access the address http://<ipaddres>:5001. If I try Gunicorn binding to unix socket and bind the proxy of package manif...

rlilla_2-1727301969939.png

 

Monitoring the snap service, gunicorn is generating  the sock file. 
rlilla_0-1727301781999.png

The snap is like below.

rlilla_1-1727301873473.png

Does anyone have any idea about what can be the problem?

8 REPLIES 8

nickH
Community Moderator
Community Moderator

Hi @rlilla 

In our sample form the sdk (samples-python/webserver) the proxyMapping is done like this: 

"services": {
    "proxyMapping": [
      {
        "name": "sdk-py-webserver",
        "url": "/python-webserver",
        "binding": "unix://{$SNAP_DATA}/package-run/sdk-py-webserver/web.sock",
        "restricted": []
      }
    ]

 

And in the snapcraft.yaml the package-run slot is defined like this: 

slots:

...

  package-run:
    interface: content
    content: package-run
    source:
      write:
        - $SNAP_DATA/package-run/${CRAFT_PROJECT_NAME}

 

I would suggest you to look into this example and see where the differences are. 

Best regards, 

Nick

rlilla
Established Member

I took the webserver example and just modified the main.py to use flask.  But I still have the Not Found error when I true to open https://127.0.0.1:8443/python-webserver

The service is running fine.

rlilla_0-1727899987614.png

rlilla_1-1727900100859.png

 

@rlilla ,

Might the issue just be a typo? You have unix:/// in your proxy mapping instead of unix://

rlilla
Established Member

I don´t think so because I used the same proxy mapping of the webserver example and it worked fine. Maybe the problem is because we have https connection with the ctrlX and flask is working for http.

So you were able to access the flask server using the proxy mapping in the sample? If you changed nothing else, doesn't that point to the mapping being the issue?

rlilla
Established Member

Not the flask server. Only the http server used in the example. If I just change the main.py including Flask instead of htt.server, the it doesn´t work.

The proxy mapping should handle HTTP & HTTPS. See documentation here.

Are you installing the app in the virtual CORE before executing? In that case, the sample code runs the unix socket server, not http.

 

def run_webserver_unixsock():
    """run_webserver_unixsock"""
    sock_dir = os.getenv("SNAP_DATA") + "/package-run/sdk-py-webserver/"
    if not os.path.exists(sock_dir):
        os.makedirs(sock_dir)

    sock_file = sock_dir + "web.sock"

    try:
        os.unlink(sock_file)
    except OSError:
        pass

    with web.unix_socket_server.UnixSocketServer(
        sock_file, web.request_handler.RequestHandler
    ) as http_server:
        print("UNIX SOCKET server started - listening on", sock_file, flush=True)

        http_server.serve_forever()

        http_server.server_close()
        os.remove(sock_file)

 

 I would suggest trying some remote debugging to see where this is getting hung up.

rlilla
Established Member

After reading carefully the documentation about the reverse proxy, I realized that I was using the incorrect route in Flask. I had @app.route('/'). After changing to @app.route('/python-webserver'), it worked. Thanks a lot for your support. 

Icon--AD-black-48x48Icon--address-consumer-data-black-48x48Icon--appointment-black-48x48Icon--back-left-black-48x48Icon--calendar-black-48x48Icon--center-alignedIcon--Checkbox-checkIcon--clock-black-48x48Icon--close-black-48x48Icon--compare-black-48x48Icon--confirmation-black-48x48Icon--dealer-details-black-48x48Icon--delete-black-48x48Icon--delivery-black-48x48Icon--down-black-48x48Icon--download-black-48x48Ic-OverlayAlertIcon--externallink-black-48x48Icon-Filledforward-right_adjustedIcon--grid-view-black-48x48IC_gd_Check-Circle170821_Icons_Community170823_Bosch_Icons170823_Bosch_Icons170821_Icons_CommunityIC-logout170821_Icons_Community170825_Bosch_Icons170821_Icons_CommunityIC-shopping-cart2170821_Icons_CommunityIC-upIC_UserIcon--imageIcon--info-i-black-48x48Icon--left-alignedIcon--Less-minimize-black-48x48Icon-FilledIcon--List-Check-grennIcon--List-Check-blackIcon--List-Cross-blackIcon--list-view-mobile-black-48x48Icon--list-view-black-48x48Icon--More-Maximize-black-48x48Icon--my-product-black-48x48Icon--newsletter-black-48x48Icon--payment-black-48x48Icon--print-black-48x48Icon--promotion-black-48x48Icon--registration-black-48x48Icon--Reset-black-48x48Icon--right-alignedshare-circle1Icon--share-black-48x48Icon--shopping-bag-black-48x48Icon-shopping-cartIcon--start-play-black-48x48Icon--store-locator-black-48x48Ic-OverlayAlertIcon--summary-black-48x48tumblrIcon-FilledvineIc-OverlayAlertwhishlist