flask + nginx + uwsgi - Python application not found - python

cat /etc/nginx/sites-available/mywebsite
server {
listen 80;
server_name mywebsite;
location /static {
alias /var/www/mywebsite/static;
}
location / {
include uwsgi_params;
uwsgi_pass unix:/tmp/website.sock;
uwsgi_param UWSGI_PYHOME /var/www/mywebsite/env;
uwsgi_param UWSGI_CHDIR /var/www/mywebsite;
uwsgi_param UWSGI_MODULE mywebsite;
uwsgi_param UWSGI_CALLABLE mywebsite;
}
error_page 404 /404.html;
}
cat /etc/uwsgi/apps-available/website.ini
[uwsgi]
plugins=python
vhost=true
socket=/tmp/website.sock
cat /var/www/mywebsite/mywebsite.py
from flask import Flask
app = Flask(__name__)
#app.route("/")
def index():
return "It works!"
if __name__ == "__main__":
app.run()
I'm running nginx, then uwsgi and has uWSGI Error 'Python application not found' in browser.

I had the same error, in the same configuration, and my problem was simply that the uwsgi service wasn't started. Restarting both nginx and uwsgi solved the problem.

UWSGI_CALLABLE must be 'app' (is the name of the function to call on the request)

Related

Nginx error when trying to deploy flask server

I am trying to follow this guid to deploy a flask server: https://medium.com/ymedialabs-innovation/deploy-flask-app-with-nginx-using-gunicorn-and-supervisor-d7a93aa07c18
I followed all the steps except the supervisor part which I fully skipped because the command wouldn't work, but it should not matter just to get things working.
When I run: sudo nginx -t
I get: nginx: [emerg] socket() [::]:80 failed (97: Address family not supported by protocol)
What is teh issue? I have seen other people getting this error but the solutions don;t seem to work for me?
This is my nginx conf file:
server {
listen 80;
server_name <name>;
location / {
proxy_pass http://127.0.0.1:8000;
}
}
#
# A virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
And the python flask server:
from flask import Flask
from flask import render_template
from flask import send_file
app = Flask(__name__, static_url_path="/static", static_folder="/static")
app.static_folder = 'static'
#app.route("/")
def index():
return render_template("index.html")
#app.route("/uploads/resume")
def download_resume():
return send_file("static/documents/resume.pdf")
if __name__ == '__main__':
app.run(port=5010, debug=False, host='0.0.0.0')
Go to /etc/nginx/sites-available/default
Disable IPV6
I just commented out the following line
listen [::]:80 default_server ipv6only=on;

PyMySQL + WSGI / Flask nginx Internal Server Error

