Reading POST data - CherryPy web-framework - cherrypy

I'm new with CherryPy web-framework. I would like to know how can
I read POST data that was delivered via HTTP request's body .
Thanks,
Gabriel.

You can either read the body of the request with cherrypy.request.body, cherrypy.request.params or if you use the default handler then, the distinction between GET and POST values is abstracted by cherrypy and you can get the values directly from the arguments:
#cherrypy.expose
def index(self, name, age):
return "My name is %s and age is %s" % (name, age)
Your POST request must have to provide the values for name and age on the traditional forms submission.
If you are planning on using json, then use the cherrypy.tools.json_in decorator and read the cherrypy.request.json property. http://docs.cherrypy.org/en/latest/basics.html#dealing-with-json
If you are using the MethodDispatcher, then there is another way to do it: http://docs.cherrypy.org/en/latest/tutorials.html#tutorial-7-give-us-a-rest
Maybe these posts might help you:
http://blog.joel.mx/posts/cherrypy-101
http://blog.joel.mx/posts/cherrypy-101-method-dispatcher

Cherrypy handles both get and post in a similar way by passing them into the function or method that is handling the request. A good example is located at tut03_get_and_post.py in the tutorial folder within the cherrypy package.
Here is a small portion that specifically speaks to your question...
#cherrypy.expose
def greetUser(self, name=None):
# CherryPy passes all GET and POST variables as method parameters.
# It doesn't make a difference where the variables come from, how
# large their contents are, and so on.

Related

Read data in chunks from large request_body

I am new to tornado . Currently I want to read from a post request_body . But data in post request is large so I want to implement it through stream_body_request in Tornado. But I am not able to implement it. How to read this 'img_data' in chunks?
#stream_request_body
class MyReportPDF(BaseHandler):
async def post(self):
data = escape.json_decode(self.get_body_argument('img_data'))#This data is an base_64_array
for i in range(len(data)):
# Clean the base_64 Image
data[i].replace('data:image/jpeg;base64,', '')
decode_image.append(base64.b64decode(data[i]))
When you use #stream_request_body, your RequestHandler class should define a method data_received which will be called with data as it comes in. The post method is called at the end after all of the data is received.
Note that it is not currently possible to use the argument-related methods with #stream_request_body; you'll need to parse the data in data_received as it comes in. This means that if possible you'll want to structure your API to receive the image as a plain HTTP PUT instead of being wrapped in a form-style POST.

How to implement multiple POST methods in CherryPy

I am new to cherryPy and I am working on communicating the GUI with Python functions, for it I am using CherryPy. I have followed this cherryPy tutorial. In that the POST method don't do much just return some string, but in my case there can be many functions which will communicate with GUI using the POST. I tried this:
#cherrypy.expose
class StringGeneratorWebService(object):
#cherrypy.tools.accept(media='text/plain')
def GET(self):
return cherrypy.session['mystring']
def POST(self, counter,param):
if counter == 1:
function1(param) # call a python function
elif counter == 2:
function2(param)
elif counter == 3:
function3(param)
def PUT(self, another_string):
cherrypy.session['mystring'] = another_string
def DELETE(self):
cherrypy.session.pop('mystring', None)
In above code in POST method, the counter and Param are parameters from the AJAX request. According to the counter value I am calling the respective function. The Param can be a big JSON document. The above code works but this is very crude way to do this, so is there other way which is a good coding practice?
The documentation is a little confusing, but you only need to implement the GET/POST Python methods if you want CherryPy to call different functions for you based on the HTTP method. If you don't care about GET requests on your POST URLs you can just use the #cherrypy.expose pattern.
If you look at the tutorial source for forms there's this helpful bit about exposing POST methods:
[Using HTTP POST method] would not change your application’s exposed method because CherryPy handles both the same way and uses the exposed’s handler parameters to deal with the query-string (key, value) pairs.
Modifying the handler to include the method makes this clear:
class StringGenerator(object):
#cherrypy.expose
def generate(self, length=8):
return cherrypy.request.method + ' ' + ''.join(random.sample(string.hexdigits, int(length)))
Now I can use curl make a GET then a POST request:
$ curl "http://example.com:8888/generate?length=8" # does a GET
GET 78A35e4f
$ curl "http://example.com:8888/generate" --data "length=8" # does a POST
POST 14d0D92c

