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;
Related
I'm new to python and have been put on a task of building out a spreadsheet parser. I've created a python script that reads an xlsx file and parses the data. I have an Nginx server set up that this will be hosted on. I need this script to be an API endpoint so I can pass the parsed data back as JSON. I have been reading about WSGI for production server and have tried to follow the route of building that out. I am able to serve a path on the server and have it output the wsgi python script. The script has the following:
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]
I'm a little confused as to how to receive a request and send back json with my excel parser class? Thanks and I hope I'm being clear. I do have a flask server that works, but I do not know how to have it constantly running to serve my endpoint:
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')
You don't want to use raw WSGI for this.
Use a package such as FastAPI (or Flask) to make everything easier for you.
For instance, using FastAPI, an app with an endpoint to receive a binary (Excel) file and return a JSON response is approximately
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}
See:
To get going: https://fastapi.tiangolo.com/tutorial/
To process files: https://fastapi.tiangolo.com/tutorial/request-files/
To deploy your service (behind Nginx): https://fastapi.tiangolo.com/deployment/
I use python/flask for development & gunicorn for production.
To get it to accept HTTP requests, I use function decorators. Its the most common way.
#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)
So here, the url /epp/api/v1.0/request accepts POSTed JSON and returns JSON
When you run flask in dev mode it listens on 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
These are both python/flask projects of mine. Feel free to copy. They each run multiple instances of the python code in a single container load-balanced by nginx - pretty neat combination.
UPDATE
I got things working throug NGinx, flask, and GUnicorn. However, my flask app is only working when I go to '/'. If I go to a route such as /parser/de/v1 I get a 404 Not Found.
Here is my setup for 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;
#}
my nginx.conf looks slightly different, partly becuase I am running multiple WSGI instances, then getting nginx to load-balance over them
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;
}
}
}
But with this, all the URLs are passed to the python/wsgi
i'm building web server with django and nginx, uwsgi.
I'm using macbook pro mid 14 , mojave
when i input port number, django works.
but without port number, it won't work.
i don't know what is wrong with my code.
uwsgi --http-socket 0.0.0.0:8091 --wsgi-file test.py
if i use this line, it works.
but
uwsgi --socket projectname.sock --wsgi-file test.py
like this, it won't work. i'm trying to solve this error couple times.
but it won't work
this is projectname_nginx.conf
upstream django {
#server 127.0.0.1:8001;
server unix:/Users/myname/Desktop/projectnae/name/projectname.sock;
}
server {
listen 8999;
server_name localhost;
charset utf-8;
client_max_body_size 75M;
location /media {
alias /Users/myname/Desktop/projectnae/name/media;
}
location /static {
alias //Users/myname/Desktop/projectnae/name/static
}
location / {
uwsgi_pass django;
include /Users/myname/Desktop/projectname/fido/uwsgi_params;
}
}
and this is projectname_uwsgi.ini
[uwsgi]
chdir = /Users/myname/Desktop/projectname/name/
module = projectname.wsgi
home = /Users/junbeomkwak/Desktop/venv/
master = true
process = 10
socket = /Users/myname/Desktop/projectnae/name/projectname.sock;
vacuum = true
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
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 ^_^
I don't know exactly what I am doing but I am experimenting with running Flask on nginx. I am boiling it down to the simple bit of code below. First I have a test app in Flask like this:
from flask import Flask, render_template
app = Flask(__name__, static_folder='client', template_folder='client/html')
def show_home_page():
return render_template("home.html")
#app.route('/')
def server():
return show_home_page()
if __name__ == '__main__':
app.run(threaded=True)
If I run python app.py I can go to http://localhost:5000 and see the "Hello World". Next I read that I need to run uwsgi but its not clear what params I need to pass to it. I tried different things like:
uwsgi -s /tmp/app.sock --manage-script-name --mount ./=app:app
I also noted that I need to set my nginx conf file to match, but I am stuck on that as well (I just get a welcome from nginx on port 5000) and it doesnt seem to link with my Flask app. I googled around a bit but nothing has clicked yet.
server {
listen 5000;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
You can use refer this for Flask with Nginx and uWSGI:
Python flask with Nginx and uWSGI