Error "name "true" not defined when sending POST request - python

I am trying to send a POST request that requires the literal true to be sent as part of the JSON payload. I know I can change it to True which Python likes but it fails with an API (SCIM) that I am testing.
How do I send the word true and have Python submit it as-is? This does work when I send via Postman. Using an example with httpbin below with the same error.
import requests
headers = {
"Accept": "Application/json",
"Content-Type": "Application/json"
}
payload = {
"emails": [{
"primary": true,
"value": "jack#justjack.com",
"type": "work"
}]
}
print (type (payload))
print (payload)
resp = requests.post ('http://httpbin.com/post',headers=headers,data=payload)
print(resp.content)
Error Message I get is
"primary": true,
NameError: name 'true' is not defined"

Use Python's regular True and convert your dict to a JSON string when you create your payload:
import json
payload = {
"emails": [{
"primary": True,
"value": "jack#justjack.com",
"type": "work"
}]
}
resp = requests.post('http://httpbin.com/post', headers=headers, data=json.dumps(payload))
# ^^^^^^^^^^

in python we are using True or False instead of true / false
you can read further here in PEP-285

Related

Creating Jira issue with REST API

Having issues with trying to create an issue with Jira through the APIs, below is a sample of my code. We are using enterprise jira, I have to replace certain sections with so I hope it wont effect your ability to provide help.
from requests.auth import HTTPBasicAuth
import requests
user = '<ID>'
password = '<password>'
url = 'https://<enterprise>jira.<domain>.com/projects/<MYKEY>/rest/api/3/issue'
headers = {
'Content-Type': 'application/json',
}
json_data = {
"fields": {
"project": {
"key": "<MYKEY>"
},
"summary": "Creating From Collection",
"description": {
"type": "doc",
"version": 1,
"content": [
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": "This is an autogenerated issue from a demo."
}
]
}
]
},
"issuetype": {
"name": "Task"
}
}
}
response = requests.post(
url,
headers=headers,
json=json_data,
verify=False,
auth=(user, password),
)
I get error code 405 and the following message when running print(response.text):
<!doctype html>HTTP Status 405 – Method Not Allowedbody {font-family:Tahoma,Arial,sans-serif;} h1, h2, h3, b {color:white;background-color:#525D76;} h1 {font-size:22px;} h2 {font-size:16px;} h3 {font-size:14px;} p {font-size:12px;} a {color:black;} .line {height:1px;background-color:#525D76;border:none;}HTTP Status 405 – Method Not AllowedType Status ReportMessage HTTP method POST is not supported by this URLDescription The method received in the request-line is known by the origin server but not supported by the target resource.Apache Tomcat/8.5.78
Im sure I'm doing something wrong so any help will be appreciated.
Also I have verified I have the right access by manually going to the project and creating an issue.
Your URL is wrong. For creating a Jira issue you want to use the create issue endpoint.
For server/datacenter:
url = 'https://<enterprise>jira.<domain>.com/rest/api/2/issue'
For cloud:
url = 'https://<enterprise>jira.<domain>.com/rest/api/3/issue'
You need to use a POST request to either of these endpoints.

Discord API "Cannot send an empty message"

I'm trying to manually respond to a discord API call by getting the token from the logs of my API but when i send the request, it responds with
<Response [400]>
{"message": "Cannot send an empty message", "code": 50006}
Code is below:
import requests
application_id = "9999999999032"
payload = {"type": 4,
"data": {"content": "Congrats on sending your command!"}}
interaction_token = "aW50****lm"
headers = {'content-type': 'application/json'}
r = requests.patch(f"https://discord.com/api/v9/webhooks/{application_id}/{interaction_token}/messages/#original", headers=headers, json=payload)
print(r)
print(r.text)
Link to docs https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-response-object-interaction-callback-type
I haven't tested your code yet, but I think the problem is in the payload variable, instead of doing this:
{
"type": 4,
"data": {
"content": "Congrats on sending your command!"
}
}
Do this:
{
"type": 4,
"content": "Congrats on sending your command!"
}
If it doesn't work, I don't know how to fix it.

Elastic search Api

Hey Stackoverflow fam,
I am working on an API which pulls requests from elastic search tool and displays it.
I am trying to pull data using get request
import requests
import json
payload = {
"query": {
"match": {
"metric": "metric_name"
}
}
}
url = "https://url_name:9200/siren-kinesis*/_search"
payload = json.dumps(payload)
print(type(payload))
headers = {
'Content-Type': 'application/json',
}
result = requests.get(url=url,data=payload,headers=headers,auth=("test#example.com","*"))
print(result.json())
and getting the following error
{
"error": {
"root_cause": [
{
"type": "security_exception",
"reason": "unable to authenticate user [test#example.com] for REST request [/_search]",
"header": {
"WWW-Authenticate": "Basic realm=\"security\" charset=\"UTF-8\""
}
}
],
"type": "security_exception",
"reason": "unable to authenticate user [test#example.com] for REST request [/_search]",
"header": {
"WWW-Authenticate": "Basic realm=\"security\" charset=\"UTF-8\""
}
},
"status": 401
}
I am Basic Auth .i.e. passing username and password for authorization.
Can somebody help me ?
In the case of Basic Auth in any request, if you're requesting via postman you can provide the credentials in the Authentication tab. But In the case of Code/Console/Browser, the certificates must be given in the request URL.
e.g.
https://username:password#URL
https://admin:admin#www.the-internet.herokuapp.com/basic_auth

Alpha Vantage API Key returns invalid error in Python, and what is Response[200]?

Using the following code, I am not getting any data from alphavantage, I get the following API error:
"Error Message": "Invalid API call. Please retry or visit the documentation (https://www.alphavantage.co/documentation/) for TIME_SERIES_DAILY." }
import requests
import alpha_vantage
API_URL = "https://www.alphavantage.co/query"
data = {
"function": "TIME_SERIES_DAILY",
"symbol": "NIFTY",
"outputsize": "compact",
"datatype": "csv",
"apikey": "xxx",
}
response = requests.get(API_URL, params=data)
print(response.json())
I edited the code to try something else, but I still got something strange, this time it was:
Response [200]
Here is the code for that:
import requests
import alpha_vantage
API_URL = "https://www.alphavantage.co/query"
data = {
"function": "TIME_SERIES_DAILY",
"symbol": "US",
"outputsize": "compact",
"datatype": "csv",
"apikey": "xxx"
}
response = requests.get(API_URL, params=data)
print(response)
What going on here?
(Key obfuscated below to xxx)
There are three issues going on with your attempts to call this API.
In your first attempt, you correctly call the API but use an invalid ticker. NIFTY along with other global indexes are not supported by the Alpha Vantage API.
On your second attempt, you print out a response object, which when converted to string looks just like the output you received, Response[200] meaning a successful API call was made. To get the data from it, you have to print response.text or response.json()
The third issue is more subtle, and depends on what you are trying to return. If you want to return a csv file using the datatype: "csv", you cannot use response.json() since the format isn't for json. You can instead use the default datatype: "json", by leaving that field blank.
If you want to get a csv file, you can use print(response.text)
JSON example
import requests
import alpha_vantage
API_URL = "https://www.alphavantage.co/query"
data = {
"function": "TIME_SERIES_DAILY",
"symbol": "M&M.NSE",
"outputsize": "compact",
"apikey": "xxx"
}
response = requests.get(API_URL, params=data)
print(response.json())
CSV example
import requests
import alpha_vantage
API_URL = "https://www.alphavantage.co/query"
data = {
"function": "TIME_SERIES_DAILY",
"symbol": "M&M.NSE",
"outputsize": "compact",
"datatype": "csv",
"apikey": "xxx"
}
response = requests.get(API_URL, params=data)
print(response.text)

