Flask not recognising two URL parameters - python

I'm trying to send two parameters to a URL routed with Flask.
If I do:
curl -i http://127.0.0.1:5000/api/journeys/count?startStationName=Hansard%20Mews,%20Shepherds%20Bush&endStationName=Farringdon%20Lane,%20Clerkenwell
Then my code which is:
#application.route('/api/journeys/count', methods=['GET'])
def journeys():
print request.args
startStationName = request.args.get('startStationName')
endStationName = request.args.get('endStationName')
Should print a dict with startStationName and endStationName defined.
However, instead, only the first parameter seems to be received:
ImmutableMultiDict([('startStationName', u'Hansard Mews, Shepherds Bush')])
Anybody got any idea what I'm doing wrong? I have a feeling there must be some kind of stupid mistake or misunderstanding somewhere but I've been looking for an hour and can't find it.

Your shell interprets the & as a put the command in the background character. To prevent this, quote the whole URL:
curl -i "http://127.0.0.1:5000/api/journeys/count?startStationName=Hansard%20Mews,%20Shepherds%20Bush&endStationName=Farringdon%20Lane,%20Clerkenwell"

Related

Is there a way to pass a web-link as an argument with agrparse in python? [duplicate]

I am working through the Node.js The Right Way book by Jim Wilson. I am currently trying to use a PUSH request to create a new bundle with the specified name.
* curl -X POST http://:/api/bundle?name=
However, when I use the command:
$ curl -s -X POST localhost:60702/api/bundle?name=light%20reading | jq '.'
rather than getting the JSON indicating that a Bundle has been created, I get: zsh: no matches found: localhost:60702/api/bundle?name=light%20reading
The command should be using a POST request to create a new All of my code is bit for bit identical to the code listed in the book. Any ideas?
Can you try
curl -s -X POST 'localhost:3000/api/bundle?name=light%20reading'
i.e wrap the url within '
This seems to be an issue with zsh solved here.
There are several ways to solve this:
You can escape the question mark ? in the url by quoting the url as explained by #huzaifa-saifuddin to avoid zsh treating it as a wildcard character.
As explained here, you can create an alias for curl: alias curl='noglob curl'
As explained here, you can disable to nomatch handling by adding the following to your ~/.zshrc: unsetopt nomatch

Python required list parameter is not present

I'm trying to imitate the following cURL command to POST my url-encoded list to a form:
curl "https://website.com/update/" --data "simChangesList=%5B%7B%22simId%22%3A760590802%2C%22changeType%22%3A2%2C%22targetValue%22%3A%220003077%22%2C%22effectiveDate%22%3Anull%7D%5D" --compressed
The data I need to url-encode is the simChangesList. Essentially, this data is decoded as simChangesList: [{"simId":760590802,"changeType":2,"targetValue":000307,"effectiveDate":null}]
With the following script, I come across a Required List parameter 'simChangesList' is not present error.
Here's my script:
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
enc = urllib.quote('simChangesList: [{"simId":760590802,"changeType":2,"targetValue":000307,"effectiveDate":null}]')
auth = session.post(uri, data=enc, headers=headers)
print auth.text
However, executing the above script returns the above missing list parameter error.
How can I pass in the missing list parameter when my encoded list looks like this:
simChangesList%3A%20%5B%7B%22simId%22%3A760590802%2C%22changeType%22%3A2%2C%22targetValue%22%3A000307%2C%22effectiveDate%22%3Anull%7D%5D
Notice it's missing the '=' operator, why can I not execute my script and make it closely resemble my cURL command to post my url-encoded information?
I also encountered a similar situation landlord, but I just prompted one of the parameters inside json does not exist, is looking for a solution.
On the landlord to pass parameters, it is recommended to add a json.dumps (data)
try it.

CherryPy only receiving 1st query string parameter

