How to handle web api by flask - python

I am using Nginx+uWSGI+Flask to build up a web service API.
I follow http://flask.pocoo.org/docs/0.10/deploying/uwsgi/ as below
In Nginx, I want Flask handle all request appapi, and others handle by nginx.
ex.
http://www.example.com/appapi/query?name=123 will be handled by flask
http://www.example.com/ will be handled by nginx.
I add below configuration to let flask handle.
location = /appapi { rewrite ^ /appapi /; }
location /appapi { try_files $uri #appapi ; }
location #appapi {
include uwsgi_params;
uwsgi_param SCRIPT_NAME /appapi;
uwsgi_modifier1 30;
uwsgi_pass 127.0.0.1:3301;
}
uWSGI has listen 3301 port, and will load flask app, In Flask app code. I have defined route for appapi
#app.route('/appapi/query', methods=['GET'])
def query():
print 'query()'
But I find query function is not called, and in log. it return 404, not found.
Thanks in advance!

You can do this:
#app.route('/query', methods=['GET'])
def query():
print 'query()'
Then in the Nginx config:
location /appapi/ {
include uwsgi_params;
uwsgi_pass 127.0.0.1:3301;
}

Related

How to run wordpress on localhost and django on localhost/product?

I have developed a wordpress website for a product.And the product is made using django.So after the user logs in ,i have to redirect him to the django project.I have to achieve this on the same domain.I have nginx installed.
You can try this
www.egwordpress.com (your Wordpress)
egproduct.egwordpress.com (your Django app)
NGinx config
server {
listen 80 default_server;
server_name www.egwordpress.com;
location / {
root /path/to/your/wordpress;
index index.html;
try_files $uri $uri/ /index.html;
}
}
server {
listen 80;
server_name egproduct.egwordpress.com;
location /api/ { # your django product app
proxy_pass http://127.0.0.1:5000; # change port following your Django config
}
}

Deploying Gunicorn using subpath in NGINX

According to this tutorial, there is section below that says this.
You must now configure your web proxy to send traffic to the new Gunicorn socket. Edit your nginx.conf to include the following:
/etc/nginx/nginx.conf:
...
http {
server {
listen 8000;
server_name 127.0.0.1;
location / {
proxy_pass http://unix:/run/gunicorn/socket;
}
}
}
...
What I want to do is use location /mysubpath. How should I do it?
I'm using mysubpath since I have 2 different projects running on the same server.
Something like this.
...
http {
server {
listen 8000;
server_name 127.0.0.1;
location /mysubpath {
proxy_pass http://unix:/run/gunicorn/socket;
}
}
}
...
Usually, we do proxy_pass http://someip:someport/; but in my case, it might require a different approach. Can someone please help.

Django application with nginx and gunicorn only showing welcome page rest all pages showing 404 error

