<!DOCTYPE Article PUBLIC "-//Davenport//DTD DocBook V3.0//EN" [
<!entity index SYSTEM "indice.sgml">
]>

<Article id="snakelib">
<ArtHeader>
<Title>Snake Lib</Title>
<Author>
  <FirstName>Jon</FirstName>
  <Surname>Travis</Surname>
  <Affiliation>
    <address><email>jtravis@p00p.org</email></address>
  </Affiliation>    
</Author>
<PubDate>v0.50, 01 October 2000</PubDate>

<Abstract>
  <Para>
    The mod_snake distribution includes a variety of useful PyMods which
    provide features found in other popular packages, such as mod_perl.
    This makes it very easy for developers to pick and choose existing
    PyMods which provide functionality that they need without requiring
    them to write their own code. This bundling of standard included PyMods
    is called Snake Lib.
  </Para>
</Abstract>

</ArtHeader>

<Sect1 id="setup"><Title>Setting Up Snake Lib</Title>
  <Para>
    Snake Lib is the library of modules which ship with mod_snake.  After 
    unpacking the distribution, snake_lib is in:
      <Filename class="Directory">mod_snake-x.y.z/snake_lib</Filename>.  Snake
    Lib can be used regardless of its location on the system.  The only 
    requirement is that <Filename>httpd.conf</Filename> be updated to reflect
    the location.  To add the directory to mod_snake's internals, the following
    line can be added:
  </Para><Para>
<ProgramListing>
    SnakeModuleDir  /path/to/snake_lib
</ProgramListing>    
  </Para><Para>
    Adding this directive is not a requirement to use mod_snake, nor is using
    any of the snake_lib modules.      
  </Para>
</Sect1>

<Sect1 id="mod-snake-cgi"><Title>mod_snake_cgi</Title>

  <Para>
    mod_snake_cgi is a PyMod which accelerates and caches CGIs written in
    Python.  In addition, for added functionality, these Python CGIs loaded 
    into mod_snake_cgi have access to the mod_snake module and its routines
    such as logging.
  </Para>

  <Sect2><Title>Configuration Directives</Title>
    <Para>
      To use mod_snake_cgi, it must be first loaded into the server.  To do 
      this, the following line can be placed in 
      <Filename>httpd.conf</Filename>:
    </Para><Para>
<ProgramListing>
    SnakeModule     mod_snake_cgi.SnakeCGI
</ProgramListing>
    </Para><Para>
      In order to notify mod_snake_cgi that it needs to process a given file
      type, a handler needs to be associated with certain files.  This is 
      commonly done in the main configuration as:
    </Para><Para>
<ProgramListing>
    Alias /pycgi/ ``/home/httpd/apache/pycgi/''
    &lt;Directory ``/home/httpd/apache/pycgi''&gt;
        SetHandler snakecgi
        AllowOverride None
        Options ExecCGI
        Order allow,deny
        Allow from all
    &lt;/Directory&gt;
</ProgramListing>
    </Para><Para>
      When requests for URI's in the form of: http://your.host.com/pycgi/foo.py
      are made, they will be run via mod_snake_cgi.  The CGIs can be placed
      in <Filename class="Directory">/home/httpd/apache/pycgi</Filename>.
    </Para><Para>
      The directive SnakeCGILogFile will send error information to an 
      alternative file. If this directive is not specified, any output errors 
      or tracebacks will be sent to the ErrorLog.
    </Para>
  </Sect2>

  <Sect2><Title>Inner Workings</Title>
    <Para>
      mod_snake_cgi is a very simple PyMod. When an incoming request is made,
      the following actions are performed.

      <orderedlist>
      <listitem><para>
        The handler is checked against 'snakecgi'. If the handler is 
        otherwise, mod_snake_cgi returnes DECLINE.
      </para></listitem>

      <listitem><para>
        mod_snake_cgi checks its internal cache to see if the CGI has 
        been loaded already.

        <orderedlist>
        <listitem><para>
          If the CGI is not loaded, it is loaded from the disk and 
          byte-compiled.
        </para></listitem>
        <listitem><para>
          If the CGI has been loaded before, the modification time of the 
          on-disk version is checked and reloaded if necessary.
        </para></listitem>
        </orderedlist>
      </para></listitem>

      <listitem><para>
        The compiled code runs in its entirety.
      </para></listitem>
      </orderedlist>
    </Para>
  </Sect2>

  <Sect2><Title>Future Enhancements</Title>
    <Para>
      Potential future enhancements could include any one of the following:

      <itemizedlist>
      <listitem><para>
        Handlers for .pyc or .so Python modules which act as CGIs.
      </para></listitem>
      <listitem><para>
        Seperate logging facilities within each virtual server.
      </para></listitem>
      </itemizedList>
    </Para>
  </Sect2>
