Pexels API Python Request - python

I tried doing API request with Python for Pexels, but get authentication error. Documentation link Here is my code:
import requests
video_base_url = 'https://api.pexels.com/v1/search'
api_key = 'my_key'
my_obj = {'Authorization':api_key, 'query':'Stock market'}
x = requests.get(video_base_url,data = my_obj)
print(x.text)
But I get "error": "Authorization field missing". Any help is appreciated.

You are sending the authorization in the body of the request
You need to send it in the header
r = requests.get(video_base_url, headers = {'Authorization': api_key}, data = my_obj)

Related

FitBit API "Get Activity TCX" Not Returning The Expected Content (Response Code 200)

I have tried for hours getting the content of the .tcx file via the fitbit api. But, with no luck. I have no issue getting "Heartrate-, Sleep- og Profile data i.e.". Maybe I can't get the .tcx data simply because it's .tcx format, and not .json format?
According to the FitBit Developer Reference:
"Response Code 200 = A successful request."
Response should be in an XML format
Any help would be greatly appreciated, thanks :-)
import requests
import json
# Connect to API using Implicit Grant Flow
access_token = 'eyJhbGciOXXXXI1NiJ9.eyJhdWXiOiIyMXXXU0giLCJzdWIiOiI0WU5HM1EiLFFUEOWMiOiJGaXRiaXQXXXeXAiOiJhY2Nlc3NfdG9rZWXiLCJzY29wZXMiOiJ3584WF3BybyB3bnV0IHdzbGUgd3dXXXXc29jIHdhY3Qgd3NlXCB3bG9jIiwiZXXXXjoxNjQxNXXXMDc1LCJpYXQiOjE2XXXXXDc0ODR9.cuioifVTTG1ThUWXXAQH1Y816dTnWXXXkfsyANc-Qc'
# Get TCX Data
def get_activity_tcx():
logid = '44962596407'
url = f'https://api.fitbit.com/1/user/-/activities/{logid}.tcx?'
header = {'Authorization' : 'Bearer {}'.format(access_token)}
response = requests.get(url, headers=header)
return response
get_activity_tcx())
Output
<Response [200]>

Im trying login a website with requests in python

I'm trying to login to my coingecko account, but it says the login is wrong even though my account information is correct.
I tried updating the header etc. but it doesn't work
Here is my code:
import time
import requests
import json
s = requests.session()
r = s.get("https://www.coingecko.com/accounts/csrf_meta.json")
token = r.json()["token"]
cookie2 = s.cookies.get_dict()
cookie2 = json.dumps(cookie2)
cookie2 = json.loads(cookie2)
cookie3 = cookie2["_session_id"]
cookie = {
"_session_id":f"{cookie3}"
}
data = {
"utf8": "✓",
"authenticity_token": token,
"user[email]": "my mail",
"user[password]": "my passw",
}
r2 = s.post("https://www.coingecko.com/account/sign_in?locale=tr",json=data,cookies=cookie)
print(r2.text)
print(s.cookies.get_dict())
It gives me 5B%5B%22alert%22%2C%22Invalid+Email+or+password.%22%5D%5D cookie value, But my password & Email are true
You send it as JSON (json=...) but have to send it as normal form (data=...)
s.post(url, data=data)
Minimal working code with other changes.
I used locale=en to get flash message in English - and it shows me Signed in successfully.
Because you use Session so you don't need add cookies=... because Session should do it automatically.
import requests
import json
import urllib
s = requests.Session()
r = s.get("https://www.coingecko.com/accounts/csrf_meta.json")
token = r.json()["token"]
data = {
"utf8": "✓",
"authenticity_token": token,
"user[email]": "my_email",
"user[password]": "my_password",
#"user[redirect_to]": "https://www.coingecko.com/en",
#"user[remember_me]": ["0"]
}
r = s.post("https://www.coingecko.com/account/sign_in?locale=en", data=data)
#print(r.text)
cookies = s.cookies.get_dict()
print('cookies:', cookies)
if 'flash' in cookies:
flash = cookies['flash']
flash = urllib.parse.unquote_plus(flash)
flash = json.loads(flash)
print('flash:', flash[0][1])
Result:
cookies: {'flash': '%5B%5B%22notice%22%2C%22Signed+in+successfully.%22%5D%5D', '_session_id': '0c457f737330527a1eae7f98b0e8df5e'}
flash: Signed in successfully.

Selenium Python - Get Network response body

