How to print a Locust response (JSONDecodeError) - python

I have a flask app which looks like the following:
(note I have simplified it for the sake of this question)
#app.route("/app/ent/", methods=['POST'])
def methodpost():
req_data = request.get_json()
msg = req_data['msg']
output = jsonify(msg=msg)
return output
then for this, I have a locust file that looks like this:
from locust import HttpLocust, TaskSet, task, between
class MyClass(TaskSet):
#task(1)
def send_post(self):
self.client.headers['Content-Type'] = "application/json"
response = self.client.post("/app/ent/", json=
{
"msg": "test mesg example"
})
#temp
json_response_dict = response.json()
msg = json_response_dict['msg']
print("Post nessage returned is " + msg)
class MyTest(HttpLocust):
task_set = MyClass
wait_time = between(0.5, 3.0)
host = "http://localhost:5000"
I start locust as follows:
locust -f locust_myExample.py
Then when I run it using UI, I get following error:
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
Any idea how I can print the "msg" that is returned by the flask app?
However, just to make sure it works, when I do manual test using cURL, it returns "msg"
curl --header "Content-Type: application/json" \
--request POST \
--data '{"msg":"test mesg example"}' \
http://localhost:5000/app/ent
test mesg example

The solution is:
The response returned was not json and when finally it came back as JSON, it works.
This line was missing:
output = jsonify(msg=msg)

Related

Flask- Not able to get PUT method working?

