ZopePerl Presentation Download

Transcript
Copyright 2001, ActiveState
Using perl with Zope
Andy McKay, ActiveState
Python 9 Conference
Copyright 2001, ActiveState
Agenda
• About using Perl with Zope
• Why Perl with Zope?
• Example of use
– Perl Restricted methods
– Perl Unrestricted methods
– Perl DBI
• Perl from Python
• Internals
Copyright 2001, ActiveState
Perl with Zope
• Created by ActiveState for Digital
Creations.
• Developed done by Gisle Aas.
• Goal: "To provide an alternative to
Python for scripting Zope in the same
process."
• Currently in beta?
Copyright 2001, ActiveState
Perl with Zope does not…
• Mean a rewriting of Zope
• Allow the creation of a Perl only product
• Zope speaks lots of different things (FTP,
SOAP, WebDAV etc.)… and now Perl
Copyright 2001, ActiveState
Perl with Zope does allow…
• Creation of Perl Scripts through the web
– Perl Script
– Similar to Python Script
• Creation of Perl External Methods
– Perl Script (Unrestricted)
– Similar to External Method
• Using Perl within Python
Copyright 2001, ActiveState
Why use perl with Zope?
• Code reuse
– Access to legacy scripts and modules
– Most things have already been done in perl
– Perl Cookbook, Programming Perl etc…
• Large number of Perl developers
– Community and knowledge
– Perl is on Linux and most people use Linux
What OS do you primarily run Zope on?
–Linux 43.09%
–Windows NT/2000 25.97%
–Windows 9x 6.91%
–Unix 6.91%
362 users polled, from www.ZopeZen.org.
Copyright 2001, ActiveState
Why use perl with Zope?
• CPAN
– CPAN: Comprehensive Perl Archive Network
– PPM: Perl Package Manager
Copyright 2001, ActiveState
Why use perl with Zope?
• CPAN
–
–
–
–
CPAN: Comprehensive Perl Archive Network
PPM: Perl Package Manager
CPAN: 1,964 modules
Zope.org: 296 products
2000
1500
1000
CPAN
500
0
Zope.org
Copyright 2001, ActiveState
Technical Overview
• Two parts:
– Pyperl
• Python Perl integration, not Zope specific.
• Current version 1.0
– Zoperl
•Depends on pyperl. Zope specific, platform
independent code.
–Script Perl (restricted)
–Script Perl (unrestricted)
–Z DBI Database Connection
•Current version beta 0.5
Copyright 2001, ActiveState
Script Perl (restricted)
• Zope object: Script (Perl)
–
–
–
–
Edited through the web
Access to most of the Perl core
Can’t use modules
Runs in strict
• Similar in idea to Script (Python)
Copyright 2001, ActiveState
Example, Object listing (DTML)
• Get a listing of Zope objects using
objectIds() in a container
• In DTML…
<dtml-in "objectIds()">
<dtml-var sequence-item>
</dtml-in>
Example: List
Copyright 2001, ActiveState
Example, Object listing (Python)
• In Script Python…
– context is bound by default in Python methods
– can use print / printed shortcut
for item in context.objectIds():
print item
return printed
Example: ListPY
Copyright 2001, ActiveState
Example, Object listing (Perl)
• In Script Perl…
– self is declared as an argument
my @res;
for ($self->objectIds()) {
push(@res, $_);
}
return join("\n", @res);
Example: ListPL
Copyright 2001, ActiveState
Gotchas
• Can’t get an item (such as a folder) the
same as python
– context.folder.objectIds() works.
– $self->folder->objectIds() doesn’t.
Zope Error
Error Type: AttributeError
Error Value: __call__
Note: Perl errors are raised as Python
errors…
Copyright 2001, ActiveState
Python::getitem
• Use Python::getitem(..)
– Arguments: object, subobject id
my @res;
my $folder = Python::getitem($self, ‘Control_Panel');
for ( (Python::getitem($folder, 'Products'))->objectIds() ) {
if ($_ =~ m/perl/i) {
push(@res, $_);
}
}
return join("\n", @res)
Example: ListProducts
Copyright 2001, ActiveState
The good, the bad and the ugly
• Good
– Regex’s, transliterations etc are available
• Bad
–
–
–
–
Regex’s, transliterations etc are available
No loop limit
No bindings and other Python Script features
getitem
• Ugly
– Through the web editing
– “Guilty as charged. Perl is happily ugly, and
happily derivative”, Larry Wall
Copyright 2001, ActiveState
Script Perl, unrestricted
• Zope object: Script (Perl, unrestricted)
–
–
–
–
Edited on file system
Access to all of the Perl core
Can use modules
Can choose “strictness”
• Similar in idea to External Method
Copyright 2001, ActiveState
Example (Calendar)
• A web based calendar that uses some
interesting CPAN modules…
• Elements:
– CPAN Modules
– Actual perl module for finding monthly and daily
information
– Scripts (Perl, unrestricted) to call from DTML
– DTML Method to display calendar
Copyright 2001, ActiveState
Calendar: Perl Setup
• Installing CPAN modules:
– Installed from CPAN or via PPM
• File location:
<Zope>/Extensions/ZopeExt/Calendar.pm
#! /usr/bin/perl -w
use strict;
package ZopeExt::Calendar;
# import modules
use Date::Calc;
use Date::Manip; …
Example: Calendar.pm
Copyright 2001, ActiveState
Calendar: Perl Scripts
sub Month {
my ($year, $month, $day) = split('/', $_[0]);
if (!Date::Calc::check_date ($year, $month, $day)) {
Python::raise('DateError', “Date not valid");
}
}
my %hash;
$hash{'month_name'} = Date::Calc::Month_to_Text($month);
…
return \%hash;
}
Note: Having "month" as an argument ensures I will be
passed something.
Example: Calendar.pm
Copyright 2001, ActiveState
Calendar: Perl Scripts (Alt)
sub Day {
my ($year, $month, $day);
my $self = shift;
my %request = %{$self->{'REQUEST'} };
if (exists $request{'day'}) {
($year, $month, $day) = split('/', $request{'day'});
if (!Date::Calc::check_date ($year, $month, $day)) {
Python::raise('DateError', 'Date not valid');
}
} else {
Python::raise('DateError', 'No day given');
}
Note: Having "self" as an argument ensures I will be
passed "self", so I can call REQUEST etc…
Example: Calendar.pm
Copyright 2001, ActiveState
Calendar: Access
• Requires hack to AccessControl to allow hashes
and arrays to be returned without security
machinery complaining.
– from Chris McDonough
import Record
Calendar: Perl Scripts
try:
import perl
perlhash = perl.get_ref("%")
except:
perlhash = {}
ContainerAssertions ={
… type(perlhash): 1, …
}
Copyright 2001, ActiveState
Calendar: Scripts
• Create objects to be called.
• Eg:
–
–
–
–
Id: CalendarMonthPM
Function name: Month
Function arguments: month
Perl module: ZopeExt::Calendar
Example: CalendarMonthPM
Copyright 2001, ActiveState
Calendar: DTML
• DTML to show calendar
• Returning a hash reference, uses
mapping.
<dtml-with “CalendarMonthPM(month)” mapping>
<dtml-var month_name> <dtml-var year>
• For array use <dtml-in..>
Example: CalendarExample
Copyright 2001, ActiveState
Calendar: End Result
Example: CalendarExample
Copyright 2001, ActiveState
Gotchas
• Use getattr and setattr to modify things
such as REQUEST/
• Returning complex data structures can
be tricky to DTML.
Copyright 2001, ActiveState
ZDBI DA
• One other product, ZDBI_DA
• Perl DBI has access to most
databases, can go where Python
can’t…
• A Python object that forwards
requests to Perl DBI.
• Roughly 30% performance hit over
native drivers
Copyright 2001, ActiveState
Using Perl in Python
• As of pyperl-1.0, released Thursday...
• Added in a wrapping around Perl objects so
they can be called from Python.
– Currently works best on Perl objects
• Syntax:
from perlmod import Perl
• think of it as a dot (.) instead of two colons in
an object…
Copyright 2001, ActiveState
Using Perl in Python
Python 1.5.2 (#0, Jul 30 1999, 09:52:18) [MSC 32 bit (Intel)] on
win32
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>> from perlmod import Perl
>>> import time
>>> s = Perl.Date.Tolkien.Shire(time.time())
>>> print s.on_date()
Highday Rethe 11 7465
Gollum visits Shelob, 1419.
…
Copyright 2001, ActiveState
Using Perl in a Zope Product
• FSCounter, simple Zope product to
provide a hit counter.
– File system used to avoid Data.fs bloat
• Problem:
– No simple and easy cross platform locking
mechanism in Python
– fcntl is Unix only
• Solution:
– File::Counter from CPAN
Copyright 2001, ActiveState
Example: FSCounter
from perlmod import Perl # perl
…
def write(self):
''' increment file, perl '''
p = Perl.File.CounterFile(self._filename())
return p.inc()
def read(self):
''' read file, perl '''
p = Perl.File.CounterFile(self._filename())
return p.value()
Example: counter, footer
Copyright 2001, ActiveState
Internals
• Full API not of interest here, whole
talk all of its own.
• Discussed by Gisle Aas in the paper.
• Of interest:
– Exceptions
– Complex data types
– Threading
Copyright 2001, ActiveState
Exceptions
• Can raise an error by:
– Python::raise($type, $value)
• The Python::Err::-functions also return the
standard python exception type objects
if called without arguments.
– Python::raise(Python::Err::IndexError, "out
of range")
Copyright 2001, ActiveState
Complex data types
• PyPerl does conversion of simple data
type (strings, int etc)
• Perl ref object is a reference to a python
object that encapsulates a perl
reference.
Python 1.5.2 (#0, Jul 30 1999, 09:52:18) [MSC 32 bit (Intel)] on win32
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>> import perl
>>> inc = perl.get_ref("@INC")
>>> inc
<perl ARRAY(0x95f07c) ref at 8a45e8>
>>> len(inc)
3
Copyright 2001, ActiveState
Threading
• Perl is multi-threaded when used with
Python.
• A Perl interpreter is opened up for each
thread.
• It is released when Zope releases its
thread.
• Perl references cannot be passed
between Perl threads. Don’t try and
pickle a Perl reference.
Copyright 2001, ActiveState
Future
• PyPerl the python-perl part of Zope Perl
as part of PPM, meaning very easy
install.
• PyPerl finalised.
• ZoPerl the zope-perl part of Zope Perl as
part of the Zope core?
• Currently in beta, be finished RSN.
Copyright 2001, ActiveState
More information
• Project homepage:
www.zope.org/Wikis/zope-perl/FrontPage
• Zope Perl available from:
www.ActiveState.com/download/Zope-Perl/
• Examples, plus this talk at:
www.zope.org/Members/andym
• Mailing list: [email protected]
Copyright 2001, ActiveState