</Sect1>

<Sect1 id="mod-snake-epy"><Title>mod_snake_epy</Title>
  <Para>
    mod_snake_epy is a PyMod which allows Python code to be embedded within
    standard HTML pages.  It provides extensive caching by storing the 
    post-processed code across multiple requests. In addition, it contains
    the ability to store persistant data such as functions and other objects.
    This greatly speeds up code execution.
  </Para>

  <Sect2><Title>Configuration Directives</Title>
    <Para>
      To load the embedded Python processor, the folowing directive can be 
      placed in the main configuration file, <Filename>httpd.conf</Filename>:
    </Para><Para>
<ProgramListing>
    SnakeModule mod_snake_epy.SnakeEPy
    AddType application/x-httpd-epy .epy
</ProgramListing>
    </Para><Para>

      This allows filenames with the extention '.epy' to be interpreted
      as embedded Python scripts.
      The directives which may be used after loading this module are:
  
      <itemizedlist>
      <listitem><para>
        <Command>SnakeEPy</Command>
        <Parameter>on|off</Parameter>
        - This directive takes one flag, 'on' or 'off', and signifies
        whether or not processing of embedded Python code should be performed.
      </para></listitem>
  
      <listitem><para>
        <Command>SnakeEPyErrSend</Command>
        <Parameter>on|off</Parameter>
        - During the debugging stage of embedded Python,
        it is sometimes useful to send traceback information directly to
        the browser instead of to the logs. If this directive is 'on', 
        tracebacks will be dumped to the browser on failure.
      </para></listitem>
  
      <listitem><para>
        <Command>SnakeEPyLogFile</Command>
        <Parameter>path</Parameter>
        - If logging other than the ErrorLog is required, this directive 
        specifies a file where such information should go.
      </para></listitem>
      </itemizedlist>
    </Para>
  </Sect2>

  <Sect2><Title>Usage</Title>
    <Para>
      Within text/html documents, Python can be embedded in a number of ways. 
  
      <itemizedlist>
      <listitem><para>
        &lt;+ ... Python code ... +&gt; 
        - The ``plus'' delimiters designate a section of Python code which 
        should be executed <Emphasis>ONLY</Emphasis> on the first time the
        script is loaded.  This provides a convenient place to create database
        connections, open logs, or import other modules.  
        <Warning><Para>If other code blocks require objects created in the 
          ``plus''delimiter, persistance will be required.  
          See <xref linkend="epy-methods">.
        </Para></Warning>
      </para></listitem>

      <listitem><para>
        &lt;| ... Python code ... |&gt; 
        - The ``pipe'' delimiters designate a section of Python code which 
        should be <Emphasis>executed</Emphasis>, and the resultant data 
        discarded.
      </para></listitem>

      <listitem><para>
        &lt;: ... Python code ... :&gt; 
        - The ``colon delimiters designate a section of Python code which 
        should be <Emphasis>evaluated</Emphasis>, and the resultant data 
        sent to the remote client.
      </para></listitem>

      </itemizedlist>
    </para>
  </Sect2>

  <Sect2><Title>The EPY Object</Title>
    <Para>
      Interaction between embedded Python code and mod_snake/Apache is done
      by using the EPY object.  This includes things such as setting up
      CGI style environment, setting persistance, setting headers, and more.
      ``EPY'' is a global variable in all executed blocks.  It can be used
      like any other object. e.g.: EPY.set_persist(1)
    </Para>

    <Sect3 id='epy-methods'><Title>EPY Methods and Attributes</Title>
      <Para><itemizedlist>
      <listitem><Para>
        <Command>environ</Command> 
        - A dictionary containing all the key/value CGI variables.  This is
        setup via the setup_cgi() method.  cgi.py contains several functions
        which can take both an environment and a file object.  This attribute
        should be passed to such functions:  
        e.g.: cgi.FieldStorage(environ=EPY.environ,fp=EPY)
      </Para></listitem>

      <listitem><Para>
        <Command>set_persist</Command>(
        <Parameter>persist</Parameter>)
        - Set the persistance of data created and used in the code blocks.  
        If <Emphasis>persist</Emphasis> is true, global objects created during 
        execution will be available during subsequent requests.
      </Para></listitem>

      <listitem><Para>
        <Command>set_header</Command>(
        <Parameter>header</Parameter>,
        <Parameter>value</Parameter>)
        - Set an output header that gets sent back to the remote client,
        such as ``content-type''.  
      </Para></listitem>

      <listitem><Para>
        <Command>setup_cgi</Command>()
        - Setup CGI environment variables.  After calling this method, 
        EPY.environ contains standard CGI key/value pairs.
      </Para></listitem>

      <listitem><Para>
        <Command>write</Command>(
        <Parameter>data</Parameter>)
        - write data to the remote client.  
      </Para></listitem>
      </itemizedlist></Para>
    </Sect3>
  </Sect2>

  <Sect2><Title>Examples</Title>
    <Para>
      A small example for displaying the time:</Para><Para>
