Flask : understanding POST method to transmit data - python

my question is quite hard to describe, so I will focus on explaining the situation. So let's say I have 2 different entities, which may run on different machines. Let's call the first one Manager and the second one Generator. The manager is the only one which can be called via the user.
The manager has a method called getVM(scenario_Id), which takes the ID of a scenario as a parameter, and retrieve a BLOB from the database corresponding to the ID given as a parameter. This BLOB is actually a XML structure that I need to send to the Generator. Both have a Flask running.
On another machine, I have my generator with a generateVM() method, which will create a VM according to the XML structure it recieves. We will not talk about how the VM is created from the XML.
Currently I made this :
Manager
# This method will be called by the user
#app.route("/getVM/<int:scId>", methods=['GET'])
def getVM(scId):
xmlContent = db.getXML(scId) # So here is what I want to send
generatorAddr = sgAdd + "/generateVM" # sgAdd is declared in the Initialize() [IP of the Generator]
# Here how should I put my data ?
# How can I transmit xmlContent ?
testReturn = urlopen(generatorAddr).read()
return json.dumps(testReturn)
Generator
# This method will be called by the user
#app.route("/generateVM", methods=['POST'])
def generateVM():
# Retrieve the XML content...
return "Whatever"
So as you can see, I am stuck on how to transmit the data itself (the XML structure), and then how to treat it... So if you have any strategy, hint, tip, clue on how I should proceed, please feel free to answer. Maybe there are some things I do not really understand about Flask, so feel free to correct everything wrong I said.
Best regards and thank you
PS : Lines with routes are commented because they mess up the syntax coloration

unless i'm missing something couldn't you just transmit it in the body of a post request? Isn't that how your generateVM method is setup?
#app.route("/getVM/<int:scId>", methods=['GET'])
def getVM(scId):
xmlContent = db.getXML(scId)
generatorAddr = sgAdd + "/generateVM"
xml_str = some_method_to_generate_xml()
data_str = urllib.urlencode({'xml': xml_str})
urllib.urlopen(generatorAddr, data=data_str).read()
return json.dumps(testReturn)
http://docs.python.org/2/library/urllib.html#urllib.urlopen

Related

submit request (post) internally in python-eve

I have a resource in eve e.g. ABC, I want to manipulate another resource e.g. BCD when some condition meet while I am posting a new item to ABC, I know I can hook the event for post/pre_POST_ABC but is there a 'internal' way to do post on BCD without going through via the HTTP again?
In your callback function you could either:
A) use the data driver to store data directly to the database
Something like this:
def update_ABC(request, payload):
accounts = app.data.driver.db['abc_collection']
account = accounts.insert(docs)
app = Eve()
app.on_post_POST_ABC += update_ABC
app.run()
Would do the trick. You would be bypassing the framework this way, and storing directly on the database.
B) Use app.test_client.post() to POST through directly through the application.
app.test_client().post('/bcd', json.dumps({"field":"value"}, content_type='application_json'))
This is probably a better option since the request goes through the framework (meta fields like data_created are handled for you.)
Update: With v0.5+ you can now use post_internal to achieve the same result. There are equivalent internal methods available for other CRUD methods as well.

Structring data flow in GAE without using globals

