Category Archives: spring python

See how Spring Python works with Jython

I recently completed a patch that replaces the amara library with python’s default elementTree library. As much as I like amara’s API, its C-extension basis was unacceptable. I just merged the patch into the trunk, and verified it works with Jython 2.5.1.FINAL. When Spring Python’s 1.1.0.M2 release comes out, we will be Jython-compatible.

With this change, there were only a couple of tweaks to the rest of Spring Python.

What does this mean? How about looking at some code to see how we can start with a Java app, and migrate things over to Python. To kick this off, let’s start with an uber-contrived example Java app: a wiki engine. The wiki engine calls into a data access layer in order to look up some statistics on the site.

public interface DataAccess {

public void statistics();

}
public class MySqlDataAccess implements DataAccess {

public void statistics() {
System.out.println("MySQL: You are calling for some statistics.");
}

}
public class WikiService {

private DataAccess dataAccess;

public DataAccess getDataAccess() {
return this.dataAccess;
}

public void setDataAccess(DataAccess dataAccess) {
this.dataAccess = dataAccess;
}

public void calculateWikiStats() {
System.out.println("You are passing through a pure Java WikiService...");
dataAccess.statistics();
}

}

Let’s assume this is a Spring app. That means we need an XML application context. Let’s create one and call it javaBeans.xml.



xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">








We can start up our pure java app along with its context by writing jython script javabeans.py. It uses Spring Python’s SpringJavaConfig parser.

if __name__ == "__main__":
from springpython.context import ApplicationContext
from springpython.config import SpringJavaConfig
ctx = ApplicationContext(SpringJavaConfig("javaBeans.xml"))
service = ctx.get_object("wikiService")
service.calculateWikiStats()

We just need to compile the java code, and then run our script using jython.

gregturn@startrek:~$ javac *.java
gregturn@startrek:~$ jython javabeans.py
You are passing through a pure Java WikiService...
MySQL: You are calling for some statistics.
gregturn@startrek:~$

Okay, we’re off to a good start. We have tapped a running java system. For our next step, let’s write a pure python version of the data access code and put it into Py.py.

import DataAccess

class MySqlDataAccess(DataAccess):
def statistics(self):
print "PyMySQL: You are calling for some statistics."

class StubDataAccess(DataAccess):
def statistics(self):
print "PyStub: You are calling for some statistics."

Now, to really crank things up a bit, let’s migrate from the Spring Java XML configuration over to Spring Python’s pure Python container.

from springpython.config import PythonConfig, Object
from Py import MySqlDataAccess
import WikiService

class WikiProductionAppConfig(PythonConfig):
def __init__(self):
PythonConfig.__init__(self)

@Object
def data_access(self):
return MySqlDataAccess()

@Object
def wiki_service(self):
results = WikiService()
results.dataAccess = self.data_access()
return results

if __name__ == "__main__":
from springpython.context import ApplicationContext
ctx = ApplicationContext(WikiProductionAppConfig())
service = ctx.get_object("wiki_service")
service.calculateWikiStats()

The top half of our mixed.py script contains an IoC container, except there is no XML whatsoever. Instead, its raw python. You can see how we are also using our python version of MySqlDataAccess.

gregturn@startrek:~$ jython mixed.py
You are passing through a pure Java WikiService...
PyMySQL: You are calling for some statistics.
gregturn@startrek:~$

This shows that we are still using the pure java WikiService class, and it calls into our pure python MySqlDataAccess.

Another useful feature that Spring Python provides is easy access to Pyro, the Python Remote Objects library. This library is for making RPC calls from Python-to-Python. Spring Python makes it easy to link clients and services together with Pyro.

First, let’s take our wiki service, and export it with a server script.


from springpython.config import PythonConfig, Object
from springpython.remoting.pyro import *

from Py import MySqlDataAccess
import WikiService

class WikiProductionAppConfig(PythonConfig):
def __init__(self):
PythonConfig.__init__(self)

@Object
def data_access(self):
return MySqlDataAccess()

@Object
def wiki_service(self):
results = WikiService()
results.dataAccess = self.data_access()
return results

