How to get the data submitted using POST on Python using Pyramid? - python

I'm looking for the equivalent of PHP's $_POST[] in Python.
On PHP, when you submit a form you can get its value by using the $_POST[].
How can I get this data on python?
here is my code.
function NewUser(){
var firstName = $('#firstName').val();
var dataString = '&firstName='+firstName;
$.ajax({
type:"POST",
url:"newusers",
data:dataString,
dataType:'text',
success:function(s){
alert(s);
},
error:function(){
alert('FAILED!');
}
})
}
This is where I throw the data.
#view_config(route_name='newusers', renderer='json')
def newusers(self):
return '1';
This code works fine and it returns and alert a string "1".
My question is, how can I get the submitted firstName? and put it on the return instead of "1".
Thank you in advance!

Another variation that should work:
#view_config(route_name='newusers', renderer='json')
def newusers(self):
# Best to check for the case of a blank/unspecified field...
if ('firstName' in self.request.params):
name = str(self.request.params['firstName'])
else:
name = 'null'
return name
Note: Be careful using str() function, particularly in python 2.x, as it may not be compatible with unicode input using characters beyond ascii. You might consider:
name = (self.request.params['firstName']).encode('utf-8')
as an alternative.

I manage to make it work with this code.
#view_config(route_name='newusers', renderer='json')
def newusers(self):
name = str(self.request.POST.get('firstName'))
return name

Related

How to include a variable in api call in python?

I am trying to implement a searchbar in django. I am getting the search input as movie_title from the html form. Now, how do i include it in my api call ? I tried with curly braces. Here's is the code
def searchbar(request):
if request.method == 'GET':
movie_title = request.GET.get('movie_title')
searched_movie = requests.get(
'http://www.omdbapi.com/?apikey=9a63b7fd&t={movie_title}')
You can create the url as an object using f-strings (one of the ways) and pass that to the get() method:
url = f'http://www.omdbapi.com/?apikey=9a63b7fd&t={movie_title}'
searched_movie = requests.get(url)
Note: You don't need to create a different object and can directly use:
searched_movie = requests.get(f'http://www.omdbapi.com/?apikey=9a63b7fd&t={movie_title}')
The above approach helps with readability when there are several dynamic attributes involved.
If you want to use { and } in your query string you can simply write
searched_movie = requests.get('http://www.omdbapi.com/?apikey=9a63b7fd&t={'+movie_title+'}')
Otherwise you can write
searched_movie = requests.get('http://www.omdbapi.com/?apikey=9a63b7fd&t='+movie_title)

Understanding lambdas in pystache

