Re: a little wsgi framework

2009-07-09 Thread timmyt
On Jul 7, 5:19 am, Bruno Desthuilliers bruno.
42.desthuilli...@websiteburo.invalid wrote:
 timmyt a écrit :

  i'm interested in getting opinions on a smallwsgiframework i
  assembled from webob, sqlalchemy, genshi, and various code fragments i
  found on the inter-tubes

  here is the interesting glue - any comments / suggestions would be
  much appreciated

 meta
 Well... My first comment would be about the usefulness of yet another
 Python web framework, but let's not worry about this...
 /meta

  --
  thewsgiapp
  --
  def application(environ, start_response):
      path = environ.get('PATH_INFO', '').lstrip('/')

      for regex, callback in urls:
          match = re.search(regex, path)

 I don't know where these urls come from. But anyway : if they live in
 some sort of long-running process, you may want to precompile them.

          if match:
              environ['myapp.url_args'] = match.groups()
              request = webob.Request(environ)

              try:
                  return callback(request, start_response)
              except Exception, ex:

 How are redirect etc handled ?

                  start_response('500 Internal Server Error', [('Content-
  Type', 'text/plain')])
                  return [traceback.format_exc()]

 A configuration option controlling the display of the traceback would be
 fine - I surely don't want the traceback being displayed to anyone when
   the app goes into production.

 Also, logging the error and traceback might be useful.

      start_response('404 Not Found', [('Content-Type', 'text/plain')])
      return [Couldn't find the URL specified.]

 And in both cases, having the ability to use custom 500 and 404 pages
 might be nice too.



  --
  the controller decorator
  --
  def web_decorator(filename, method='html'):

      def decorator(target):

 May I suggest some renaming here ?

 filename = path (or 'template_path' ?)
 method   = content_type
 target   = controller or function or callback or

          def wrapper(request, start_response):

              #genshi TemplateLoader
              template = loader.load(filename)

              global config

 Probably not thread-safe

              try:
                  return_dict = target(request, start_response)
                  return_string = template.generate(**return_dict).render
  (method)

 Renaming again:
 return_dict = context
 return_string = data or text or ???

                  config['database.Session'].commit()
              except:
                  config['database.Session'].rollback()
                  raise
              finally:
                  config['database.Session'].remove()

 This doesn't leave much control on transactions... Sometimes you want to
 handle it manually one way or another.

              #TODO: alter 'Content-Type' per method being passed
              start_response('200 OK', [('Content-Type', 'text/html')])
              return [return_string]

 Ok, so here again, I don't understand how redirects can work. Also, if
 you do use start_response here, I don't get why you still pass it to the
 callback function.

          return wrapper

      return decorator

 slightly OT, but preserving infos on the decorated function might help
 too (introspection, debugging etc).

 My 2 cents...

thank you gentlemen

i'm now looking for Redirect exceptions as well, and returning the
appropriate response code (stole this idea from turbogears)

i like doing the response codes and exceptions myself which is why i'm
not using the webob response - i think it's more explicit and
straightforward

the conditional display of errors goes without say - that will be
trivial to add

the 'global config' line was an error - config is a module level
variable set before the application definition

i assume as long as i don't write to the config variable within the
application it is thread-safe - is that correct

the underlying assumption is the wsgi application setup does not have
to be thread safe - this is only run once per process






-- 
http://mail.python.org/mailman/listinfo/python-list


a little wsgi framework

2009-07-01 Thread timmyt
i'm interested in getting opinions on a small wsgi framework i
assembled from webob, sqlalchemy, genshi, and various code fragments i
found on the inter-tubes

here is the interesting glue - any comments / suggestions would be
much appreciated

--
the wsgi app
--
def application(environ, start_response):
path = environ.get('PATH_INFO', '').lstrip('/')

for regex, callback in urls:
match = re.search(regex, path)

if match:
environ['myapp.url_args'] = match.groups()
request = webob.Request(environ)

try:
return callback(request, start_response)
except Exception, ex:
start_response('500 Internal Server Error', [('Content-
Type', 'text/plain')])
return [traceback.format_exc()]

start_response('404 Not Found', [('Content-Type', 'text/plain')])
return [Couldn't find the URL specified.]


--
the controller decorator
--
def web_decorator(filename, method='html'):

def decorator(target):

def wrapper(request, start_response):

#genshi TemplateLoader
template = loader.load(filename)

global config

try:
return_dict = target(request, start_response)
return_string = template.generate(**return_dict).render
(method)
config['database.Session'].commit()
except:
config['database.Session'].rollback()
raise
finally:
config['database.Session'].remove()

#TODO: alter 'Content-Type' per method being passed
start_response('200 OK', [('Content-Type', 'text/html')])
return [return_string]

return wrapper

return decorator
-- 
http://mail.python.org/mailman/listinfo/python-list


Standard CRUD

2009-03-03 Thread timmyt
my buddy and i have created a Standard CRUD (SCRUD) spec that we'd
like to use across projects and frameworks

before we get totally dependent on the pattern, I want to make sure
there's not some better solution out there, or some ideas that will
improve the design

below is the spec we came up with:


SCRUD (Standard CRUD)
=

Overview
---

Standard CRUD is a design pattern for:

* displaying a single instance
* displaying a filterable list of instances

* displaying a form to create a new single instance
* actually creating a new single instance

* displaying a form to update a single instance
* actually updating a single instance

* displaying a form to delete a single instance
* actually deleting a single instance

* displaying a form to perform a bulk insert
* actually performing a bulk insert

* displaying a form to perform a bulk update
* actually performing a bulk update

* displaying a form to perform a bulk delete
* actually performing a bulk delete

The intention is that all methods supported by the model will have
a consistent Class Method Interface - for example any model that
supports bulk insert will have a standard class method to support this
functionality.

Important Considerations


* SCRUD should work the same in an ajax context as well as in a
  traditional page submit
* SCRUD state changing methods should be easily testable using
selenium,
  twill or some other web testing tool in either an ajax or page
submit
  context

General Design


A method performs one distinct action. For example the act of drawing
an update form is different than the act of actually updating an
object
instance.  This helps to enable testability and use in various
contexts.

Page Urls


=
Method  URLWhat it does
=
GETmodel/  gets a list of model instances, using
filters like ?key=value1key=value2

GETmodel/searchdisplays a search form

GETmodel/iddisplays a readonly instance

GETmodel/edit/id   displays an edit form

POST   model/update/id updates an instance and redirects

GETmodel/createdisplays an insert form

POST   model/insertinserts a new record and redirects

POST   model/delete/id deletes a record and redirects

GETmodel/bulk/edit display a bulk edit ui

POST   model/bulk/update   performs a bulk update and redirect

GETmodel/bulk/create   display a bulk insert form

POST   model/bulk/insert   performs a bulk insert and redirect

POST   model/bulk/delete   performs a bulk delete and redirect
=

--
http://mail.python.org/mailman/listinfo/python-list