@Object
def exported_wiki_service(self):
return PyroServiceExporter(service=self.wiki_service(), service_name="wiki", service_port=9000)

if __name__ == "__main__":
from springpython.context import ApplicationContext
print "Starting up exported WikiService..."
ctx = ApplicationContext(WikiProductionAppConfig())

We made some slight tweaks to the IoC container by adding exported_wiki_service. It targets wiki_service, and links it with a name and port to expose it as a Pyro service. Spring Python by default will instantiate every object, so in this case, it creates the PyroProxyExporter. Because this isn’t the caller, we don’t need to fetch anything from the context.

Next, let’s code a client to call our service.


from springpython.config import PythonConfig, Object
from springpython.remoting.pyro import *

class WikiProductionAppConfig(PythonConfig):
def __init__(self):
PythonConfig.__init__(self)

@Object
def wiki_service(self):
results = PyroProxyFactory()
results.service_url="PYROLOC://localhost:9000/wiki"
return results

if __name__ == "__main__":
from springpython.context import ApplicationContext
ctx = ApplicationContext(WikiProductionAppConfig())
service = ctx.get_object("wiki_service")
service.calculateWikiStats()

Now, let’s start up the server.


gregturn@startrek:~$ jython mixed_with_pyro_server.py &
[1] 4953
Starting up exported WikiService...

The script is backgrounded, because it is running a Pyro daemon advertising our service. Now, let’s launch the client script.


gregturn@startrek:~$ jython mixed_with_pyro_client.py
You are passing through a pure Java WikiService...
PyMySQL: You are calling for some statistics.
gregturn@startrek:~$

As you can see, our client makes remote to the exported WikiService, which happens to be a pure java service. The java service then calls our python version of MySqlDataAccess to do its statistics call. This goes to show how easy Spring Python makes it mix and match Java and Python.

Welcome Sven Wilhelm!

I wanted to introduce another team member: Sven Wilhelm. We just granted him commit privileges this week. Sven has been using Spring Python as a core piece of his team’s system. He has been doing a bit of work on making Spring Python work with Jython (which I’m VERY interested in!), as well as working on a Spring Python Ldap module. With Sven on the team, we will be able to make these parts available to you as well.

Sven, thanks for joining the Spring Python team!

Welcome Dariusz Suchojad

