python3 uwsgi不使用uwsgi.applications字典

时间:2018-08-21 20:57:05

标签: python python-3.x nginx uwsgi

这很长。 tl; dr在结尾。

因此,我正在学习如何使用python。尽管我在其他语言方面有丰富的经验,所以每当我看到适合自己的东西时,我就会跳入深渊。这可能是我的错误,但是肯定会更有趣。

我正在使用 Ubuntu 16.04 LTS。

python3 已安装!其版本描述如下:

python3 --versionPython 3.5.2

我还安装了 uwsgi

python3 -m pip show uwsgi | grep LocationLocation: /home/user/.local/lib/python3.5/site-packages

uwsgi --version2.0.17.1

我创建了一个证书颁发机构,并将其作为受信任的根安装到我的浏览器中。

我已经安装了nginx。 Default.conf有两个server块:一个被配置为提供localhost证书,另一个为我的工作站的标准主机名提供第二个证书。这似乎正常工作(使用Firefox访问https://localhost/会连接并显示404页面,因为没有静态内容,并且我删除了nginx安装的index.html)。在每个服务器块的内部,我包括另一个文件,该文件通过UNIX域套接字配置WSGI后端。这似乎也可以正常工作:运行wtf的基本uwsgi进程可以提供我期望的数据。

/etc/nginx/conf.d/default.conf

server {
    listen       127.0.0.1:80 default_server;
    listen       [::1]:80 default_server;
    listen       127.0.0.1:443 default_server ssl http2;
    listen       [::1]:443 default_server ssl http2;

    ssl_certificate /etc/nginx/sites-certs/localhost.fullchain.pem;
    ssl_certificate_key /etc/nginx/sites-certs/localhost.key.pem;

    server_name  localhost;

    location / {
        return 444;
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    include sites/ftls.conf;
}

server {
    listen 0.0.0.0:80;
    listen [::]:80;
    listen 0.0.0.0:443 ssl http2;
    listen [::]:443 ssl http2;

    server_name my.workstation.internal.com;

    ssl_certificate /etc/nginx/sites-certs/my.workstation.internal.com.fullchain.pem;
    ssl_certificate_key /etc/nginx/sites-certs/my.workstation.internal.com.key.pem;

    include sites/ftls.conf;
}

/etc/nginx/sites/ftls.conf

location ~ /ftls/ {
    rewrite /ftls/(.*) /$1 break;

    include uwsgi_params;
    uwsgi_pass unix:/home/user/dev/mytest/py/www/backend.sock;
}

/home/user/dev/mytest/py/www/wtf

#!/usr/bin/env python3

import uwsgi
import wsgiref.util

def application(env, start_response):
    start_response('200 OK', [('Content-Type', 'text/plain')])
    return "application()\n\n{}\nHELLO WORLD\n{}\n{}\n".format(
        env,
        wsgiref.util.request_uri(env),
        wsgiref.util.application_uri(env)
    ).encode("utf-8")

然后我通过在 bash 中调用以下内容来开始 uwsgi

cd ~/dev/mytest/py/www; uwsgi --uwsgi-socket ./backend.sock --wsgi-file ./wtf

然后,在Firefox中,打开https://localhost/ftls/。我看到application(),然后是环境变量!是的!

好的,很酷,所以我在读the documentation for uWSGI。如果我正确理解它,可以让 uwsgi 将不同的URL端点路由到不同的python可调用对象。听起来很方便!所以我尝试了一下,但似乎没有用。这是我尝试过的

  • 我不知道django.core.handlers.wsgi.WSGAHandler()的作用,但看起来它接管了我的应用程序。我不希望我的申请被接管!所以我这样尝试了:

    #!/usr/bin/env python3
    
    import uwsgi
    import wsgiref.util
    
    def application(env, start_response):
        start_response('200 OK', [('Content-Type', 'text/plain')])
        return "application()\n\n{}\nHELLO WORLD\n{}\n{}\n".format(
            env,
            wsgiref.util.request_uri(env),
            wsgiref.util.application_uri(env)
        ).encode("utf-8")
    
    def wtfapp(env, start_response):
        start_response('200 OK', [('Content-Type', 'text/plain')])
        return "wtfapp()\n\n{}".format(env).encode("utf-8")
    
    uwsgi.applications = {
        '': application,
        '/wtf': wtfapp
    }
    

    访问https://localhost/ftls/后,我仍然被发送到application()。但是,当我去https://localhost/ftls/wtf时,我 仍然被发送到application()。嗯?

  • 好的,所以我注意到,尽管在nginx的配置中使用了rewrite子句,uwsgi仍会将GET登录到/ftls/。奇怪的。有解决办法吗?是什么原因造成的?无论如何,我尝试更新uwsgi.applications来查看。

    uwsgi.applications = {
        '': application,
        '/wtf': wtfapp,
        '/ftls': wtfapp,
        '/ftls/wtf': wtfapp
    }
    

    尽管如此,所有端点仍指向application()

  • 好的,所以我读了一些文档,上面写着:

    > Passing this Python module name (that is, it should be importable and without the .py extension)
    

    老实说,我不知道这意味着什么。我的wtf python文件没有.py扩展名。可导入是什么意思?

    它还会继续提及

    > to uWSGI’s module / wsgi option, uWSGI will search the uwsgi.applications dictionary for the URL prefix/callable mappings.
    

    好吧,我正在通过--wsgi-file将python文件传递给uwsgi。这和--wsgi不同吗?

    uwsgi --help | grep \\-\\-wsgi

    说:

    --wsgi-file                             load .wsgi file
    -w|--wsgi                               load a WSGI module
    

    选项的帮助文本明显不同,因此另一个选项可能有用吗?如果我终止uwsgi并改用该选项运行它,那么我会发现事情做得不好:

    uwsgi --uwsgi-socket ./backend.sock --wsgi ./wtf

    > blah blah blah log messages and junk
    > ...
    > ImportError: No module named './wtf'
    > unable to load app 0 (mountpoint='') (callable not found or import error)
    > *** no app loaded. going in full dynamic mode ***
    > ...
    > blah
    

    而且,当我尝试通过浏览器进行连接时,我看到一条日志消息,内容为--- no python application found, check your startup logs for errors ---,浏览器显示了一个非常普通的Internal Server Error页面。没有错误信息发送到浏览器。天哪,确定很方便(讽刺)。不仅如此,为什么uwsgi在明显出现配置错误时不立即停止运行?它被告知要加载某些内容,但无法加载它,因此它继续报告未加载任何应用程序,并进入了完全动态模式。那是 极不合常规的 ,肯定是我还没有准备好挖的另一个兔子洞。

  • 但是,嘿,一个不同的症状,一个不同的错误消息,也许这是一件好事。

    那么,这里所说的WSGI模块是什么?我尝试阅读documentation for Python Modules。它说:

     > A module is a file containing Python definitions and statements.
    

    听起来对我来说,我的wtf代码就是这样。所以我一直在读书。

     > The file name is the module name with the suffix .py appended.
    

    除了,这是uwsgi文档所说的相反。 uwsgi再次声明it should be ... without the .py extension。我很困惑。无论如何,我将假定他们在谈论同一件事。继续说,键入import wtf应该可以在python3 shell中进行。 Python3说:ImportError: No module named 'wtf'。如果我将文件重命名为wtf.py,则python3会给出另一个错误,ImportError: No module named 'uwsgi'

    奇怪。但是我似乎记得,我只是因为an obscure issue on Github而发现了uwsgi可执行文件。我花了小时的时间在Google搜索中找到了那个,错误消息是一样的!

    所以,我假设如果我离开了名为wtf.py的文件,那么uwsgi(可执行文件)应该使uugi(该模块)可用于Python代码,并且一切都会好起来!

  • uwsgi --uwsgi-socket ./backend.sock --wsgi ./wtf

    这个人说:ImportError: No module named './wtf'

    好的,所以也许它不喜欢相对路径。

  • uwsgi --uwsgi-socket ./backend.sock --wsgi wtf

    这个人说:

    > found a multiapp module...
    > the app mountpoint must be a string
    

    哦,我知道这个错误!我在another Github issue上看到了它!

  • 所以那里的解决方案似乎很适合我的情况:

    uwsgi.applications = {
        b'': application,
        b'/wtf': wtfapp,
        b'/ftls': wtfapp,
        b'/ftls/wtf': wtfapp
    }
    

    现在,当我运行uwsgi --uwsgi-socket ./backend.sock --wsgi wtf时,我看到:

    > WSGI app 0 (mountpoint='') ready in 0 seconds on interpreter 0x22cf2b0 pid: 12553 (default app)
    > WSGI app 1 (mountpoint='/ftls') ready in 0 seconds on interpreter 0x22cf2b0 pid: 12553
    > WSGI app 2 (mountpoint='/wtf') ready in 0 seconds on interpreter 0x22cf2b0 pid: 12553
    > WSGI app 3 (mountpoint='/ftls/wtf') ready in 0 seconds on interpreter 0x22cf2b0 pid: 12553
    

    我的天哪!看起来很有希望!

  • ...除了...

    :: rageface ::

    所有端点仍在浏览器中返回application()wtfapp()仍未被调用

因此,在这一点上,我已经尽力尝试了。我敢肯定,我忽略了这件事。任何帮助或见识将不胜感激。

tl;博士,我的问题是:

  • 为什么在rewrite中使用了nginx指令,uwsgi仍然可以看到完整的URI?
  • uwsgi看到几个应用程序“挂载点”,但它们似乎都已转到默认应用程序。导致uwsgi不能将不同的URL路由到不同的python函数定义,我做错了什么?

0 个答案:

没有答案