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.
Related
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.
Is it possible to run a daphne process or even just Django channels from a python script?
The recommended way to do it, is to run
daphne -b 0.0.0.0 -p 8001 django_project.asgi:channel_layer
I was wondering if I could bind that to a variable and run it the way Tornado could
from tornado.web import Application
application = Application([(r"/", RosbridgeWebSocket), (r"", RosbridgeWebSocket)])
This is kind of a work around, but you may use the subprocess module like this:
subprocess.run(["daphne", "-b 0.0.0.0 -p 8001 django_project.asgi:channel_layer"])
Check this thread Calling an external command in Python for more info on the use of subprocess module.
I am not familiar with Django Channels but have you tried using inmemory or redis Channels directly? You might be able to avoid daphne altogether. From what I understand, daphne seems to be the protocol translator layer so outside clients can communicate with Django through daphne (Django uses wsgi rather than asgi so Django alone cannot handle certain protocols, such as, websocket communication). Tornado does not rely on wsgi.
There are examples in daphne tests:
https://github.com/django/daphne/blob/master/daphne/tests/test_http.py
The inmemory ChannelLayer is not cross-process. I'm not sure if that even matters in your use case. If it does, you can check the other backends (such as redis channels) https://channels.readthedocs.io/en/stable/backends.html
This might be more directly what you are looking for:
https://github.com/django/asgi_redis
have you tried it swap the tornado to NGINX ?
http://masnun.rocks/2016/11/02/deploying-django-channels-using-daphne/
I ran into this same issue...
from daphne.cli import CommandLineInterface
CommandLineInterface().run(('my.asgi', '--bind', ip_address, '--port', '8000'))
Should do the trick. The trouble is that I don't see this documented anywhere and so the API may not be very stable.
This is the same code route as calling Daphne through subprocess:
https://github.com/django/daphne/blob/main/daphne/cli.py#L167
https://github.com/django/daphne/blob/main/daphne/cli.py#L204
Currently I'm developing web services in python using web.py, that serves different functions. Something like
BigQueryService.py
LogicImplementer.py
PostgreService.py
Each service works perfectly when running on the local machine. After deploying on the server, due to I'm refering an other python script, it returns a module error.
Since we have to run all the services on the same port, I pasted all the scripts into a single file named Engine and made it to work using the command
$ nohup python Engine.py 8080 &
Is there any better way to structure the service in web.py? Or is there a way to run all the individual scripts on the same port?
If each service creates its own listener/server socket on the port, then the answer is no. You will need to use the equivalent of an app server that has a single server port and distributes the incoming request to the relevant app (running on the server) based typically on the relative path - so e.g. http://myserver.net:8080/bqs paths get passed to your BiqQueryService, /li to LinkImplementor, /pgs to PostgreService. Flask will do something like this, I'm sure other web service frameworks will too. The server will handle all the communication stuff, pass requests to the app (e.g. bqs) and handle sending response to the client.
I have a long-running Python program on a server that already listens for messages on one serial port and forwards them out another serial port.
What do I need to do to allow that program to accept data from a web server (that ultimately gets that data from a web browser on a laptop)?
The options I've seen so far are:
flask()
The solution at "
Communicating with python program running on server " server
doesn't seem to work for me, because
(I may be doing this wrong)
the long-running Python program can't seem to grab port 80,
I guess because the web server is already running on port 80 (serving other pages).
Have a CGI script that writes the data to the file, and the long-running script reads the data from that file. I'm a little reluctant to do this on a system where flash wear-out may be a concern.
Somehow (?) convert the long-running script
to a FastCGI script that includes everything it used to do plus new stuff to accept data from the web server.
Somehow (?) convert the long-running script
to a WSGI script that includes everything it used to do plus new stuff to accept data from the web server.
Write a brief web script that the web server starts up, that communicates with a long-running script using asynchat / asyncore / sockets / twisted , which seem designed for communication between two different computers, and so seems like overkill when talking between a long-running Python script and a web server (perhaps with a short-time CGI script or FastCGI script between them) running on the same server.
Perhaps some other option?
Is there a standard "pythonic" way for a web server to hand off data to a Python program that is already up and running? (Rather than the much more common case of a web server starting a Python program and hand off data to that freshly-started program).
(Details that I suspect aren't relevant: my server runs Lighttpd on Ubuntu Linux running on a Beaglebone Black).
(Perhaps this question should be moved to https://softwareengineering.stackexchange.com/ ?)
You could setup your python process to use any other port (f.e. 8091). Than configure your webserver to forward certain (or all) requests to that port using proxypas. Example for Apache:
<VirtualHost yourdomain.for.python.thread>
ServerName localhost
ServerAdmin webmaster#example.com
ProxyRequests off
ProxyPass * http://127.0.0.1:8091
</VirtualHost>
I've done this before for quickly getting a Django server in development mode to show pages via a webserver. If you actually want to serve html content, this is not the most efficient way to go.
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.