Return from before_request() in flask

I'm new to flask and currently converting an existing WSGI application to run through flask as long term it'll make life easier.
All requests are POST to specific routes however the current application inspects the post data prior to executing the route to see if the request needs to be run at all or not (i.e. if an identifier supplied in the post data already exists in our database or not).
If it does exist a 200 code and json is returned "early" and no other action is taken; if not the application continues to route as normal.
I think I can replicate the activity at the right point by calling before_request() but I'm not sure if returning a flask Response object from before_request() would terminate the request adequately at that point? Or if there's a better way of doing this?
NB: I must return this as a 200 - other examples I've seen result in a redirect or 4xx error handling (as a close parallel to this activity is authentication) so ultimately I'm doing this at the end of before_request():
if check_request_in_progress(post_data) is True:
response = jsonify({'request_status': 'already_running'})
response.status_code = 200
return response
else:
add_to_requests_in_progress(post_data)
Should this work (return and prevent further routing)?
If not how can I prevent further routing after calling before_request()?
Is there a better way?
Based on what they have said in the documents, it should do what you want it to do.
The function will be called without any arguments. If the function returns a non-None value, it’s handled as if it was the return value from the view and further request handling is stopped.
(source)
#app.route("/<name>")
def index(name):
return f"hello {name}"
#app.before_request
def thing():
if "john" in request.path:
return "before ran"
with the above code, if there is a "john" in the url_path, we will see the before ran in the output, not the actual intended view. you will see hello X for other string.
so yes, using before_request and returning something, anything other than None will stop flask from serving your actual view. you can redirect the user or send them a proper response.

How to get resource path in flask-RESTPlus?

I am fairly new at working with flask and flask-RESTPlus. I have the following and it is not clear how can I determine which path was used in the get request?
ns = api.namespace('sample', description='get stuff')
#ns.route(
'/resource-settings/<string:address>',
'/unit-settings/<string:address>',
'/resource-proposals/<string:address>',
'/unit-proposals/<string:address>')
#ns.param('address', 'The address to decode')
class Decode(Resource):
#ns.doc(id='Get the decoded result of a block address')
def get(self, address):
# How do I know what get path was called?
pass
A better solution would be to use the request context. To get the full path, you can do:
from flask import request
def get(self, address):
# How do I know what get path was called?
print(request.full_path)
Through lot's of digging I found that url_for in flask import.
Still feels a bit wonky but I can create a fully qualified link with:
result = api.base_url + url_for('resource-settings', address=id)
So this works and I get the desired results.

bottle httprequest object manual update

Just yesterday got that I can't use one function that would return one template depending on cookies, and wich would be called by different methods of different routes. The reason is all the response.set_cookie() are not applied to main Bottle object HTTPResponse before the method finishes serving current route. So the question is there a way to explicitly cast application of all the changes to HTTPResponse object, so i could avoid passing complex structures to subroutines and etc.
Thank you for help!
UPD: there is a response.set_cookie('temp', 'sampletext') line for example. And then i am calling subroutine and it calls another one and so on. So In each of them i won't have request.get_cookie('temp') returning 'sampletext'. Because changes to cookies wasn't applied yet. There are in the Bottle.py code you can find following code:
class HTTPResponse(Response, BottleException):
def __init__(self, body='', status=None, headers=None, **more_headers):
super(HTTPResponse, self).__init__(body, status, headers, **more_headers)
def apply(self, response):
response._status_code = self._status_code
response._status_line = self._status_line
response._headers = self._headers
response._cookies = self._cookies
response.body = self.body
that seems to be executing once per request and changes from httpresponse objects are appliied to the response object only on finish of the rout's serving method termination.
I am asking if there is a way to apply changes to response object manually, during the route's serving method evaluation.
I am asking if there is a way to apply changes to response object manually, during the route's serving method evaluation.
No.
I'm not completely sure, but it sounds like you just want to store some state during a request.
The mechanism for this is to simply set attributes on the request object. E.g.
#route(...)
def index_page():
...
request.mydata = 'hello'
...
This is completely independent of cookies. If you need both, just set both; one on the request object and the other on the response.

Resources