I tried to deploy a sample django application in amazon ec2 server with the help of nginx and gunicorn. I added proxy pass in nginx. After I run the server and accessing my IP I was able to view the welcome to django page. But when I navigate to some other urls, say admin its shows 404 not found error.
How to fix this error.
Nginx config:
upstream app {
server 127.0.0.1:8000;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
server_name IP;
location /static/ {
root /home/ubuntu/workspace/business;
}
location / {
proxy_pass http://app;
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
}
You need change this:
location / {
proxy_pass http://app;
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
For this:
location / {
proxy_pass http://gunicorn:8888; #use your gunicorn port
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
The problem was with the line
try_files $uri $uri/ =404;
This line is causing every url except the main url to route to 404 page.
I removed it and hence working.
Thanks to #Richard Smith for mentioning it in the comment

Nginx Configure Static Site and Django+uWSGI

I am having a bit of trouble getting Nginx to serve a static index.html page, and also to serve a a Django site. Could anyone point me out to what I'm doing wrong?
I have port 80 and 8000 open.
I have spent three days trying to get this working.
Locally I have no problems, then again I'm not using nginx for that.
I placed uwsgi_params within /etc/nginx/uwsgi_params
/etc/nginx/sites-enabled
Here are my symlinks to the actual configuration files
site1.conf -> /home/jesse/projects/site1/conf/site1.conf
site2.conf -> /home/jesse/projects/site2/conf/site2.conf
/home/jesse/projects/site1/conf/site1.conf
This is just a basic static site, but it won't load :(
server {
listen 80;
server_name www.site1.com;
rewrite ^(.*) http://site1.com$1 permanent;
location / {
root /home/jesse/projects/site1/;
}
}
/home/jesse/projects/site2/conf/site2.conf
= The manage.py/wsgy.py is located under /home/jesse/projects/site2/site2/
= This is a Django site using uWSGI, I installed it with $ pip install uwsgi.
server {
listen 80;
server_name www.site2.com;
rewrite ^(.*) http://site2com$1 permanent;
root /home/site2/projects/site2/site2;
location /static/ {
alias /home/jesse/site2/projects/site2/site2/static/;
#expires 30d;
}
location /media/ {
alias /home/jesse/site2/projects/site2/site2/media/;
#expires 30d;
}
location / {
include uwsgi_params;
uwsgi_pass 127.0.0.1:8000;
}
}
/home/site2/projects/site2/conf
[uwsgi]
projectname = site2
projectdomain = site2.com
base = /home/jesse/site2/projects/site2/site2
# Config
plugins = python
master = true
protocol = uwsgi
env = DJANGO_SETTINGS_MODULE=%(projectname).settings
pythonpath = %(base)/src/%(projectname)
module = %(projectname).wsgi
socket = 127.0.0.1:8000
logto = %(base)/logs/uwsgi.log
# Runs daemon in background
daemonize = /home/jesse/log/$(projectname).log
Nginx Restart
$ sudo service nginx restart
* Restarting nginx nginx [ OK ]
= The site1 produces a Not Found (Not a 404)
= The site2 produces a
I would appreciate any assistance :)
rewrite ^(.*) http://site1.com$1 permanent;
this in site1, is not managed by any server, because no server_name handles site.com (without www).
then again with site2
rewrite ^(.*) http://site2com$1 permanent;
first fix those lines.
the correct way in my opinion is to write a server rule that catches www. names and rewrites them to non www, and place site1.com or site2.com as server_name in the rules you have now, as an example of rewiring
server {
listen 80;
server_name www.site1.com
return 301 http://site1.com$request_uri?;
}

Nginx configuration for static sites in root directory, Flask apps in subdirectories

I'd like to have a static site in my root public_html directory, then Flask apps in their own subdirectories (e.g. public_html/foo). The static root directory functions as expected.
I have spent hours editing the nginx configuration to get the Flask apps working, but always end up back in the same place, namely that the following code always returns 'Bad Config' when I migrate to mysite/foo. I want it to return 'Hello World!'
If I alter the nginx configuration so that the server root is in public_html/foo, the Flask applications work as expected (i.e. mysite.com returns 'Hello World!'). In the following configuration, the Flask index still points to mysite.com when I believe it should point to mysite.com/foo
/etc/nginx/sites-enabled/mysite
upstream frontends {
# gunicorn
server 127.0.0.1:18000;
}
server {
listen 80;
server_name www.mysite.com;
rewrite ^/(.*) http://mysite.com$1 permanent;
}
server {
listen 80;
server_name mysite.com;
server_name_in_redirect off;
root /home/ubuntu/public_html/mysite;
access_log /home/ubuntu/logs/mysite/access.log;
error_log /home/ubuntu/logs/mysite/error.log;
location / {
index index.html;
}
location /foo {
try_files $uri #foo;
}
location #foo {
proxy_pass http://frontends;
break;
}
}
/home/ubuntu/public_html/mysite/foo/foo.py
from flask import Flask
from flask import render_template
app = Flask(__name__)
#app.route('/')
def index():
return 'Hello World!'
#app.route('/foo')
def test():
return 'Bad config'
#app.errorhandler(404)
def page_not_found(e):
return render_template('404.html'), 404
if __name__ == '__main__':
app.run()
/home/ubuntu/public_html/mysite/foo/deploy.py
workers = 2
bind = '127.0.0.1:18000'
proc_name = 'foo_gunicorn'
pidfile = 'foo.pid'
Flask is launched with gunicorn -c deploy.py foo:app
Update
Adding rewrite /foo/(.*) /$1 break; to the nginx location /foo block makes mysite/foo return 'Hello World', however all its links (such as those to the stylesheet from a template) still point to the site root (e.g. mysite/static/style.css instead of mysite/foo/static/style.css)
Got an answer from mitsuhiko (Flask lead dev):
http://flask.pocoo.org/snippets/35/
You need to define a ReverseProxied class in your Flask app and add several proxy-set-header lines to the location /foo block in the nginx config.

Categories