Add note with attachments on Freshservice Ticket with Python - python-3.x

I am trying to add a note with an attachment to a Freshservice ticket using python but it is not working.
Below is my code:
# * Construct the Freshservice URL
fresh_service_url = VALUE_URL_BASE_FRESHSERVICE_NOTE.format(
self.domain,
self.ticket['id']
)
# * Make the API call to get the ticket details
response = requests.post(
fresh_service_url,
headers={
"Content-Type": "multipart/form-data",
"Authorization": f"Basic {api_key}"
},
files = [
('attachments[]', ('test.txt', open("test.txt", 'rb'), 'text/plain')),
]
)
# * Log the freshservice response
logging.info(f"fs note response: {response.text}")
# * Checks if update is successfull
if response.status_code != 201:
raise FreshserviceException(f"The note couldn't be added to ticket {self.ticket['id']}: {response.text}")
However, when running it, I am getting the below error:
File ".../freshservice_ticket.py", line 62, in add_note_with_attachments
raise FreshserviceException(f"The note couldn't be added to ticket
{self.ticket['id']}: {response.text}")
models.exceptions.FreshserviceException:
The note couldn't be added to ticket 777: {"description":"Validation failed","errors":[{"field":"--4bae5bb5c9d1b1a219beff9e504009d4\r\nContent-Disposition: form-data; name","message":"Unexpected/invalid field in request","code":"invalid_field"}]}
Can someone please help me ?

Related

URLFetch does not support granular timeout settings, reverting to total or default URLFetch timeout

We have an application (app-a) that is on python2.7 standard google app engine. We are attempting to do programmatic authentication to access another application (app-b) using service account based on the example here. App-b is on python3.7 standard google app engine.
When we do the iap authenticated call we get the following error in the logs of App-A.
resp = requests.request(
method, url,
headers={'Authorization': 'Bearer {}'.format(
google_open_id_connect_token)}, **kwargs)
AppEnginePlatformWarning: urllib3 is using URLFetch on Google App Engine sandbox instead of sockets. To use sockets directly instead of URLFetch see https://urllib3.readthedocs.io/en/latest/reference/urllib3.contrib.html.
AppEnginePlatformWarning: URLFetch does not support granular timeout settings, reverting to total or default URLFetch timeout.
The requests.request errors with
Exception("Bad response from application: 500 / {'content-type': 'text/html', 'x-cloud-trace-context':
In App-B we are trying to receive the data sent from app-a.
json.loads(request.data)
We get the following error in the logs of app-b.
in decode obj, end = self.raw_decode(s, idx=_w(s, 0).end()) File "/opt/python3.7/lib/python3.7/json/decoder.py", line 355, in raw_decode raise JSONDecodeError("Expecting value", s, err.value) from None json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
This leads me to believe that app-a is able to call app-b successfully. But for some reason it is not able to pass the data. Please help.
UPDATE -
Per suggestion to use HTTPlib we tried this.
payload = {
'test_data' : "data_test"
}
payload_json_dumps = json.dumps(payload)
conn = httplib.HTTPConnection(host)
conn.request("POST", path, payload_json_dumps, request_headers)
resp = conn.getresponse()
Added the following to app.yaml.
env_variables:
GAE_USE_SOCKETS_HTTPLIB : 'true'
In App-B we changed to
from flask import request
#app.route('url', methods = ['GET','POST'])
def content_from_client():
if (request.data):
data_received = request.get_json()
We are still not able to get the data on App-B. We get
AttributeError("'NoneType' object has no attribute 'get'")
UPDATE -
Changed the header formation and got it working.
request_headers = {
"Content-Type": 'application/json',
"follow_redirects": False,
"X-Appengine-Inbound-Appid": "app-A.appspot.com",
"Connection": "keep-alive",
'Authorization': 'Bearer {}'.format(google_open_id_connect_token)
}
AppEnginePlatformWarning is raised by urllib3 which is used by the requests library.
Urllib3 provides a pool manager that uses URL Fetch API by default. Sometimes though may not be the best option for your use case. A solution is to use sockets instead. In order to do that you have to configure your app.yamland include the following field:
env_variables:
GAE_USE_SOCKETS_HTTPLIB : 'true'
You may also find this documented in Google documentation.
As of the error on your app-B I would use response.json() method, requests builtin method instead of json.loads() as it detects automatically which decoder to use.
Let me know if this was helpful.
Per suggestion above the following helped solve the issue. Changed to httplib instead of urlfetch.
conn = httplib.HTTPConnection(host)
conn.request("POST", path, payload_json_dumps, request_headers)
resp = conn.getresponse()
Added the following to app.yaml -
env_variables:
GAE_USE_SOCKETS_HTTPLIB : 'true'
Changed header formation to -
request_headers = {
"Content-Type": 'application/json',
"follow_redirects": False,
"X-Appengine-Inbound-Appid": "app-A.appspot.com",
"Connection": "keep-alive",
'Authorization': 'Bearer {}'.format(google_open_id_connect_token)
}

How to test an API with the basic auth using YAML, tavern and pytest

I am implementing a Delete API which requires basic authentication before deleting any user. following is my code for basic auth and deleting a user which works perfectly fine via curl commands.
def auth_required(f):
#wraps(f)
def decorated(*args, **kwargs):
if(request.authorization != None and request.authorization["username"] != None and request.authorization["password"] != None):
username = request.authorization["username"]
password = request.authorization["password"]
else:
return make_response('User does not exists.\n' 'Please provide user credentials', 401,
{'WWW-Authenticate': 'Basic realm="Login Required"'})
if check_auth(username, password):
return f(*args, **kwargs)
else:
return make_response('Could not verify the credentials.\n' 'Please use correct credentials', 401,
{'WWW-Authenticate': 'Basic realm="Login Required"'})
return decorated
def check_auth(username, password):
cur = get_db().cursor().execute("SELECT user_name, password from users WHERE user_name=?", (username,))
row = cur.fetchone()
if row and row[0] == username and pbkdf2_sha256.verify(password, row[1]):
return True
else:
return False
#curl command to execure delete function - curl -u parag:parag --include --verbose --request DELETE --header 'Content-Type: application/json' http://localhost:5000/delete_user/
#app.route('/delete_user', methods=['DELETE'])
#auth_required
def api_delete_user():
if request.method == 'DELETE':
status_code:bool = False
cur = get_db().cursor()
username = request.authorization["username"]
try:
cur.execute("UPDATE users SET active_status =? WHERE user_name=?",(0, username,))
if(cur.rowcount >= 1):
get_db().commit()
status_code = True
except:
get_db().rollback()
status_code = False
finally:
if status_code:
return jsonify(message="Passed"), 201
else:
return jsonify(message="Fail"), 409
I have created a YAML file to test the above delete API but I am unable to add basic authentication in it. following is my YAML file for testing the delete API.
test_name: Delete existing user
stages:
- name: Make sure you delete existing user
request:
url: http://localhost:5000/delete_user
json:
method: DELETE
headers:
content-type: application/json
response:
status_code: 201
body:
message: Passed
save:
$ext:
context:
parameters:
auth_required:
username: parag
password: bhingre
Above file does not help me delete user by basic authenticating before deleting user.
Please let me know if any solutions or suggestions.
try to add Authorization in your header & read the Authorization value from header.
It worked for me.
headers:
content-type: application/json
Authorization: "Basic trydtfjgbyugvyujbbyy"

'Error': 'JSON parse error - Expecting value: line 1 column 1 (char 0)' How do I fix this

I am writing a script to make requests from different web services. I am having problem when posting data from the json data below. When I run the
patient_create_bill()function I get the logs below from response.
RESPONSE IS!!!!!
{'Error': 'JSON parse error - Expecting value: line 1 column 1 (char 0)'}
DEBUG:urllib3.connectionpool:Starting new HTTP connection (1): 0.0.0.0:9000
DEBUG:urllib3.connectionpool:http://0.0.0.0:9000 "POST /api/bill/patient/bills/ HTTP/1.1" 400 72
Creating Patient Bill .....................................
I have attempted to make a POST on post man I get 201 response meaning the payload is fine there is nothing wrong with it.
This is my POST payload.
I have a separate file called mocks.py contains
has PATIENT_BILL_CREATE_PAYLOAD
PATIENT_BILL_CREATE_PAYLOAD = {
"bill_items": [{
"item": "Syringes",
"qty": 2,
"description": "Medicorp syringes"
}],
"bill_services": [{
"service": "Diagnosis",
"service_type": "1",
"duration": 5,
"description": "diagnosis"
}],
"client": "Sandra Hernandez"
}
This is the function
i've imported the PATIENT_BILL_CREATE_PAYLOAD and using it in this function.
def patient_create_bill(headers):
"""This function uses login creds provided and returns token plus logged in user data."""
url = "http://0.0.0.0:9000/api/bill/patient/bills/"
data = PATIENT_BILL_CREATE_PAYLOAD
res = requests.post(url, data=data, headers=headers)
res_data = res.json()
print("Creating Patient Bill .....................................\n")
return res_data
Your own answer is right (encode your data to json), and here is the code fixed. This worked for me:
instead of
res = requests.post(url, data=data, headers=headers)
the correct way to write it is...
import json
...
res = requests.post(url, data=json.dumps(data), headers=headers)
# or
res = requests.post(url, json=data, headers=headers)
More info about this type of requests in requests library docs.
My error was because of using data instead of json in request and also specified the header Content-Type as `application/json :-).
This log tells that you not received body in HTTP reponse (HTTP CODE 400):
DEBUG:urllib3.connectionpool:http://0.0.0.0:9000 "POST /api/bill/patient/bills/ HTTP/1.1" 400 72
Python trying to parse emtry string.
You can run this:
import json
json.loads('')
And this code will raise:
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
I think, you should check your URL endpoint to call.

Microsoft Face API [find similar] api key error

So I'm trying to follow The microsoft face api documentation here for the "FindSimilar" feature. There is an example at the bottom of the page where I use this code:
########### Python 3.2 #############
import http.client, urllib.request, urllib.parse, urllib.error, base64
headers = {
# Request headers
'Content-Type': 'application/json',
'Ocp-Apim-Subscription-Key': '{api key}',
}
params = urllib.parse.urlencode({
})
try:
conn = http.client.HTTPSConnection('westus.api.cognitive.microsoft.com')
conn.request("POST", "/face/v1.0/findsimilars?%s" % params, "{body}",
headers)
response = conn.getresponse()
data = response.read()
print(data)
conn.close()
except Exception as e:
print("[Errno {0}] {1}".format(e.errno, e.strerror))
I'm getting an error where it tells me my subscription key is invalid, but I checked my azure account status and I see no issues:
b'\n\t\t\t\t\t{"error":{"code":"Unspecified","message":"Access denied due to invalid subscription key. Make sure you are subscribed to an API you are trying to call and provide the right key."}}\n \t\t'
Access denied due to invalid subscription key. Make sure you are subscribed to an API you are trying to call and provide the right key.
It indicates that Invalid subscription Key or user/plan is blocked. I recommand that you could check the APi Key.
headers = {
# Request headers
'Content-Type': 'application/json',
'Ocp-Apim-Subscription-Key': '3c658abc64b348c1a5...',
}

Get Survey Response Survey Monkey (Python)

Im quite new to http request. Im having abit of troubleshooting trying to get survey results/responses from survey monkey api 3.
Here is the following code i have:
import requests
import json
client = requests.session()
headers = {
"Authorization": "bearer %s" % "VVZEO3u35o3JVDdd8z5Qhl-eRR5Er2igaV1gf8GS4dvRfYVk3SWu9nHginwyNnU.tAHEr-AtikR9Zpg7vL3-jIg3-6yuQkPBvVIw0AkpYN5807SCLIrGojsii3ihdGV-",
"Content-Type": "application/json"
}
data = {}
HOST = "https://api.surveymonkey.net"
#SURVEY_LIST_ENDPOINT = "/v3/surveys/%s/responses/%s/details" %("85160626","161")
SURVEY_LIST_ENDPOINT = "/v3/surveys/85160626/responses"
uri = "%s%s" % (HOST, SURVEY_LIST_ENDPOINT)
response = client.post(uri, headers=headers, data=json.dumps(data))
response_json = response.json()
#survey_list = response_json["data"]["surveys"]
print(response_json)
I keep getting error:
{'error': {'docs': 'https://developer.surveymonkey.com/api/v3/#error-codes', 'message': 'There was an error retrieving the requested resource.', 'id': '1020', 'name': 'Resource Not Found', 'http_status_code': 404}}
Any help is much appreciated, thanks,
Pon
If you're trying to fetch data, then you should be doing a GET request, not a post.
response = client.get(uri, headers=headers)
Otherwise it looks fine, just make sure the Survey ID is correct.

Resources