I am setting up an app in GAE. The app relies on up to three successive AJAX calls from the client that produces an individual string in each request. I would like to retain and combine the data on the server side in order to perform some more parsing on it.
I have been told that using global variables is really really bad, but I'm not sure how I would structure this flow without using globals to combine the data. Any suggestions? I don't want to do one single AJAX call because I would like to continue to update the user as to the progress. Abstractly it looks something like this-
finalData = ""
class func1(webapp2.RequestHandler):
def get(self):
func1data = some.command()
global finalData
finalData += func1data
class func2(webapp2.RequestHandler):
def get(self):
func2data = some.command()
global finalData
finalData += func2data
class func3(webapp2.RequestHandler):
def get(self):
func3data = some.command()
global finalData
finalData += func3data
It's a terrible idea, as in, it won't work. Or worse, it might appear to work sometimes when your requests happen to hit the same instance, but it won't work otherwise.
Store the data in an entity in the the datastore/memcache (if you use ndb it'll automatically be put in memcache), and use a get() to fetch the data on each successive request.
Alternatives are to use sessions, or return the data in a cookie to the client so it's sent back to the server with the next request (though that would insecurely allow the client to modify the value).

using GAE datastore for job management

I have a 'Calculation' entity in my datastore with say, 7 million objects under that entity. It has the following properties (python runtime):
class Calculation(db.Model):
question = db.StringProperty(required=True)
answer = db.StringProperty()
suppose examples of the 'question' property are things like '1+1', '2+2', '3+3' (not really important). All the calculation objects start out with empty answer properties.
When a user connects to the app, an ajax call is made and my app is supposed to [1] fetch a Calculation object with an empty answer property and send it to the user's browser. The user's browser then evaluates the question and sends it back to a different server handler.
How do I update that specific Calculation object's answer property[2]?
If someone could provide me with code for [1] and [2] that would be great. Not really experienced with App Engine and the query stuff is confusing. What is the best solution for this if I want to conserve as much server-CPU as possible?
Thanks!
I don't know if i have really understand. But you simply need to return for your first ajax call the key of the entity Calculation and the question. When the user makes a response you firstly get the entity by the key and update the property answer.
Step 1, The ajax call return a question in JSON (for example):
# To fetch an empty answered question
qry = Calculation.All().filter('answer =', None)
ref = qry.get()
# The Json response
{ 'key': unicode(ref.key()),
'question': ref.question}
Step 2, You update the entity by the key:
# key and answer are variable from an http GET or POST request.
ref = db.get(key)
ref.answer = answer
ref.put()

What is the best REST implemenation when using tornado RequestHandlers

I would like to define a REST API with a general pattern of:
mysite.com/OBJECT_ID/associations
For example:
mysite.com/USER_ID/vacations - manage a users vacation
mysite.com/USER_ID/music - manage music in the user's music library
mysite.com/PLAYLIST_ID/music - manage music in the context of the given playlist
I am using tornado on the server side and looking for suggestions about how to define the RequestHandlers for this API. For instance, I want to define a handler like:
/([0-9,a-z,A-Z,-]+)/music",MusicHandler), but I'm stuck on the implementation of MusicHandler, which needs to know if the object specified by in the uri supports music in the first place i.e. how to guard against a call like
mysite.com/LOCATION_ID/music
Where locations have no associations with music.
Is the best fix to modify the api to include the type i.e.:
mysite.com/users/USER_ID/music or
mysite.com/playlists/PLAYLIST_ID/music
and then a separate handler for each:
/users/([0-9,a-z,A-Z,-]+)/music",UserMusicHandler),
/playlists/([0-9,a-z,A-Z,-]+)/music",PlaylistMusicHandler)
That doesn't seem right, but I don't really understand how to make this work. I'm sure this is a simple issue, I am new to python and tornado.
First of all, to guard against mysite.com/LOCATION_ID/music I would create differences between all of your id's. For instance, have LOCATION_ID be a 32 character string, and PLAYLIST_ID 34, etc. This way you can check for the string length as soon as the handler is called.
Alternatively, you can use regular expression groups to catch it right in the URI and then define different handlers for each. (Also, your ID should probably be after all of the static text in the URI, just for good convention). For instance, if your PLAYLIST_ID is a UUID and you LOCATION_ID is a string:
(r"/music/([\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12})", PlaylistMusicHandler), #playlistID
(r"/music/([A-Za-z0-9]+)", LocationHandler), #locationID
if not self.db.get("SELECT 1 FROM objects WHERE music_id = %s", object_id):
raise HTTPError(404, "Music object %s not found" % name)
FWIW a mysite.com/music/MUSIC_ID scheme makes more sense to me.

Is it possible to cache a python suds client?

I'm currently running python suds against a wsdl file and its corresponding 50+ xsd files. The following call to Client takes about 90 seconds:
from suds.client import Client
url = 'http://localhost:7080/webservices/WebServiceTestBean?wsdl'
client = Client(url)
After I run the last line above, I get a Client instance. Creating that client takes a long time. Does caching work with Python objects or is it restricted to primitives like strings and integers?
Here's what I want to do in code, the syntax is wrong but it's to convey what I want:
from suds.client import Client
if 'current_client' in cache:
client = cache.get('current_client')
else:
url = 'http://localhost:7080/webservices/WebServiceTestBean?wsdl'
client = Client(url)
cache.put('current_client', client)
suds caches WSDL and XSD files for a day by default so that each instantiation of a Client object doesn't require a separate URL request.
90 seconds seems like a really long time, is that time spent waiting on the wsdl response, or is it spent parsing the wsdl? If it's taking that long to parse it, the built-in caching isn't going to help much.
I've done something like this before, but instead of the singleton pattern, I just used a module-level global dictionary. It's the singleton pattern without all the class noise.
Something like this:
from suds.client import Client
_clients = {}
def get_client(name):
if name not in _clients:
_clients[name] = Client(url_for_name)
return _clients[name]
if i understand well your problem i think you don't want to create each time a new Client() and that you want to put in a cache so you can retrieve it ; but i think that you're complicating thing and i will suggest using the singleton pattern this will allow you to create only one instance of the client and every time you want to create an new instance it will just return the old instance that was created.
Here is an example that can help you understand what i'm suggesting.
class MyClient(Client):
__instance__ = None
def __new__(cls, *args, **kws):
if not cls.__instance__:
cls.__instance__ = super(Client, cls).__new__(cls, *args, **kws)
return cls.__instance__
N.B: i wanted to use the borg pattern which is like singleton but more beautiful but i wasn't able to figure out how to not call Super.init (which take a long time) and in the mean time sharing the same state, if some one has a better idea of how to put it using the Borg pattern it will be great , but i don't think borg pattern can be useful in this case
Hope this can help
suds >= 0.3.5 r473 provides some URL caching. By default, http get(s) such as getting the WSDL and importing XSDs are cached.

Categories