I am making a post request and it has been done successfully on reqbin but when I use the code in my script, even if I copy and paste exactly, it doesn't work. I'm getting a 500 status on these and if I try other languages i get a 301. But I don't know what exactly is going on or what I'm missing.
expected response:
```{
"data": {
"txGasUnits": 132500,
"returnMessage": "",
"smartContractResults": null
},
"error": "",
"code": "successful"
}```
response from python:
b'{"data":null,"error":"transaction not found","code":"internal_issue"}
response from php and bash:
```<html>
<head><title>301 Moved Permanently</title></head>
<body bgcolor="white">
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/1.14.0 (Ubuntu)</center>
</body>
</html>```
the code provided for Python:
import requests
from requests.structures import CaseInsensitiveDict
url = "http://testnet-gateway.elrond.com/transaction/cost"
headers = CaseInsensitiveDict()
headers["Authorization"] = "Bearer mt0dgHmLJMVQhvjpNXDyA83vA_PxH23Y"
headers["Content-Type"] = "application/json"
data = """
{"value": "0",
"sender": "erd1qgjj3t38fgv0pscvr3xk0xq2gkm974mx0wz8afnqfewkevpn7v8s70np82",
"receiver": "erd14edl4fvr8wc2sczrz5af6tfmfucgqzsh4u73hnxw96l07cekdg6schwtsh",
"data": "RVNEVFRyYW5zZmVyQDUyNDk0MzQ1MmQ2MjM0MzA2MjMyNjJAMDRlNzNlZjNjNjdlMTUwMDAwCg==",
"chainID": "T",
"version": 1}
"""
resp = requests.post(url, headers=headers, data=data)
print(resp.status_code)
I added the php and bash just to show that other code snippets also failed, and in a different way, incase that may be relevent. I tried my own code and had the same result. Then when I used reqbin i got it to succeed, and then after struggling with it a bit I simply copied the code they generated and tried that precisely but it still didn't work. What could be the error?
The mistake is in the URL you're using.
Instead of http://, use https:// and it'll work.
As a rule of thumb, try to use https to interface with any service Elrond exposes, as that's the secure and supported way to go. The http port might be dead or straight up closed.
Related
I am trying to make a POST request for Indexnow protocol, which allows the user to send link massive to search engine (BING) for instant indexing. As I read all documentation, I found that this protocol suggests such JSON request construction:
POST /indexnow HTTP/1.1
Content-Type: application/json; charset=utf-8
Host: <searchengine>
{
"host": "www.example.com",
"key": "265f7fb3bd6c41118f6bf05568d9c825",
"urlList": [
"https://www.example.com/url1",
"https://www.example.com/folder/url2",
"https://www.example.com/url3"
]
}
I chose to use Python, and here is my code for this POST request:
import advertools as adv
import pandas as pd
import requests
import json
import time
def submit_url_set(set_:list, key, location, host="https://www.bing.com", headers={"Content-type":"application/json", "charset":"utf-8"}):
key = "91ca7c564b334f38b0b1ed90eec8g8b2"
data = {
"host": "www.bing.com",
"key": key,
"keyLocation": "https://uchet.kz/91ca7c564b334f38b0b1ed90eec8g8b2.txt",
"urlList": [
'https://uchet.kz/news/formirovanie-obshchestva-chistogo-ot-korruptsii-dobivaetsya-tokaev/',
'https://uchet.kz/news/pravila-polucheniya-iin-inostrantsu-v-rk-izmeneny/',
'https://uchet.kz/news/zabolevaemost-koronavirusom-sredi-shkolnikov-vyrosla-v-13-raza/',
'https://uchet.kz/news/izmeneny-pravila-provedeniya-tamozhennoy-ekspertizy/'
]
}
r = requests.post(host, data=data, headers=headers)
return r.status_code
After script runs, nothing returns.
I expected the script to return server response code HTTP-code 200 OK
What was I really expected
Getting the server response code for each indexing url.
I am the author of the code.
IndexNow API doesn't return a response, if you don't take an error message it means that the request has been taken.
You can check your log files to validate that.
Also, https://www.searchenginejournal.com/indexnow-api-python/429726/ in the article, this is stated.
Go to the Post Requests Online
Type your search engine URL
Put your code in the window below in this format:
{
"host": "your_site",
"key": "your_key",
"urlList": [
"https://your_site/1",
"https://your_site/2",
"https://your_site/3"
]
}
Press SEND.
Done
SCREENSHOT
I'm trying to use Google's API for geolocation giving wifi data to determine location. This is their intro. And this is my code
#author: Keith
"""
import requests
payload = {
"considerIp": "false",
"wifiAccessPoints": [
{
"macAddress": "00:25:9c:cf:1c:ac",
"signalStrength": -43,
"signalToNoiseRatio": 0
},
{
"macAddress": "00:25:9c:cf:1c:ad",
"signalStrength": -55,
"signalToNoiseRatio": 0
}
],
'key':'<MyAPIKey>'
}
r = requests.post('https://www.googleapis.com/geolocation/v1/geolocate',
params=payload)
print(r.text)
This is the output
{
"location": {
"lat": 32.3643098,
"lng": -88.703656
},
"accuracy": 6061.0
}
The request ignored all of the payload except the key portion and just found the geolocation using my IP address. So I'm sending the json payload incorrectly. I know this is probably really simple, but I'm stuck and couldn't find an example of python being used with requests to do this type of API query. Thanks
Edit:
Picked up the cURL library and executed this command with success:
curl -d #your_filename.json -H "Content-Type: application/json" -i "https://www.googleapis.com/geolocation/v1/geolocate?key=<myapikey>"
and got the output I expected. I just want to be able to do the same thing in requests, but the data I'm trying to send is in "your_filename.json".
Please try the following:
r = requests.post('https://www.googleapis.com/geolocation/v1/geolocate?key='+ '<MyAPIKey>', json=payload)
Note the key was moved to query params (URL) and json argument was used in place of params.
Okay I figured out the error of my ways. Taking a better look at requests.post function, I see that I'm not using the parameters argument correctly. After this, it worked perfectly,
r = requests.post('https://www.googleapis.com/geolocation/v1/geolocate', params=parameters, json=mydata, headers=headers)
I was given a request in Bash and I have to translate it to Python 2.7. I did this kind of translations several times, but now I am not able to make it work and I do not understand why.
First of all, I was given this Bash request:
curl -X POST -v -u user#domain:password --data "#file.json" -H "Content-Type:application/json" http://destination_url_a
With the file file.json, whose content is the following one:
{
"username":"user#domain",
"password":"password",
"shortName":"a-short-name",
"visibility":"PRIVATE",
"sitePreset":"site-dashboard",
"title":"A Title",
"description":"A description."
}
If I execute the Bash line in my computer, the result is succesful.
As always, I tried to use requests library in Python to make it work. What I did is:
import requests
from requests.auth import HTTPBasicAuth
import json
data = {
"username": "user#domain",
"password": "password",
"shortName": "a-short-name",
"visibility": "PRIVATE",
"sitePreset": "site-dashboard",
"title": "A Title",
"description": "A description.",
}
headers = {'Content-Type': 'application/json'}
data_json = json.dumps(data)
r = requests.post(
url='http://destination_url_a',
data=data_json,
headers=headers,
auth=HTTPBasicAuth('user#domain', 'password'),
verify=False,
)
Unfortunately, the response, stored in r variable, is an error, despite the status code is 200.
What could be happening? Does anyone find a problem in my code or has any idea?
EDIT
However, this is another example very similar which worked perfectly:
Bash:
curl -v -H "Content-Type:application/json" -X POST --data "#file.json" -u user#domain:password http://destination_url_b
My Python code
import requests
from requests.auth import HTTPBasicAuth
import json
data = {
"userName": "user#domain",
"password": "password",
"firstName": "Firstname",
"lastName": "Lastname",
"email": "email#domain.com",
"disableAccount": "False",
"quota": -1,
"groups": ["a_group",],
}
headers = {'Content-Type': 'application/json'}
data_json = json.dumps(data)
r = requests.post(
url='http://destination_url_b',
data=data_json,
headers=headers,
auth=HTTPBasicAuth('user#domain', 'password'),
verify=False,
)
It seems to be almost the same to the other request, but this works. Different data is sent, and to a different subdomain (both are sent to the same domain). Will these modifications be important if we are talking about the User-Agent you mentioned?
Sometimes, webservices filter on user-agent. User agent of curl and python are different. That may explain.
Try to forge a "legitimate" user-agent by modifying the request header.
Finally, there was no error in the code neither in the User-Agent.
The problem was that the destination application did not accept sites with the same short-name value.
What I was doing is creating the site from Bash, which worked, then removing it from the interface of the app and trying to create it from Python with the same data. I was getting error when doing that because in spite of having removed the site, I had to remove some residual data of it from the trashcan of the app too. If not, app returned an error since it considered that the site I was trying to create already existed.
So if I had introduced different short-name in each attempt, I would not have had any error.
I'm trying to get the FB messenger API working using Python's Flask, adapting the following instructions: https://developers.facebook.com/docs/messenger-platform/quickstart
So far, things have been going pretty well. I have verified my callback and am able to receive the messages I send using Messenger on my page, as in the logs in my heroku server indicate the appropriate packets of data are being received by my server. Right now I'm struggling a bit to send responses to the client messenging my app. In particular, I am not sure how to perform the following segment from the tutorial in Flask:
var token = "<page_access_token>";
function sendTextMessage(sender, text) {
messageData = {
text:text
}
request({
url: 'https://graph.facebook.com/v2.6/me/messages',
qs: {access_token:token},
method: 'POST',
json: {
recipient: {id:sender},
message: messageData,
}
}, function(error, response, body) {
if (error) {
console.log('Error sending message: ', error);
} else if (response.body.error) {
console.log('Error: ', response.body.error);
}
});
}
So far, I have this bit in my server-side Flask module:
#app.route('/', methods=["GET", "POST"])
def chatbot_response():
data = json.loads(req_data)
sender_id = data["entry"][0]["messaging"][0]["sender"]["id"]
url = "https://graph.facebook.com/v2.6/me/messages"
qs_value = {"access_token": TOKEN_OMITTED}
json_response = {"recipient": {"id": sender_id}, "message": "this is a test response message"}
response = ("my response text", 200, {"url": url, "qs": qs_value, "method": "POST", "json": json_response})
return response
However, running this, I find that while I can process what someone send my Page, it does not send a response back (i.e. nothing shows up in the messenger chat box). I'm new to Flask so any help would be greatly appreciated in doing the equivalent of the Javascript bit above in Flask.
Thanks!
This is the code that works for me:
data = json.loads(request.data)['entry'][0]['messaging']
for m in data:
resp_id = m['sender']['id']
resp_mess = {
'recipient': {
'id': resp_id,
},
'message': {
'text': m['message']['text'],
}
}
fb_response = requests.post(FB_MESSAGES_ENDPOINT,
params={"access_token": FB_TOKEN},
data=json.dumps(resp_mess),
headers = {'content-type': 'application/json'})
key differences:
message needs a text key for the actual response message, and you need to add the application/json content-type header.
Without the content-type header you get the The parameter recipient is required error response, and without the text key under message you get the param message must be non-empty error response.
This is the Flask example using fbmq library that works for me:
echo example :
from flask import Flask, request
from fbmq import Page
page = fbmq.Page(PAGE_ACCESS_TOKEN)
#app.route('/webhook', methods=['POST'])
def webhook():
page.handle_webhook(request.get_data(as_text=True))
return "ok"
#page.handle_message
def message_handler(event):
page.send(event.sender_id, event.message_text)
In that scenario in your tutorial, the node.js application is sending an HTTP POST request back to Facebook's servers, which then forwards the content on to the client.
So far, sounds like your Flask app is only receiving (AKA serving) HTTP requests. The reason is that that's what the Flask library is all about, and it's the only thing that Flask does.
To send an HTTP request back to Facebook, you can use any Python HTTP client library you like. There is one called urllib in the standard library, but it's a bit clunky to use... try the Requests library.
Since your request handler is delegating to an outgoing HTTP call, you need to look at the response to this sub-request also, to make sure everything went as planned.
Your handler may end up looking something like
import json
import os
from flask import app, request
# confusingly similar name, keep these straight in your head
import requests
FB_MESSAGES_ENDPOINT = "https://graph.facebook.com/v2.6/me/messages"
# good practice: don't keep secrets in files, one day you'll accidentally
# commit it and push it to github and then you'll be sad. in bash:
# $ export FB_ACCESS_TOKEN=my-secret-fb-token
FB_TOKEN = os.environ['FB_ACCESS_TOKEN']
#app.route('/', method="POST")
def chatbot_response():
data = request.json() # flasks's request object
sender_id = data["entry"][0]["messaging"][0]["sender"]["id"]
send_back_to_fb = {
"recipient": {
"id": sender_id,
},
"message": "this is a test response message"
}
# the big change: use another library to send an HTTP request back to FB
fb_response = requests.post(FB_MESSAGES_ENDPOINT,
params={"access_token": FB_TOKEN},
data=json.dumps(send_back_to_fb))
# handle the response to the subrequest you made
if not fb_response.ok:
# log some useful info for yourself, for debugging
print 'jeepers. %s: %s' % (fb_response.status_code, fb_response.text)
# always return 200 to Facebook's original POST request so they know you
# handled their request
return "OK", 200
When doing responses in Flask, you have to be careful. Simply doing a return statement won't return anything to the requester.
In your case, you might want to look at jsonify(). It will take a Python dictionary and return it to your browser as a JSON object.
from flask import jsonify
return jsonify({"url": url, "qs": qs_value, "method": "POST", "json": json_response})
If you want more control over the responses, like setting codes, take a look at make_response()
Im using python requests library to make google a drive api request to change permissions of a file, in this case the owner.
Here is what my code looks like
fileId = "123abcEfJl-mNooP45Kl6u" #fake file id
url = https://www.googleapis.com/drive/v2/files/%s/permissions' % fileId
payload = {"role":"owner", "type":"user", "value":"<some_user>#gmail.com"}
headers = {'Authorization': 'Bearer %s'%access_token, 'Content-Type':'application/json'}
permResponse = requests.post(url, data=payload, headers=headers)
print permResponse.text
When I run this, I get the following response:
{
"error": {
"errors": [
{
"domain": "global",
"reason": "parseError",
"message": "Parse Error"
}
],
"code": 400,
"message": "Parse Error"
}
}
I've been following the google docs api for this and have not been able to figure out what im doing incorrectly.
https://developers.google.com/drive/v2/reference/permissions/insert
Even their Try It! section is broken because there isn't an option to add the required 'value' field.
What am I doing incorrectly? Is anyone else running into these issues?
Thanks
I'm using the urllib.request module, and It works fine. This is my code:
key = "?key=" + MY_API_KEY
url_destino = ("https://www.googleapis.com/drive/v2/files/%s/permissions" % source_id)+ key
values = "{"role":"owner", "type":"user", "value":"<some_user>#gmail.com"}"
data = values.encode('utf-8')
request = urllib.request.Request(url_destino, data, method='POST')
request.add_header("Authorization", "Bearer " + token)
request.add_header("Content-Length", len(data))
request.add_header("Content-Type", "application/json")
print(request.header_items()) # for debugging purpouse
f = urllib.request.urlopen(request)
print(f.read())
I've thought to replace the urllib.request by Requests module (it's more clean to work with) in my little library but, now works.
Because I use Python 3 I can't use the google-api-python-client.