Python: flask app can't find dependencies

I’m trying to set up a nix-shell to develop a Flask application, and I set up a minimal example that depends on flask and flask-restful. The relevant import statements are:

# nix_flask/app.py
from flask import Flask
from flask_restful import Resource, Api

My shell.nix is:

with (import (builtins.fetchTarball {
  url = "https://github.com/NixOS/nixpkgs/archive/8746c77a383f5c76153c7a181f3616d273acfa2a.tar.gz";
}) { });

( python37.withPackages (ps: with ps; [ flask flask-restful ]) ).env

If I start the app with python directly, it works:

# server
FLASK_APP=nix_flask/app.py FLASK_ENV=development \
    python nix_flask/app.py
# client
$ curl localhost:5000
{"hello": "world"}

But if I start it with flask run, it’s unable to find flask-restful:

# server
FLASK_APP=nix_flask/app.py FLASK_ENV=development \
    flask run
# client
$ curl localhost:5000
...
Traceback (most recent call last):
  File "/nix/store/...-python3.7-Flask-1.0.3/lib/python3.7/site-packages/flask/cli.py", line 236, in locate_app
    __import__(module_name)
  File "/path/to/nix-flask/nix_flask/app.py", line 2, in <module>
    from flask_restful import Resource, Api
ModuleNotFoundError: No module named 'flask_restful'

My Nix knowledge outweighs my Python knowledge, and I’m not sure what I need to change to fix this (PYTHONPATH?). Does anyone know what I’m doing wrong?

Huh, can’t reproduce

$ nix-shell -E 'with (import (builtins.fetchTarball {
  url = "https://github.com/NixOS/nixpkgs/archive/8746c77a383f5c76153c7a181f3616d273acfa2a.tar.gz";
}) { }); (python37.withPackages(p: [ p.flask p.flask-restful ])).env' --run 'FLASK_APP=/tmp/app.py flask run'
 * Serving Flask app "/tmp/app.py"
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
127.0.0.1 - - [23/Mar/2020 21:02:00] "GET / HTTP/1.1" 200 -

Do you reproduce this with nix-shell --pure?

Ooh, interesting. It happens if you set FLASK_ENV=development but not otherwise.

cc @FRidh, is this best we can do?

1 Like

This seems different from the argv[0] issue, since I’m not getting a SyntaxError (from trying to interpret a shell script as Python, as described in this issue), but rather an ImportError.

I tried the hotfix you suggested, but the problem remained the same.

1 Like

which means, my Nixpkgs is quite old… But now I can reproduce your issue (with your nixpkgs revision), and it works with my revision (and argv hack):

$ nix-shell -E '
with (import (builtins.fetchTarball {
  url = "https://github.com/NixOS/nixpkgs/archive/bea1a232c61.tar.gz";
}) { }); (python37.withPackages(p: [ p.flask p.flask-restful ])).env' --run 'FLASK_APP=/tmp/app.py FLASK_ENV=development flask run'

Maybe you can bisect git revisions from bea1a232c61 to 8746c77a383f5c and find out which one breaks reloader.

1 Like

This thread just got mentioned on Flask patch reversion causing breakage in development mode · Issue #72345 · NixOS/nixpkgs · GitHub which may be of interest.

1 Like