[albatross-users] Newbie albatross question :)

Cameron Blackwood korg at darkqueen.org
Sun Nov 10 15:07:45 EST 2002


<warning>More questions below... :) </warning>


Dave Cole writes In message <m3adkijkzu.fsf at ferret.object-craft.com.au>:
  | 
  | The "easy cgi's" is probably the most important thing about Albatross.
  | Building small to medium web applications which capture and process
  | complex user input is where Albatross is intended to shine.

*nod* Yep. Ive had to fight some things, but now I think I
have a handle on it.

One thing that I did spend __AGES__ on was trying to track
down :

  [Sun Nov 10 03:27:19 2002] [error] [client 10.0.0.1] Premature end of script headers: /home/httpd/cgi-bin/20c

It turns out that Id accidently deleted my:

  def page_display(s,ctx):
    ctx.run_template('login.html')

So albatross was processing my object and then displaying nothing.
Man, that sucked!! It took me about an hour to find. (I
deleted it as I cut and pasted some of my methods into a
parent class, so I thought it was that.)

Maybe albatross should return 'no output generated by object NAME'
or something from the flush()?  

I cant see any reason why you'd want to not return _anything_. 
Maybe an overwritable 'default/no output' return would be a good thing?

  | 
  | Cameron> I tried Random*App too, but have gone back to the simple.  I
  | Cameron> considered the Page stuff, but *shrugs* Ill change it if it's
  | Cameron> a problem. :)
  | 
  | Once you use server-side sessions you are able to mostly avoid using
  | forms to propagate state.  This means that the redirect becomes
  | useable again.


Actually I do have a question... 


step1
=====
Im using:

from albatross import SessionFileAppContext as Albatross_Context
from albatross import SimpleSessionFileApp as Albatross_Application
from albatross import SessionFileContextMixin   # <---to hack the content type
from albatross.cgiapp import Request

and Im finding that if i have an error in my code that makes
a traceback dump, then my state is lost. (IE, if i fix the
code and then hit reload (which then gives the warning about
'post'ing the data again), I am back to my login screen
(which is my startup page)).

Is this because my context is being saved as 'empty' because
   * the context is created at the start of the request 
   * my code is processed and bombs out
   * the empty context is saved? 
or something silly like that?

(Or would this problem go away if I use Client based state?
I just changed it to SimpleAppContext and now if I get an
error, I can reload the page and my state remains. Hmmm.)


step2
=====
Ok, Im dumb. :) 

It turns out that it was caused by my not setting 
ctx.add_session_vars in each 'create_context'.


step3
=====
Errr, ok maybe it wasnt that either.

Um. Ok. Confused now.

Somehow my context is being lost if I get a traceback (I put
a button which causes a divide by zero error in my code. If
I hit reload, then my login screen appears.

If I use SimpleAppContext rather than SessionFileAppContext
then my problem goes away (becuase the state is stored in
the form, so when I 'repost' it reloads the state, I guess)


Questions
=========
So, I guess Im asking what happens in the SessionFileAppContext
state then and how do I get around this?

And just to check, but I dont need to add create_context()
each create_context() do I? Once it's in the state it's
there for good?


  | 
  | Cameron> One annoyance I found in changing, is that the keywords used
  | Cameron> by the __init__ of the App classes wont accept keywords from
  | Cameron> other App classes.
  | 
  | Hmmm...  I am not sure that there is much we can do about that without
  | introducing very hard to find problems.

Well the documentation uses the form:
 ModularSessionApp.__init__(self,
                      base_url = 'popview.py',
                      module_path = '.',
                      template_path = '.',
                      start_page = 'login',
                      secret = '-=-secret-=-',
                      session_appid = 'popview4')


Ok, this us ugly, so stick with me here....

  def   __init__(self,*static_args,**keywords):
    static_arg_names=[  'base_url', 'module_path', 'template_path', 
                        'start_page', 'secret', 'session_appid'
                     ]
    if len(static_args)>len(static_arg_names):
      print 'too many args... '
      sys.curl_up_and_die(-1)

    for i in range(len(static_args)):
      keywords[ static_arg_names[i] ]=static_args[i]
    for i in range(len(static_arg_names)):
      if not keywords.has_key: 
        print 'You didnt supply the arg',static_arg_names
        sys.curl_up_and_die(-1)
    base_url=keywords['base_url']
    secret=keywords['secret']
    template_path=keywords['template_path']
    # etc 
    # and then the standard __init__ code


So if people used:

   __init__(self,'popview.py','.','.','login','-=-secret-=-','popview4') 

or
   __init__(self, base_url = 'popview.py', module_path = '.', template_path = '.', start_page = 'login', secret = '-=-secret-=-', session_appid = 'popview4')

it should work fine in both cases.

_But_, if the same stuff is done to all the __init__
functions, then I could change the class from
SimpleSessionFileApp to SimpleApp and the extra args would
just be ignored (if i used the 2nd format!)

This would be a 'good thing' as it would mean you could
change storage systems easily. It should be transparent,
yeah?




  | Maybe the write_headers() method should write out a list/dictionary of
  | headers for which a default was established in the constructor.
  | During request processing all you would then need to do is alter the
  | headers.
  | 
  | Something like:
  | 
  |     ctx.set_header('Content-Type', 'image/png')

Yep. Im in heaven :) Perfect :)

  | 
  | - Dave
cam

--
 / `Rev Dr' cameron.blackwood at darkqueen.org    Roleplaying, virtual goth \
<   http://darkqueen.org        Poly, *nix, Python, C/C++, genetics, ATM  >
 \  [+61 3] 9809 1523[h]         skeptic, Evil GM(tm). Sysadmin for hire /
                      ---------- Random Quote ----------
	God decided to take the devil to court and settle their differences
once and for all.
	When Satan heard of this, he grinned and said, "And just where do you
think you're going to find a lawyer?"



More information about the Albatross-users mailing list