I use Selenium to react to the reception of data following a GET request from a website.
The API called by the website is not public, so if I use the URL of the request to retrieve the data, I get {"message":"Unauthenticated."}.
All I've managed to do so far is to retrieve the header of the response.
I found here that using driver.execute_cdp_cmd('Network.getResponseBody', {...}) might be a solution to my problem.
Here is a sample of my code:
import json
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
capabilities = DesiredCapabilities.CHROME
capabilities["goog:loggingPrefs"] = {"performance": "ALL"}
driver = webdriver.Chrome(
r"./chromedriver",
desired_capabilities=capabilities,
)
def processLog(log):
log = json.loads(log["message"])["message"]
if ("Network.response" in log["method"] and "params" in log.keys()):
headers = log["params"]["response"]
body = driver.execute_cdp_cmd('Network.getResponseBody', {'requestId': log["params"]["requestId"]})
print(json.dumps(body, indent=4, sort_keys=True))
return log["params"]
logs = driver.get_log('performance')
responses = [processLog(log) for log in logs]
Unfortunately, the driver.execute_cdp_cmd('Network.getResponseBody', {...}) returns:
unknown error: unhandled inspector error: {"code":-32000,"message":"No resource with given identifier found"}
Do you know what I am missing?
Do you have any idea on how to retrieve the response body?
Thank you for your help!
In order to retrieve response body, you have to listen specifically to Network.responseReceived:
def processLog(log):
log = json.loads(log["message"])["message"]
if ("Network.responseReceived" in log["method"] and "params" in log.keys()):
body = driver.execute_cdp_cmd('Network.getResponseBody', {'requestId': log["params"]["requestId"]})
However, I ended using a different approach relying on requests. I just retrieved the authorization token from the browser console (Network > Headers > Request Headers > Authorization) and used it to get the data I wanted:
import requests
def get_data():
url = "<your_url>"
headers = {
"Authorization": "Bearer <your_access_token>",
"Content-type": "application/json"
}
params = {
key: value,
...
}
r = requests.get(url, headers = headers, params = params)
if r.status_code == 200:
return r.json()
Probably some responses don't have a body, thus selenium throws an error that "no resource" for given identifier was found. Error message is a bit ambiguous here.
Try doing like this:
from selenium.common import exceptions
try:
body = chromedriver.execute_cdp_cmd('Network.getResponseBody', {'requestId': log["params"]["requestId"]})
log['body'] = body
except exceptions.WebDriverException:
print('response.body is null')
This way responses without body will not crash your script.

POST request fails "The CSRF token could not be verified" (Python 3)

I have been trying to log on to this site with the python requests module, but I keep seeing "The CSRF token could not be verified". I have tried doing what other answers said but it doesn't seem to work.
client = requests.Session()
url = 'https://www.biopharmcatalyst.com/account/login/'
client.get(url)
token = client.cookies['CRAFT_CSRF_TOKEN']
headers = {'Cookie':token}
print(token)
login_data = {'loginName':'login',
'password':'pass',
'CRAFT_CSRF_TOKEN':token}
r1=client.post(url,data=login_data, headers=dict(Referer=url))
print(r1.text)
I'm really not sure what I'm doing wrong here. When I go to the html, I see a different value for the CRAFT_CSRF_TOKEN than what the cookie shows under headers.
The page is setting the CRSF token using JS and the DOM.
You will need to parse the initial GET request to get the token and then pass that to your login.
Something like the following:
import re
client = requests.Session()
url = 'https://www.biopharmcatalyst.com/account/login/'
r = client.get(url)
match = re.search(r'window.csrfTokenValue = "(.*?)";', r.text)
if match:
crsf = match.group(1)
login_data = {
'loginName':'login',
'password':'pass',
'CRAFT_CSRF_TOKEN':crsf}
Handling the headers and so forth will be different depending on what happens after you get the login (I don't have an account).

How to get current user with Discourse API

I'm accessing the Discourse API from python using urlfetch. The Get a single user by username endpoint requires a GET request such as /users/{username}.json
From a browser, this command returns a json response as expected, however from an API call like:
from google.appengine.api import urlfetch
result = urlfetch.fetch('{}/users/{}.json'.format(domain, username))
it returns a HTML page. I've even tried setting the content type to application/json:
headers = {'Content-Type': 'application/json'}
result = urlfetch.fetch('{}/users/{}.json'.format(domain, username), headers=headers)
What am I doing wrong?
Resolved:
Need to add api_key and api_username to GET request:
result = urlfetch.fetch('{}/users/{}.json?api_key={}&api_username={}'.format(domain, username, discourse_api_key, discourse_api_username))

Categories