Posts in Python

Monday, July 13, 2009

AIR, Titanium and webOS: 10 Things You Can’t Do in A Browser

You can't do that

In the past two years I’ve spent most of my free time working on desktop applications written in JavaScript, HTML and CSS. I write them on top of web runtime platforms like Titanium and Adobe AIR, and more recently Palm’s webOS. In this time, I’ve heard a misconception raised repeatedly: that “local” (desktop or mobile) applications written on top of web runtimes offer no advantage over remotely-hosted, browser based apps. Or, to paraphrase something I overheard recently:

HUH huh your app is written in JavaScript and HTML, why don’t you just load the web site DURRRR.

I suppose this kind of thinking comes from the JS+HTML+CSS being almost exclusively used for web site front-ends for so many years. It’s a knee-jerk reaction, much like the one that says “oh, you can’t use PHP in the ‘enterprise’” or “Oreos aren’t for breakfast.” Proved my mom wrong on that one.

So, I decided to make a list of what things you can do in a web runtime platform that you can’t do in a browser. Now some of these vary depending on the platform or the browser, and I’ll try to make note of them in my list:

  1. Cross-browser compatibility issues are a thing of the past
    I should offer a caveat here — even though the rendering engines are the same, you’ll sometimes run into OS rendering differences. AIR, for example, supported CSS3 box shadows on OS X until v1.5, but never did on Windows. But the differences are far, far smaller than you’d see between, say, Safari 3 and IE6. Trust me — you will love not having to worry about getting your layout working in some ass-tastic box model implementation anymore

  2. Advanced rendering features (CSS3, etc)
    Since you don’t have to worry about looking the same in different browsers, you can take advantage of the special features your runtime’s rendering engine supports. Titanium, for example, supports the same advanced CSS features that Safari 4 does, like box shadow, border radius, and CSS gradients.

  3. File system access
    On desktop web runtime platforms like AIR and Titanium, you can interact with the filesystem just like any other application: read, write, and create files and folders with the permissions of the executing user. webOS offers less freedom in this respect, but you can read and write files on a limited basis.

  4. Networking
    Both of the major desktop web runtime platforms provide much more advanced networking capabilities than are available within a browser. I’m not much of a networking programmer, but both platforms allow the developer to open TCP socket connections and communicate over them. Titanium seems especially well-prepared in this area, with its ability to leverage Python and its powerful networking capabilities.

  5. No same-origin policy restrictions
    If you want to pull data from a web site other than your own in the browser, you have to resort to JSONP — basically an XSS attack waiting to happen — or set up a proxy on your site’s server. Web runtime app platforms don’t have this issue, so you can make XHR calls to any domain you wish, and interact with any APIs.

  6. No need to support non-JS users
    This might seem like a small issue, but having to support users who have disabled JS was one of the major reasons I never did serious browser-based frontend programming before I started working on Spaz two years ago. Now the cool kids at SXSW will tell you that “nobody” disables JavaScript, but I think that’s kind of short-sighted.

    Nevertheless, this argument and the need for graceful degradation and “unobtrusive” JavaScript become moot in the web runtime app platform. JavaScript is there, it’s expected, and you can’t disable it. So go crazy.

  7. Using/interacting with platform-specific UI elements
    This includes things like window chrome, menu systems, Dock items (OS X), menulings (OS X) and the System tray (Win/Linux). Both major web runtime platforms display your application within the native window chrome, allow you to create native menus, and give you some access to the system tray and OS X’s Dock. Titanium is a bit better in this regard in that it inherits the native look of form widgets and scrollbars, and provides access to the OS X menubar (those little icons in the top-right).

  8. Sound playback without plugins
    Until HTML5 becomes standard in all browsers and bestows the grace of plugin-less media playback, we’re stuck <embed>ing <object>s in our gorgeously crafted markup. Funk dat. Web runtime platforms provide sound playback APIs that mean we don’t have to stick a Flash applet in our document and hope it doesn’t catch the CPU on fire. AIR has a particularly good playback API (probably because the whole thing is running in a Flash engine. Small victories).

  9. Interacting with other applications/shell interaction
    Being able to leverage other applications on the machine/device can be really valuable, especially on Unix OSes (Mac OS X, Linux, etc) that have a bevy of useful utilities available from the shell. Titanium is the only desktop web runtime platform that allows the developer full access to these capabilities; AIR is limited to interacting with other Flash-based applications at this time (although this may change in the future). Runtimes on mobile devices are typically much more limited, although webOS’s Application Manager service does let applications launch and pass arguments to other apps.

  10. Database support
    Typically this is implemented either via the HTML5-style database stuff (usually asynchronous) or a platform-specific SQLite (usually synchronous). Out of the box, support isn’t provided for external DB servers (MySQL, PostgreSQL, MS-SQL, etc), but with Titanium this should be possible by delegating to Python or Ruby scripts, or Titanium kernel modules. DB servers that provide HTTP interfaces (like CouchDB) will work fine, though.

