Switch between FCGI and CGI with Python and Flup - python

I'm currently moving all my Python CGI scripts to WSGI standard using Flup (http://trac.saddi.com/flup), I created a dispatch.fcgi file calling and using Flup as described in the documentation:
from flup.server.fcgi import WSGIServer
...
and works like a charm, the problem comes when I try to switch to CGI to debug something in non-cached mode, avoiding to kill processes or touch files, this should be as simple as replace the Flup server to import:
from flup.server.cgi import WSGIServer
...
but then the browser returns me a 500 error, I checked the headers and html executing through SSH and seems to be ok, then I figured should be some server misconfiguration (Dreamhost shared) and I discover the server is not able to execute Python scripts with .fcgi extension, so I found a workaround adding this to .htaccess file:
AddHandler cgi-script .fcgi
then the CGI mode almost works (wsgi.input is always empty, even reading it in a proper way passing the length) but FCGI caching doesn't works at all, starting a lot of processes. At this moment I'm totally deadlocked, I just want a simple way to switch from FCGI to CGI, is this method valid? or I'm missing something?
Thanks a lot.

FCGI protocol is different from CGI. That's why the simple change from FCGI to CGI didn't work and the FCGI would not work when changing the Apache .fcgi file handler to CGI handler.

Related

Running a Python script that creates a webpage on a server

I have a Python script that creates a web page displaying some text at localhost port 8080. I have access to a server, and would the script to run there so that it is always running and available anywhere.
I am using the bottle, requests and json libraries.
This is the last line of code in the script that is executed to locally create a web page:
run(host='localhost', port=8080, debug=True)
How would I change this to run on a server? I also have WinSCP and PuTTy to add the script to the public_html directory of the server and I can change permissions. Sorry, I am a novice in this subject.
Thanks for any help!
That depends on the Apache httpd configuration. But, assuming most defaults were left in place and Apache httpd serves index.html, you can just create your webpage (which you tested locally on port 8080) and overwrite that file. But, this only works well if you have a static page and no logic in your Python code. If you want to combine the power of Apache httpd and Python (have the former call the latter) you'll have to use mod_wsgi.
Seeing as you're novice in this subject, I suggest starting off with a simple Apache httpd server according to their quickstart. Then, once you have a few successful requsets under your belt, add mod_wsgi.

How to handle Python files with Apache

So I want to get into React Native development and have decided Python to be my backend, but for some reason I cannot configure the Apache correctly. The only way to successfully get the result from the request is to include path to python.exe at the start of the document like so:
!C:\Users\Name\PycharmProjects\AppName\venv\Scripts\python.exe
But the problem is that the file is than executed by the Python console, and if I want to access it via mobile phone I get this error:
The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there was an error in a CGI script.
So my question is:
Is there any way in which I can configure Apache to execute a file, without the requirement of the py console, so the request might be handled by devices, which doesn't have a Python console installed?
if you connect from mobile device to http://192.168.1.3/HelloWorld.py on server with CGI then code should be executed on server, not on mobile device. If CGI doesn't work then server may try to send code as normal file and then mobile mdevice ay try to run it locally but it is wrong - CGI server should run code on server.
At start I would put code in subfolder cgi-bin to run it as http://192.168.1.3/cgi-bin/HelloWorld.py because most CGI servers as default run code only in this subfolder.
On Linux script would need shebang
#!/usr/bin/env python
in first line and it should be executable
chmod a+x script.py
CGI has also some rules how to generate data which it will send to client. It may need at start extra information for HTTP protocol - and using only print("Hello World") may generate wrong data and it may have problem to send it. You should have it in any tutorial for CGI scripts. See module cgi
To run Python's code Apache needs module mod_cgi, mod_fcgi or mod_python
mod_cgi and mod_fcgi can run scripts in different languages: Python, Perl, Ruby, etc. and even Bash, PHP or C/C++/Java
Python3 has standard module http which can be used also as simple server
python3 -m http.server --cgi
and it will serve all files in folder in which you run it. And it runs files from subfolder cgi-bin/ - see doc: http

Configure apache to run python (cgi)