Having trouble trying to get PUT method to work. Every time I try
curl http://127.0.0.1:5000/videos/video3 -d "title=YES" -X PUT in the terminal, I end up with an error that says: {"message": "The browser (or proxy) sent a request that this server could not understand."}
I've tried the code below and was able to get the GET method working and thought I was getting close with PUT method but now got stuck.
from flask import Flask
from flask_restful import Resource, Api, reqparse, abort
app = Flask("VideoAPI")
api = Api(app)
parser = reqparse.RequestParser()
parser.add_argument('title',required=True)
videos = {
'video1': {'title': 'Hello World in Python'},
'video2': {'title': 'Why Matlab is the Best Language Ever'}
}
class Video(Resource):
def get(self, video_id):
if video_id == "all":
return videos
if video_id not in videos:
abort(404, message=f"Video {video_id} not found")
return videos[video_id]
def put(self, video_id):
args = parser.parse_args()
new_video = {'title': args['title']}
videos[video_id] = new_video
return {video_id: videos[video_id]}, 201
api.add_resource(Video, '/videos/<video_id>')
if __name__ == '__main__':
app.run()
Expected Output: {"video1": {"title": "Hello World In Python"}, "video2": {"title": Why Matlab is the best language ever"}, "video3": {"title": "YES"}}
Since you don't specify the Content-Type header in the request, curl sends it as application/x-www-form-urlencoded by default. Therefore, if you add location='form' to the argument definition it should work correctly:
parser.add_argument('title', required=True, location='form')
Your put method is expecting a JSON format {"title": "YES"} but the data you sent was not that format.
Curl request should be
curl -H "Content-Type: application/json" -X PUT -d '{"title": "YES"}' http://127.0.0.1:5000/videos/video3
Response
{
"video3": {
"title": "YES"
}
}
To get your expected output
def put(self, video_id):
args = parser.parse_args()
new_video = {'title': args['title']}
videos[video_id] = new_video
# return {video_id: videos[video_id]}, 201
return videos, 201

Python urllib2 open request fails with urllib2.HTTPError: HTTP Error 401: Unauthorized

Below is my python code using urllib2 library and it keeps failing with an Unauthorized error although I am using the correct API key. If I user curl, the POST/GET works just fine.Anyone got ideas? Thanks.
Adding the curl commands below that works just fine
Create Credential
curl -X POST 'https://myurl.com' \
-H 'Content-Type: application/json' \
-u 'XXXXXXXXXX:' \
-d #- << EOF
{
"vendorAccountId": "1234567",
"type": "my_role"
}
EOF
Below is the python code which doesn't work.
Basically, the line of code where it is failing is: response = opener.open(request)
import boto3
import json
import logging
import signal
import requests
from urllib2 import build_opener, HTTPHandler, Request
import urllib2
LOGGER = logging.getLogger()
LOGGER.setLevel(logging.INFO)
def main():
auth_token = "XXXXXXXXXX"
account_id = "1234567"
request_type = "CreateCredentials"
content_type = ""
request_body = json.dumps({})
if request_type == "CreateCredentials":
target_url = 'https://myurl.com'
request_method = "POST"
content_type = "application/json"
request_body = json.dumps({
"vendorAccountId": account_id,
"type": "my_role"
})
handler = urllib2.HTTPHandler()
opener = urllib2.build_opener(handler)
request = urllib2.Request(target_url, data=request_body)
request.add_header("Content-Type", content_type)
request.add_header("Content-Length", len(request_body))
request.add_header("Authorization", auth_token)
request.get_method = lambda: request_method
response = opener.open(request) #*****Fails here******
if __name__ == "__main__":
main()
Finally, I figured out what the issue was. My lack of patience for not reading the vendor manuals. The HTTP request I was sending was missing some parameters that was required and I needed to send the Key in an encrypted format too.

Python requests handle JSON output

I'm trying to query API to get a JSON response, the following is my code.
import requests
query_url = 'https://IP-Address/api/v1/request'
data = {"token":"8f86788b04637676b1f66eed902", "query":"days>50", "type":"json", "size":10}
response = requests.post(query_url, json=data, verify=False)
print(response.json())
I'm getting the following error,
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
I also have a option to have CSV as "type" instead of JSON.
I created this Python request from cURL, which works good and outputs a JSON data. The following is the cURL command.
curl -kv -H 'Content-Type: application/json' 'https://IP-Address/api/v1/request' -d '{"token":"64bd230a775656a739b4673eb18", "query":"days>50", "type":"json", "size":10}'
Any suggestions please?

Quickblox getting a session receives "Unexpected signature" error

When getting a session, I get an "unexpected error".
Here is my code to get the signature (modified from this since that code is without some imports and notably hmac.new() is used instead of hmac() since that code doesn't work for me.
import sys
import json
import time
import random
import hashlib
import hmac
import urllib
import httplib
application_id = '3427'
auth_key = 'PLYHedAmxwdvt59'
auth_secret = '*some secret key*'
nonce = str(random.randint(1, 10000))
timestamp = str(int(time.time()))
signature_raw_body = ("application_id=" + application_id + "&auth_key=" + auth_key +
"&nonce=" + nonce + "&timestamp=" + timestamp)
signature = hmac.new(auth_secret, signature_raw_body, hashlib.sha1).hexdigest()
params = urllib.urlencode({'application_id': application_id,
'auth_key': auth_key,
'timestamp': timestamp, 'nonce' : nonce,
'signature' : signature})
conn = httplib.HTTPSConnection("api.quickblox.com")
conn.request("POST", "/session", params, {})
response = conn.getresponse()
print response.read()
print "signature = '%s'" % signature
The output:
<?xml version="1.0" encoding="UTF-8"?>
<session>
<application-id type="integer">3427</application-id>
<created-at type="datetime">2013-08-04T12:19:10Z</created-at>
<device-id type="integer" nil="true"/>
<id type="integer">3552056</id>
<nonce type="integer">5855</nonce>
<token>686840081c18c7dd0e0a779c233e0d9605bcb567</token>
<ts type="integer">1375618748</ts>
<updated-at type="datetime">2013-08-04T12:19:10Z</updated-at>
<user-id type="integer" nil="true"/>
</session>
signature = 'f08b68b645184619bbe59bac217506e66a840425'
Next I use curl to attempt to create a session:
curl -X POST -H "Content-Type: application/json" -H
"QuickBlox-REST-API-Version: 0.1.0" -d
'{"application_id":"3427","auth_key":"PLYHedAmxwdvt59","nonce":"33432","timestamp":"1375619372","signature":"f08b68b645184619bbe59bac217506e66a840425"}'
http://api.quickblox.com/session.json
I get this as a result:
{"errors":{"base":["Unexpected signature"]}}
Something went wrong?
Here is my example:
curl -X POST -H "Content-Type: application/json" -H "QuickBlox-REST-API-Version: 0.1.0" -d '{"application_id":"92","auth_key":"wJHdOcQSxXQGWx5","nonce":"315","timestamp":"1375624737","signature":"f36336b8bc8449b8252edbc0ee441cdb5856112c"}' http://api.quickblox.com/session.json
Result:
{"session":{"application_id":92,"created_at":"2013-08-04T13:59:50Z","device_id":null,"id":3553701,"nonce":315,"token":"1d423b6633e2fc82f81d88b65f3e26198853c84c","ts":1375624737,"updated_at":"2013-08-04T13:59:50Z","user_id":null}}
You should check code which generates your signature

RESTFUL POST with Python request to Glassfish Server

I'm having a difficulty trying to make a Python REST POST to a webservice running on Glassfish. I have verified that POST works ok using CURL but having no luck with Python.
Here is the CURL request that works ok.
curl -X POST -H "Content-Type: application/json" -d '{"id":1,"lastname":"smith"}'
http://192.168.0.20:8080/field1/resources/com.field1entity.field1
Here is the Python code to make the POST request
import urllib
import httplib2
def call():
http = httplib2.Http()
url = 'http://192.168.0.20:8080/field1/resources/com.field1entity.field1'
params = urllib.urlencode({"id":11111,"lastname":"oojamalip"})
response, content = http.request(url, 'POST', params, headers={'Content-type':'application/json'})
print "lets stop here to have a looksy at the variables"
print content
if __name__ == '__main__':
namesPage = call()
print namesPage
Output from console,
Unexpected character ('l' (code 108)): expected a valid value (number, String, array, object, 'true', 'false' or 'null')
at [Source: org.apache.catalina.connector.CoyoteInputStream#18f494d; line: 1, column: 2]
Hope someone can shed some light on the problem.
thanks
Nick
You are url encoding the prams and then telling the server it is json encoded
import json
params = json.dumps({"id":11111,"lastname":"oojamalip"})
# then
response, content = http.request(url, 'POST', body=params, headers={'Content-type':'application/json'})

Categories