All of this doesn’t mean web runtime platforms are going to replace browser-based apps anytime soon. There are clear advantages to remotely hosting an application (speed of updating comes to mind), and supporting an app on a user’s machine brings a new group of debugging headaches. But for applications already chafing at the limitations of the browser, web runtime platforms offer a compelling option.

Posted in AIR, JavaScript, Python, Spaz, webOS by funkatron on 07/13 at 10:29 AM

Thursday, November 06, 2008

The Funkatron.com PHPMAX 2008 US Tour

The Funkatron.com PHPMAX 2008 US Tour

The coming weeks are gonna be a little hectic for me, as I fly to Atlanta on the 12th to attend php|works / PyWorks 2008. I’ll be doing the following talks:

I’m pretty excited about php|works / PyWorks 2008, especially because we can interact with the Python community and learn more about each other’s tech. Cross-pollination is a Good Thing.

I’m flying back to IND on the 15th, but then I’m leaving again on the 16th for San Francisco and the Adobe MAX 2008 conference. I’m giving the following talk:

Originally this talk was going to be given by John Resig, creator of the jQuery library, but he ran into some time constraints and thoughtfully suggested me. Of course, the description still mentions his name, which likely means I’ll be tarred and feathered by the audience. This also looks like it may be the largest audience I’ve ever given a talk before: there are currently about 70 folks listed as attending, with ~300 capacity. So if I wet myself on stage, please forgive me.

Posted in AIR, JavaScript, jQuery, Python, PHP by funkatron on 11/06 at 06:29 PM

Wednesday, June 25, 2008

Give me your money, suckers

Gopher Robbery

I have these five promo codes from Dreamhost. They expire in three days. Apparently you get super-hot deals with them, like:

  • Four times the normal disk and bandwidth
  • $150 off a 5-year plan
  • $200 off a 10-year plan

I would not sign up for 5 years with any shared host. However, I do think DH is pretty decent for small-ish sites that can work with shared hosting. I’m well aware that they’ve had a couple embarrassing public flubs in the past couple years, but I generally think they’re good folks who try to do right by their customers. Some will certainly disagree, of course. 8)

I still maintain my old account there for low-cpu, high-bandwidth/storage stuff. They do quite well with PHP hosting, and can handle Ruby and Python setups with a little effort. They’ll let you do crazy stuff like compile your own PHP if you are fine with using FastCGI, and have a nice GUI to setup SVN repos. Not many shared hosts will do the same at a similar price point.

Anyway, here are the codes. They’re first come, first serve. Yes, I make money if you sign up with one of them. I will not be hurt if you don’t use them.

  • 998942362256
  • 916860787004
  • 591140700044
  • 047271781406
  • 160643597831

Dreamhost Signup Page

Posted in Development, The Web Problem, Python, PHP by funkatron on 06/25 at 05:26 PM

Tuesday, June 03, 2008

Google App Engine from a PHP developer’s perspective

My cheatin' heart

When Google AppEngine was announced, a lot of sturm und drang went through the PHP community because it only supported Python. Of course, the same thing went through the Ruby community. The Perl community, not so much, because they’re used to getting ignored.

Anyway, I didn’t really give a crap, because Python is a cool language, and I’ve been interested in learning new languages and frameworks lately. PHP is cool and all, but having done it for 9 years, you kinda look for new challenges. Plus, getting hung up on one language is a sure way to be a boring dude who gets caught up in lame religious language wars.

I’ve actually toyed a little with Python here and there, but never dove in on a significant project. I’m someone who really likes whitespace and indenting rules and such, so those aspects of the language never bothered me. Otherwise, Python is a good fit for me philosophy-wise, because it’s totally the anti-Perl, lacking goofy magic characters and 1000 ways of doing the same thing. I can’t stand languages where “~^s” means “find all numbers that start with the letter ‘s’, add them, multiply them by 75, and then post the result to Twitter”. I’m not freakin’ R2D2 here.

So anyway, I started working on a little side project with Alex Payne on GAE. It’s been an enjoyable experience to work with a new language and framework, and there’s a lot to like about what GAE offers. It also has some rough edges, though, in some areas you’d be surprised by.

The good

The webapp framework

The built-in framework for handling requests is webapp, a nicely straightforward system for mapping requests to handlers.

class MainPage(webapp.RequestHandler):
    def get(self):
        self.response.out.write('Sup dogg?')

class FooPage(webapp.RequestHandler)
    def get(self):
        self.response.out.write('This is the foo page')

def main():
    wapp = webapp.WSGIApplication([
                                    ('/', MainPage),
                                    ('/foo', FooPage)
                                  ],
                                  debug=True)

    wsgiref.handlers.CGIHandler().run(wapp)

So we define a class to handle a specific URL request, and define methods for GET or POST or whatever HTTP commands inside those classes. Then in the main function we map URLs to those handler classes in the webapp.WSGIApplication constructor, and then start it up.

I like this because it’s simple and easy to follow. I could read the code before I’d written any myself and get what’s going on. There’s no magic happening here; no auth-mapped stuff or relationships established because I happened to name something the right way and put it in the right directory. Convention is good, and we have conventions here, but the conventions are clear and obvious.

Django templating