Send a request with a body to AWS Lambda

I have uploaded an AWS Lambda function where the lambda_handler looks as follows:
import json
def lambda_handler(event, context):
print(event)
return {
'statusCode': 200,
'body': json.dumps('Hello from Lambda!'),
'event': event
}
Problem 1: returning event
When I test it using the Lambda Management Console I can create a test event with parameters which also return the exact same format and all works fine:
{
"key1": "value1",
"key2": "value2",
"key3": "value3"
}
However, when I use Postman, then I get something totally else, which returns to me:
{
"message": "Internal server error"
}
I suspect its because the event looks something more like:
{'resource': '/hello', 'path': '/hello', 'httpMethod': 'GET', 'headers': {'Accept': '*/*', ... etc
Problem 2: adding json parameters in body creates an error
When I try in Postman to add in the body > raw > JSON(application/JSON) the keys above, then I get the error:
ERROR: The request could not be satisfied
Questions
I have two questions:
How do I pass parameters in the body and be able to capture it in AWS lambda using the event or context?
How do I return the event properly?
Assuming you have set up your Lambda as proxy integration in AWS API Gateway. If you want to attach query string params and no body then your method type should be GET.
The event you would receive in your Lambda for request /GET your-path/?myKey1=value1&myKey2=value2 should something like:
{
"resource": "",
"path": "/your-path",
"httpMethod": "GET",
"headers": {
},
"queryStringParameters": {
"myKey1": "value1",
"myKey2": "value2"
},
"pathParameters": {
},
"body": "{}"
}
You can access query string params in queryStringParameters property.
If you send request using Postman and attach body then your Lambda integration type should be POST/PUT. Data that you add in Postman request body would be available in event["body"].
Last thing if you test Lambda directly in the console then event will be received as you put in the body. You will need to format your event according to the integration method type. If it is POST/PUT then:
{
"body": {
"someValue": {..}
}
}
If it is GET then:
{
"queryStringParameters": {
"myKey1": "value1",
"myKey2": "value2"
}
}
Figrued it out, after help from #Althar Khan.
Apparently the API Gateway of AWS Lambda only accepts certain properties:
...
return {
"statusCode": 200,
"headers": {
"my_header": "my_value"
},
"body": JSON.stringify(responseBody),
"isBase64Encoded": false
};
In this response, there are four fields: statusCode, headers, body, and isBase64Encoded.
In this example, the function's response is in the format that the API Gateway expects. For additional information, see Output Format of a Lambda Function for Proxy Integration.

Categories