NixOS / nixpkgs

Nix Packages collection & NixOS
MIT License
18.18k stars 14.19k forks source link

Python flask module crashing when passed the --debug flag #245450

Closed henningphan closed 10 months ago

henningphan commented 1 year ago

Describe the bug

When starting a python flask app in debug mode it says syntax error because it seems to parse bash code as python.

Steps To Reproduce

Steps to reproduce the behavior:

  1. change directory to an empty dir
  2. Save this bash script and run it, it creates a minimal flask file, and a shell.nix, and executes it
    
    #!/usr/bin/env bash
    echo "==> create minimal flask app"
    cat > app.py << EOF
    from flask import Flask
    app = Flask(__name__)

@app.route('/') def hello_world(): return 'Hello, World!' EOF

echo "==> create small shell.nix" cat > shell.nix << EOF { pkgs ? import {} }: let my-python-packages = ps: with ps; [ flask ]; in pkgs.mkShell { packages = [ (pkgs.python311.withPackages my-python-packages) ];

inputsFrom = [];

shellHook = '' export DEBUG=1 ''; } EOF

echo "==> run command that fails" nix-shell --command "flask -A app run --debug"

echo "==> run command without --debug and it works" echo 'nix-shell --command "flask -A app run"'


### Expected behavior
The webserver should be running and serving webpages, not crashing on a syntax error

### Screenshots
Here is a picture of me running it and flask crashing.
![image](https://github.com/NixOS/nixpkgs/assets/1679039/1de6f322-a640-4f9b-9583-f3d6ff699245)

### Additional context
Add any other context about the problem here.

### Notify maintainers
@SuperSandro2000 

### Metadata
Please run `nix-shell -p nix-info --run "nix-info -m"` and paste the result.

```console
[user@system:~]$ nix-shell -p nix-info --run "nix-info -m"
 - system: `"x86_64-linux"`
 - host os: `Linux 6.1.35, NixOS, 23.05 (Stoat), 23.05.1375.9790f3242da`
 - multi-user?: `yes`
 - sandbox: `yes`
 - version: `nix-env (Nix) 2.13.3`
 - channels(henning): `"home-manager-23.05.tar.gz, nixos-23.05"`
 - nixpkgs: `/nix/var/nix/profiles/per-user/root/channels/nixos`
SuperSandro2000 commented 1 year ago

Here is a picture of me running it and flask crashing.

I think flask tries to import the wrapper script instead of python script. Somewhere in the flask code there is an import statement which we need to patch to fix that.

awooff commented 11 months ago

Bumping this issue, is there any progress? I've managed to reproduce the same result, repository is on my Gitlab

Here's my metadata:

kae@akayashi:~/Projects/Ceres/src/processor$ nix run nixpkgs#nix-info
system: "x86_64-linux"
multi-user?: yes
version: nix-env (Nix) 2.18.1
channels(root): "nixpkgs"
nixpkgs: /nix/var/nix/profiles/per-user/root/channels/nixpkgs
SuperSandro2000 commented 11 months ago

@nickcao can you take a look? You are now maintaining the package

NickCao commented 11 months ago

I'm unable to reproduce the issue on master. Which channel are you on?

awooff commented 11 months ago

Ah, I'm on unstable. Currently posting from my MacBook and the issue is the same regardless

λ ~ nix-channel --list
darwin https://github.com/LnL7/nix-darwin/archive/master.tar.gz
home-manager https://github.com/nix-community/home-manager/archive/release-22.05.tar.gz
nixpkgs-unstable https://nixos.org/channels/nixpkgs-unstable
NickCao commented 11 months ago

Tried again with the repro script, still unable to get the failure (even if I manually trigger a reload with touch). Maybe the issue is related to kernel version (or darwin specific?). Also the code for handling the reload is actually in werkzeug, that's [sys.executable, *sys.orig_argv[1:]] for our default python version. May you prepend the following code to app.py and see what it prints?

import sys
print([sys.executable, *sys.orig_argv[1:]])
awooff commented 11 months ago

Heya, thank you for your patience :) I've prepended it to my app.py, full file is now just this:

from flask import Flask
import sys
print([sys.executable, *sys.orig_argv[1:]])

app = Flask(__name__)

@app.route('/')
def hello_world():
        return '<p>Hiya! It all works :)</p>'

And the following output is this:

processor main• 8.1s ❱ flask --app processor run --debug
['/nix/store/95cxzy2hpizr23343b8bskl4yacf4b3l-python3-3.10.11/bin/python3.10', '/nix/store/n0syiwyy2bxg30l13sia42y13isgacqg-python3.10-flask-2.2.3/bin/.flask-wrapped', '--app', 'processor', 'run', '--debug']
 * Serving Flask app 'processor'
 * Debug mode: on
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
 * Running on http://127.0.0.1:5000
Press CTRL+C to quit
 * Restarting with watchdog (inotify)
  File "/nix/store/n0syiwyy2bxg30l13sia42y13isgacqg-python3.10-flask-2.2.3/bin/flask", line 2
    PATH=${PATH:+':'$PATH':'}
         ^
SyntaxError: invalid syntax
NickCao commented 11 months ago

Well that's strange, so the general logic is: on reload, the command [sys.executable, *sys.orig_argv[1:]] is re-executed. However in your case, despite that the command is pointed to flask unwrapped, the log says the opposite.

Edit: I'm able to reproduce the issue on 23.05! So it is specific to older flask versions.

NickCao commented 11 months ago

The commit fixing this issue is: https://github.com/pallets/werkzeug/commit/51b8402ec419b7afdc098cbd37953c8e125df10c, we can patch this on 23.05 but it would be a mass rebuild I guess?

awooff commented 11 months ago

For the package or for other users, do you mean? But yea that seems like the best way to go. Do you know when at all that patch will be released?

Thanks for all your help btw :)

NickCao commented 11 months ago

I mean 23.05 is near the end of its lifecycle, pushing such a mass rebuild for all users might not be the most economical choice.

SuperSandro2000 commented 10 months ago

If this issue is fixed on 23.11, I think we can close this.