Showing posts with label interfaces. Show all posts
Showing posts with label interfaces. Show all posts

Wednesday, August 27, 2008

Thoughts on Python interfaces

Python does not have interfaces. Yet people have implemented interfaces in Python via some really innovative code (PEAK and Zope 3 comes to mind, but Trac also has them). Those people have great arguments for interfaces, claiming documentation and enhancement of system structure. From what I gather the theory is that if you use interfaces its easy to create truly componentized architectures because you know what to expect from a component.

Now that said, I find it really amusing how often interfaces end up being just so much boilerplate. By this, I mean an empty, (or marker), interface. We are given to understand that one can do so much more, but sometimes a framework demands an interface in a particular place, and often that interface is just plain empty.

I've never played with PEAK elements beyond easy_install. I've toyed with the innards of Trac and been shocked by what makes up the core of that so important software tool. Zope 3 is weel organized and I've done some shockingly fun stuff there after I got over the Zope 3 ZCML hump. And in all of that, I barely saw the need for interfaces. So often I wonder if interfaces are needed.

Well, upon reflection for those systems interfaces work surprising well. The underlying code for Trac might be questionable but anyone can make a plugin by following rules obviously managed by the interface system. Zope 3 is really nice once you get past the curve because you can make components and tie them easily in knots with ZCML (or with python in the case of Grok).

The point of these thoughts? Nothing really. I can live with or without interfaces, and use them in the frameworks that need them.

Friday, August 15, 2008

Pluggable Authentication System for Plone

It took me a little to get started, because the paster template for Plone 3 Pluggable Authentication System (PAS) products doesn't work for me. Not sure why, so I submitted a ticket.

Anyway, once I figured out that it was the template, and not me, things went very fast. PAS is rather straightforward when you get the hang of it. The quick summary of how to do a PAS plugin as how I've done it:
  • Grab the gmail auth plugin and use that as your base.
  • In your 'content type', import and register the appropriate method and in the content type's class, create the appropriate method.
  • Follow the PAS documentation on Plone.org for different actions you might need to do.
Yeah, very basic. I also figured out how to detail properties that can be set via the ZMI. Easy, but the documentation is not as easy to find as it should be.

I might document things in more depth since in some ways this took much longer than it should have considering the simplicity of the end code. I'm sure the Plone folks would love a detailed set of PAS examples to reinforce the current documentation, and I seem to enjoy doing that quite a bit.

Heh, while I'm at it, maybe I should finish my KSS documentation that I left hanging since the Naples Plone Conference in 2007?

Anyway, my quick review of PAS is that its really powerful. That each element (Authentication, Authorization, Challenges, etc) is seperated into its own plugin/module means that you can switch out components without jeopordizing the security and role system that might already exist. So, for example, if you want to use LDAP for authentication and SQL for authorization and a Smart Card to handle security challenges, you can do that without having do rewrite the core Plone engine. Another big bonus is that to do the actual replacement of individual plugin/modules is really easy once you figure out how. And that is pretty damned hot.

Friday, April 4, 2008

Issues with zope.formlib

Disclaimer: I am not an expert on Zope 3, much less Five, which lets you integrate Zope 3 technology into your Plone efforts. on the other hand, that arguably lets me speak as joe developer trying to meet a deadline, so I think things balance out.

I was tasked with extending a Five based package to include several extra new forms. This post details my efforts, what pleases me about zope.formlib and what annoys me.

