You are not logged in Log in Join
You are here: Home » Members » klm » ZopeDebugging » ConversingWithZope

Log in
Name

Password

 
 

History for ConversingWithZope

??changed:
-
<h2> Conversing with Zope: Interactive Debugging With the Python Prompt </h2>

  <p align="right">
    Ken Manheimer, "[email protected]":[email protected] <br>
    March, 2003
  </p>

Introduction

  <blockquote>
    "All parts should go together without forcing.  You must remember
    that the parts you are reassembling were disassembled by you.
    Therefore, if you can't get them together again, there must be a
    reason.  By all means, do not use a hammer." <br>
    &nbsp;&nbsp;-- IBM maintenance manual, 1925 (via someone on python-dev)
  </blockquote>

  This paper presents some basic techniques for interactively delving
  into and intervening in the operation of a running Zope application.

  Developing and debugging Zope applications can be tricky,
  particularly since the system usually runs as a daemon process in
  the background.  The system, however, and typical applications built
  with it, are very much about interactivity, and are good candidates
  for incremental development.  Open availability of the source,
  support for shared client access (with ZEO[1]), and the fact that
  its built on a comprehensible, dynamic like Python, provide rich
  avenues for interactive development, debugging, and exploration -
  even while Zope is serving normal visitor's requests.

  We'll explore practical examples involving sessions independent of
  other server activity, and also intervention in Zope's service of
  ongoing requests.  Examples will involve interaction with the server
  at the level of trusted (security-exempt) filesystem-based code and
  also at the level of through-the-web untrusted (security-regulated)
  code and web requests.

  "Appendix A":#appendixA has a complete recipe for setting up a Zope
  site running under ZEO (on Linux, but you should be able to adapt it
  to other platforms) so you can play along, poking and prodding your
  running Zope instance as you read.  Working familiarity with Python
  is a must - see [2] for leads on introductions.

  In addition to debugging opportunites, interacting with the server
  directly provides immediate, hands-on experience with sophisticated
  Zope mechanisms like the object database, transactions, acquisition,
  object publishing, fine-grained security, and so on.  With direct
  experience you can substantiate and solidify your understanding not
  only of your application but also of Zope, itself.

  Here's one final introductory note, about debugging as a development
  practice.  The most powerful development and debugging tool is
  careful thought.  When debugging, it usually helps to have or seek a
  good conceptual model of the situation, not just poke and prod.  The
  tools and techniques we'll be exploring can help you to discover,
  test, and act on your model in useful - and sometimes crucial -
  ways.

  I'll be maintaining a copy of this paper, some of the ingredients
  for the site construction recipe, notes and errata, and a place for
  feedback, in a wiki at http://www.zope.org/Members/klm/ZopeDebugging .

[1] http://www.zope.org/Documentation/Books/ZopeBook/current/ZEO.stx

[2] The classic quick introduction to Python is the Python tutorial,
available online at http://www.python.org/doc/current/tut/tut.html .
Additionally, http://www.python.org/doc/Newbies.html points to lots of
great beginners guides.

  Python Prompt vs Intervening On An In-Progress Request

    There are two fundamental access modes we'll use:

      - from the python prompt - starting up Python and opening access
        to the Zope server

      - trapping and triggering a debugging session in the midst of
        normal service of a network request.

    We'll start with the simpler situation, entry from the Python
    prompt.

    For both we'll be using a ZEO-served Zope instance so that you can
    open a connection to a running storage server while other clients
    - like a Zope web site or another interactive session - are
    concurrently interacting with the server.  We'll use the Python
    prompt or a pdb session triggered in the server launch process.

  Setup - Establishing a ZEO-based Zope

    "Appendix A":appendixA has a complete recipe for setting up Zope
    running with ZEO, useful for both modes.

    The recipe includes a script, izctl.py, for starting the server,
    with an option to start an interactive prompt instead of the web
    (and ftp, webdav, ...) server.  You can adapt this configuration to an
    existing Zope/ZEO setup, if you already have one that you want to
    use, by changing the settings in 'zope.conf'.  You can also just
    emulate what the script does for an existing installation, if you
    prefer.

Starting From the Python Prompt

  Interacting with Zope using the Python prompt gives you maximum
  latitude.  You can navigate the object filesystem, grab objects, and
  "manipulate" them by calling methods on them directly.  (You do not
  get the effects of the Zope publisher, like conveyance of
  authorization credentials, unless you explicitly invoke it - which
  we'll be discussing, later.)  By running Zope under ZEO you can get
  python prompt access without interfering with simultaneous access by
  others to your site.  With it you can interact with your site
  simultaneously via the network and via the python prompt.  We'll be
  exploiting this in our explorations.

  The script 'izctl.py' from the recipe ("Appendix A":appendixA)
  provides the means to situate yourself in the Python prompt talking
  to Zope: 'izctl.py debug'.  This:

    - ensures that the ZEO server is going on the port indicated in
      'zope.conf', starting the server if necessary

    - sets environment variables INSTANCE_HOME and ZEO_SERVER_PORT

    - starts Python so that your SOFTWARE_HOME/lib/python directory is
      on the path

    - imports 'Zope'

    - sets 'app = Zope.app()' - 'Zope.app()' returns the application
      instance, by which we connect to the server.

    - prints an orientation greeting

  'izctl.py debug' leaves you at the python prompt with a connection
  to the ZEO storage server, in the context of a transaction within
  which your work will occur.  We will use the application instance,
  assigned to 'app', to get at objects in the application.  Changes we
  make to those objects will be hidden from other transactions until
  we commit our transaction.  We'll explain this as we proceed.

  Looking Around The Root Folder

    Once we've invoked 'izctl.py debug' from the shell prompt, we have
    a hold of the Zope application object, 'app'.

      % ./izctl.py debug
      Stopping ZEO pid: 17178 17179
      sh: line 1: kill: (17178) - No such process
      sh: line 1: kill: (17179) - No such process
      Starting ZEO server on 4000
      waiting for ZEO server to start 1/160
      waiting for ZEO server to start 2/160
      ZEO server ready.

                Zope debugging session for /home/klm/work/zope/instance1
                The root application object is bound to name 'app'.
                To let other people see your changes, you must:
                  get_transaction().commit()
                To see other people's changes, you must:
                  app._p_jar.sync()
      >>> 

    The Zope application object is the root folder of your Zope site.
    Among other things it operates as a Zope object manager,
    containing the top-level object in the site .  Those objects are
    what you would see if you visit the management screen
    ('manage_main') of the site's root through the web.

    Let's take a look at the names of the objects it holds::

       >>> app.objectIds()
       ['acl_users', 'Control_Panel', 'temp_folder',
       'browser_id_manager', 'session_data_manager', 'Examples',
       'error_log', 'index_html', 'standard_error_message',
       'standard_html_footer', 'standard_html_header',
       'standard_template.pt']

    '.objectIds()', is an object manager method which returns the ids
    of the immediately contained objects, as the list you see.  A
    companion method, '.objectItems()', obtains a list of tuples of
    the objects it contains, '(id, contained_object)'.
    '.objectValues()' lists just the contained objects. [1]

    Some notable entries in the root folder:

      - 'acl_users' - the base user folder, which holds user accounts
        that encompass the entire site

      - 'Control_Panel' - the site's online control center

      - 'index_html' - the page presented when you visit the root
        folder, itself, through the web

    Actually, all the items are interesting in one way or another,
    dictating general behavior across the site.

[1] The !Zope2 !ObjectManager is a wild and woolly beast.  It has evolved
from one of the earliest members of the Zope repertoire, and has
accumulated a lot of history along with a lot of functionality - not
[836 more lines...]