import os
from functools import partial
import wsgiref.simple_server
from ll.xist import xsc
from ll.xist.ns import html, specials
from uw.sql.wrap import ConnectionPool, open_psycopg2_db_service_connection
from uw.web.wsgi.delegate import delegate_value, always
from uw.web.wsgi.demo import delegate_demo
from uw.web.wsgi.errors import handle_errors
from uw.web.wsgi.function import return_html_template
from uw.web.wsgi.sql import sql_db, sql_transaction, sql_pool_transaction
# Temporary for testing
[docs]def test_template (title, page, environ, header_insert=None):
return xsc.Frag (
html.DocTypeHTML5 (),
html.html (
html.head (
header_insert,
html.title (title),
),
html.body (page, class_="wcms-fullwidth front")
)
)
[docs]def wsgimain (wsgifunc, db=None, connection_pool=None, server_address=None, template=test_template, header_insert=None):
"""Standard WSGI main function.
Each application is started by invoking this routine with the proper
wsgifunc which is responsible for handling web requests.
The db parameter should be an instance of uw.local.dbtools.Database.
If provided the given wsgifunc will be wrapped with the sql_db and
sql_transaction handlers.
The provided wsgifunc will be wrapped in the following order, from innermost
(first) to outermost (last):
- Demo handler, if environment variable DEMO_MODE is set to 'yes'
- Standard wrappers, as per wsgiwrap()
- SQL access wrappers, if db parameter is specified
The SQL access is outermost so that exceptions used within the other
handlers to return valid results (e.g., 302 HTTP Found results) do not
interfere with the SQL wrappers' handling of transactions.
"""
demo_mode = os.getenv ('DEMO_MODE') == 'yes'
server_mode = os.getenv ('SERVER_MODE')
wsgifunc = wsgiwrap (wsgifunc, demo_mode=demo_mode, connection_pool=connection_pool, template=template, header_insert=header_insert)
if db is not None:
wsgifunc = sql_transaction (wsgifunc)
wsgifunc = sql_db (wsgifunc, db=db)
if server_mode == 'fastcgi':
from flup.server.fcgi import WSGIServer
WSGIServer (wsgifunc).run ()
else:
if server_address is None:
host, port = ('0.0.0.0', 8080)
else:
host, port = server_address
server = wsgiref.simple_server.make_server (host, port, wsgifunc)
print ("http://%s:%s/" % (host, port))
server.serve_forever ()
[docs]def wsgiwrap (handler, demo_mode=False, connection_pool=None, template=test_template, header_insert=None):
"""Standard WSGI wrapper.
This introduces the CLF template and error handling.
Note that the CLF is wrapped after the error handler. If this order is
reversed, it actually still works because the same environ is passed down
and the template variable is added to it. If a modified copy of the
environment were passed down (i.e., proper functional style) then the
other would not work.
"""
if demo_mode:
handler = delegate_demo (handler)
handler = handle_errors (handler)
handler = return_html_template (handler, template=partial (template, header_insert=header_insert))
if connection_pool is not None:
handler = sql_pool_transaction (handler, connection_pool)
return handler
[docs]def web_main (Cursor, wsgifunc, template=test_template, header_insert=None):
connection_pool = ConnectionPool (open_psycopg2_db_service_connection (), Cursor)
server_address = os.getenv ('WSGI_PORT') or None
if server_address is not None:
server_address = ('127.0.0.1', int (server_address))
wsgimain (wsgifunc, connection_pool=connection_pool, server_address=server_address, template=template, header_insert=header_insert)
[docs]def wsgi_application (Cursor, wsgifunc, demo_mode=False, template=test_template, header_insert=None):
connection_pool = ConnectionPool (open_psycopg2_db_service_connection (), Cursor)
return wsgiwrap (wsgifunc, demo_mode=demo_mode, connection_pool=connection_pool, template=template, header_insert=header_insert)