views:

96

answers:

3

I'm trying to simulate some data in to the datastore to emulate POSTs.

What I'm looking for is a way to post named arguments but as one argument. So I can use the same method as a normal POST would do.

The method I want to invoke get params in two ways.

def HandlePost(params):
    params.get('name')
    params.get_all('collection')

class SavePartHandler(webapp.RequestHandler):
    def post(self):
        HandlePost(self.request)

I'm trying to find out what type the self.request are but can't find it anywhere in appengines source code.

My goal is to simulate multiple POST to fill the datastore by the methods users would.

EDIT:

Or is the anyway to change the behavior of dict so it could use the get_all method?

EDIT 2:

I'm using appengins webapp.

Out of curiosity is there a way to invoke a dummy webapp.RequestHandler and populate it with arguments? I'm browsing the source code to see how it's done and made a new instance of it but can't find how to populate it.

EDIT 3:

Updated method name so it's not confused with webapp request handlers.

Thanks to pthulin I'm almost there. Only thing left is how to simulate data that has the same key. Since using a dict will override other keys with the same name. Sometimes in HTML forms a post can contain multiple values for the same key that we get with self.request.get_all('key'). So how to create a dict (or something equal) that supports multiple key=value with same key.

..fredrik

+1  A: 

For sure they are request objects that represents a http request. It should usually contain typical http request information like method , uri, message etc.

To find out what type self.request are, you could do introspection without the doc. if self.request is a instantiation of a class then you could obtain the class name through

print self.request.__class__

[Edit]:

The information is provided in the google app engine document

pyfunc
He's not using webapp.
Nick Johnson
@Nick Johnson: @fredrik: The question mentions app engine source. I presumed it. Although using the print statement, fredrik should be able to find the class name and locate further information by greping the source
pyfunc
@pyfunc, yes webapp. Found the class name in the source and looking in to it.
fredrik
That's not a webapp handler. Either you're doing it wrong, or you're using a different framework.
Nick Johnson
@nick, updated the question. It's webapp, but the PostHandler was just a bad name. It's a method called by a webapp request handler
fredrik
+1  A: 

I think what you want to do is prepare a webapp Request object and then call the post method of your handler:

from google.appengine.ext.webapp import Request
from google.appengine.ext.webapp import Response
from StringIO import StringIO
form = 'msg=hello'
handler.response = Response()
handler.request = Request({
    'REQUEST_METHOD': 'POST',
    'PATH_INFO': '/',
    'wsgi.input': StringIO(form),
    'CONTENT_LENGTH': len(form),
    'SERVER_NAME': 'hi',
    'SERVER_PORT': '80',
    'wsgi.url_scheme': 'http',
})
handler.post()

TIP: 'msg=hello' above works fine in this case, but to pass multiple POST parameters you need to create a URL encoded string:

>>> form = {
...     'first_name': 'Per',
...     'last_name': 'Thulin',
... }
>>> from urllib import urlencode
>>> urlencode(form)
'first_name=Per&last_name=Thulin'

If you want to pass in multiple POST parameters with the same name, I think you need to do a little bit of the url encoding work yourself. For example:

>>> from urllib import urlencode
>>> form_inputs = [
...     {'someparam': 'aaa'},
...     {'someparam': 'bbb'},
...     {'someparam': 'ccc'},
... ]
>>> '&'.join([urlencode(d) for d in form_inputs])
'someparam=aaa&someparam=bbb&someparam=ccc'

Then in the RequestHandler, you can extract the parameters with the Request.get_all method.

pthulin
Thanks, this is what I was looking for. But the only thing I can't figure out. I updated the question.
fredrik
OK, I updated my response with a solution on how to send multiple post parameters
pthulin
Thanks. Works great. Also urlencode([('test',1), ('test', 2)]) seems to work fine!
fredrik
A: 

Yes, that can be done. Here's the webapp response handler. The way to do it is to use the response.argument() which returns a list of the data arguments. Then iterate and get(each one). Just for clarity, I show how to handle named arguments that are known ahead of time and also multiple arbitrary arguments as you ask:

from google.appengine.ext import webapp

class postHandler(webapp.RequestHandler):
def post(self):

    # Handle arguments one at a time
    var1 = self.request.get('var1')

    # or get them all and build a dict:
    args = self.request.arguments()
    arg_dict = {}
    for arg in args:
        arg_dict.update(arg: self.request.get(arg))

Here's some documentation: http://code.google.com/appengine/docs/python/tools/webapp/requestclass.html#Request_get_all

vonkohorn