I am trying to adapt this script so that even if multiple messages are sent at the same time the script will just keep trying until they are let through.
The original script is: https://github.com/4rqm/dhooks
My version is:
def post(self):
"""
Send the JSON formated object to the specified `self.url`.
"""
headers = {'Content-Type': 'application/json'}
result = requests.post(self.url, data=self.json, headers=headers)
if result.status_code == 400 or result.status_code == 429:
print(result.status_code)
#its the line below that does not work.
post(self)
else:
print("Payload delivered successfuly")
print("Code : "+str(result.status_code))
time.sleep(2)
Related
I am trying to set up a notification from on a payment. Here is my code:
def PayPal_IPN():
'''This module processes PayPal Instant Payment Notification messages (IPNs).'''
# Switch as appropriate
VERIFY_URL_PROD = 'https://ipnpb.paypal.com/cgi-bin/webscr'
VERIFY_URL = VERIFY_URL_PROD
# Read and parse query string
params = request.form.to_dict()
# Add '_notify-validate' parameter
params['cmd'] = '_notify-valudate'
# Post back to PayPal for validation
headers = {'content-type': 'application/x-www-form-urlencoded',
'user-agent': 'Python-IPN-Verification-Script'}
r = requests.post(VERIFY_URL, params=params, headers=headers, verify=True)
r.raise_for_status()
# Check return message and take action as needed
if r.text == 'VERIFIED':
print("SUCCESSFULL")
elif r.text == 'INVALID':
print("FAILURE")
else:
print("NOTHING HAPPENED?")
return ""
Here is my error message:
requests.exceptions.HTTPError: 404 Client Error: Not Found for url: https://ipnpb.paypal.com/cgi-bin/webscr....
Can someone help me figure out what I am not understanding? maybe the link has changed?
Here is the documentation I'm looking at https://developer.paypal.com/api/nvp-soap/ipn/IPNIntro/
I've tried changing the ipnpb to www. and still no luck.
The problem is the format of params. I'm not sure what request.form.to_dict() returns, but I do know that when you add cmd=_notify_validate it should be in this format:
params.append(('cmd', '_notify-validate'))
Also returning the appropriate format is urllib.parse.parse_qsl
I'm trying to write the output of an API 'get' request to a file. I know the function works as the output of the request is returned successfully and in full in shell.
The function creates the file, but the file only includes the status code for the get request - can anyone help me understand why? Still pretty new to Python and very new to calling APIs...
def user_info(token):
heads = {"Authorization": "bearer " + token, "Content-type": "application/json"}
url = "xxxxx"
request = req.get(url, headers=heads)
with open('userdata.txt', 'w') as f:
f.write(str(request))
if request.status_code == 200:
return request.json()
else:
return "User Info FAILED! Failure code: {}, error: {}".format(request.status_code,request.json()['error'])
The file just contains:
<Response [200]>
Thanks!
A Response object in the requests module when called as a string will return its status code as detailed in the Response python code
def __repr__(self):
return '<Response [%s]>' % (self.status_code)
If you want to write the json from the response as a string then you can use the built in json module and use its dumps method to dump it as a string not a dict.
import requests
import json
with open("myfile.txt", "w") as output:
resp = requests.get("https://jsonplaceholder.typicode.com/todos/1")
output.write(json.dumps(resp.json()))
I have the following python function where im trying to upload a file over to an API that accepts a file as multipart stream. The API correctly works with postman, however im struggling to identify the problem here.
I have parameters (json body) to post to the API along with the file which I have tried to encode inside my mp_encoder variable.
def callAPIwithFile(apiData,apiUrl):
file_ids = ''
jsonData = {'type':apiData['type'],'fromId':apiData['fromid'],'toUserIds':apiData['userIds'],'toGroupIds1':apiData['groupIds'],'toDepartmentIds1':apiData['departmentIds'],'subject':apiData['subject'],'body':apiData['body'],'attachment':apiData['attachment'],'report':apiData['report']}
mp_encoder = MultipartEncoder(fields={'type':apiData['type'],'fromId':apiData['fromid'],'toUserIds':apiData['userIds'],'toGroupIds1':apiData['groupIds'],'toDepartmentIds1':apiData['departmentIds'],'subject':apiData['subject'],'body':apiData['body'],'attachment':apiData['attachment'],'report':apiData['report'],'file': (apiData["attachment"], open(apiData["attachment"], 'rb'), 'application/vnd.ms-excel')})
print mp_encoder
headers = {'Authorization': 'Bearer jwt'}
resp = requests.post(apiUrl,headers=headers,data=mp_encoder)
print resp.text
print "status code " + str(resp.status_code)
if resp.status_code == 201:
print ("Success")
data = json.loads(resp.text)
file_ids = data['file_ids']
print file_ids
else:
print ("Failure")
On running the code I get the following errors :
{"statusCode":400,"message":["type must be a valid alpha, beta, Or gamma","body should not be empty"],"error":"Bad Request"}
status code 400
Failure
As per my understanding the JSON Body that im trying to post to the API is not being recognised correctly. How do I go about this?
Please note, I have tried using request.post(apiUrl,file=files,data=data,header=header) which results in an error of unexpected field.
The below answer could solve my problem :
headers = {'Authorization': 'Bearer '+token}
mydict = dict(type=apiData['type'], fromId=apiData['fromid'], toUserIds1=apiData['userIds'], toGroupIds=apiData['groupIds'], toDepartmentIds1= apiData['departmentIds'], subject= apiData['subject'], body= apiData['body'], attachment= apiData['attachment'], report= apiData['report'])
resp=requests.post(apiUrl, headers = headers, files=dict(attachment=(apiData["attachment"], open(apiData["attachment"], 'rb'), 'application/vnd.ms-excel')),data=mydict)
I am trying to parse json data from a site that shows values of crypto currency. I am trying to parse it using python. I am a little lost on how to show the output.
API: https://min-api.cryptocompare.com/data/price?fsym=XMR&tsyms=USD
# code starts below
import requests
# Set the request parameters
url = 'https://min-api.cryptocompare.com/data/price?fsym=XMR&tsyms=USD'
# Fetch url
print("Fetching url..")
# Do the HTTP get request
response = requests.get(url, verify=True) #Verify is check SSL certificate
# Error handling
# Check for HTTP codes other than 200
if response.status_code != 200:
print('Status:', response.status_code, 'Problem with the request. Exiting.')
exit()
# Decode the JSON response into a dictionary and use the data
USD = response.json()
output = USD[0]['USD']
print('Output USD:'), USD
# code ends
I am getting a response code 200 because IDLE tries to exit. The code is based off another project and I don't believe I am parsing json correctly?
The problem is here:
if response.status_code != 200:
print('Status:', response.status_code, 'Problem with the request. Exiting.')
exit()
The way you've indented, Python will always call exit(). You want it to call exit() only if there was actually an error, like so:
if response.status_code != 200:
print('Status:', response.status_code, 'Problem with the request. Exiting.')
exit()
However, you have another problem. You're trying to assign "output" the value of an object in USD; USD doesn't exist:
data = response.json()
output = USD[0]['USD'] #"USD" doesn't exist. It's the value you're trying to find, not the json that contains the object itself.
print('Output USD:'), USD #"USD" doesn't exist. I think you meant to print "output" here, which is the value you're setting in the line above.
Instead, try this:
data = response.json()
output = data["USD"]
print('Output USD:'), output
Your exit() line is not indented correctly. Try this:
if response.status_code != 200:
print('Status:', response.status_code, 'Problem with the request. Exiting.')
exit()
Additionally, even though you are parsing the JSON correctly, you incorrectly use the resulting data. Try this:
output = USD['USD'] # Note: "[0]" not required
print('Output USD:', USD) # Note: ", USD" inside the parentheses
I'm currently using the python requests library to interact with an external api which uses json.
Each endpoint works via a method (of the api class) and uses the collect_data method.
However I want the scraper to continue running whenever it encounters a http error (and ideally output this to a log).
What's the best way to do this as currently it just breaks when I use http.raise_for_status()
It seems like I should be using a try/except in someway but not sure how best to do this here?
def scrape_full_address(self, house_no, postcode):
address_path = '/api/addresses'
address_url = self.api_source + address_path
payload = {
'houseNo': house_no,
'postcode': postcode,
}
return self.collect_data(url=address_url, method='get', payload=payload)
def collect_data(self, url, method, payload=None):
if method == 'get':
data = None
params = payload
elif method == 'post':
params = None
data = payload
response = getattr(requests, method)(url=url, params=params, json=data, headers=self.headers)
if response.status_code == 200:
return response.json()
else:
return response.raise_for_status()
When you call scrape_full_address() elsewhere in your code wrap that in a try statement.
For more info see: https://wiki.python.org/moin/HandlingExceptions
try:
scrape_full_address(659, 31052)
except HTTPError:
print "Oops! That caused an error. Try again..."