I want to welcome our newest team member: Dariusz Suchojad. He has coded several patches in the past, including support for SQLServer. You will notice his name in the credits at the top of the reference docs (http://springpython.webfactional.com/1.1.x/reference/html/index.html). I submitted a request today that he be given commit rights to Spring Python’s code base.

He is working on some new Spring Python features as well. Dariusz, thanks for joining Spring Python!

VMware set to buy SpringSource

Rod Johnson posted a blog entry today that is also sweeping the twitterverse, indicating that they “have signed a definitive agreement with VMware, who will acquire SpringSource”. It says that the Spring Framework software will remain as free as ever. That should be the case, and I haven’t seen reason to doubt SpringSource would do anything differently.

Considering SpringSource has been at play using venture capital to grow its business and enter markets, this should definitely be a sign of success. A lot of startup companies get venture capital, but die off through the fact that no bigger company seeks them. This is definitely the opposite. The way I see it, SpringSource has succeeded by getting acquired by a well known company. One thing is keen in the article: both SpringSource and VMware have their eyes on the cloud computing market. And given their successful record, I think they can do pretty well.

I don’t know what VMware thinks about python, but I sure will keep me ears open. This project isn’t slowing down!

UPDATE: Acquisition is complete. Read all about it at http://www.vmware.com/company/news/releases/springsource-close.html.

Spring Python makes final 1.0.0 release

Please read the official press release from SpringSource about this historic release of Spring Python. Please visit http://www.springsource.com/download/community in order to download a copy. NOTE: Spring Python has now been relocated to the top level, instead of being inside EXT.

  • It’s the first Spring Extension to reach live status and also progress to a stable 1.0.0 final release.
  • The trunk has been updated to allow work on next major release 1.1 to begin. This means we aren’t through, but just getting started.
  • Another branch has been created to support backporting critical fixes into the 1.0 baseline, meaning it will have the same type of strong support as other SpringSource projects.

This demonstrates that Spring Python has a nicely honed development process, committed to providing stable APIs, while also focusing on new and innovative changes. While we have worked hard since the start of this project back in 2006, we still lots of ideas and have plenty more work to do.

I wish to thank Mark Pollack, the current sponsor of Spring Python and code geek that developed Spring .NET, for coming on board quickly, and supporting me in every way possible to get this release wrapped up and pushed out for everyone to use. I also want to thank Russ Miles, former SpringSource consultant, who has supported me for over the past year with encouragement and feedback. I also thank the community for its valuable comments, questions, and suggestions that has helped steer this project in a positive direction.

Key changes used to this release include:

Improvement

  • [SESPRINGPYTHONPY-96] – When making builds, use “.” as separator between version and tag; support python 2.4/2.5/2.6

Task

  • [SESPRINGPYTHONPY-56] – Assess impact of python’s deprecation of md5 and sha modules to spring python’s security segment

Is Spring Python a framework or a library?

I was tracking some comments, and recently noticed a thread of discussion (in English) on a python mailing list. This is a follow-up to someone else posting about his discovery of Spring Python through the news announcement from SpringSource. (I appreciated that the person also caught on to my article defending the usage of AOP in python.)

They concluded their response by indicating:

Aunque para convencerme de usarlo todavía le falta compararse con otros frameworks de python.

(Run this through Google Translate if you need to.) Apparently, this person, while slightly impressed that I wasn’t coding in horrible java paradigms, didn’t see enough to use this instead of other python frameworks.  I knew that he was comparing it to other python web frameworks.

History Lesson

I started thinking about the basis of all this, and realized a little bit of a history lesson is in order. Anybody who has ever heard of Spring, knows it by its full name, The Spring Framework. This should help illuminate why Spring is referred to as a framework, and why Spring Python is often thought of as a framework itself.

Starting around 1999, the first EJB spec came out. This was the technology everyone in the java industry started using, and people were throwing together any and all java web apps using EJBs. It caused a resurgance in the value of java, and arguably catapulted java into the enterprise space. EJBs promised much. The application servers that would run your EJB-based app had many features, like transactions, security, failover, messaging, and web services to name a few. All you had to do was extend a few interfaces, write a few configuration files, and do a little configuration to the app server.

Well, that was how it was supposed to be, right? The truth was, EJB apps required lots of XML file configuration. Each container had deviations, so your app tended to be container-specific. People usually had too many services turned on, and unit testing was next to impossible. You couldn’t test your app outside the container, so turn around time to see your changes was a nightmare. That is what generated the flurry of frameworks, like Struts, to help make EJB app development simpler. By extending these framework’s classes, you had a little bit less to extend, less to write, and less to configure. But you still had to do it anyway. And that turn around time to test your app? No better. And you had to make your WHOLE app do this. There was no such thing as, “Part of my app is using Struts, another part is using Wicket.”

Then in 2002, Rod Johnson, a java software consultant, wrote a book Expert One-on-One J2EE Development without EJB. When Rod’s book hit the shelves, the message he was sending was completely unorthodox. He showed tactics of code development that quickly made these container-based services obsolete. You didn’t have to extend anyone’s classes. And…you didn’t have to adopt any framework lock-stock-and-barrel. Instead, your app could be 99% based on POJOs. The code he was writing for examples in the book was very pragmatic, and was just like the other frameworks, only it was a framework based on POJOs. Another consultant approached Rod about releasing that software as an open source project, and thus was born The Spring Framework.

This code, while acting similar in output as other frameworks, had a peculiar difference: it did not require actually extending anybody’s classes. In fact, you could write your code 99% framework-free, and Rod & Co. encouraged this.

“So…is Spring a framework or a library?”

I argue: both!

Considering that a library is a set of functions and classes you download and install in your software development toolbox, Spring fits this perfectly. It was inspired by the need to overcome the lethargic development process of the EJB spec. Not only did they improve over EJB’s way of doing things, they also enhanced JDBC, JDNI, JMX, and other things.

  • Ben Alex decided to develop a Security library based on the pragmatic concepts behind Spring, which has since become the most widely adopted security solution for java.
  • Mark Pollack was also watching Spring cut through the java industry and coded a similar solution for C#/.NET and called it Spring .NET.
  • …and the list goes on of other widely adopted libraries/tools developed for the java industry based on Spring’s approach to solving problems

So, yes, Spring is a library. But it is ALSO a framework, in that its original intention was to faciliate building enterprise-grade web applications inside EJB containers. They simply showed that the servlet container was enough. In fact, many shops started fresh adopted the concept of using Apache Tomcat or Jetty as the servlet container, which has been challening the commerical app server market. Combined with the fact that your app could run inside and outside an EJB container, and also be easily JUnit-tested without the slow make-deploy cycle made it a hit.

And…its NOT a framework!

“But, you just SAID Spring is a framework!”

Yeah, I know I did, but many people interpret framework as code meant to be extended. Spring doesn’t require this. It may accomplish the same end result as these other EJB frameworks, but through simpler means. I know this first hand, because I have developed thick Java client apps using Swing. No EJB container to be found! And yet, I have found Spring provided much leverage and functionality. I didn’t have to extend anything. Okay…I had a unique situation involving security where I needed to extend a Spring Security interface, but 99% of my code doesn’t do that. And that’s the point.

“Enough Java already! I thought this was a Python blog!”

Okay, if you’re still reading, it means you are really a cross technology buff. Or maybe you just read blogs instead of sword fighting while waiting while waiting for your code to compile. Otherwise, you freaked that I spent so much time talking about Java, XML, EJBS, and fled the scene. Well, I’m a polyglot programmer. I use all kinds of stuff: C/C++, Java, Python, Tcl/Tk/Expect, PERL, bash/csh, jython, scala, groovy, clojure, anything! Actually, I had never heard the term until I saw Russ’s Skills Matter presentation where he presented himself as an “self professed, unapologetic, polyglot programmer”. But I immediately connected with it.

Anyway, the point I’m trying to make is that the concepts Rod presented are of incredible value. Its not the fact that he was working in Java, but instead the idea that pragmatism is valuable. Instead of always resting comfortably against specs, we need to always be on the lookout for places and paradigms where we are wasting countless cycles in coding and re-coding the same thing. I contend that repetition is one of the top ranking source of bugs, if not the highest.

I believe Spring Python is a library

My first entry into the world of Spring was through their fabulous JdbcTemplate. Writing SQL queries without leaking cursors and connections was of high important to me. When I decided to code  a carputer application, I picked Python because reading Dive Into Python had sold me on the beauty of it. However, I quickly realized I was missing my lean-and-mean JdbcTemplate. I started coding a DatabaseTemplate to help me, and realized I was starting to do something just like Rod. Well, I decided then and there to share my library with anyone who was interested. Hope it helps you like it has helped me.

I think, and it’s not a mockery, that the Java world is rather a framework type of environment which leads usually to have as many frameworks as you have developers for the very reason I described above. Python has also its share of frameworks but the language is flexible enough to encourage libraries. I *strongly* believe that Python Spring[sic] has both functionalities that could be attractive to many developers while having the chance of doing so as a library rather than a framework. –Sylvain while commenting about Spring Python w/CherryPy 3

And that’s why I call it Spring Python. It takes the cool concepts of Spring, and write them in a slick-and-quick, pythonic library. And yes, it is a library.

Is Spring Python notable enough to keep its wikipedia article?

Spring Python has had a wikipedia article for some time. I know, I wrote it. Today, someone has proposed deleting the article, citing that  the it doesn’t establish its notability. I encourage anyone interested to put in their $0.02. However, please do NOT go rabid. Whether you think this fits wikipedia’s criteria for an individual article or not, please put in your opinion backed up by links to resources, while following wikipedia’s guide for article deletion (as show on the site).

Please vote your conscience. What am I trying to say? If you think Spring Python is good, but doesn’t fit their criteria of an article, go ahead and vote it down. If you think this project has something unique and distinct, then vote it up. (Can anyone say unobtrusive AOP?) A key factor is that there is about 7 days before they will make a decision of which way to go, so if you’re going to vote, please vote soon.

Personally, I would like to keep the article. But it’s not the end of the world if its deleted, because this blog, the official website, and our source code repository are the heart and sole of this project. Whatever your opinion is, if you only express it here on this blog, it won’t influence the vote on whether or not to delete this article.

Thanks everyone,

Greg Turnquist, Spring Python project lead

UPDATE:

The wikipedia article has been deleted.

00:05, 18 June 2009 Cirt (talk | contribs) deleted “Spring Python” ‎ (Wikipedia:Articles for deletion/Spring Python)

Spring Python 1.0.0 (RC2) is released

What is Spring Python?

For those of you new to this project, Spring Python takes the concepts implemented by the Spring Framework (Java), and applies them to Python. This provides a powerful library of functionality to help you get back to writing the code that makes you money. You can visit Spring Python’s official web page, or skip right to the downloads.

You’re Late!

Yes, we’re a tad late. Okay, we’re really late, but in case you fell off the planet, SpringSource lost a valuable member of its team, Russ Miles, who was also the sponsor for this project. There were other high priority things happening, so considering this is an extension, it took a little longer than usual to get to making a release. Which brings me to my next point. I want to welcome Mark Pollack as the new sponsor for this extension. He is the code geek that developed Spring .NET. I have had the benefit of meeting him at least year’s SpringOne Americas conference and attending his presentation, and we have also corresponded over email and IM.

So what’s in this release?

You can scroll down to see the release notes. There actually isn’t much change in the code. We are trying to freeze things into a stable API. However, one thing not listed was a key problem we had to solve with coily. coily is the command-line tool that let’s you download Spring Python plugins. Coily was having trouble handling data hosted on the S3 servers used to stage these downloads, so I had to fix it. It now offers you the correct name.

When you query this version to see what plugins are available, you should see this:

$ ./coily --list-available-plugins
Coily v1.0.0 - the command-line management tool for Spring Python
===============================================================================
Copyright 2006-2008 SpringSource (http://springsource.com), All Rights Reserved
Licensed under the Apache License, Version 2.0

Available plugins:
gen-cherrypy-app springpython-plugin-gen-cherrypy-app-1.0.0-RC1.tar.gz 2009-01-22 18:08
gen-cherrypy-app springpython-plugin-gen-cherrypy-app-1.0.0-RC2.tar.gz 2009-06-03 18:23

You may be seeing two copies listed here, but when you try to install, it will grab RC2’s version.

Release Notes

Release Notes – SX Spring Python – Version 1.0.0-RC2

Improvement

Task

What is coming next?

Well, I have been in contact with a company in Germany that is using Spring Python as a key piece of their software solution. They have even granted me access to view their code base. It is exciting seeing them in action, especially since they are writing some extensions to Spring Python and also experimenting with using it inside Jython.

What does this boil down to? Community feedback is a key ingredient to finding out what features need to be added, modified and improved.  Through IM and email, we have already identified some mods to DatabaseTemplate supporting convention-over-configuration, and have already coded a SimpleRowMapper. If your POPO’s attributes match the column names of a query, you don’t need to create a custom RowMapper. Instead, plug-in this one, and it will link them together, without requiring you to extend any of Spring Python’s classes.

self.databaseTemplate.query(
"select name, category from animal",
rowhandler=SimpleRowMapper(testSupportClasses.Animal))

SimpleRowMapper only needs a class name. It will instantiate one of these classes for each row, and then populates the name and category attributes with the results of the query.

There is also a DictionaryRowMapper, which returns a list of dictionaries, instead of tuples. The key point is that convention-over-configuration has become an accepted way to rapidly write essential code without getting caught up the details, and Spring Python embraces this concept.

There is just one wrinkle to make this work: the API used in RowMapper has a slight change (we added metadata as an optional attribute). Since 1.0 is a frozen API, and we are trying to get to a final release, Sven and I agreed to put this change into Spring Python v1.1, so for now, you can only get it from our source repository. Stay tuned for updates!