Zope.formlib is a Zope 3 product that lets you create HTMl forms with handy bits of Python code. In general I like this approach, because if done right it means less work (thanks to DRY or Don't repeat yourself), and instead of just hand-coding the same form elements again and again - you utilize easily understood libraries that take advantage of inheritance and polymorphism.

Since we weren't storing any of the data I just extended a few existing interfaces, added a new view, a new response template written in a few lines of TAl, and tied it together with ZCMl. It was very straightforward and I had lots of fun. I had done a few bits before with zope.formlib and things were so easy I was delighted. Zope technology is like this, in that you can accomplish tasks quickly.

The basic form looked good, the form submission worked without a hitch, now I just needed to change some checkboxes to radio buttons. I didn't do it earlier because the documentation didn't have that described, but I figured it would essentially be really fundamental to the bool type in zope.schema (for you Django folks, Zope schemas can be likened to your models).

After many efforts at googling the answer I was nowhere. I dove into my 3rd edition copy of Web Component Development with Zope 3. No answer. I started checking the Zope 3 APIDOCs which has tons of information but nothing on turning a field/attribute into a radio button. I did introspection everywhere and might have stumbled across it eventually but a coworker made a suggestion that answered the problem.

So that was done. Now I wanted to encapsulate my forms in a set of macros that other products could easily use. I wanted to wrap SubPageForms in template macros containing form tags so whoever used these forms just needed to a macro include. Again the documentation was lacking, and for the release going as I write this, we created a temporary work around.

So there are described a couple major annoyances. Another one to list right now would be that anything besides a template change in Zope 3 based technology requires a server restart. Now pardon me for saying this, but I thought modern application servers did refresh.

Now keep in mind that when I wasn't trying to unearth the hidden mysteries of zope 3 and five or waiting for my server to restart yet again, I was incredibly productive. The frustrating thing was enough time was wasted with monkeying around zope.formlib that I could have written the TAl for the forms and then used old style Plone forms and been done much more quickly. Yes, I won't make the same mistake again, but I shouldn't have had to poke around as long as I did.

Alright, it may not be quite that bad. But it's bad enough. In my opinion, every HTMl formlib should have in its core documentation working examples of all the standard HTML input tag types. Text, textarea, checkboxes, radio buttons, and so forth.

For example, with the Django Newforms library, you have clear documentation of how to substitute one widget type for another. You are also clearly told that the forms library does not handle wrapping your input fields with form tags. Zope.formlib, combined with the rest of the Zope 3 API is much more powerful, but the Django documentation makes it much more accessible. Here is the Django newforms documentation if you are curious:

http://www.djangoproject.com/documentation/newforms

And here is the current zope.formlib documentation:

http://pypi.python.org/pypi/zope.formlib/3.4.0

The former is complete while the latter is verbose. That's an important distinction.

Just so it is known, I'm wouldn't mind documenting zope.formlib more and putting it somewhere useful on the web once someone gives me a good suggestion as to where to put it.

In any case soon after these issues were resolved I was essentially done and most of the remaining work is/was dealing with the normal sort of last minute unwritten requirements that makes life 'so much fun'. In fact, I rolled out another form in record time and using zope.formlib. I had fun! Just the learning experience was not.

Monday, June 4, 2007

Plone Introspection

So you have a Plone content type with some fields. What are the properties of that content type? Well, you can look it up by finding in your file system the product that content type comes from, then examining the schema and finding out your information. Of course, if the product extends another product, then you have to look up that other product.

Bleah.

Introspection is what we really want. Python has it in spades. On pretty much any object in Python I can wrap it in dir() or help(), or check the __dict__ attribute. But you can't do this easily in Plone. Cooking up a universal instrospection view is something that ought to be done for my CMS of choice. I know there are lots of various barely documented utility methods I can find. I can wrap it up in a product and just use it by having a special introspection view that lays out some pretty HTML.

Sigh.

My coworker Reed pointed out that Zope 3, and the Five stuff in Zope 2 uses Interfaces that give some neat tricks you can do for introspection. I think I'll give that method a try. I think thats the right way to go because:
  1. The Zope 3 specification handles introspection much more gracefully than Zope 2. And the methods for doing it seem better documented.
  2. The technology is going that way anyhow.

Friday, May 25, 2007

Image of the Day 'extension' of FeedFeeder experience

Introduction

For a huge work project I was asked to extend FeedFeeder so we could have an image of the day type. I like FeedFeeder and this would give me the chance to speed up on Five and Zope 3. I was so excited! Five turned out to be lots of fun and not that hard to learn. Zope 3 Products looked like tons of fun, sort of like Plone products on steroids or J2EE done right.

And yet the effort turned into an exercise of frustration. Why?

The thing I like about Plone (and now Five / Zope 3 (Z3)) is that once you grok something, it is really easy to make new content types or extend new ones. You can do that via UML using ArchGenXML, or simply code it out yourself. I really enjoy this part of plone, being able to handle new content types so easily.

Things go downhill

Alas, FeedFeeder is a weird amalgam of ArchGenXML output and Five technology. ArchGenXML generated a lot of the boilerplate, but then the authors went and did things in all sorts of weird places that violate what you are supposed to do with ArchGenXML output. It is very obvious that FeedFeeder is the designer's method of learning and Five and component based design. Which is nice, but what you get is something that is very hard to extend and control. By combining ArchGenXML and Zope 3 and Five the way they did, it is actually more work to make it do what we want.


Normally adding a new content type in Plone / Five / Zope 3 / ArchGenXML, you just extend/implement an existing content type and modify either a ZCML (Z3, Five) or Install.py (Plone) or AppInstall (ArchGenXML) and maybe stick in an adapter (Z3, Five). Well, not so much in FeedFeeder, where to add an extended/new content type you have to modify the following: configure.zcml, install.py, and pretty much rebuild the content type from scratch. Then add in views and skins. Then pray it works. Just getting a simple extension without any modification to work was looking to be way, way to much work.

After working on it for hours yesterday at CC, and an hour last night, and during the wee hours between 3 and 5 am when I thought I had an epiphany, I was getting really frustrated. This wasn't like association classes where I knew that if I could just find the right bits in the lackluster docs it would work, I really felt like I was walking through someone's spaghetti code.

The Recovery

So I start thinking about building my own product from scratch to do the work. This annoyed me. I hate reinventing the wheel. Oh well, time to take notes on what it was doing. And I discovered right away that Feedfeeder curiously had something called enclosures. I researched it out, and you know what? Enclosures where a way to include content in Atom and RSS feeds.

I tested it out. I created a set of sample Atom and RSS feeds with enclosures with images. Then I created a FeedFeeder folder called 'iotd feed' to grab them. Then I check, and FeedFeeder grabbed the images and stored them as enclosure objects!

POW!!! Done!!! Feedfeeder does it already! All we need to do now is create a smart folder or view that looks for the 'iotd feed' folder to supply image of the day views!

Notes & Lessons learned

  • I'm still not happy with FeedFeeder's internal architecture. But since out of the box it does everything we need and probably more, do we need to care?
  • When I hit a brick wall like this I need to do more research. Especially when it comes to something that is using a standard. For example, I need to get a 100% understanding of something before I start trying to invent something new.
  • Time Summary:
    • Time spent learning Five: 1 hour
    • Time spent playing with Zope 3: 2 hours
    • Time spent trying to extend FeedFeeder gracefully: 4 hours
    • Time spent extending FeedFeeder via gruesome hacking: 2 Hours
    • Time spent examining FeedFeeder for things needed in a new product: 15 minutes
    • Time spent researching Atom/RSS for how they handle enclosures: 5 minutes
    • Time spent testing out how FeedFeeder handled enclosures: 15 minutes
    • Total Time: 9 hours and 35 minutes
  • Lesson Learned: Do your @#$%ing research before you commence work!

Wednesday, May 23, 2007

Interfaces in Zope 3 and Five

We use Plone a lot on the job. And Plone is leaning towards Zope 3 these days, which means Interfaces (thanks to Zope 2's inclusion of Five)! Until now I've not had a reason to really poke at Interfaces, because Python, unlike Java, doesn't really need them. Also, the Plone work I've done so far has been via UML, external methods, views (ZPT), and fancy install scripts.

However, now I'm working with feedfeeder, a Plone ATOM/RSS handler and we need to extend it to include an image-of-the-day content type. And feedfeeder is built with a lot of Interfaces and Five technology.

Alas, I don't have a Zope 3 book handy here at work.

Until my copy comes in, I'm using the Zope 3 tutorial created by the Zope 3 book author. Good stuff indeed. I'll post my thoughts when I'm done.