Say I want to write a function that format floats with 2 digits in pystache.
I want both the float number and the function in the context (I believe this is the correct philosophy of Mustache).
What should I do?
In order to make the problem clear, I will show a pair of code snippets I have written. They do not work.
Snippet (a):
import pystache
tpl = "{{#fmt}}{{q}}{{/fmt}}"
ctx = {
'q' : 1234.5678,
'fmt' : lambda x: "%.2f" % float(x)
}
print pystache.render(tpl, ctx)
This fails, with error "could not convert string to float: {{q}}". I can understand this error: {{fmt}} is evaluated before {{q}}.
Snippet (b):
import pystache
tpl = "{{#q}}{{fmt}}{{/q}}"
ctx = {
'q' : 1234.5678,
'fmt' : lambda x: "%.2f" % float(x)
}
print pystache.render(tpl, ctx)
This fails with error: "lambda() takes exactly 1 argument (0 given)". I can't understand this error: shouldn't the context be passed as argument?
Short answer: mustache doesn't support this. It expects all data values to come preprocessed.
In 2012, at formating of dates, numbers and more · Issue #41 · mustache/spec, ppl suggessted various implementations, incl. from other template engines, and couldn't reach any conclusion.
As per mustache.js date formatting , ppl have constructed several extensions and/or workarounds (To me, the most promising one looks to be the {{value | format}} syntax extension), or suggested moving to other markup engines.
Additional info:
The spec at http://mustache.github.io/mustache.5.html (linked from http://mustache.github.io front page no less) is obsolete, dated 2009. The latest spec that pystache follows resides at https://github.com/mustache/spec , and looks abandoned, too: the latest commit is dated 02.2015 and the latest spec update is from 2011. Nor does it have a successor.
So, by this point, the standard is dead, and the markup is thus free-for-all to augment.
I'd still suggest to consider other formats linked to in the aforementioned discussions before reinventing the wheel.
According to ivan_pozdeev's comments, I will post my own answer. I will not accept it, because I think it's a too ugly solution.
import pystache
import copy
tpl = "{{#fmt}}{{q}}{{/fmt}}"
ctx = {
'q' : 1234.5678,
}
class OtherContext(object):
def __init__(self, renderer):
self.renderer = renderer
def fmt(self):
return lambda s: "%.2f" % float(copy.deepcopy(self.renderer).render(s, self.renderer.context))
renderer = pystache.Renderer(missing_tags='strict')
ctx2 = OtherContext(renderer)
print renderer.render(tpl, ctx, ctx2)
I also had this problem. After setting a breakpoint on a defined method that I called with my lambda, I found that the data Pystache passes is only the lambda subsection of the template. Not very helpful.
Then, after a lot of digging around, I found that
on Nov 5, 2013, cjerdonek mentions accessing the current context via the renderer, and ultimately this code comment from the pystache.renderer module:
# This is an experimental way of giving views access to the current context.
# [...]
#property
def context(self):
"""
Return the current rendering context [experimental].
"""
return self._context
Thankfully, this experiment works 😄😄 Ultimately:
Your lambda must call a defined method.
A strict inline lambda doesn't work in my experience.
Your defined method must be able to access an instance of the Renderer class.
In the method, you'll get the context, process the value, and print it.
Your Renderer instance must be used to render your template and context, so that it then has access to the context.
I built the following to meet your requirements. This is in Python 3.6.5, and I expanded the names for readability.
import pystache
RENDERER = None
def format_float(template):
'''
#param template: not actually used in your use case
(returns '{{value}}' in this case, which you could render if needed)
'''
context_stack = RENDERER.context._stack
# the data has been last in the stack in my experience
context_data = context_stack[len(context_stack) - 1]
x = float(context_data['value'])
print("%.2f" % x)
if __name__ == '__main__':
RENDERER = pystache.Renderer()
template = '{{#formatter}}{{value}}{{/formatter}}'
context = {
'value' : 1234.5678,
'formatter' : lambda template: format_float(template)
}
RENDERER.render(template, context)
This prints 1234.57 to the console. 👍👍

How to handle a post request in Flask that contains a list

What i want is to handle an order placed to a server from an android app.
To test things i am using POSTMAN.
I tested it
with the following code.
class newOrder(Resource):
'''
this class receives credentials from a post request
and returns the full menu of the establishment.
'''
def post(self):
try:
parser = reqparse.RequestParser()
parser.add_argument('username', type=str, help='Password to create user')
parser.add_argument('password', type=str, help='Email address to create user')
args = parser.parse_args()
_userUsername = args['username']
_userPassword = args['password']
return jsonify({'username':_userUsername,'password':_userPassword})
except Exception as e:
return {'error': str(e)}
and got this.
So far so good
how can i alter this to work and be tested on POSTMAN and return the following?
{'usename':'foo','password':'bar',
"order":
[
[1,"ΚΡΗΤΙΚΗ",5,,'tt'],
[2,"ΣΑΛΑΤΑ","ΦΑΚΗ",6,'tt'],
[3,"ΣΑΛΑΤΑ","ΚΟΥΣ-ΚΟΥΣ",5,'tt'],
]
}
i am having trouble with the list. 'order':[[],[],[],...]
How to i enter that list to POSTMAN parameters?
Also, i am returning it to my self to simply view it. i just want to know that the data was entered properly.
Thank you.
You need to come up with a format in which to send the list. I believe the most common format is just a comma seperated string like so
thing1,thing2,thing3,etc
Pass this in the url like
https://127.0.0.1:3000/postendpoint?arrayParameter=thing1,thing2,thing3,etc
Then on the python end parse it like this
arrayParameter=args['arrayParameter'].split(',')
Obviously you'll have to make sure the format is correct though
edit:
If you want to pass a sorta multidimentional array then maybe you need to re-evaluate the way your program works. If you really want to do it then try this.
str = 'a,;1;2;3;4;,c,d'
str = str.split(',')
str[1] = str[1].split(';')