I've just begun my journey into the realms of the CherryPy module in Python. It's pretty awesome how easy it makes it to setup a server with a RESTful api, however I've ran into an issue. My code is only acknowledging the first parameter in a query string.
I want to make a GET request like so:
curl -X GET 127.0.0.1:8080/api/sum/?a=2&b=3
My Python code is as follows:
import cherrypy
class getSum:
exposed = True
def GET(self, **params):
a = float(params['a'])
b = float(params['b'])
return a+b
if __name__ == '__main__':
cherrypy.tree.mount(getSum(), '/api/sum/', {'/': {'request.dispatch': cherrypy.dispatch.MethodDispatcher()}})
cherrypy.engine.start()
cherrypy.engine.block()
After fiddling with the code for a while I've come to the following diagnosis:
When the query string is being read into params, instead of starting a new entry in the dictionary when it reaches the '&' it just stops instead.
Has anyone got any advice on how to read multiple parameters in as a single query string?
With Thanks, Sean.
The Python script posted in my question is actually a working implementation of what I wanted to do. The problem was instead with the curl request that I was making.
The '&' character in my curl request was truncating my bash command, resulting in this: curl -X GET 127.0.0.1:8080/api/sum/?a=2
The fix for this is to wrap my url in quotes like so: curl -X GET "127.0.0.1:8080/api/sum/?a=2&b=3"
When executing this command 5.0 is returned to the terminal, as expected.
This following post contains a useful discussion on the use of ampersands in curl requests: How to include an '&' character in a bash curl statement

Why Does My Put request fail?

Using Python 2.5 and httplib......
I am admittedly a python novice.....but this seems straight forward, why doesn't this work?
httpConn = HTTPConnection('127.0.0.1', 44789)
httpConn.request('PUT','/ShazaamMon/setmfgdata.cgi?serial=', hwSerialNum)
httpResp = httpConn.getresponse()
xmlResp = httpResp.read()
httpConn.close()
it returns the following response: <HTML><HEAD><TITLE>HTTP 404.......
Any clues anyone???
I think you should replace PUT with GET.
You should consider sanitizing the input, trye
httpConn.request('GET','/ShazaamMon/setmfgdata.cgi?serial=%s' % (urllib.quote(hwSerialNum)))
HTTP 404 means that the resource you requested does not exist. Are you sure that the URL is correct?
Moreover, you put in the body of the request (third parameter of request()) a variable that I think is a parameter of the request.
Try the following:
httpConn.request('PUT','/ShazaamMon/setmfgdata.cgi?serial=' + str(hwSerialNum))
or maybe (if GET is required instead of PUT):
httpConn.request('GET','/ShazaamMon/setmfgdata.cgi?serial=' + str(hwSerialNum))
#Angelom's answer is concise and correct. For a nice example-filled explanation of using PUT in urllib and urllib2 try http://www.voidspace.org.uk/python/articles/urllib2.shtml#data.

Using Python Web GET data

I'm trying to pass information to a python page via the url. I have the following link text:
"<a href='complete?id=%s'>" % (str(r[0]))
on the complete page, I have this:
import cgi
def complete():
form = cgi.FieldStorage()
db = MySQLdb.connect(user="", passwd="", db="todo")
c = db.cursor()
c.execute("delete from tasks where id =" + str(form["id"]))
return "<html><center>Task completed! Click <a href='/chris'>here</a> to go back!</center></html>"
The problem is that when i go to the complete page, i get a key error on "id". Does anyone know how to fix this?
EDIT
when i run cgi.test() it gives me nothing
I think something is wrong with the way i'm using the url because its not getting passed through.
its basically localhost/chris/complete?id=1
/chris/ is a folder and complete is a function within index.py
Am i formatting the url the wrong way?
The error means that form["id"] failed to find the key "id" in cgi.FieldStorage().
To test what keys are in the called URL, use cgi.test():
cgi.test()
Robust test CGI script, usable as main program. Writes minimal HTTP headers and formats all information provided to the script in HTML form.
EDIT: a basic test script (using the python cgi module with Linux path) is only 3 lines. Make sure you know how to run it on your system, then call it from a browser to check arguments are seen on the CGI side. You may also want to add traceback formatting with import cgitb; cgitb.enable().
#!/usr/bin/python
import cgi
cgi.test()
Have you tried printing out the value of form to make sure you're getting what you think you're getting? You do have a little problem with your code though... you should be doing form["id"].value to get the value of the item from FieldStorage. Another alternative is to just do it yourself, like so:
import os
import cgi
query_string = os.environ.get("QUERY_STRING", "")
form = cgi.parse_qs(query_string)
This should result in something like this:
{'id': ['123']}
First off, you should make dictionary lookups via
possibly_none = my_dict.get( "key_name" )
Because this assigns None to the variable, if the key is not in the dict. You can then use the
if key is not None:
do_stuff
idiom (yes, I'm a fan of null checks and defensive programming in general...). The python documentation suggests something along these lines as well.
Without digging into the code too much, I think you should reference
form.get( 'id' ).value
in order to extract the data you seem to be asking for.

Categories