Blogging on App Engine Interlude: Editing and listing
Posted by Nick Johnson | Filed under coding, app-engine, tech, bloggart
Blogging on App Engine, part 2: Basic blogging
Posted by Nick Johnson | Filed under coding, app-engine, tech, bloggart
Blogging on App Engine, part 1: Static serving
Posted by Nick Johnson | Filed under coding, app-engine, tech, bloggart
Win a Dell Netbook and $1000 of App Engine credit!
Posted by Nick Johnson | Filed under coding, app-engine, tech
Just a quick note: We recently announced a competition on the App Engine blog: Develop an App Engine app that uses Twilio, and you could win a Dell Netbook and $1000 of App Engine credit! Twilio is an excellent service that lets you write sophisticated telephony applications, entirely over HTTP.You have until October 4th to enter. I really wish I could, but as part of the team, I'm disqualified. ;)
Writing a blog system on App Engine
Posted by Nick Johnson | Filed under coding, app-engine, tech, bloggart
I'm going to spend the next few posts working through the process of writing a simple, robust and scalable blogging system for App Engine. This first post is going to be fairly dull, unfortunately, as it will serve to cover what our requirements and non-requirements are, and the general approach we're going to take to achieve those objectives. In other words: Lots of bullet points, and little to no code. Don't worry, it'll get more exciting soon.
First, let's outline what we (or at least, I) expect out of a blogging system:
- Simple authoring. I personally don't want to juggle with WYSIWYG HTML editors in order to write blog posts - I prefer to enter markup directly. But at the same time, I don't intend to make all potential users conform to the same expectations - so we should be able to support rich text editors if they're desired.
- Good isolation of code and markup. Users shouldn't have to understand the innards of our blogging software if all they want to do is change how the blog looks or is laid out.
- RSS and Atom support. This should go without saying, these days ...
Handling file uploads in App Engine
Posted by Nick Johnson | Filed under coding, app-engine, cookbook, tech
This is the ninth in a series of 'Cookbook' posts describing useful strategies and functionality for writing better App Engine applications.One issue that comes up frequently on the App Engine groups is how to handle file uploads from users. Part of the confusion arises from the fact that App Engine apps cannot write to the local filesystem. Fortunately, the Datastore comes to the rescue: We can easily write an app that accepts file uploads and stores them in the datastore, then serves them back to users.
To start, we need an HTML form users can upload files through:
<html>
<head>
<title>File Upload</title>
</head>
<body>
<form method="post" action="/">
<input type="file" name="file" />
<input type="submit" value="Upload" />
</form>
</body>
</html>
We'll also need a datastore model we can store the uploaded file in:
class DatastoreFile(db.Model):
data = db.BlobProperty(required=True)
mimetype = db.StringProperty(required=True)
And finally, a Request Handler that can handle the uploads:
class UploadHandler(webapp.RequestHandler):
def get(self):
self.response.out.write(template.render("upload.html", {}))
def post(self):
file = self.request.POST['file']
entity = DatastoreFile(data=file.value, mimetype=file.type)
entity.put()
file_url = "http://%s/%d/%s ...
Custom Datastore Properties 1: DerivedProperty
Posted by Nick Johnson | Filed under coding, app-engine, cookbook, tech
Advanced Bulk Loading Part 5: Bulk Loading for Java
Posted by Nick Johnson | Filed under coding, app-engine, cookbook, tech
This is the seventh in a series of 'cookbook' posts describing useful strategies and functionality for writing better App Engine applications.When it comes to Bulk Loading, there's currently a shortage of tools for Java users, largely due to the relative newness of the Java platform for App Engine. Not all is doom and gloom, however: Users of App Engine for Java can use the Python bulkloader to load data into their Java App Engine instances! Because App Engine treats each major version of an app as a completely separate entity - but sharing the same datastore - it's possible to upload a Python version specifically for the purpose of Bulk Loading. This won't interfere with serving your Java app to your users.
To follow this guide, you won't need to understand much of the Python platform, though you will need to know a little Python. If your bulkloading needs are straightforward, you won't need to know much at all - it's essentially connect-the-dots - but if your bulkloading needs are a little more complex, you'll need to understand some of the basics of programming in Python - defining and calling functions and methods, basically. Who knows, you ...
Advanced Bulk Loading, part 4: Bulk Exporting
Posted by Nick Johnson | Filed under coding, app-engine, cookbook, tech
return converter
Advanced Bulk Loading, part 3: Alternate datasources
Posted by Nick Johnson | Filed under coding, app-engine, cookbook, tech
This is the fifth in a series of 'cookbook' posts describing useful strategies and functionality for writing better App Engine applications.
The bulkloader automatically supports loading data from CSV files, but it's not restricted to that. With a little work, you can make the bulkloader load data from any datasource you can access with Python. The key to this is the generate_records method. This method accepts a filename, and is expected to yield a list of strings for each entity to be uploaded. By overriding this method, we can load from any datasource we wish - for example, a relational database such as MySQL. To make this reusable, let's define a base class we can use to load data from MySQL databases:
import MySQLdb
class MySQLLoader(bulkloader.Loader):
def __init__(self, kind_name, query, converters):
self.query = query
bulkloader.Loader.__init__(kind_name, converters)
def initialize(self, filename, loader_opts)
self.connect_args = dict(urlparse.parse_qsl(loader_opts))
def generate_records(self, filename):
"""Generates records from a MySQL database."""
db = MySQLdb.connect(self.connect_args)
cursor = db.cursor()
cursor.execute(self.query)
return iter(cursor.fetchone, None)
What we've done here is extended the bulkloader's Loader class to load from a MySQL database instead ...
Newer Older