Sign in

Google Cookbook - Google App Engine

Posted by peplafi on Thu 02 Jul 2009 in Python
I wrote a small piece of python code that allows you to run automatically scheduled tasks on your local development server. It is useful when you have a lot of tasks and you just don't want to hit "Run" thousand times from the admin console. Basically, it is a stand-alone script that you have to run while the development server is on. Here is how it works:

1. Download BeautifulSoup from http://www.crummy.com/software/BeautifulSoup/
and make it accessible in the Python's import path. My script uses BeautifulSoup to parse some HTML.

2. Edit the following line in my script:

COOKIE = 'uid=thaye0mr; dev_appserver_login="test@example.com:True:185804764220139124118"'

The value of COOKIE should be equal to the value of the cookie that your browser sends to the development server when you view the admin console. It is used for authentication and is different for everyone. So, you have to put the correct value for you. You can easily find it when you look at the Request's headers that your browser sends i.e. for the page 'http://localhost:8080/_ah/admin/queues'. So, just copy/paste its value from there in the python script.

3. Add some tasks to one of your queues (i.e. my-queue)

4. Run the script with the name of the queue:
run_tasks.py my-queue

Enjoy :)
Feedback is welcome!
Posted by billkatz on Tue 30 Jun 2009 in Datastore
A simple full text search module has been released under the MIT license.

Full article is here:
http://www.billkatz.com/2009/6/Simple-Full-Text-Search-for-App-Engine

The test app code repository is here:
http://github.com/DocSavage/appengine-search

An example of its use:

class Page(Searchable, db.Model):
author_name = db.StringProperty()
content = db.TextProperty()
myPage = Page(author_name='John Doe', content='My amazing content!')
myPage.put()
# This will queue indexing via Task Queue API
myPage.queue_indexing(url='/tasks/searchindexing')
# After index is complete, you can run searches
Page.search('search phrase') # -> Returns Page entities
Page.search('stuff', keys_only=True) # -> Returns Page keys

Posted by tytung on Mon 15 Jun 2009 in Datastore
GoogleFileService is based on Google App Engine for Java, and its aim is to provide data models and APIs for uploading and downloading large files of each size is up to 10MB to and from Google Datastore via HTTPS securely.

For more information on GoogleFileService, please visit http://code.google.com/p/google-file-service/

With GoogleFile and GoogleUnit data models (datastore), you can upload a large file of size up to 10 MB very easily via our static method DatastoreUtils.insertGoogleFile().

Some main code of FileUploadServlet.java is as follows:
String fileId = "";
String fileOwner = "";
String fileName = "";
int fileSize = -1;
String contentType = "";
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload();
// Set overall request size constraint: the default value of -1 indicates that there is no limit.
upload.setSizeMax(10240000); //10MB, the maximum allowed size, in bytes.
// Set the UTF-8 encoding to grab the correct uploaded filename, especially for Chinese
upload.setHeaderEncoding("UTF-8");
// Parse the request
FileItemIterator iter = upload.getItemIterator(req);
while (iter.hasNext()) {
FileItemStream item = iter.next();
InputStream stream = item.openStream();
String fieldName = item.getFieldName();
if (item.isFormField()) {
//process a regular form field
if (fieldName.equals("fileId"))
//set the UTF-8 encoding to grab the correct string
fileId = Streams.asString(stream, "UTF-8");
if (fieldName.equals("fileOwner"))
//set the UTF-8 encoding to grab the correct string
fileOwner = Streams.asString(stream, "UTF-8");
} else {
//process a file upload
fileName = item.getName();
if (fileName != null)
fileName= FilenameUtils.getName(fileName);
contentType = item.getContentType();
if (fieldName.equals("upfile")) {
// Check if the fileId conforms to the Key format of the Google datastore
// and all other uploaded fields are not empty.
if (DatastoreUtils.isKey(fileId) AND(please replace with java AND) fileOwner.length() > 0 AND fileName.length() > 0) {
// Save into Google datastore
fileSize = DatastoreUtils.insertGoogleFile(fileId, fileOwner, fileName, contentType, stream);
}
}
}
}

Posted by tytung on Mon 15 Jun 2009 in Java
GoogleFileService is based on Google App Engine for Java, and its aim is to provide data models and APIs for uploading and downloading large files of each size is up to 10MB to and from Google Datastore via HTTPS securely.

For more information on GoogleFileService, please visit http://code.google.com/p/google-file-service/

With GoogleFile and GoogleUnit data models (datastore), you can upload a large file of size up to 10 MB very easily via our static method DatastoreUtils.insertGoogleFile().

Some main code of FileUploadServlet.java is as follows:
String fileId = "";
String fileOwner = "";
String fileName = "";
int fileSize = -1;
String contentType = "";
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload();
// Set overall request size constraint: the default value of -1 indicates that there is no limit.
upload.setSizeMax(10240000); //10MB, the maximum allowed size, in bytes.
// Set the UTF-8 encoding to grab the correct uploaded filename, especially for Chinese
upload.setHeaderEncoding("UTF-8");
// Parse the request
FileItemIterator iter = upload.getItemIterator(req);
while (iter.hasNext()) {
FileItemStream item = iter.next();
InputStream stream = item.openStream();
String fieldName = item.getFieldName();
if (item.isFormField()) {
//process a regular form field
if (fieldName.equals("fileId"))
//set the UTF-8 encoding to grab the correct string
fileId = Streams.asString(stream, "UTF-8");
if (fieldName.equals("fileOwner"))
//set the UTF-8 encoding to grab the correct string
fileOwner = Streams.asString(stream, "UTF-8");
} else {
//process a file upload
fileName = item.getName();
if (fileName != null)
fileName= FilenameUtils.getName(fileName);
contentType = item.getContentType();
if (fieldName.equals("upfile")) {
// Check if the fileId conforms to the Key format of the Google datastore
// and all other uploaded fields are not empty.
if (DatastoreUtils.isKey(fileId) AND(please replace with java AND) fileOwner.length() > 0 AND fileName.length() > 0) {
// Save into Google datastore
fileSize = DatastoreUtils.insertGoogleFile(fileId, fileOwner, fileName, contentType, stream);
}
}
}
}

