Here am using the AWSSigV4 library to request the API.
Am using the "Get" API getting response 200.
But using the "Patch" API getting response 400 and content showing as the b'{"message":"1 validation error detected: Value null at \'clientToken\' failed to satisfy constraint: Member must not be null"}'
and the header error is 'x-amzn-ErrorType': 'ValidationException'
The code I used is
import requests, json, os
from requests_auth_aws_sigv4 import AWSSigV4
path = "~/sfs.json"
full_path = os.path.expanduser(path)
with open(full_path, 'r') as j:
contents = json.loads(j.read())
accesskey = contents['credentials']['accessKeyId']
secretkey = contents['credentials']['secretAccessKey']
session_token = contents['credentials']['sessionToken']
data = {"fulfillmentStatus": "COMPLETE", "overrideItems": [{"itemId": "089f845c38-c3b3026f69", "unitDetails": [{"quantity": 1, "status": "SHIPPED", "trackingUpdate": {"trackingId": "trackingID23456789", "carrierCode": "usps"}}]}]}
value=json.dumps(data)
print(data)
print(value)
aws_auth =AWSSigV4('Service',
aws_access_key_id=accesskey,
aws_secret_access_key=secretkey,
aws_session_token=session_token
)
r = requests.request("Patch", "https://yyyyyyyyyy.execute-api.us-east-1.amazonaws.com/prod/fulfillmentManagers/xxxxxxxxxx/fulfillments/7Z1LUF9yFBaN/override", auth=aws_auth, data=value)
Related
I am attempting to send a POST request using an API in PowerQuery on Excel/PBI. The request requires a body, and I've tried a few different ways (see below) but I keep recieving a DataSource.Error: Web.Contents failed to get contents from 'https://myapi.com/data' (400): Bad Request.
My request looks like this:
let
Source = Json.Document(Web.Contents("https://myapi.com/data", [Headers=[#"X-Impersonate-User"="usr_12345", Authorization="Bearer tok_12345", #"Content-Type"="application/json"],
Content=Json.FromValue({[start_date="2022-08-01T08:00:00.000Z", end_date="2022-08-10T08:00:00.000Z", space_ids="spc_12345", time_resolution="day"]})
]))
in
Source
I also tried it this way, but ran into the same issue:
let
url = "https://myapi.com/data"
body = "{""start_date"" : ""2022-08-01T08:00:00.000Z"", ""end_date"" : ""2022-08-10T08:00:00.000Z"", ""space_ids"" : ""spc_12345"", ""time_resolution"" : ""day""}",
Parsed_JSON = Json.Document(body),
BuildQueryString = Uri.BuildQueryString(Parsed_JSON),
Source = Json.Document(Web.Contents(url,[Headers=[#"Content-Type"="application/json", #"X-Impersonate-User"="usr_12345", Authorization="Bearer Bearer tok_12345"], Content = Text.ToBinary(BuildQueryString) ] ))
in
Source
I am able to call the API from Postman with no problems.
You want something closer to
let
url = ...,
headers = [#"Content-Type" = "application/json"],
postData = Json.FromValue(
[
start_date = "2022-08-01T08:00:00.000Z",
end_date = "2022-08-10T08:00:00.000Z",
space_ids = "spc_12345",
time_resolution = "day"
]
),
response = Web.Contents(
url,
[
Headers = headers,
Content = postData
]
),
jsonResponse = Json.Document(response)
in
jsonResponse
I' a bit lost with something I haven't seen before. I hope I will be able to explain my issue with clarity. I have the cloud function below:
url = 'https://reports.api.clockify.me/v1/workspaces/xxxx/reports/detailed'
headers = {'X-Api-Key': '{}'.format(api_key)}
Start = "2022-01-01T00:00:00.000"
End = "2022-03-26T23:59:59.000"
page = 1
raw_data = []
while True:
parameters = {"dateRangeStart":"{}".format(Start),"dateRangeEnd":"{}".format(End), "rounding": True, "exportType": "JSON", "amountShown": "EARNED","detailedFilter":{ "page":"{}".format(page),"pageSize":"1000"}}
print(parameters)
request = requests.post(url, headers=headers, json=parameters)
#response = request.json()['timeentries']
response = request.json()
if len(response) == 0:
break
raw_data.append(response)
page = page + 1
print(raw_data)
Everything is pretty standard (I think!). I'm looping through pages of clockify API request. The issue I have is that I found some logging information in my raw_data array.
When I'm printing the response I can see the following output in the log:
"severity": "INFO", "message": "{'totals': [{'_id': '', 'totalTime': 1345687, 'totalBillableTime': 1223465435, 'entriesCount': 1500, 'totalAmount': 23457354.0, 'amounts': [{'type': 'EARNED', 'value': 3746553.0}]}], 'timeentries': [{ .... standard clockify time entries ....
Why do I get "severity": "INFO", "message": when printing my response? Why is this part of my request? Then I found it in my raw_data array messing up with my JSON object... When using print I always have the raw value and not these logging info messages...
Using the ibm-watson Python SDK version 5.3.0 with the following code example:
from ibm_watson import DiscoveryV2, ApiException
from ibm_cloud_sdk_core.authenticators import IAMAuthenticator
import json
url = 'https://api.eu-de.discovery.watson.cloud.ibm.com'
version = '2020-08-30'
apikey = '...'
project = '...'
collection = '...'
authenticator = IAMAuthenticator(apikey)
discovery = DiscoveryV2(version=version, authenticator=authenticator)
discovery.set_service_url(url)
try:
result = discovery.query(
project_id=project,
collection_ids=collection,
query='text:searchterm',
table_results=True
).get_result()
print(json.dumps(result, indent=2))
except ApiException as ex:
print(f'Failed. Status code {ex.code}: {ex.message}')
Returns the following error from the server.
Failed. Status code 400: Failed to translate JSON in request: Cannot
deserialize value of type
`scala.collection.immutable.List<java.lang.String>` from String value
(token `JsonToken.VALUE_STRING`)
The error only occurs if collections_ids or table_results is specified.
The server is telling you that the JSON sent to it doesn't match what it expects to process.
The collections_ids and table_results are incorrectly formatted for the API request.
As per the API documentation.
collections_ids must be a list. So change to collections_ids=[collections]
table_results expects an object. To correct use table_results={ 'enabled': True }
I am trying to get financial data from my APP store connect account and am receiving a JSON error, see below:
import requests, time, json
from authlib.jose import jwt
KEY_ID = "KEY"
ISSUER_ID = "ID"
EXPIRATION_TIME = int(round(time.time() + (20.0 * 60.0))) # 20 minutes timestamp
PATH_TO_KEY = "C:\\Users\\justi\\Desktop\\Script Files\\App Store Connect\\private_key\\AuthKey_KEY.p8"
with open(PATH_TO_KEY, 'r') as f:
PRIVATE_KEY = f.read()
header = {
"alg": "ES256",
"kid": KEY_ID,
"typ": "JWT"
}
payload = {
"iss": ISSUER_ID,
"exp": EXPIRATION_TIME,
"aud": "appstoreconnect-v1"
}
# Create the JWT
token = jwt.encode(header, payload, PRIVATE_KEY)
# URL Query Params
report_type = "filter[reportType]=FINANCE_DETAIL"
region_code = "filter[regionCode]=Z1"
report_date = "filter[reportDate]=2021-03"
vendor_number = "filter[vendorNumber]=VEND_###"
# API Request
JWT = 'Bearer ' + token.decode()
URL = 'https://api.appstoreconnect.apple.com/v1/financeReports?'+ report_type +'&' +region_code+ '&' + report_date + '&' +vendor_number
HEAD = {'Authorization': JWT}
r = requests.get(URL, params={'limit': 200}, headers=HEAD)
# Write the response in a pretty printed JSON file
with open('financial_report.json', 'w') as out:
out.write(json.dumps(r.json(), indent=4))
I am getting a 200 response from my r object but when I go to dump the JSON data, here is my error:
https://www.screencast.com/t/ODMojS13WH
Has any one seen this before?
Is the response not a JSON object (which would be strange)?
Thank you in advance!
check if r.ok is True
check if r.json() returns json string. Use print statement.
Also r.text may be enough to write json to output file.
Example :
r = requests.get(URL, params={'limit': 200}, headers=HEAD)
print(r.json())
print(r.text())
Finance Reports Endpoint response content type is application/a-gzip, not application/json, so as you have commented, you have to decompress the binary content yourself.
However, there is a drawback in your code:
decompressed_data=zlib.decompress(r.content, 16+zlib.MAX_WBITS)
response.content triggers python-requests to load the content at once into memory, it could consume large amount of memory for large gzip responses.
Use response.raw file-like object and decompress data incrementally is more preferable. You can find example code here.
Or you can use applaud directly, it is a Python client library for accessing App Store Connect API. Your code can be shortened by using applaud:
import os
from applaud.endpoints.finance_reports import FinanceReportsEndpoint
from applaud.connection import Connection
KEY_ID = "XXXXXXXXXX"
ISSUER_ID = "XXXXXX-XXXXXXX-XXXXXX-XXXXXXX"
PATH_TO_KEY = os.path.expanduser('path/to/your/key.p8')
VENDOR_NUMBER = '12345678'
with open(PATH_TO_KEY, 'r') as f:
PRIVATE_KEY = f.read()
# Create the Connection
connection = Connection(ISSUER_ID, KEY_ID, PRIVATE_KEY)
r = connection.finance_reports().filter(
report_type=FinanceReportsEndpoint.ReportType.FINANCE_DETAIL, # or 'FINANCE_DETAIL'
region_code='Z1',
report_date='2021-03',
vendor_number=VENDOR_NUMBER
).get()
r.save('finance_reports.txt', decompress=True)
Full disclosure, I'm original author of applaud.
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.