Thursday, September 07, 2006

web server via python

I dicided to use rpc for that. Now I have three thing:

  1. The server which is actually a python process which is running allways somewhere.
  2. The client which connect to the server and process the data given by user, the data I get from the webserver.
  3. The webserver, which starts the client's process, when user come to my site.

So I used xmlrpc for client server communication.

Server:

>>> import SimpleXMLRPCServer as S
>>> x = S.SimpleXMLRPCServer(('', 6000))
#You need to give a object of a class which will be exposed to client.
class myfunctions:
...     def add(self, a, b): return (a+b)
...
>>> obj = myfunctions()
>>> x.register_instance(obj)
#Now just keep listening:
>>> while 1: x.handle_request()
...


Client:
>>> import xmlrpclib
#Simply connect to the server:
>>> sp = xmlrpclib.ServerProxy("http://127.0.0.1:6000")
#And call the function
>>> sp.add(10,20)
Here I wasn't able to give arguments with their name, like add(a=10, b=20) :( . WHY


So now I am able to connect to the server from outside and call it's functions. But I want the data from web.
Here I need to run a web server

$ service https start

Hay how will my client will run.
Put that in /var/www/cgi-bin/
Or just make one symbolic link to your client.py from here.
$cd /var/www/cgi-bin/
$ln -s my_tool /home/monu/client.py

If you are making any html they should be available from /var/www/html
If you are making symbolic link, then you will have to make it enable from cnfiguration file of web server:
$vim /etc/httpd/conf/httpd.conf

<Directory "/var/www/cgi-bin">
    Options FollowSymLinks
</Directory>

Same for html dir also if neede.


But it's not running :(
You will have to make it executable
$ chmod 755 client.py

and tell the computer how to run it
#!/usr/bin/python

Now how will I get data from the user?

Simple:
If a user sends data from GET you will get it in environment variable called "QUERY_STRING", and if it's POST you will get as it is in stdin.
The type of method is written in env variable "REQUEST_METHOD"
Here is my client program:

req = os.environ.get("REQUEST_METHOD", '')

print "Content-Type: text/html\r\n\r\n"
#print "Req: ", req
if req.lower() == 'get':
    query_string = os.environ.get("QUERY_STRING", '')
elif req.lower() == 'post':
    query_string = sys.stdin.read()
else:
    print "I listen only GET or POST. You are talking in %s"%req
    sys.exit()
#print "query_string: ", query_string
#To parse the query string you can use cgi function
import cgi
args = cgi.parse_qs(query_string)
#it will be a dictionary with input name as key and data as list in value.
#print "Args: ", args
#print "Hi"
try:
    ##Connect to the server
    sp = xmlrpclib.ServerProxy("http://127.0.0.1:8117")
    output = sp.html_serialize(0, '/cgi-bin/GMRF', args)

    print output
except:
    print "Exception Occured :("
    print '<br>'
    print ''.join(traceback.format_exception(*(sys.exc_info())))
    print '<br>'

#print "Hello"

Little html:

I created a small form to get the data:

<form action="/cgi-bin/GMRF" method="POST">
Title: <input name="Ti" value="" type="text"/>
<br>
Description: <textarea name="De" value="" cols=30 rows=5 > </textarea>
<br>
Keywords (separated by ;): <input name="Ke" value="" type="text" />
<br>
<input name="submit" value="Go" type="submit" />
</form>


When I click the Go button, the data goes to client as POST.
Now there when I do
args = cgi.parse_qs(query_string)
I get areg as dictionary:
{'De': ["It's a description"], 'submit': ['Go'], 'Ke': ['No kw'], 'Ti': ["It's a title"]}
And I get the data back from the server.

0 Comments:

Post a Comment

<< Home