Dict type throws error in json.dumps

I am passing a dictionary to json.dumps and it is still throwing an error:
TypeError: Undefined is not json serializable
I even check the type before calling the function to make sure it is a dictionary type.I'm using the Flask microframework and trying to return a Response object containing really simple json to an ajax request:
$(document).ready(function() {
$.getJSON($SCRIPT_ROOT + '/getDictionary', function(data) {
console.log(data);
});
});
#app.route('/getDictionary')
def getDictionary():
empty_dic = {'empty' : 'dict'}
if type(empty_dic) is dict:
return Response(json.dumps(empty_dic), mimetype = "application/json")
Here's an example that works:
import json
emptydic = {'simple' : 'dict'}
if isinstance(emptydic, dict): # Note capitalization
print(json.dumps(emptydic)) # {"simple": "dict"}
The type checking condition has changed slightly, and I stripped the Response/mimetype stuff, because it seems orthogonal to your issue.
Your capitalization is off, note you define emptydic but try to serialize emptyDic. Try this:
empty_dict = {'simple' : 'dict'}
if type(empty_dict) is dict:
return Response(json.dumps(empty_dict).encoded('utf8'), mimetype = "application/json")
Note it's also against PEP8 to use camel case for variables. Snake case is recommended
Your dictionary has name "emptydic"
In the condition, you use "emptyDic"
Try:
emptyDic = {"simple": "dict"}
if type(emptyDic) is dict:
return Response(json.dumps(emptyDic).encoded('utf8'), mimetype = "application/json")
Are you trying this by any chance
json.dumps(emptydic, encoding='utf-8')
I am trying this on Python 2.7 and the string object will not have an attribute called encoded.

jQuery getJSON Output using Python/Django

So, I'm trying to make a simple call using jQuery .getJSON to my local web server using python/django to serve up its requests. The address being used is:
http://localhost:8000/api/0.1/tonight-mobile.json?callback=jsonp1290277462296
I'm trying to write a simple web view that can access this url and return a JSON packet as the result (worried about actual element values/layout later).
Here's my simple attempt at just alerting/returning the data:
$.getJSON("http://localhost:8000/api/0.1/tonight-mobile.json&callback=?",
function(json){
alert(json);
<!--$.each(json.items, function(i,item){
});-->
});
I am able to access this URL directly, either at http://localhost:8000/api/0.1/tonight-mobile.json or http://localhost:8000/api/0.1/tonight-mobile.json&callback=jsonp1290277462296 and get back a valid JSON packet... So I'm assuming it's in my noob javascript:)
My views.py function that is generating this response looks as follows:
def tonight_mobile(request):
callback = request.GET.get('callback=?', '')
def with_rank(rank, place):
return (rank > 0)
place_data = dict(
Places = [make_mobile_place_dict(request, p) for p in Place.objects.all()]
)
xml_bytes = json.dumps(place_data)
xml_bytes = callback + '(' + xml_bytes + ');'
return HttpResponse(xml_bytes, mimetype="application/json")
With corresponding urls.py configuration:
(r'^tonight-mobile.json','iphone_api.views.tonight_mobile'),
I am still somewhat confused on how to use callbacks, so maybe that is where my issue lies. Note I am able to call directly a 'blah.json' file that is giving me a response, but not through a wired URL. Could someone assist me with some direction?
First, callback = request.GET.get('callback=?', '') won't get you the value of callback.
callback = request.GET.get( 'callback', None )
Works much better.
To debug this kind of thing. You might want to include print statements in your Django view function so you can see what's going on. For example: print repr(request.GET) is a helpful thing to put in a view function so that you can see the GET dictionary.

Categories