i've wampserver with apache 2.4.4 installed in
I've installed python and i created a test file :
#!/Python34/python
print "Content-type: text/html"
print
print "<html><head>"
print ""
print "</head><body>"
print "Hello."
print "</body></html>"
i wanna know how to run this script ?
I personally don't like the way CGI and all this stuff work (slow to spawn processes, need to use some kind of tricks like "fastcgi" to bypass this, etc...)
I think you may build your Python programm as an HTTP server (Use cherrypy for example, or whatever you want.), start your Python program to listen on localhost:whatever, then, from the Apache side, just configure a proxy to localhost:whatever.
Pros:
No need for apache to fork a Python process each requests (An expensive operation)
You'll change your web server easily (like switch to Nginx) as nginx also support proxying.
You'll be able to start multiple Python servers and load balance between them
You'll be able to host your python servers on different host to load balance charge
You'll be able to completly bypass Apache if you put a Varnish in front of your app to cache results.
Cherrypy can automatically reload files if they are changed, no need to restart apache.
You'll stick to HTTP, no need to use protocols like fastcgi.
Easy to test on your dev machine without Apache, just point your browser to your localhost:whatever
Configuring apache 2 to pass your requests to your python daemon is as easy as:
<VirtualHost *:80>
ServerName example.com
ProxyPass / http://localhost:8080/
</VirtualHost>
And an hello world from the cherrypy documentation:
import cherrypy
class HelloWorld(object):
def index(self):
return "Hello World!"
index.exposed = True
cherrypy.quickstart(HelloWorld())
+1 to what Julien Palard says about not using CGI, it's really slow and inefficient. An alternative to running your server standalone and proxying through to it using Apache is to use mod_wsgi, which allows you to run Python processes inside the Apache process. Most web frameworks (Django, Bottle, Flask, CherryPy, web2py, etc) work well with it.

mod_wsgi: Global statements execute only when the file is modified

I'm using python over mod_wsgi and I have some statements (debug messages and other things) in the global part of the script (outside the application function).
Those global statements are executed only once just after the .py file is modified (touched). If I update the webpage again those statement are not executed until the next time I edit/touch the .py file.
I guess the reason is a caching mechanism at some level (python level? wsgi level?).
Is there something I can configure or anything so that the statement in the global part of the script are always executed?
Read the mod_wsgi documentation on source code reloading.
http://code.google.com/p/modwsgi/wiki/ReloadingSourceCode
In short, use daemon mode not embedded mode and touch the WSGI script file after any changes to any code and it will force a reloaded of the daemon process.
I found a solution:
MaxRequestsPerChild 1
Setting apache to process only one request per child before killing it, forces to reload the source code every time.
I don't know if this is the best way, but at least works for now.

MOD_WSGI difficulties on Mac OS X Snow Leopard

I've been trying to get MOD_WSGI working on Apache via XAMPP on my Mac OS X Snow Leopard all day today without any success. I've followed all the instructions, searched the internet for solutions, etc but no luck so far. Below are my exact steps and details. When I run localhost all I get is a white screen. When I remove "LoadModule wsgi_module modules/mod_wsgi.so" from httpd.conf localhost runs as expected.
Downloaded and installed Xcode.
XAMPP is already installed and working.
I Don't need to install Python as OS X already has Python 2.6 in 64-bit mode.
Download and unpack mod_wsgi-2.6.tar.gz to desktop.
Terminal "./configure --with-apxs=/Applications/XAMPP/xamppfiles/bin/apxs --with-python=/System/Library/Frameworks/Python.framework/Versions/2.6/bin/python2.6" (no errors)
Terminal "make" (message "make: Nothing to be done for `all'.")
Terminal "sudo make install" (no errors)
Add to XAMPP's httpd.conf file:
LoadModule wsgi_module modules/mod_wsgi.so
AddType text/html .py
WSGIScriptAlias /app-sample "/Applications/xampp/xamppfiles/htdocs/app-sample/main.py"
<Directory "/Applications/xampp/xamppfiles/htdocs/app-sample">
Order deny,allow
Allow from all
</Directory>
Restart Apache via XAMPP
First off, run 'make distclean' and then redo configure/make/make install for mod_wsgi. Where you have 'Terminal "make" (message "make: Nothing to be done for `all'.")' indicates there were prior build results in directory and nothing got built for that execution of make.
Next, use '.wsgi' extension instead of '.py' to ensure that you don't have a conflict with an existing definition saying that '.py' files should be executed as CGI scripts. This is one common reason for blank responses. The Apache error logs should give you clues as to this being the problem.
Also, what does your sample application do? Have you tried with a simple hello world program as per the documentation on the mod_wsgi site rather than jump to using your own program. If using your own program only, then you may possibly be causing Apache processes to crash due to some shared library conflict between Apache and Python modules being used, something else that will cause blank responses. Again, carefully check the Apache error logs for information logged at time request is made.
Finally your program could just be buggy and have bad syntax in returned HTML response causing it to not be displayed. Ask the browser to show the source for the page returned by the request and make sure it isn't malformed HTML.

Categories

Resources