[Zope] Re: replicating stand-alone applications

Paul Winkler slinkp23@yahoo.com
Thu, 1 Nov 2001 13:04:08 -0500


Jerry,

I'm CC'ing the mailing list. I'm not a rocket-scientist expert on this
stuff, maybe somebody else could help with things I miss.

On Thu, Nov 01, 2001 at 04:32:51PM -0000, 1jerry@usd1.com wrote:
> The current Ap loads the pickle file (which has class instances in
> it), loads an additional scripting file, loads an input file (usually
> .txt), then does all the processing using MetaKit.  Once I created
> the Product, would all I need to do is change the load (from cPickle
> to reading from ZODB) to get the whole process to run from an
> External Method?

Yes, or from a DTML page, or Script (Python)...  To get started with
product programming, the Boring and Minimal products are useful.

>  I would like the option of running (for testing)
> from within Zope, updating a local MetaKit file on the server.
>
> detours: I attempted to create an External Method to read the pickled
> data and make it available in a namespace in Zope, just trying to
> print from my ap corrupted the data.fs file:
>    def load():
>        import myapplication
>        myinstance = myapplication.load('test.pkl')
>        print myinstance  # prints facts about itself
> Clicking on 'test' for this External Method produced various results

That should work. You should see the printed output on the console
where you started Zope. If you want to see it in your browser,
replace the last line with something like:

    return str(myinstance)

> - namely, unable to import modules within myapplication

What error did you get?
Does the user that runs Zope have these modules on PYTHONPATH?
If not, edit your Zope start script to add to the PYTHONPATH.

The following works for me:

1) Create a module on my PYTHONPATH:
# foo.py
class Foo:
   def __init__(self, data):
      self.data = data
   def __repr__(self):
      return repr(self.data)
   def __str__(self):
      return str(self.data)

2) Create a file in my Zope installation's Extensions directory:
#foo_extmeth.py
import foo

def load_foo():
    f = foo.Foo('hello, world!')
    return str(f)

3) In the Zope management interface, add an External Method:
id:            load_foo
Title:         Test the Foo class.
Module Name:   foo_extmeth
Function Name: load_foo

4) Save the External Method, then click on the Test tab. My browser now shows:

hello, world!

5) Changes to your external method will be reflected immediately in a
running Zope. However, changes to your imported classes do NOT show up
unless you restart zope *OR* add a reload(foo) statement to your
external method AND click on "Save Changes" in the ZMI for the
external method.  It seems the reload isn't triggered until you do
"Save Changes", I don't know why.

> and after
> much experimenting, it overwrote some of my folder icons (never did
> run).

I have no idea how you did that. {:-/

> I found little (and conflicting) documentation on External
> Methods.  Will creating a Product work without using External Methods?

Yes. The two are completely independent.

I get the feeling you're not clear on the various ways to write python
code for Zope. There are four ways:

1) Simple expressions embedded in DTML or ZPT. Obviously this is very
limited.

2) Python Script (aka Script (Python)). THese are objects that live in
the ZODB and provide a single method or function each. Due to security
concerns, there are strict limitations on what modules you can use in
a Python Script.

3) External Method. A file on the filesystem, usually in your
Extensions directory under the zope installation, can contain one or
more functions, each of which can be loaded into zope as an External
Method. These are used just like Python Scripts without the
restrictions on importing. But objects created by an External Method
are not automatically persistent - new instances will be created at
each call, and if Zope should happen to restart in the middle of a
session, the user will have to start over.

4) Product. This provides a way to extend Zope with persistent objects
that can be added from the Zope management interface and define
management methods for instances (e.g. instantiate, modify,
delete). There are no restrictions on python code you can write in a
Product.

A Product's code can contain calls to other Zope objects written as
DTML, External Methods, Python Scripts, anything it needs. THese are
all just objects in Zope, and the calling object shouldn't need to
know what kind of method it's calling. The only restrictions are the
same as for any Zope object: the caller must be able to find the
callee (via acquisition if necessary), and the zope user must have
appropriate permissions.

If you don't need your instances to be persistent, then you don't
really need a Product and should be able to do everything with
External Methods.

> detour 2: tried XML-RPC to access Zope from Python, using xmlrpclib
> with and without BasicAuthTransport mod.  Creating the connection
> was no problem.  Every time I attempted to access anything, (lists,
> page source) it returned a string with HTML code for HTML, HEAD, etc
> as an invalid exception string.  Does XML-RPC work with 2.4.1?  What
> could be wrong?

Sorry, I've never tried XML-RPC. This is a question for the zope list.

-- 

paul winkler
home:  http://www.slinkp.com
music: http://www.reacharms.com
calendars: http://www.calendargalaxy.com