Python Web Programming
Obtained from:
http://www.object-craft.com.au/projects/albatross/download.html
Installed via:
tar xzvf albatross-1.40.tar.gz cd albatross-1.40 su python setup.py install
Program 1
A first program is installed thusly:
cd albatross-1.40 cd samples/templates/simple2 su python install.pyThis puts two files in the /var/www/cgi-bin/alsamp/simple2 directory.
simple.html
<html> <head> <title>My CGI application</title> </head> <body> Hello from my second simple CGI application! </body> </html>simple.py
#!/usr/bin/python
from albatross import SimpleContext
# Specifies the directory - in this case ".", or the present working directory - from
# which the template file(s) will be loaded.
ctx = SimpleContext('.')
# Specifies the specific template file (simple.html) to be loaded.
templ = ctx.load_template('simple.html')
# Execute the template.
templ.to_html(ctx)
# Output the HTTP headers.
print 'Content-Type: text/html'
print
ctx.flush_content()
This can be accessed at:
http://csanady.tamu.edu/cgi-bin/alsamp/simple2/simple.py
Program 2
A second program that introduces using application data into Albatross is:
cd samples/templates/simple3 su python install.py
The template file simple.py is:
<html>
<head>
<title>The CGI environment</title>
</head>
<body>
<table>
# The <al-for> tag iterates over the list of environment variable
# names in the keys value from ctx.local.keys. The iter value name
# specifies the name of the iterator used to retrieve values.
<al-for iter="name" expr="keys">
<tr>
# The content enclosed by <al-for> is evaluated for each value in
# the sequence returned by evaluating the "expr" attribute. The <al-value> tag
# retrieves values from the execution context. The "expr" attribute can contain any
# Python expression that can legally passed to the eval() function.
<td><al-value expr="name.value()"></td>
<td><al-value expr="environ[name.value()]"></td>
<tr>
</al-for>
</table>
</body>
</html>
|
and the CGI program is:
#!/usr/bin/python
import os
from albatross import SimpleContext
ctx = SimpleContext('.')
templ = ctx.load_template('simple.html')
# Constructs a list of all defined environment variables os.environ and
# and places it in the keys variable.
keys = os.environ.keys()
# Sorts the keys variable.
keys.sort()
# The Albatross execution context (ctx) is constructed with an empty object (locals)
# that is used as a conduit between the application and the toolkit. It is used as
# local namespace for expressions evaluated in template files. We make the environment
# available to the template file by assigning names that can be referenced by
# the template file (keys, environ).
ctx.locals.keys = keys
ctx.locals.environ = os.environ
templ.to_html(ctx)
print 'Content-Type: text/html'
print
ctx.flush_content()
|
The Python environment variables are os.environ. A brief Python sessions demonstrates:
import os
os.environ
{'TERM_PROGRAM_VERSION': '240.2', 'LOGNAME': ... COMMAND_MODE': 'unix2003'}
keys = os.environ.keys
keys
['TERM_PROGRAM_VERSION', 'LOGNAME', ... , 'COMMAND_MODE']
This example can be accessed at:
http://csanady.tamu.edu/cgi-bin/alsamp/simple3/simple.py
and returns the following:
DOCUMENT_ROOT /var/www/html GATEWAY_INTERFACE CGI/1.1 HTTP_ACCEPT text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 ... SERVER_SIGNATURE Apache/2.0.52 (Fedora) Server at csanady.tamu.edu Port 80 SERVER_SOFTWARE Apache/2.0.52 (Fedora)
We can simplify the above example - as well as separating the presentation logic from the application - using the flexibility of the "expr" attribute. We rewrite the CGI program as:
#!/usr/bin/python
import os
from albatross import SimpleContext
ctx = SimpleContext('.')
templ = ctx.load_template('simple.html')
ctx.locals.environ = os.environ
templ.to_html(ctx)
print 'Content-Type: text/html'
print
ctx.flush_content()
|
and rewrite the template file as:
<html>
<head>
<title>The CGI environment</title>
</head>
<body>
<table>
<al-exec expr="keys = environ.keys(); keys.sort()">
<al-for iter="name" expr="keys">
<tr>
<td><al-value expr="name.value()"></td>
<td><al-value expr="environ[name.value()]"></td>
<tr>
</al-for>
</table>
</body>
</html>
|
In this example only the environ variable is passed from the application to the toolkit.
Program 3 - Introducing Forms In the forms example we learn how to create and store data input from forms.
The CGI program form.py is:
#!/usr/bin/python
import cgi
from albatross import SimpleContext
ctx = SimpleContext('.')
# The variables chosen in the forms are saved in and accessed via the FieldStorage class from
# the CGI module. The FieldStorage object behaves like a dictionary that is indexed by
# field name.
ctx.locals.form = cgi.FieldStorage()
templ = ctx.load_template('form.html')
templ.to_html(ctx)
print 'Content-Type: text/html'
print
ctx.flush_content()
|
and the template file form.html presents an input form to obtain values and displays the values when they are submitted.
<html> <head> <title>Display Form Input</title> </head> <body> Input some values to the following form and press the submit button. <form method="post" action="form.py"> Text field: <input name="text"><br> Singleton checkbox: <input type="checkbox" name="singleton"><br> Checkbox group: <input type="checkbox" name="group" value="check1"> <input type="checkbox" name="group" value="check2"><br> Radio buttons: <input type="radio" name="radio" value="radio1"> <input type="radio" name="radio" value="radio2"><br> Option menu: <select name="select"><option>option1<option>option2<option>option3</select> <input type="submit" value="submit"> </form> <al-include name="form-display.html"> </body> </html> |
The form-display.html file contains the logic for displaying the values chosen via form.html.
<al-for iter="f" expr="form.keys()"> <al-exec expr="field = form[f.value()]"> <al-if expr="type(field) is type([])"> Field <al-value expr="f.value()"> is list: <al-for iter="e" expr="field"> <al-exec expr="elem = e.value()"> <al-if expr="e.index() > 0">, </al-if> <al-value expr="elem.value"> </al-for> <al-else> Field <al-value expr="f.value()"> has a single value: <al-value expr="field.value"> </al-if> <br> </al-for> |
Sending Non-HTML Content
From http://www.object-craft.com.au/projects/albatross/wiki/Sending_non-HTML_content:
This example sends the file named in ctx.locals.filename to the browser, but the content could be a dynamically generated PDF file.
import mimetypes
def page_display(ctx):
# Decide which file to send back
filename = ctx.locals.filename
# Read the file's content (ignores errors for brevity)
data = file(filename).read()
# Find the MIME type
mime_type = mimetypes.guess_type(filename)[0]
# Set the content-type header
# Set the MIME type and send the data
ctx.set_header('Content-Type', mime_type)
ctx.send_content(data)
Python Web Without Albatross
An example of web programming without Albatross is at:
http://www.linux.com/archive/feature/136602
and is:
#!/usr/bin/python
import cgi
print "Content-type: text/html"
print
form = cgi.FieldStorage()
laptops = form.getvalue('laptops','0')
desktops = form.getvalue('desktops','0')
print """
<html>
<body>
<form action='second.py'>
How many laptops do you own?
<input type='radio' checked name='laptops' value='0' />0
<input type='radio' name='laptops' value='1' />1
<input type='radio' name='laptops' value='2' />2
<p>
How many desktops do you own?
<input type='radio' checked name='desktops' value='0' />0
<input type='radio' name='desktops' value='1' />1
<input type='radio' name='desktops' value='2' />2
<p>
<input type='submit' />
<p>
You own %d computers.
</form>
</body>
</html>""" % (int(laptops)+int(desktops))
|
WCS - OWSlib
Commands illustrating the capabilities of OWSlib WCS. This is sparsely documented elsewhere, with the following developed mostly via trial and (extensive) error. Some documentation can be found at:
http://home.badc.rl.ac.uk/spascoe/ndg3/ds_workshop/cows.html
http://pypi.python.org/pypi/OWSLib/
# Import the appropriate routines from the OWSlib package.
from owslib.wcs import WebCoverageService
# Create an object containing the virtual concatenated file on the server.
#wcs=WebCoverageService('http://megara.tamu.edu:8080/thredds/wcs/gcoos/seadas?service=WCS&version=1.0.0')
wcs=WebCoverageService('http://megara.tamu.edu:8080/thredds/wcs/gcoos/seadas_sst?service=WCS&version=1.0.0')
wcs.identification.service
wcs.identification.title
wcs.identification.abstract
wcs.identification.keywords
wcs.identification.fees
wcs.identification.accessConstraints
wcs.provider.name
wcs.provider.url
wcs.provider.contact.name
wcs.provider.contact.email
wcs.provider.contact.organization
wcs.provider.contact.address
wcs.provider.contact.city
wcs.provider.contact.region
wcs.provider.contact.postcode
wcs.provider.contact.country
# Find out what's available from the server.
wcs.contents
{'cloud_mask': ,
'l2_flags': ,
'seadas_sst': }
# Create and obtain an object representing the metaedata of the seadas_sst coverage.
sst = wcs['seadas_sst']
# Get the spatial extent of the coverage.
sst.boundingBoxWGS84
(-98.0, 18.010390000000001, -79.010989999999993, 31.0)
# Get the temporal extent of the coverage.
sst.timelimits
['2009-10-12T02:59:47Z', '2010-06-21T07:44:36Z']
# Get all of the time positions of the coverage.
sst.timepositions
['2009-10-12T02:59:47Z', '2009-10-12T04:38:06Z', ... '2010-06-24T08:15:43Z']
# Get the supported formats for the coverage.
sst.supportedFormats
['GeoTIFF', 'GeoTIFF_Float', 'NetCDF3']
# Get the support CRS.
sst.supportedCRS
['OGC:CRS84']
# Use the above info to formulate a GetCoverage request.
output=wcs.getCoverage(identifier='seadas_sst',time=['2009-10-12T02:59:47Z'],bbox=(-90,-85,20,25),format='NetCDF3')
# Write the coverage file to disk as file test.nc.
f=open('test.nc','wb')
f.write(output.read())
f.variables