Django has a really nice templating system. GAE lets you use it outside of the whole Django stack. This is cool. For example:

# define some values to plug into the template
tpl_data = {
    'page_title':"This is an awesome page",
    'body':"Here's the page body, sucker"
    }

# get the template path
path = os.path.join(os.path.dirname(__file__), 'index.html')

#render and output the template
self.response.out.write(template.render(path, tpl_data))

Here’s a super simple index.html template:

<html>
    <head>
        <title>{{ page_title.striptags }}</title>
    </head>
    <body>
        {{ body }}
    </body>
</html>

Google User Auth

Writing a user system is a pain. Making people set up new accounts to use your site is yet another barrier to experiencing your amazing new Google sellout project site. You could presumably do these things if you want in GAE, but most of the time that seems kinda stupid. GAE offers you very easy integration with Google user accounts, so you can use that as your authentication system. Since everyone and their mom has a Gmail account, it’s a pretty good bet many or most of your users will be able to skip account setup.

Pricing

GAE is free for your first 500MB of storage and “around” 5 million pageviews. That’s plenty to host a smallish app or do initial testing on something you want to get big (because big == profit, right?). If you push past that, the pricing is in-line with similar services from Amazon. That means it’s totally reasonable to set up an app just for goofing around and learning.

Python

Python is a cool language: easy to pick up and quite powerful. It doesn’t fit some tasks as well as PHP IMHO, but it does a ton of stuff well, and its large community means there is lots of support and library development. Some stuff it does really well includes:

  • Network programming (example)
  • Parsing HTML
  • Email parsing and manipulation
  • OS X scripting
  • String manipulation
  • Unit testing
  • Other stuff I probably don’t know about

AppEngineLauncher

Recently the GAE team released the Google App Engine Launcher, an app for OS X that handles launching the development server and deploying your app to Google’s servers. You can of course script all this stuff yourself on the command line, but for folks less comfortable with that, this is a godsend. I actually did use the CLI before, but I don’t touch it now because the GAEL is just so fly. Single-click deployment is especially awesome.

Leveraging Google’s Infrastructure

They gots some big computers, rite? You’d certainly think so, and they probably have better uptime than your $5 shared hosting account. We hope.

The lame

Datastore query limitations & primitive text search

The Datastore API is GAE’s database system. It has some similarities to traditional relational DBs like MySQL and PostgreSQL, but it is fundamentally different. It stores data objects as entities instead of rows, and properties instead of columns. Objects are described by model classes, defined in Python:

class Page(db.Model):
    title = db.StringProperty(required=True)
    keywords = db.StringProperty()
    date_added = db.DateProperty(required=True)
    date_updated = db.DateProperty(required=True)
    body = db.StringProperty()

Models are to entities as classes are to objects, then (I think).

The object approach has some cool flexibility, like expando models that let you add arbitrary properties to entities (very unlike rows in a relational database).

You can do SQL-like queries against the Datastore with GQL. It’s a lot like SQL, but a lot more basic. In fact, this is a summary of the entire language:

SELECT * FROM <kind>
[WHERE <condition> [AND <condition> ...]]
[ORDER BY <property> [ASC | DESC] [, <property> [ASC | DESC] ...]]
[LIMIT [<offset>,]<count>]
[OFFSET <offset>]

<condition> := <property> {< | <= | > | >= | = | != } <value>
<condition> := <property> IN <list>
<condition> := ANCESTOR IS <entity or key>

This lets you do basic queries, but it’s missing a lot of powerful stuff present in SQL. Most notably there is no equivalent to the LIKE comparison operator. That means there is no way to do partial string matches!

Okay, so you can do kludgy prefix matching, and there is an as-of-yet undocumented whole word search using the SearchableModel class, but those are primitive compared to the string matching capabilities in MySQL. Personally I would’ve thought that the search company would have given GAE really awesome text search capabilities out of the box, but for now folks have to roll their own hacks.

I guess now I have an idea of why Gmail’s search can’t match partial strings.

No “beginner” docs

GAE’s docs are aimed at experienced developers who have already built web apps. Most of it is reference, and it’s a little light on examples. If you’ve not used Python before, here’s the entire introduction form the GAE docs:

For more information about Python, see the Python website and the Python documentation.

I think Python is easy to pick up, but GAE doesn’t even bother pointing out some good tutorials for beginners. Compare this to The Django Book or The Definitive Guide to Symfony, both of which aren’t really for beginners, but do a good job of helping them get up to speed.


I’m early in my development experience with GAE, so this is by no means comprehensive. Google has already demonstrated that the GAE feature set will be growing, having introduced memcache and image manipulation APIs just a week ago. I’m sure the documentation will be improved and supplemented by third parties in short order, and the issues with text search will almost certainly be addressed soon – it’s an obvious deficiency.

For now, I’m having a lot of fun working with GAE. It’s a solid platform with a lot of promise, and it offers a lot of learning opportunities for folks who want to explore web app dev with Python.

Posted in Development, The Web Problem, Python, PHP by funkatron on 06/03 at 09:11 PM
Page 1 of 1 pages