I have Flask Installed with PyMysql
When im running it in dev mode python test.py then everything is allright and in browser im able to see result of SQL Select under port 5000
When im running through Nginx service test start which is using WSGI then im getting Internal Server Error. I guess its not a port issue but rather user access issue? I have no idea why same file is running fine in DEV but not under WSGI. Or it could be that under nginx it cant identify localhost?
app.py
from flask import Flask, request, render_template
import pymysql
db = pymysql.connect("localhost", "root", "123", "test1")
app = Flask(__name__)
#api = api(app)
#app.route('/')
def someName():
cursor = db.cursor()
sql = "SELECT name,password FROM Users"
cursor.execute(sql)
results = cursor.fetchone()
return results[0] + str(results[1])
# return render_template('index.html', results=results)
if __name__ == '__main__':
app.run(host='0.0.0.0')
app.debug = true
nginx configuration
server {
listen 80 default_server;
# root /usr/share/nginx/html;
root /var/www/html;
index index.html index.htm;
# Make site accessible from http://localhost/
server_name mywebsite.com;
location / { try_files $uri #rocket; }
location #rocket {
include uwsgi_params;
uwsgi_pass unix:///var/www/rocket/myproject.sock;
}
location /images {
alias /var/www/rocket/im;
index index.html;
}
location /phpmyadmin {
root /usr/share/;
index index.php index.html index.htm;
location ~ ^/phpmyadmin/(.+\.php)$ {
try_files $uri =404;
root /usr/share/;
fastcgi_pass unix:///run/php/php7.0-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~* ^/phpmyadmin/(.+\.(jpg|jpeg|gif|css|png|js|ico|html|xml|txt))$ {
root /usr/share/;
}
}
location /phpMyAdmin {
rewrite ^/* /phpmyadmin last;
}
}
wsgi.py
from rocket import app
if __name__ == "__main__":
app.run()
app.debug = true
app.ini
[uwsgi]
module = wsgi:app
master = true
processes = 5
socket = myproject.sock
chmod-socket = 660
vacuum = true
die-on-term = true
logto = /var/www/rocket/%n.log
error.log
--- No python application found, check your startup logs for errors

How to setup nginx + tornado + flask?

These are my fully working tornado and flask files:
Tornado:
from flaskk import app
from tornado.wsgi import WSGIContainer
from tornado.ioloop import IOLoop
from tornado.web import FallbackHandler, RequestHandler, Application
class MainHandler(RequestHandler):
def get(self):
self.write("This message comes from Tornado ^_^")
tr = WSGIContainer(app)
application = Application([
(r"/tornado", MainHandler),
(r".*", FallbackHandler, dict(fallback=tr)),
])
if __name__ == '__main__':
application.listen(5052)
IOLoop.instance().start()
Flask:
from flask import Flask, jsonify
from flask_restful import Resource, Api
app = Flask(__name__)
api = Api(app)
class Report(Resource):
def get(self):
return 'hello from flask'
api.add_resource(Report, '/report')
Now I'm trying to setup nginx in front of tornado.
My nginx config file is:
worker_processes 3;
error_log logs/error.;
events {
worker_connections 1024;
}
http {
# Enumerate all the Tornado servers here
upstream frontends {
server 127.0.0.1:5052;
}
include mime.types;
default_type application/octet-stream;
keepalive_timeout 65;
sendfile on;
server {
listen 5050;
server_name localhost;
location / {
proxy_pass_header Server;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_pass http://localhost:5050;
}
}
}
When I do a
localhost:5050/
then I get the nginx welcome page. But when I do
localhost:5050/report
then I get a 404. Tornado is running on port 5052.
Why is nginx not calling tornado which thereby should get the result from flask?
Am I missing something here?
Firstly, you don't want to proxy to localhost:5050 because that is Nginx itself
You want to proxy to upstream frontends.
proxy_pass http://frontends;
Regarding your Flask issues, I've gotten this to work fine.
#app.route('/report')
def report():
return 'hello from flask'
$ curl localhost:5052/report
hello from flask
When I added in Flask Restful, that still worked.
You said you see the index page of nginx, so it is running, you just need to correctly hook the other ports together.
The proxy_pass fix seemed to work for me.
$ curl localhost:5050/report
"hello from flask"
$ curl localhost:5050/tornado
This message comes from Tornado ^_^

The `uwsgi_modifier1 30` directive is not removing the SCRIPT_NAME from PATH_INFO as documented

This is my nginx virtual host configuration.
debian:~# cat /etc/nginx/sites-enabled/mybox
server {
listen 8080;
root /www;
index index.html index.htm;
server_name mybox;
location /foo {
uwsgi_pass unix:/tmp/uwsgi.sock;
include uwsgi_params;
uwsgi_param SCRIPT_NAME /foo;
uwsgi_modifier1 30;
}
}
This is the source code of my WSGI application.
debian:~# cat /www/app.py
def application(environ, start_response):
path_info = script_name = request_uri = None
if 'PATH_INFO' in environ:
path_info = environ['PATH_INFO']
if 'SCRIPT_NAME' in environ:
script_name = environ['SCRIPT_NAME']
if 'REQUEST_URI' in environ:
request_uri = environ['REQUEST_URI']
output = 'PATH_INFO: ' + repr(path_info) + '\n' + \
'SCRIPT_NAME: ' + repr(script_name) + '\n' + \
'REQUEST_URL: ' + repr(request_uri) + '\n'
start_response('200 OK', [('Content-Type','text/plain')])
return [output.encode()]
I serve my WSGI application with these two commands:
service nginx restart
uwsgi -s /tmp/uwsgi.sock -w app --chown-socket=www-data:www-data
This is the output I see when I try to visit my web application.
debian:~# curl http://mybox:8080/foo/bar
PATH_INFO: '/foo/bar'
SCRIPT_NAME: '/foo'
REQUEST_URL: '/foo/bar'
Since I have mentioned uwsgi_modifier1 30; in my nginx virtual host configuration, I was expecting the PATH_INFO to be only '/bar' as explained in the following two URLs:
http://uwsgi-docs.readthedocs.org/en/latest/Nginx.html
http://blog.codepainters.com/2012/08/05/wsgi-deployment-under-a-subpath-using-uwsgi-and-nginx/
Quoting the relevant part from the first article:
The uwsgi_modifier1 30 option sets the uWSGI modifier UWSGI_MODIFIER_MANAGE_PATH_INFO. This per-request modifier instructs the uWSGI server to rewrite the PATH_INFO value removing the SCRIPT_NAME from it.
Quoting the relevant part from the second article:
Standard WSGI request followed by the HTTP request body. The PATH_INFO is automatically modified, removing the SCRIPT_NAME from it.
But I see that my PATH_INFO remains intact as '/foo/bar'. The SCRIPT_NAME part, i.e. '/foo' has not been removed from it. Why?
After reading https://github.com/unbit/uwsgi/pull/19 I understood that using uwsgi_modifier1 30; is deprecated.
So this is how I solved the problem.
First of all I removed SCRIPT_NAME handling in nginx by removing these two lines:
uwsgi_param SCRIPT_NAME /foo;
uwsgi_modifier1 30;
The resulting nginx configuration looked like this:
debian:~# cat /etc/nginx/sites-enabled/mybox
server {
listen 8080;
root /www;
index index.html index.htm;
server_name mybox;
location /foo {
uwsgi_pass unix:/tmp/uwsgi.sock;
include uwsgi_params;
}
}
Then I restarted nginx and did SCRIPT_NAME handling in uwsgi using the --mount and --manage-script-name options like this.
service nginx restart
uwsgi -s /tmp/uwsgi.sock -w app --chown-socket=www-data:www-data --manage-script-name --mount=/foo=/www/app.py
Now, I get the expected output.
debian:~# curl http://mybox:8080/foo/bar
PATH_INFO: '/bar'
SCRIPT_NAME: '/foo'
REQUEST_URL: '/foo/bar'

How to install ReviewBoard under Nginx?

Sorry for my poor english, I'm french... no one is perfect.
I'm trying to install ReviewBoard under Nginx (LEMP with Debian Wheezy, Nginx 1.4.5, MySQL 14.14, PHP 5.4.4). My python installation use Python 2.7.3, easy_install 0.6.24dev-r0, pip 1.1, virtualenv 1.11.4 and gunicorn 18.0.
I succeeded to install all that stuff and create a reviewboard site but I fail to access the reviewboard site from a browser.
I know that reviewboard recommends Apache but also that is possible to install it on Nginx. I can't find any step-by-step tutorial except many links to http: / /rramsden.ca/blog/2011/09/26/nginx-reviewboard/ but this link is dead. Does anyone know another link ?
My Nginx conf is:
server {
listen 80;
server_name review.unskontrollables.org;
root /var/www/review.unskontrollables.org/htdocs;
# Error handlers
error_page 500 502 503 504 /errordocs/500.html;
# serve directly - analogous for static/staticfiles
# Alias static media requests to filesystem
location /media {
alias /var/www/review.unskontrollables.org/htdocs/media;
# if asset versioning is used
if ($query_string) {
expires max;
}
}
location /static {
alias /var/www/review.unskontrollables.org/htdocs/static;
}
location /errordocs {
alias /var/www/review.unskontrollables.org/htdocs/errordocs;
}
location /favicon.ico {
alias /var/www/review.unskontrollables.org/htdocs/static/rb/images/favicon.png;
}
#~ location /admin/media/ {
#~ # this changes depending on your python version
#~ root /usr/local/lib/python2.6/site-packages/django/contrib;
#~ }
location / {
#alias /var/www/review.unskontrollables.org/htdocs/reviewboard.wsgi;
#root /var/www/review.unskontrollables.org/htdocs/reviewboard.wsgi/;
#proxy_pass_request_headers on;
proxy_pass_header Server;
proxy_set_header Host $proxy_host;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_connect_timeout 10;
proxy_read_timeout 10;
proxy_pass http://127.0.0.1:8000/;
}
# Prevent the server from processing or allowing the rendering of
# certain file types.
location /media/uploaded {
types {
text/plain .html .htm .shtml .php .php3 .php4 .php5 .phps .asp .pl .py .fcgi .cgi .phtml .phtm .pht .jsp .sh .rb;
}
}
}
To launch the WSGI server, I use:
root#jotunn:~# source /opt/reviewboard/rbenv/bin/activate
(rbenv)root#jotunn:~# rb-site manage /var/www/review.unskontrollables.org/ runserver
Validating models...
0 errors found
Django version 1.4.10, using settings 'reviewboard.settings'
Development server is running at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
If I try to access
http://review.unskontrollables.org/
I'm redirected to
http://127.0.0.1:8000/r/
and the console output is:
/opt/reviewboard/rbenv/local/lib/python2.7/site-packages/Django-1.4.10-py2.7.egg/django/views/generic/list_detail.py:10: DeprecationWarning: Function-based generic views have been deprecated; use class-based views instead.
DeprecationWarning
/opt/reviewboard/rbenv/local/lib/python2.7/site-packages/Django-1.4.10-py2.7.egg/django/conf/__init__.py:75: DeprecationWarning: The ADMIN_MEDIA_PREFIX setting has been removed; use STATIC_URL instead.
"use STATIC_URL instead.", DeprecationWarning)
/opt/reviewboard/rbenv/local/lib/python2.7/site-packages/Django-1.4.10-py2.7.egg/django/views/generic/simple.py:8: DeprecationWarning: Function-based generic views have been deprecated; use class-based views instead.
DeprecationWarning
[14/Mar/2014 16:59:50] "GET / HTTP/1.0" 302 0
Does any one has an idea ?
Thanks.
EDIT: I found a solution based on the following tutorial
https://github.com/shuge/man/blob/master/sa/review/reviewboard/reviewboard-quick-install-guide.md
The missing link to the config file rb.m.com.conf point this file: https://github.com/shuge/man/blob/master/sa/review/reviewboard/rb.m.com.conf
With that data, I've just add flup (fastcgi python module) and changed my conf to the following:
server {
listen 80;
server_name review.unskontrollables.org;
root /var/www/review.unskontrollables.org/htdocs;
# Error handlers
error_page 500 502 503 504 /errordocs/500.html;
# serve directly - analogous for static/staticfiles
# Alias static media requests to filesystem
location /media {
alias /var/www/review.unskontrollables.org/htdocs/media;
# if asset versioning is used
if ($query_string) {
expires max;
}
}
location /static {
alias /var/www/review.unskontrollables.org/htdocs/static;
}
location /errordocs {
alias /var/www/review.unskontrollables.org/htdocs/errordocs;
}
location /favicon.ico {
alias /var/www/review.unskontrollables.org/htdocs/static/rb/images/favicon.png;
}
#~ location /admin/media/ {
#~ # this changes depending on your python version
#~ root /usr/local/lib/python2.6/site-packages/django/contrib;
#~ }
location / {
fastcgi_pass 127.0.0.1:9090;
fastcgi_param PATH_INFO $fastcgi_script_name;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_pass_header Authorization;
fastcgi_intercept_errors off;
}
# Prevent the server from processing or allowing the rendering of
# certain file types.
location /media/uploaded {
types {
text/plain .html .htm .shtml .php .php3 .php4 .php5 .phps .asp .pl .py .fcgi .cgi .phtml .phtm .pht .jsp .sh .rb;
}
}
}
After that nginx is restarted, everything works fine.

Categories

Resources