Reputation: 1238
I have spent about a week on this issue and although I have made considerable progress I am stuck at a key point.
I am writing a simple client-server program in Python that is supposed to accept key/value pairs from the command line, formulate them into an url, and request the url from the server. The problem appears to be either that the url is not properly formatted or that the server is not parsing it correctly. (That is, the key-value pairs appear to be properly making it from the command line to the function that contains the request.)
import sys
import requests
server_url = "http://0.0.0.0:5006"
def test(payload):
print('payload in function is ' + payload)
r = requests.get('http://0.0.0.0:5006/buy', params=payload)
print(r.url) #debug
print(r.encoding)
print(r.text)
print(r.headers)
if __name__ == '__main__':
payload = sys.argv[2]
print('payload from cli is ' + payload)
test(payload)
Server:
import subprocess
from flask import Flask
from flask import request
import request
# Configure the app and wallet
app = Flask(__name__)
@app.route('/buy', methods=['GET', 'POST'])
def test(key1, key2):
key1 = str(request.args.get('key1'))
key2 = str(request.args.get('key2'))
print('keys are' + key1 + key2)
fortune = subprocess.check_output(['echo', 'key1'])
return fortune
# Initialize and run the server
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5006)
Client console output:
payload from cli is {"key1": "foo", "key2": "bar"}
payload in function is {"key1": "foo", "key2": "bar"}
http://0.0.0.0:5006/buy?%7B%22key1%22:%20%22foo%22,%20%22key2%22:%20%22bar%22%7D
ISO-8859-1
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>500 Internal Server Error</title>
<h1>Internal Server Error</h1>
<p>The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.</p>
{'Content-Type': 'text/html', 'Content-Length': '291', 'Date': 'Fri, 09 Sep 2016 22:16:44 GMT', 'Server': 'Werkzeug/0.11.10 Python/3.5.2'}
Server console output:
* Running on http://0.0.0.0:5006/ (Press CTRL+C to quit)
[2016-09-09 18:30:33,445] ERROR in app: Exception on /buy [GET]
Traceback (most recent call last):
File "/usr/local/lib/python3.5/dist-packages/flask/app.py", line 1988, in wsgi_app
response = self.full_dispatch_request()
File "/usr/local/lib/python3.5/dist-packages/flask/app.py", line 1641, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/usr/local/lib/python3.5/dist-packages/flask/app.py", line 1544, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python3.5/dist-packages/flask/_compat.py", line 33, in reraise
raise value
File "/usr/local/lib/python3.5/dist-packages/flask/app.py", line 1639, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/local/lib/python3.5/dist-packages/flask/app.py", line 1625, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
TypeError: test() missing 2 required positional arguments: 'key1' and 'key2'
127.0.0.1 - - [09/Sep/2016 18:30:33] "GET /buy?%7B%22key1%22:%20%22foo%22,%20%22key2%22:%20%22bar%22%7D HTTP/1.1" 500 -
I take this as showing that the subprocess call is for some reason not able to decipher key1 and key2 from the URL so is failing when it runs "fortune None None".
Upvotes: 0
Views: 2134
Reputation: 20729
test
is expecting values for key1
and key2
. Flask would provide those through your route.
@app.route('/buy/<key1>/<key2>')
def test(key1, key2):
Visiting /buy/value1/value2
would give values to the arguments. You want to pass values through the query string though.
You just need to remove them from the function's signature.
@app.route('/buy', methods=['GET', 'POST'])
def test():
Upvotes: 1
Reputation: 12140
The problem seems to be in your payload.
The payload needs to be a dictionary. You're giving it a string.
sys.argv[2]
will be a string, even if you format the text to look like a dictionary. So unless there's something missing from your client code snippet, payload isn't actually a dictionary like requests would expect.
I can infact confirm this by looking at the URL being generated, which is:
http://0.0.0.0:5006/buy?%7B%22key1%22:%20%22foo%22,%20%22key2%22:%20%22bar%22%7D
Had the payload been a dictionary and correctly encoded, it would've looked something like this:
http://0.0.0.0:5006/buy?key1=foo&key2=bar
To see what type payload your really is, do print(type(payload))
somewhere inside the test
function.
Once you've converted your payload
into a proper python dictionary (you'll have to parse your sys.argv[2]
), then requests should work as expected.
Upvotes: 2