I registered a domain and it allows the use of CGI scripts. But I don't know how to run flask + python with the script.
https://flask.palletsprojects.com/en/1.1.x/deploying/cgi/ gives a decent description of what to do but still was unable to get flask and python to run. My python file:
from flask import Flask
app = Flask(__name__)
#app.route('/')
def index():
return '<h1>Hello World!</h1>'
Also the cgi file:
#!/usr/bin/python
from wsgiref.handlers import CGIHandler
from yourapplication import app
CGIHandler().run(app)
And the htaccess file:
DirectoryIndex Home.html
# Begin EnforceSSL double-numbersign-freelancer.com
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_HOST} ^(www.)?double-numbersign-freelancer.com$
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L]
</IfModule>
# End EnforceSSL
Okay. I checked it
Answering for my configuration → CentOS 7 / httpd 2.4.6
Open /etc/httpd/conf/httpd.conf and add python handler
# standard part
<Directory "/var/www/cgi-bin">
AllowOverride None
Options None
Require all granted
# add handler here
AddHandler cgi-script .py
</Directory>
Put run.py inside /var/www/cgi-bin
#!/usr/bin/python3
from wsgiref.handlers import CGIHandler
from flask import Flask
app = Flask(__name__)
#app.route('/')
def index():
return '<h1>Hello World!</h1>'
#app.route('/suburl')
def index2():
return '<h1>Hello World 2!</h1>'
CGIHandler().run(app)
Change script permissions to allow execution:
chmod +x /var/www/cgi-bin/run.py
Now you can access:
http://your_server_url.com/cgi-bin/run.py → Hello World!
http://your_server_url.com/cgi-bin/run.py/suburl → Hello World 2!
Huh. That was my first experience with Flask CGI. Pretty simple and good for small or test projects.
Anyway I recommend to use gunicorn, uwsgi or mod_wsgi for apache in production.
EDIT1: Using CGI without flask
Actually you don't need flask for run CGI scripts. It can be written with any language that can read environment variables and output some data.
Bash example /var/www/cgi-bin/run.cgi:
#!/usr/bin/bash
echo "Content-type:text/plain"
echo
echo -e "HELLO WORLD\nYour URL path is $PATH_INFO"
Output will be:
http://example.com/cgi-bin/run.cgi/suburl
HELLO WORLD
Your URL path is /suburl
Related
I'm working with a shared hosting account which uses apache 2.4 , trying to deploy a flask app using http://fgimian.github.io/blog/2014/02/14/serving-a-python-flask-website-on-hostmonster . I've put the code and the fcgi script in public_html folder The contents of the folder are in the screenshot above:
The manage_apache.fcgi script is:
#!/home/username/anaconda2/bin/python
import sys,os
from flup.server.fcgi import WSGIServer
sys.path.insert(0, '/home/username/public_html')
from myflaskapp.settings import Config, SharedConfig
from myflaskapp.app import create_app
if __name__ == '__main__':
app = create_app(SharedConfig)
WSGIServer(app).run()
I've gotten to the last step and while testing it at the command line using putty to SSH in:
[~/public_html]# ./manage_apache.fcgi
I can see the correct web page being generated, so I assume that fast cgi is supported by my host. I'm not getting any python errors.
The .htaccess file out of the article is :
AddHandler fcgid-script .fcgi
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ manage_apache.fcgi/$1 [QSA,L]
In the browser when I surf to mysite.org I am getting
Not Found
The requested URL /manage_apache.fcgi/ was not found on this server.
Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.
according to support The .htaccess file is redirecting to manage_apache.fcgi/$1
-rwxr-xr-x 1 myusername myusername Nov 22 17:26 manage_apache.fcgi*
How can I fix this?
I suspect
sys.path.insert(0, '/home/username/public_html')
is an absolute path, but flask application is looking to a relative path respect to flask gateway, and cannot find it.
Have you tried to wrap the libraries in the app instance - move the absolute path in the app instance?
As an example, see http://werkzeug.pocoo.org/:
from werkzeug.wrappers import Request, Response
#Request.application
def application(request):
return Response('Hello World!')
if __name__ == '__main__':
from werkzeug.serving import run_simple
# move absolute path here
run_simple('localhost', 4000, application)
I suspect that fcgi is not supported on that host. Just because a host lets you run a Python script on the command line does not mean that they have configured mod_fcgi in Apache.
Try this: apachectl -t -D DUMP_MODULES | grep cgi. You should see fcgi_module or fastcgi_module, or possibly a cgi_module.
If you only see a cgi_module, then you should be able to use AddHandler cgi-script .py instead of AddHandler fcgid-script .fcgi.
If you see none of those, then you can try wsgi: apachectl -t -D DUMP_MODULES | grep wsgi. If you see wsgi_module, then you know you can use wsgi. At that point, you might be able to follow instructions here under .htaccess.
I cannot for the life of me figure of why this flask application I'm trying to launch is not working. I am running it on a $5 Digital Ocean droplet. Here's (hopefully) everything you need to know about it:
Directory layout (contained within /var/www/):
FlaskApp
FlaskApp
__init__.py
static
templates
venv
flaskapp.wsgi
__init__.py:
from flask import Flask
app = Flask(__name__)
#app.route("/")
def hello():
return "yay it worked"
if __name__ == "__main__":
app.run()
flaskapp.wsgi:
#!/usr/bin/python
import sys
import logging
logging.basicConfig(stream=sys.stderr)
sys.path.insert(0,"/var/www/FlaskApp/")
from FlaskApp import app as application
application.secret_key = 'Add your secret key'
FlaskApp.conf (contained in /etc/apache2/sites-availble):
<VirtualHost *:80>
ServerName the.ip.blah.blah
ServerAdmin admin#mywebsite.com
WSGIScriptAlias / /var/www/FlaskApp/flaskapp.wsgi
<Directory /var/www/FlaskApp/FlaskApp/>
Order allow,deny
Allow from all
</Directory>
Alias /static /var/www/FlaskApp/FlaskApp/static
<Directory /var/www/FlaskApp/FlaskApp/static/>
Order allow,deny
Allow from all
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
venv was created from calling virtualenv venv within /var/www/FlaskApp/FlaskApp/. I installed flask in venv using pip install flask after entering venv using source venv/bin/activate.
Wsgi has been enabled (a2enmod wsgi). FlaskApp.conf was enabled (a2ensite FlaskApp). And, finally, I restarted apache many times, but to no success (service apache2 restart).
I was following this guide on how to set up a flask application.
Here is a screenshot of what my error looks like:
Any help on getting this to work would be greatly appreciated.
Thanks in advance.
EDIT: I found the problem: ImportError: No module named flask. This is a little strange since I did do pip install flask within the virtualenv. When I just open a python console session in the virtualenv and try import flask I get no error, so not sure what's going on.
Also, how is this application even using venv? I don't see it getting accessed anywhere so how is it even using it? Perhaps this is why i'm getting the ImportError, because I only have flask installed on the virtualenv but it's not being used?
The problem is essentially that you are installing Flask, and possibly other required libraries, in a virtual environment but the python (wsgi interface) is running with the system python which does not have these extra libraries installed.
I have very little recent experience running Python on Apache (I come from an era of mod_python and cgi), but apparently one way to handle this is to use the site package to add the site-packages from your venv to the Python that is executed. This would go in your .wsgi file.
import site
site.addsitedir('/path/to/your/venv/lib/pythonX.X/site-packages')
I think the best way to solve your problem is to add tell your wsgi file about your virtual environment and activate it:
put the following code in your your flaskapp.wsgi
activate_this = '/path/to/env/bin/activate_this.py'
execfile(activate_this, dict(__file__=activate_this))
and restart apache.
hope it will help!
find more here
I'm having trouble deploying my REST API and keep getting a 500 Internal Server Error. I've gone through several possible solutions and guides to fix this problem, including those below:
http://flask.pocoo.org/docs/0.10/deploying/cgi/
Deploy flask application on 1&1 shared hosting (with CGI)
and was following this guide:
http://blog.miguelgrinberg.com/post/designing-a-restful-api-with-python-and-flask
Here is my code:
restapplication.py
#!/home/myusername/public_html/todo-api/flask/bin/python
from flask import Flask
app = Flask(__name__)
#app.route('/')
def index():
return "Hello, World!"
run.cgi
#!/home/myusername/public_html/todo-api/flask/bin/python
import cgitb; cgitb.enable()
from wsgiref.handlers import CGIHandler
from restapplication import app
CGIHandler().run(app)
.htaccess (stored at /home/myusername/public_html/)
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /home/myusername/public_html/todo-api/flask/run.cgi/$1 [L]
I appreciate all the help I can get.
Not sure if you got the solution, but for records-
if you have your virtual environment set, then you will have to add these lines in your restapplication.py to point to the site-packages, so that your code can access Flask library.
import os
import sys
sys.path.insert(0, '/home/username/public_html/cgi-bin/myenv/lib/python2.6/site-packages')
Rest everything looks okay.
Maybe you can check the file permissions of the .cgi file and .py file. The file permissions should be 755.
refer : http://www.comfycoder.com/home/how_to_deploy_a_flask_app_in_apache_shared_hosting
I have an Apache (ver. 2.2.15) server (running on Linux CentOS), where I have a lot of .cgi scripts located in /var/www/cgi-bin, aliased:
ScriptAlias /cgi-bin "/var/www/cgi-bin"
And it works fine when I enter mydomain/cgi-bin/something.cgi.
Now I want to have also Flask application running within Apache server on 80 port. The app is located in /var/www/cgi-bin/app. So, I created simple Flask app - a.py:
from flask import Flask
app = Flask(__name__)
#app.route('/')
def hello_world():
return 'Hello World!'
and a.wsgi file:
import sys
import site
sys.path.insert(0, '/var/www/cgi-bin/app')
site.addsitedir('/var/www/cgi-bin/app:/<my_python_path>/Lib/site-packages')
from app import app as application
Also in /etc/httpd/conf/httpd.conf I have created required virtualhost:
<VirtualHost *:80>
ServerName app.<mydomain>:80
WSGIDaemonProcess app python-path=/var/www/cgi-bin/app:/<my_python_path>/Lib/site-packages user=user1 group=user1 threads=5
WSGIScriptAlias /cgi-bin/app /var/www/cgi-bin/app/a.wsgi
<Directory /var/www/cgi-bin/app>
WSGIProcessGroup app
WSGIApplicationGroup %{GLOBAL}
Order deny,allow
Allow from all
</Directory>
ErrorLog /var/www/cgi-bin/app/logs/error.log
CustomLog /var/www/cgi-bin/app/logs/custom.log combined
</VirtualHost>
But everytime I try to open mydomain/cgi-bin/app/ in the error.log file I see this error:
(...) attempt to invoke directory as script: /var/www/cgi-bin/app/
Do you have an idea what have I done wrong here?
You should not put your Flask app under cgi-bin, in fact it should not be under the DocumentRoot at all. Move it somewhere else entirely - I like /srv/, but it's up to you - and change the WSGI alias appropriately.
I am new on django. I tried this but I can't deploy. How can I do
#!/usr/bin/python
import sys
import os
base = os.path.dirname(os.path.abspath(__file__)) + '/..'
sys.path.append(base)
os.environ['DJANGO_SETTINGS_MODULE'] = 'myfirstapp.settings'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
AddHandler fcgid-script .fcgi
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteRule ^(media/.*)$ - [L]
RewriteRule ^(adminmedia/.*)$ - [L]
RewriteCond %{REQUEST_URI} !(cgi-bin/myproject.fcgi)
RewriteRule ^(.*)$ mysite.fcgi/$1 [L]
Here's the alwaysdata wiki entry for setting up Django with fastcgi. Only down-side: it's written in French.
Well, I don't speak French, but what it basically says is:
Create a directory named public in the folder of your django project.
In that directory create the file django.fcgi with the following content:
#!/usr/bin/python
import os, sys
_PROJECT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, _PROJECT_DIR)
sys.path.insert(0, os.path.dirname(_PROJECT_DIR))
_PROJECT_NAME = _PROJECT_DIR.split('/')[-1]
os.environ['DJANGO_SETTINGS_MODULE'] = "%s.settings" % _PROJECT_NAME
from django.core.servers.fastcgi import runfastcgi
runfastcgi(method="threaded", daemonize="false")
Next, create a .htaccess in the public folder with the following content:
AddHandler fcgid-script .fcgi
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ django.fcgi/$1 [QSA,L]
If you're planning to include the django admin interface, create this symbolic link in your public directory:
ln -s /usr/local/alwaysdata/python/django/1.1/django/contrib/admin/media/ media
In the end your folder tree hierarchy should somehow look like this:
myproject/
__init__.py
manage.py
public/
django.fcgi
.htaccess
media/
settings.py
urls.py
myapp/
views.py
models.py
Hope this helps. I talked with the admin, and he said he will soon provide an English wiki. Let's hope this is going to happen anytime soon.
UPDATE: There is an English wiki article now.
You are trying to mix two different web server integration methods: fcgi (fast cgi) and wsgi.
Your first snippet is for a wsgi interface with the web server and is the recommended method for integrating Django with Apache. Very good resources (including examples) to help you set this up correctly can be found in the official Django docs How to use Django with Apache and mod_wsgi and the mod_wsgi docs Integration with Django
The second snippet (with AddHandler line) is for fcgi. This is the kind of interface that is more typically used to interface Django with the lighttpd and nginx web servers. Resources for setting up fcgi interface can be found in official Django docs How to use Django with FastCGI, SCGI, or AJP.
Since it looks like alwaysdata.com only uses FastCGI (fcgi) interface you are stuck with this method. It looks like there are examples on their wiki page Déployer une application Django and particulary you'll need to replace your first (wsgi) snippet with this:
#!/usr/bin/python
import os, sys
_PROJECT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, _PROJECT_DIR)
sys.path.insert(0, os.path.dirname(_PROJECT_DIR))
_PROJECT_NAME = _PROJECT_DIR.split('/')[-1]
os.environ['DJANGO_SETTINGS_MODULE'] = "%s.settings" % _PROJECT_NAME
from django.core.servers.fastcgi import runfastcgi
runfastcgi(method="threaded", daemonize="false")
We got now (since a couple of months) an article in english:
Django on alwaysdata.com
Regards,