views:

214

answers:

6

Hi,

I'm trying to create site using Django framework. I looked on tutorial on Django project site but contains much information which I don't need. I have python scripts which provides output and I need to have this output on the web. My question is how simply manage Django to have link which start the script and provides its output on the web or perhaps you provide the link where I can read about this?

Thank you.

A: 

That's not how Django works. Do the tutorial, you'll save a lot of time and frustration.

Javier
I know but I'm going to create web server with a lot of information and this is just initial information and if I decided to use Django as web framework for storing forms, getting information from the database then I'm looking for the way to handle this simple things through Django as well.
yart
A: 

I have python scripts which provides output and I need to have this output on the web.

What is Django for? Use either CGI script on python (probably you already have one) or WSGI application (which is a bit harder to deploy)

Yaroslav
A: 

Django is a frame work. Just use CGI scripts.

dotty
+3  A: 

"I have python scripts which provides output and I need to have this output on the web."

That is not what Django is for. What you want to do can be achieved with something as simple as this:

from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer

class Handler(BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.send_header("Content-type", "text/html")
        self.end_headers()

        self.wfile.write("magic content goes here")

if __name__=="__main__":
    try:
        server = HTTPServer(("", 8080), Handler)
        server.serve_forever()
    except KeyboardInterrupt:
        server.socket.close()

Observe the self.wfile.write line. Whatever you write there ends up in the browser. If it matters, you can use self.path in the Handler to check which file was requested.

Tested with Python 2.6.4, accessed the server with Chrome browser.

mizipzor
+1  A: 

Everyone is right. This is the wrong way to use django. However, if you need a stop-gap measure while you convert your script to the proper idiom:

import sys
from django.http import HttpResponse

def cgi_view(request, my_module):
    __import__(my_module)
    mod = sys.modules[my_module]
    text = mod.main()

    resp = HttpResponse(text)
    # Then set your headers on resp
    return resp

I leave it as an exercise to figure out how to set the headers. Sorry for the laziness, but I gotta go get to work.

P.S. if your script is not factored to wrap all its output producing functions in a main() function, you can use subprocess to get the output instead.

jcdyer
+1  A: 

Use mod_wsgi plugin to Apache.

You can do this to see how an existing script might be transformed into a WSGI application. This is a starting point, to show how the WSGI interface works.

import sys
def myWSGIApp( environ, start_response ):
    with file( "temp", "w" ) as output:
        sys.stdout= output
        execfile( "some script.py" )
        sys.stdout= __stdout__

    status = '200 OK'
    headers = [('Content-type', 'text/plain')]

    start_response(status, headers)

    result= file( "temp", "r" )
    return result

Note that you can easily rewrite your scripts to conform to the WSGI standard, also. This is still not quite the best approach.

If you had this

if __name__ == "__main__":
    main()

You simply have to add something like this to each script.

def myWSGIApp( environ, start_response ):
    with file( "temp", "w" ) as output:
        sys.stdout= output
        main()
        sys.stdout= __stdout__

    status = '200 OK'
    headers = [('Content-type', 'text/plain')]

    start_response(status, headers)

    result= file( "temp", "r" )
    return result

Then each script is callable as a WSGI application and can be plugged into a WSGI-based framework.

The best approach is to rewrite your scripts so they do not use sys.stdout, but write to a file that's passed to them as an argument.

A test version of your server can be this simple.

from wsgiref.simple_server import make_server
httpd = make_server('', 8000, myWSGIApp)

Once you have WSGI applications for your scripts, you can create an smarter WSGI application that

  1. Parses the URL. Updates the environ with the name of the script to run.

  2. Runs your WSGI application with an appropriate environment.

Look at http://docs.python.org/library/wsgiref.html for information.

You can then configure Apache to use your WSGI server via mod_wsgi.

Look at http://code.google.com/p/modwsgi/ for details.

S.Lott
You shouldn't return a file object as iterable from a WSGI application because the WSGI stack is required to send each returned item one at a time with a flush between them to trigger immediate sending back to client. Since file iterable returns a single character at a time, you will get abysmal performance as response is sent one character at a time. Your technique of replacing sys.stdout is also not thread safe and will not work in the typical multithreaded WSGI hosting mechanisms.
Graham Dumpleton
Further \_\_stdout\_\_ is not the same as stdout under mod_wsgi as mod_wsgi replaces stdout with special file object which causes output to go via the Apache error log. By restoring \_\_stdout\_\_ you will cause a potential loss of information where stdout was used for logging outside of the context of that section of code.
Graham Dumpleton
The alternative (which is to use `subprocess.Popen` is just a tad more complex, but possibly safer.
S.Lott
Whoops, file iterable actually probably returns a line at a time. So, performance is based on content. Worst case is a lot of empty lines and akin to a single character at a time.
Graham Dumpleton