Posted by rodrigo.moraes on Thu 11 Jun 2009 in Datastore
If you need to store a list of related values in a single property, this special property can be useful.

As of June 20th, 2009, the CsvProperty code is available in the repository:

http://bitbucket.org/moraes/appengine/src/tip/gaefy/db/properties.py

An example of use:

class MyModel(db.Model):
rules = CsvProperty(field_count=3)

new_entity = MyModel()
new_entity.rules = [('foo', 'bar', 'baz'), ('abc', 'def', 'ghi'), ('my', 'new', 'property')]
new_entity.put()



The data is stored in CSV format:
foo,bar,baz
abc,def,ghi
my,new,property



... but can be manipulated as the original list.
Posted by dafdaf72@yahoo.com on Thu 04 Jun 2009 in URLFetch API
Ingredients Method



1 kg diced chicken thighs - First cook the chicken in a pan with some oil .

1/5 kg button mushrooms - Then sauté the mushrooms in a pan , add the

100 gr sliced shallots garlic , spices , cook for 5 minutes

1 tbs chopped garlic then add the wine and reduce , then add the

3 gr paprika powder double cream and the chicken bring to boil

3 gr coriander powder let it reduce a little bit , and chill .

3 gr ginger powder - Put the chicken & mushroom mix in a tray

150 ml white wine and cover with puff pastry , egg wash and cook .

1 litre double cream

puff pastry
Posted by meepmeepmeepenator on Wed 03 Jun 2009 in Datastore
When working with Datastore, it is often desirable to share Model instances among functionally distinct parts of your application, in order to avoid redundant calls to db.get() and db.put().

One problem that regularly crops up when sharing like this, and often even when writing simple pieces of code, is how to track which instances have been modified, and require saving.

A simple example of this problem is when processing a form POST to update a user's profile. In order to avoid a redundant put(), your code would need to compare each of the user's provided values with the existing value stored in their profile model instance, for example:

profile = Profile.get_by_key_name('someuser')

dirty = False

for field in ['username', 'password', 'description']:
new_value = self.request.get(field)
if new_value != getattr(profile, field):
dirty = True

setattr(profile, field, new_value)
new_age = int(self.request.get('age'), 10)
dirty = dirty or (new_age != profile.age)
profile.age = new_age

if dirty:
db.put(profile)



It's clear that a very simple function is obfuscated by boilerplate code used to track whether the instance has changed.

The attached file implements a Model subclass named TrackedModel, that will automatically instrument your model classes with a magical 'dirty' variable. If any property changes value during the life of the instance, this variable will be set to true. With this class, we can now write:

profile = Profile.get_by_key_name('someuser')

for field in ['username', 'password', 'description']:
setattr(profile, field, getattr(profile, field))

profile.age = int(self.request.get('age'), 10)
if profile.dirty:
db.put(profile)



Additionally, the class overrides put() to allow replacing the last 2 lines with:

profile.put(if_dirty=True)



There, much simpler!
Posted by otto.hartvich on Mon 01 Jun 2009 in Datastore
App Engine SDK 1.2.1

Using @NamedQuery annotation in the JPA entity class be sure that you use fully qualified class name in the SQL.

Wrong - trying to use named query 'allUsers' throws ClassNotResolvedException:

package com.test.domain;

@Entity
@NamedQuery(name="allUsers", query="select u from User u")
public class User {...}

Correct - this works

package com.test.domain;

@Entity
@NamedQuery(name="allUsers", query="select u from com.test.domain.User u")
public class User {...}
Posted by matthewmatthewfl on Sun 31 May 2009 in Python
A simple URL shortener back end.
In your app.yaml you need to add
- url: .*
script: urlshort.py


and at the top of the file you should change "Conf_NotFound" to a Url to work with pages that are not found.

Note: The shortened Urls will always have a number in it.
Posted by rodrigo.moraes on Wed 27 May 2009 in Datastore
This method uses the PagerQuery class, which is based on the article "Efficient paging using __key__ instead of a dedicated unique property" [1]. It allows "efficient paging in any query, on any schema, purely in user land, without requiring extra properties or other schema changes". This means that no extra property is required as an index, and that you can easily build efficient pagination for any existing Model or query.

Get the class here:
http://bitbucket.org/moraes/appengine/src/tip/pager.py

And this is a quick example of how it works:
# Get the encoded bookmark from request.
bookmark = request.GET['bookmark']

# Build a paginated query. PagerQuery wraps db.Query and
# has the same methods, so there's nothing to learn here.
query = PagerQuery(ModelClass).filter('foo >', 'bar') \
.filter('baz =', 'ding') \
.order('foo')

# Fetch results for the current page and bookmarks for previous and next
# pages.
prev, results, next = query.fetch(10, bookmark)


Then in your template, display the results and if 'prev' and/or 'next' are available, use them to create links to the previous and/or next page of results. For example:

http://localhost:8080/?bookmark={{ prev }}
http://localhost:8080/?bookmark={{ next }}

Try it! And let me know how can we improve it. :-)

[1] http://google-appengine.googlegroups.com/web/efficient_paging_using_key_instead_of_a_dedicated_unique_property.txt