[Twisted-Python] Subclassing Resource, problems accessing persistent data/using registry

Thomas Weholt 2002 at weholt.org
Wed Jun 18 17:53:51 EDT 2003


I've subclassed twisted.web.resource to create my own type of rpys where the
content is wrapped in a site-wide template before being returned to the
client. This makes it easier and quicker to generate content in the rpys
themselves. I've also created a response-object instead of returning just a
string from the render-method or using request.write. IMHO a server should
work with a response to a request, not use the request itself to send
content back to the client.

The code in the bottom of the posting works great ( making it into a rpy,
running mktap + twistd etc. ), but if I create a rpy file called test.rpy,
with something like :

--------------------- snip
snip --------------------------------------------------

from hs.twisted.eloperesource import ElopeRespource

class test(ElopeRespource):
    def content(self, request, response, server):
        response.add('hello world, once again')

resource = test()

--------------------- snip
snip --------------------------------------------------

I cannot get the persistent data in my custom server-class to be registered,
the registry.getComponent-method is not available. Can I register persistent
data in any other way and somehow pass it to my own rpys? How can I manually
register persistent data, not use the automagical-way in rpys? I create a
web.tap file and try to serve the data using twisted -f web.tap etc. but it
raises an exception.

Any hint, idea, flame or constructive comment would be appreciated.

Best regards,
Thomas W

--------------------- snip
snip --------------------------------------------------

import os, types, sys, cgi, time, string, cStringIO, gzip, traceback, PyMeld
from twisted.web import server, resource
from twisted.internet import reactor
from twisted.web import server, resource, error
from twisted.protocols import http
from twisted.web.static import File
from twisted.internet import reactor

# special custom classes
from hs.twisted.response import response
from hs.twisted.Server import Server

server = registry.getComponent(Server)
if not server:
    registry.setComponent(Server, Server())
server = registry.getComponent(Server)

class ElopeResource(resource.Resource):

    isLeaf = True

    def __init__(self):
        resource.Resource.__init__(self)

    def content(self, request, response, server):
        # Should be overridden by the rpy
        response.add('Should be overridden') # added content is accumulated
in the response-object

    def render(self, request):
        resp = response()
        self.content(request, resp, server)

        if resp.filename and not resp.content_type in ['text/xml',
'text/plain', 'text/html', 'text/css']:
            # special handler to return files not directly available online,
located somewhere on local filesystem
            filesize = os.stat(resp.filename)[6]
            modification_time = os.stat(resp.filename)[8]
            request.setHeader("Content-Length", filesize)
            request.setHeader("Last-modified",
time.ctime(modification_time))
            request.setHeader("Content-Disposition", 'file; filename="%s"' %
os.path.split(resp.filename)[1])
            return File(resp.filename,
getContentType(resp.filename)).render(request)

        elif resp.url:
            request.redirect(resp.url)
            return 'You should be redirect to %s' % resp.url

        else:
            if resp.filename: # a plain-text, html or xml-file
                resp.content = open(resp.filename).read()

            request.setResponseCode(resp.response_code, 'OK')
            request.setHeader("Content-type", resp.content_type)
            if request.received_headers.has_key('accept-encoding'): # custom
gzip-encoding
                if 'gzip' in map(string.strip,
request.received_headers['accept-encoding'].split(',')) and \
                   resp.content_type in ['text/xml', 'text/plain',
'text/html', 'text/css']:
                    try:
                        fd = cStringIO.StringIO()
                        gz = gzip.GzipFile(filename='', mode='wb',
compresslevel=9, fileobj=fd)
                        resp.content = '<html><body>%s</body></html>' %
resp.content
                        gz.write(resp.content)
                        gz.close()
                        gzHtml = fd.getvalue()
                        request.setHeader("Content-Length", len(gzHtml))
                        request.setHeader("Content-Encoding", 'gzip')
                        return gzHtml
                    except:
                        fp = cStringIO.StringIO()
                        traceback.print_exc(file=fp)
                        content = fp.getvalue()
                        return self.templates.populateSceleton(content,
'default')
            else:
                content = '<html><body>%s</body></html>' % resp.content
                request.setHeader("Content-Length", len(content))
                return content

class Simple(ElopeResource):

    def content(self, request, response, server):
        response.add('Hello world! And there\'s even some persistent data
from the server : %s' % vars(server))
        server.data['time'] = time.ctime(time.time())

resource = Simple()





More information about the Twisted-Python mailing list