【问题标题】:Running Python Script Using Nginx and WSGI - Stuck使用 Nginx 和 WSGI 运行 Python 脚本 - 卡住
【发布时间】:2020-11-12 01:12:46
【问题描述】:

我是 python 新手,我的任务是构建一个电子表格解析器。我创建了一个读取 xlsx 文件并解析数据的 python 脚本。我有一个 Nginx 服务器设置,这将被托管。我需要将此脚本作为 API 端点,以便可以将解析后的数据作为 JSON 传回。我一直在阅读有关生产服务器的 WSGI 并尝试遵循构建它的路线。我能够在服务器上提供路径并让它输出 wsgi python 脚本。该脚本具有以下内容:

def application(environ, start_response):
status = '200 OK'
html = '<html>\n' \
       '<body>\n' \
       ' Hooray, mod_wsgi is working\n' \
       '</body>\n' \
       '</html>\n'
response_header = [('Content-type','text/html')]
start_response(status, response_header)
return [html]

我对如何使用我的 excel 解析器类接收请求并发回 json 感到有些困惑?谢谢,我希望我很清楚。我确实有一个可以工作的烧瓶服务器,但我不知道如何让它不断运行以服务我的端点:

app = Flask(__name__)

@app.route('/parser/direct_energy', methods=['GET'])

def get_data(): 返回 jsonify(commissions_data)

如果 name == 'ma​​in': app.run(host='0.0.0.0')

【问题讨论】:

    标签: python apache api nginx wsgi


    【解决方案1】:

    我的 nginx.conf 看起来略有不同,部分原因是我正在运行多个 WSGI 实例,然后让 nginx 对它们进行负载平衡

    worker_processes  3;
    events {
        worker_connections  1024;
    }
    user daemon;
    http {
        access_log      off;
        error_log       stderr error;
        include         mime.types;
        default_type    application/octet-stream;
        sendfile        on;
        keepalive_timeout  65;
        upstream dns_servers {
            server unix:/ram/dnsflsk_1.sock;
            server unix:/ram/dnsflsk_2.sock;
            server unix:/ram/dnsflsk_3.sock;
            }
    
        server {
            listen 800 ssl;
            server_name localhost;
            ssl_certificate      certkey.pem;
            ssl_certificate_key  certkey.pem;
            ssl_session_cache    shared:SSL:1m;
            ssl_session_timeout  5m;
            ssl_ciphers  HIGH:!aNULL:!MD5;
            ssl_prefer_server_ciphers  on;
            location / {
                proxy_pass http://dns_servers;
            }
        }
    }
    

    但是有了这个,所有的 URL 都被传递给了 python/wsgi

    【讨论】:

      【解决方案2】:

      更新

      我通过 NGinx、flask 和 GUnicorn 让事情顺利进行。但是,我的烧瓶应用程序仅在我转到“/”时才有效。如果我去 /parser/de/v1 之类的路线,我会得到 404 Not Found。
      这是我对 NGinx 的设置:

      server {
          listen 80 default_server;
          listen [::]:80 default_server;
      
          # SSL configuration
          #
          # listen 443 ssl default_server;
          # listen [::]:443 ssl default_server;
          #
          # Note: You should disable gzip for SSL traffic.
          # See: https://bugs.debian.org/773332
          #
          # Read up on ssl_ciphers to ensure a secure configuration.
          # See: https://bugs.debian.org/765782
          #
          # Self signed certs generated by the ssl-cert package
          # Don't use them in a production server!
          #
          # include snippets/snakeoil.conf;
      
          root /var/www/html/excel_parser;
      
          # Add index.php to the list if you are using PHP
          index index.html index.htm index.nginx-debian.html index.php;
      
          server_name 208.97.141.147;
      
          location / {
                  # First attempt to serve request as file, then
                  # as directory, then fall back to displaying a 404.
                  proxy_pass http://127.0.0.1:5000;
                  proxy_connect_timeout 75s;
                  proxy_read_timeout 300s;
                  try_files $uri $uri/ =404;
          }
      
          # pass PHP scripts to FastCGI server
          #
          #location ~ \.php$ {
          #       include snippets/fastcgi-php.conf;
          #
          #       # With php-fpm (or other unix sockets):
          #       fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
          #       # With php-cgi (or other tcp sockets):
          #       fastcgi_pass 127.0.0.1:9000;
          #}
      
          # deny access to .htaccess files, if Apache's document root
          # concurs with nginx's one
          #
          #location ~ /\.ht {
          #       deny all;
          #}
      
             
      

      【讨论】:

      • 尝试删除 rootindex
      【解决方案3】:

      我将python/flask 用于开发,gunicorn 用于生产。

      为了让它接受 HTTP 请求,我使用了函数装饰器。这是最常见的方式。

      @application.route('/epp/api/v1.0/request', methods=['POST'])
      def eppJSON():
          if flask.request.json is None:
              return abort(400, "No JSON data was POSTed")
          return jsonRequest(flask.request.json, flask.request.remote_addr)
      

      所以在这里,url /epp/api/v1.0/request 接受 POSTed JSON 并返回 JSON

      当您在开发模式下运行 flask 时,它会侦听 http://127.0.0.1:5000

      https://github.com/james-stevens/epp-restapi/blob/master/epprest.py https://github.com/james-stevens/dnsflsk/blob/master/dnsflsk.py

      这些都是我的python/flask 项目。随意复制。它们每个都在一个容器中运行多个 python 代码实例,由nginx 负载平衡——非常巧妙的组合。

      【讨论】:

      • 我在烧瓶中的所有路径除了 '/' 转到 404 在我的 NGinx 服务器上找不到吗?
      【解决方案4】:

      您不想为此使用原始 WSGI。

      使用FastAPI(或Flask)之类的包让您的一切变得更轻松。

      例如,使用 FastAPI,一个应用程序的端点接收二进制 (Excel) 文件并返回 JSON 响应大约是

      from fastapi import FastAPI, File, UploadFile
      
      app = FastAPI()
      
      
      @app.post("/process")
      def process_file(file: UploadFile = File()):
          response = my_data_processing_function(data)
          return {"response": response}
      

      见:

      【讨论】:

      • 非常感谢,我也尝试过使用烧瓶,但不知道如何不断运行烧瓶服务器,以便为路线提供服务。我在我的实际 api 脚本中有这个: app = Flask(name) @app.route('/parser/direct_energy', methods=['GET']) def get_data(): return jsonify( Commissions_data) if name == 'main': app.run(host='0.0.0.0') 但是这不适用于我的 IP 地址
      • Flask 也有关于如何运行服务器的说明:flask.palletsprojects.com/en/1.1.x/deploying/wsgi-standalone/…
      • AKX - 我试过 gunicorn api:app 并且服务器启动正常。它说它正在侦听:127.0.0.1:8000,但是我如何在服务器上点击该端点?我的 :8000 附加 IP 地址不起作用
      猜你喜欢
      • 1970-01-01
      • 2017-05-22
      • 1970-01-01
      • 2012-10-18
      • 1970-01-01
      • 2016-11-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多