<Screen width="61">
    &lt;+
    import time

    EPY.set_persist(1)
    HitCount = 1
    +&gt;

    The current time is: &lt;:time.ctime(time.time()):&gt;&lt;BR&gt;
    This page has been hit &lt;:HitCount:&gt; times.
    &lt;|HitCount = HitCount + 1|&gt;
</Screen>
    </Para>
  </Sect2
</Sect1>

<Sect1 id="mod-snake-simple"><Title>mod_snake_simple</Title>
  <Para>
    Often, creation of a full blown module takes too much time, and a developer
    may want to lay out a quick prototype in a few seconds. The 
    mod_snake_simple module allows easy creation of very simple modules 
    through simple formats, similar to that of mod_perl.
  </Para>

  <Sect2><Title>Configuration Directives</Title>
    <Para>
      All of the handler configuration directives take one argument, a 
      module.function pair to call when the cooresponding Apache phase is 
      reached. The directives are: SnakePreConnection, SnakeProcessConnection, 
      SnakePostReadRequest, SnakeTranslateName, SnakeHeaderParser, 
      SnakeAccessChecker, SnakeCheckUserId, SnakeAuthChecker, 
      SnakeTypeChecker, SnakeFixups, SnakeContentHandler, SnakeLogTransaction. 
      To load the mod_snake_simple module, the following directive should be 
      placed within the main configuration file:
      
<ProgramListing>
    SnakeModule mod_snake_simple.SnakeSimple
</ProgramListing>
      
      The other directives include:
      
      <ItemizedList>
      <ListItem><Para>
        SnakeVarSet - Set a variable that simple modules may access. If 
        per-directory variables are available, they are passed to the 
        handler's per-dir argument. Per-server variables are available 
        through a global variable called SnakeServerVars.
      </Para></ListItem>
      </ItemizedList>
    </Para>
  </Sect2>

  <Sect2><Title>Usage</Title>
    <Para>
      In the Apache configuration file and .htaccess files developers may
      place any of the directives to schedule calls to Python functions
      whenever the designated Apache phases are reached.
    </Para>
  </Sect2>

  <Sect2><Title>Examples</Title>
    <Para>
      Mod_Snake comes with a few very simple examples in the examples 
      directory.
    </Para>
  </Sect2>
</Sect1>
</Article>
