I'm trying to create an event with facebook from an external application. I've read this con events, where it states that you can create an event via POST, so i have the following-
data = dict()
data['access_token'] = self.access_token
data['name'] = 'Fb event from Python!'
data['start_time'] = datetime.datetime.now().isoformat()
data = urllib.urlencode(data)
url = 'https://graph.facebook.com/me/events'
request = urllib2.Request(url=url, data=data)
response = urllib2.urlopen(request)
Where I already have my access token and my fb permissions set so my app can create events and so forth. But I get an error 400 = Bad Request, so if anyone could help I'd be more than happy thanks in advance
Well I would say you should think about using facebook-sdk. From your error i.e http 400 you know that what you are doing wrong is how you are sending the http request itself. The request requires certain parameters in a certain form that you are not giving. If you look at
the request function in here
It makes the request in this form where path is id( I am also not sure me is valid here, but perhaps we can use me for the resource whose access-token we are using)
I think args access token .
file = urllib2.urlopen("https://graph.facebook.com/" + path + "?" +
urllib.urlencode(args),
post_data, timeout=self.timeout)
Thus change the form in which you are making the request. You can go through facebook.py's code and docs to figure out the variables mean based on your needs
Related
I need to print all requests from specific Postman collection. I have this code:
import requests
# Set up Postman API endpoint and authorization
postman_api_endpoint = "https://api.getpostman.com/collections"
postman_api_key = "PMAK-63b6bf724ebf902ad13d4bf2-e683c12d426716552861acda**********"
headers = {"X-Api-Key": postman_api_key}
# Get all requests from Postman collection
collection_id = "25184041-c1537769-f598-4c0e-b8ae-8cd185a79c03"
response = requests.get(f"{postman_api_endpoint}/{collection_id}/items", headers)
if response.status_code != 200:
print("Error retrieving collection:", response.text)
else:
# Print all requests
requests_data = response.json()["items"]
for request_data in requests_data:
request_method = request_data["request"]["method"]
request_url = request_data["request"]["url"]
request_headers = request_data["request"]["header"]
request_body = request_data["request"]["body"]["raw"] \
if request_data["request"]["body"]["mode"] == "raw" else ""
print(f"{request_method} {request_url}")
print("Headers:")
for header in request_headers:
print(f"{header['key']}: {header['value']}")
print("Body:")
print(request_body)
I received an error while I try to call response.text and have such massage:
Error retrieving collection: {"error":{"name":"notFound","message":"Requested resource not found"}}
Which means that I have 404 error. I have several assumptions what I did wrong:
I entered incorrect api key(But I checked several times and regenerated it twice)
I entered incorrect collection id, but in the screen below you can see where I took it and it is correct
And as I think the most likely variant I wrote incorrect request where I put my key and my collection id(I din't find any example how such requests should be like)
And of course I have requests in my collection, so error can not be because the collection is empty
Please give me some advice how I can fix this error. Thank you!
The answer is actually is really simple. I didn't know that I need to push button save request in Postman. I think if I create request in collection it will automatically save it. But I didn't, so I just saved all requests manually and finally receive correct response.
So I have a Python script that sends a get request to an API and returns information. For educational purposes, I wanted to create an API that I could pass parameters to which would return results from that script. I couldn't really find a similar example on stackoverflow or on the official flask documentation for an example that meets what I'm looking for. Everything I'm seeing is for returning data that you already have existing in a database or in a json file.
Here's an example of the script that I have right now.
script.py
api_url = www.statetaxes.com
parameters = {"taxinfo": "state:Texas county:soaker_county zip_code:78331"}
token = "abcd123456"
response= request.get(api_url, params=parameters, headers={"authentication":token})
print(response.json()) >----- [{tax rate: 1.5%, education_quality:great, crime_rate:0}]
The user would set the parameters in a config file somewhere like so:
[taxinfo]
county: some_county
zip_code: 12345
I'd want to read that text file, grab those parameters and push it to an API endpoint. I can figure out the part on how to read those parameters and send it to the API, but I'm not sure how I'm supposed to be configuring the rest of my FLASK app. I'd assume that I'd have to take those parameters which I'm reading from the text file as an argument. Am I on the right path here?
#app.route('/taxes/<taxinfo>', methods = ['GET', 'POST', 'PUT' ])
def state_taxes(taxinfo):
def api_call():
api_url = www.statetaxes.com
parameters=taxinfo
token = "abcd123456"
response= request.get(api_url, params=parameters, headers={"authentication":token})
return api_call
if __name__== "__main__":
app.run(debug=True)
I am using am attempting to do a bulk download of a series of PDFs from a site that requires login authentication. I am able to successfully log in, however, when I attempt a GET request for '/transcripts/transcript.pdf?user_id=3007' but, the request returns the content for '/transcripts/transcript.pdf'.
Does anyone have any idea why the URL param is not sending? Or why it would be rerouted?
I have tried passing the parameter 'user_id' as data, params, and hardcoded in the URL.
I have removed the actual domain from the strings below just for privacy
with requests.Session() as s:
login = s.get('<domain>/login/canvas')
# print the html returned or something more intelligent to see if it's a successful login page.
print(login.text)
login_html = lxml.html.fromstring(login.text)
hidden_inputs = login_html.xpath(r'//form//input[#type="hidden"]')
form = {x.attrib["name"]: x.attrib["value"] for x in hidden_inputs}
print("form: ",form)
form['pseudonym_session[unique_id]']= username
form['pseudonym_session[password]']= password
response = s.post('<domain>/login/canvas',data=form)
print(response.url, response.status_code) # gets <domain>?login_success=1 200
# An authorised request.
data = { 'user_id':'3007'}
r = s.get('<domain>/transcripts/transcript.pdf?user_id=3007', data=data)
print(r.url) # gets <domain>/transcripts/transcript.pdf
print(r.status_code) # gets 200
with open('test.pdf', 'wb') as f:
f.write(r.content)
GET response returns /transcripts/transcript.pdf and not /transcripts/transcript.pdf?user_id=3007
From the looks of it, you are trying to use canvas. I'm pretty sure in canvas, you can bulk download all test attachments.
If that's not the case, There are a few things to try:
after logging in, try typing the url with user_id into a browser. Does that take you directly to the PDF file or links to one?
if so, look at the url, it may simply not display the parameters; some websites do this, don't worry about it
If not, GET may not be enough; perhaps the site uses javascript, etc.
after looking through the '.history' of the request I found a series of 302 redirects.
The first was to '/login?force_login=0&target_uri=%2Ftranscripts%2Ftranscript.pdf'
In a desperate attempt, I tried: s.get('/login?force_login=0&target_uri=%2Ftranscripts%2Ftranscript.pdf%3Fuser_id%3D3007') and this still rerouted me a few times but ultimately got me the file I wanted!
If anyone has a more elegant solution to this or any resources that I can read I would greatly appreciate it!
I'm trying to connect our application to Streamlabs' API so we can post donation alerts. To do that, I need to get an access token for the user whose channel we want to alert on. It's a normal OAuth2 thing. We hit the /authorize endpoint and get a code back, which we're then supposed to able to use to get an access token from the /token endpoint (https://dev.streamlabs.com/v1.0/reference#token-1).
But when we send the POST request for the token, we get an error saying the request is missing the "grant_type" parameter.
We're using the normal requests library. I've tried changing the format of the request to requests.post. I've tried altering the data by wrapping it in urlencode and json.dumps. Still no luck.
streamlabs_client_id = config('STREAMLABS_CLIENT_ID')
streamlabs_client_secret = config('STREAMLABS_CLIENT_SECRET')
streamlabs_redirect_uri = config('STREAMLABS_REDIRECT_URI')
grant_type = 'authorization_code'
querydict = {
"grant_type":"authorization_code",
"client_id":streamlabs_client_id,
"client_secret":streamlabs_client_secret,
"redirect_uri":streamlabs_redirect_uri,
"code":code
}
url = "https://streamlabs.com/api/v1.0/token"
streamlabs_response = requests.request("POST", url, data=querydict)
This is the json I get back every time:
{"error":"invalid_request","error_description":"The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. Check the \"grant_type\" parameter."}
Any ideas what I'm doing wrong with the data?
I'm following the instructions mentioned here: https://api.stackexchange.com/docs/authentication
But since there is no code provided, I'm not able to understand the flow correctly.
I've been trying to get the authentication part done using two methods below but I have hit a deadend.
1)
import requests
from pprint import pprint
resp = requests.get('https://stackexchange.com/oauth/dialog?client_id=6667&scope=private_info&redirect_uri=https://stackexchange.com/oauth/login_success/')
pprint(vars(resp))
2)
import oauth2 as oauth
from pprint import pprint
url = 'https://www.stackexchange.com'
request_token_url = '%s/oauth/' % url
access_token_url = '%s/' % url
consumer = oauth.Consumer(key='mykey',
secret='mysecret')
client = oauth.Client(consumer)
response, content = client.request(request_token_url, 'GET')
print(response, content)
I'm not sure how to go forward from here? I need to use the access token that is returned and use it to query the API. A sample code would really really help! Thanks.
EDIT: This is the code I'm using currently:
from requests_oauthlib import OAuth2Session
from pprint import pprint
client_id = 'x'
client_secret = 'x'
redirect_uri = 'https://stackexchange.com/oauth/login_success'
scope = 'no_expiry'
oauth = OAuth2Session(client_id, redirect_uri=redirect_uri, scope=scope)
pprint(vars(oauth))
authorization_url, state = oauth.authorization_url('https://stackexchange.com/oauth/dialog')
print(authorization_url)
Instead of having to click on the authorization_url and get the token, is there a way I can directly fetch the token within the script itself?
Of the two methods you used, the first is the recommended method for desktop applications. It is probably correct.
OAuth is intended to force the user to go to a specific webpage and acknowledge that they are giving permission (usually through clicking a button) for an application to access their data. The HTTP responses you print are merely the webpage where a user needs to click accept.
To get a feeling for the flow, put the first address (https://stackexchange.com/oauth/dialog?client_id=6667&scope=&redirect_uri=https://stackexchange.com/oauth/login_success/) in the address bar and click accept on the loaded page. The access_token will be in the URL right after that.
If you are making the application only for yourself, the access_token can be copied into your Python script. The token expires in one day; if that is too short add no_expiry to scope to make it last forever. DO NOT share the token with anyone else, since it gives them access to details of your account! Each user of the script must generate their own token.
Test the access_token by inserting in your app's key and the access_token you just obtained into the url: https://api.stackexchange.com/2.2/me?key=key&site=stackoverflow&order=desc&sort=reputation&access_token=&filter=default
If you need a more automated, integrated, user-friendly solution, I would look at selenium webdriver to open a browser window and get the resulting credentials.
Just one minor correction on Marc's answer. If you want the access token to last forever, you should add no_expiry instead of no_expire.