I am following a simple example (or what I thought was simple) of creating a python script that used the REST api to connect to wordpress.
However, I am getting a 403 error. My credentials are correct because I can log in with them.
I have been working over this for awhile now. Can anyone see where my error might be? Thank you.
url = "https://prod-wp.xxxxxx.com/wp-json/wp/v2/posts"
user = "xxxxxx"
password = "xxxxxxxx"
credentials = user + ':' + password
token = base64.b64encode(credentials.encode())
header = {'Authorization': 'Basic ' + token.decode('utf-8')}
response = requests.get(url , headers=header)
print(response)
<Response [403]>
EDIT
I have changed the code and this seems to work.
import requests
import os
from dotenv import load_dotenv
load_dotenv()
BASE_URL = 'https://website.com/wp-json'
WP_URL = os.getenv("WP_URL")
WP_USERNAME = os.getenv("WP_USERNAME")
WP_PASSWORD = os.getenv("WP_PASSWORD")
def get_headers():
wp_credentials = {'username': WP_USERNAME, 'password': WP_PASSWORD}
jwt_response = requests.post(f'{BASE_URL}/jwt-auth/v1/token', json=wp_credentials)
jwt_token = jwt_response.json()['token']
headers = {
"Authorization": "Bearer %s" % jwt_token,
"Content-Type": "application/json",
"Accept": "application/json",
}
print(f'Headers are equal to: {headers}')
return headers
get_headers()
I've been trying to post a payload to an endpoint, the endpoint requires bearer token.
using the python requests, I'm trying to post the bearer token in the header as
from requests import Session
http= Session()
accessToken = getToken(url=uri,data=payload)
authorization_header_string = 'bearer ' + accessToken
requestHeaders = {"Content-type": "text/plain", "Authorization":authorization_header_string}
headerData={"content-type":"text/plain","authorization":requestHeaders}
resp= http.post(url=uri,data=payload,headers=headerData)
but all I get is 401 error, while if I use the same token in postman it works fine.
I'm using requestbin to check wherein the authorization shows up only sometimes in the header.
Try the following:
token = "your token"
headerData={"content-type": "text/plain", "authorization": "Bearer " + token}
I'm trying to access Gravity Forms entry data via their REST API v2 using Python, but can't figure out how to properly authenticate. Should I use basic authentication or OAuth1? I've never successfully used either so example code would be most helpful.
I've tried basic authentication which seems to be the default for the requests module.
import requests
url = 'https://<INSERT DOMAIN HERE>/wp-json/gf/v2/entries'
auth = (<CONSUMER KEY>, <CONSUMER SECRET>)
r = requests.get(url, auth=auth)
print(r.status_code)
When basic auth didn't work, I also tried OAuth1 using requests_oathlib and this post as a guideline, but I can't get that to work either. I'm not sure what the different keys/tokens/secrets are or how to get them. I have a "consumer key" and a "consumer secret" from the Gravity Forms REST API section of the WordPress dashboard, but that's it.
import requests
from requests_oauthlib import OAuth1
url = 'https://<INSERT DOMAIN HERE>/wp-json/gf/v2/entries'
auth = OAuth1('YOUR_APP_KEY', 'YOUR_APP_SECRET', 'USER_OAUTH_TOKEN', 'USER_OAUTH_TOKEN_SECRET')
r = requests.get(url, auth=auth)
print(r.status_code)
I've also tried following the docs for requests_oauthlib here, but I'm not sure which urls to use where or which path to take (session vs helper).
Gravity Forms REST API documentation says that basic authentication is acceptable as long as requests are sent using HTTPS whereas HTTP requests must use OAuth1.0a. I can't get either to work. However, I know I'm close because I can get the Postman application to work using the "Consumer Key" and "Consumer Secret" with OAuth1 and a HMAC-SHA1 "Signature Method."
I'm expecting a 200 response status code, but no matter what type of authentication I use, I keep getting a 401 response status code.
I'm not 100% sure about all the nuances with this, but after extensive research and trial/error, I got this to work for myself. Please feel free to add suggestions.
import requests
import time
import random
import string
import oauthlib.oauth1.rfc5849.signature as oauth
from urllib.parse import quote_plus
import os
import json
import datetime
def create_nonce(N = 32): # randomly generated 32 character (recommended) string
result = ''.join(random.choices(string.ascii_letters + string.digits, k = N))
return result
def create_signature(httpMethod, url, urlSuffix, nonce, timestamp, consumerKey, signatureMethod, version):
consumerSecret = <INSERT_YOUR_CONSUMER_SECRET_HERE>
# https://stackoverflow.com/a/39494701/5548564
# In case of http://example.org/api?a=1&b=2 - the uri_query value would be "a=1&b=2".
uri_query = urlSuffix
# The oauthlib function 'collect_parameters' automatically ignores irrelevant header items like 'Content-Type' or
# 'oauth_signature' in the 'Authorization' section.
headers = {
"Authorization": (
f'OAuth realm="", '
f'oauth_nonce={nonce}, '
f'oauth_timestamp={timestamp}, '
f'oauth_consumer_key={consumerKey}, '
f'oauth_signature_method={signatureMethod}, '
f'oauth_version={version}')}
# There's no POST data here - in case it was: x=1 and y=2, then the value would be '[("x","1"),("y","2")]'.
data = []
params = oauth.collect_parameters(uri_query=uri_query,
body=data,
headers=headers,
exclude_oauth_signature=True,
with_realm=False)
norm_params = oauth.normalize_parameters(params)
base_string = oauth.construct_base_string(httpMethod, url, norm_params)
signature = oauth.sign_hmac_sha1(base_string, consumerSecret, '')
return quote_plus(signature)
def send_request():
url = <INSERT_URL_HERE>
urlSuffix = "_labels=1" # Addes array at end of json results including a map to the field labels
httpMethod = "GET"
consumerKey = <INSERT_CONSUMER_KEY_HERE>
signatureMethod = "HMAC-SHA1"
timestamp = str(int(time.time()))
nonce = create_nonce()
version = "1.0"
signature = create_signature(httpMethod, url, urlSuffix, nonce, timestamp, consumerKey, signatureMethod, version)
queryString = {"oauth_consumer_key": consumerKey,
"oauth_signature_method": signatureMethod,
"oauth_timestamp": timestamp,
"oauth_nonce": nonce,
"oauth_version": version,
"oauth_signature": signature}
headers = {'User-Agent': "Testing/0.1",
'Accept': "*/*",
'Host': "<INSERT_YOUR_DOMAIN_HERE>",
'Accept-Encoding': "gzip, deflate",
'Connection': "keep-alive"}
if urlSuffix:
url = url + "?" + urlSuffix
r = requests.request(httpMethod, url, headers=headers, params=queryString)
if r.status_code == 200:
dict = json.loads(r.text)
return dict
else:
print(r.status_code)
return None
response = send_request()
For anyone who still needs this, through trial and error I found that they changed the expected auth location to be in the query instead of the headers as you'd find in most python auth libraries. You can change it like this:
import oauthlib
from requests_oauthlib import OAuth1Session
consumer_key = "banana"
client_secret = "also banana"
session = OAuth1Session(consumer_key, client_secret=client_secret, signature_type=oauthlib.oauth1.SIGNATURE_TYPE_QUERY)
url = 'https:// YOUR URL /wp-json/gf/v2/entries'
r = session.get(url)
print(r.content)
i'm working on settin up a rest api with python, however i'm having some problem getting it to work.
I'm working with the TV DB rest api: https://api.thetvdb.com/swagger
and using python with Requests library to pull out the information.
My code is currently:
import json
import requests
URL = "https://api.thetvdb.com/"
API_KEY = "Api_key"
USER_KEY = "Key"
USERNAME = "Name"
headers = {"Accept": "application/json"}
params = {
"apikey": API_KEY,
"userkey": USER_KEY,
"username": USERNAME
}
resp = requests.post(URL + "login/", headers = headers ,params=params)
if resp.status_code != 200:
print('error: ' + str(resp.status_code))
else:
print('Success')
So far i'm only getting error code 401, not sure why.
Solved:
2 Things needed to be changed
1. The resp was changed into:
resp = requests.post(URL + "login/", headers = headers, data=json.dumps(params))
The header had to have
"Content-Type": "application/json"
added to it :) It's now working, thanks everyone
The login parameters probably need to be a JSON-encoded string POSTed as the body of the message.
Try resp = requests.post(URL + "login/", headers = headers, data=json.dumps(params))
I have this code, it sends a request to my server which is run by web.py:
url = "https://sample.com/api"
auth_string = 'Basic ' + base64.encodestring('%s:%s' % ("usernamexxxx", "codexxxx"))[:-1]
headers = {"Content-Type": "application/json", "authorization": auth_string}
data = {"message":"WELCOME!..."}
req = urlfetch.fetch(url, method=urlfetch.POST, payload= simplejson.dumps(data), headers= headers)
response = req.content
So when I receive this kind of request in my web server I want to check if the username and code input to the request is valid or not? And how can I access the given data of the code above?
Probably you can access those headers via the os.environ dictionary.