Wordpress Rest API how to post content with python - python

So I am trying to post content through the wordpress rest api with my python script. The issue I am facing however is that when i do my post request i receive in response in json format all the posts already existing in the website instead of it creating a new post. Could someone please support here? My code looks like following;
import requests import json import base64
url = "https://myurl.com/wp-json/wp/v2/posts"
user = "Username"
password = "application password"
credentials = user + ':' + password
token = base64.b64encode(credentials.encode())
header = {'Authorization': 'Basic ' + token.decode('utf-8')}
post = { 'title' : 'Test WP-API',
'content' : 'This is my first post created using restAPI',
'status' : 'publish',
}
responce = requests.post(url , headers=header, json=post)
print(responce.json())
I have tried to google this issue anywhere but just cant seem anyone to having this issue. I would appreciate it soo much if someone could support.

Related

Python Twitter API v2 POST tweet returns response error 403

I’m trying to use the Twitter API v2 to post a reply to a specific tweet id. I use the python code below which returns a response error 403 although everything seems fine about my app permissions front. What am I missing ?
Many thanks
import requests
URL = "https://api.twitter.com/2/tweets?"
id = str(my_tweet_id_here)
mytext = "my_text_here"
PARAM = {"text": mytext, "reply": {"in_reply_to_tweet_id": id}}
requests.post(url = URL, params=PARAM, headers={'Authorization': 'Bearer my_bearer_token_here'})

Response 400 'Bad Request' when trying to get access token from Reddit API

I'm trying to use the reddit API to pull text data for a machine learning project, but I can't get the OAuth access token. Instead of responding with the access token, the response just says bad request.
Here's my code:
import requests
auth = requests.auth.HTTPBasicAuth('*****', '****')
data = {'grant_type':'password',
'username' : '*****',
'password':'******'}
headers = {'User Agent': 'win64 : **** v1.0.0 by /u/*****'}
res = requests.post('https://www.reddit.com/api/v1/access_token', auth=auth, data=data, headers=headers)
print(res)
I've triple checked the personal use script and secret, and so I'm struggling to think of what's wrong. Any ideas?

Using requests to login to site, when username and password element IDs are not constant

I'm trying to scrape a web forum, and having trouble accessing pages that are behind a login. Inspecting the elements of the login page, I found that the ID of the username and password input elements change each time I refresh the page. My current strategy is to
Create and use a requests session
Make GET request for the forum login page
Use BeautifulSoup to extract the IDs of the username and password input elements
Use the extracted IDs as the keys, and my account username and password as values, for a payload dict that is passed into a POST request for the login page
Make GET request for a page on the forum
I'm running into a problem in step 4: the status code of the POST request is 400, indicating that I'm doing something wrong.
Here's an MWE, in which the variables KIWIFARMS_USERNAME and KIWIFARMS_PASSWORD have been changed to not be my actual account username and password:
import os
import requests
from bs4 import BeautifulSoup
# login url for forum, and fake forum credentials (they're real in my script)
LOGIN_URL = 'https://kiwifarms.net/login/'
KIWIFARMS_USERNAME = 'username'
KIWIFARMS_PASSWORD = 'password'
with requests.Session( ) as session:
# step 1
r = session.get( LOGIN_URL )
# step 2
soup = BeautifulSoup( r.content, 'lxml' )
# step 3
username_id = soup.find( 'input', { 'autocomplete' : 'username' } )[ 'id' ]
password_id = soup.find( 'input', { 'type' : 'password' } )[ 'id' ]
payload = {
username_id: KIWIFARMS_USERNAME,
password_id : KIWIFARMS_PASSWORD }
# step 4
post = session.post( LOGIN_URL, data = payload )
# failure of step 4 (prints 400)
print( post.status_code )
I've looked at a lot of pages and links, including this, this, this, and this, but I still can't figure out why my post request is getting a 400 Bad Request error.
I have a version of this working in Selenium, but I'd really like to know the mistake I'm making and get this working using Requests. Any help would be greatly appreciated.
The website is generating a _xfToken during the login, also you missed some Form-Data for the POST request.
Here I've maintain the session using requests.Session()and then i parsed the value of _xfToken during my GET request, and then passed it via POST request.
import requests
from bs4 import BeautifulSoup
def Main():
with requests.Session() as req:
r = req.get("https://kiwifarms.net/login/login")
soup = BeautifulSoup(r.text, 'html.parser')
token = soup.find("input", {'name': '_xfToken'}).get("value")
data = {
'username': 'test',
'password': 'test',
'remember': '1',
'_xfRedirect': '/',
'_xfToken': token
}
r = req.post("https://kiwifarms.net/login/login", data=data)
print(r)
Main()
Output:
<Response [200]>
if you will check r.text so you will see that we are on the right track.
<div class="blockMessage blockMessage--error blockMessage--iconic">
The requested user could not be found.
</div>
That's confirm we are doing it correctly since i didn't passed a valid user/pass.
you're trying to post to https://kiwifarms.net/login/ , while the login form action is /login
I got the same error when I had url/login/ in the url. It passed status_code to 200 when I simply changed it to url/login ... (basically just removed the last redundant slash!)

Posting to Wordpress Rest API fails to work in Python

Cannot seem to find nor create a minimum working example of posting an article to the REST API. I have the following set up and code.
import requests
import json
import base64
user = 'NASA'
password = 'bah bah ...'
url = 'http://any.com/wp-json/wp/v2'
data_sauth = user + ':' + password
post = {
'title': 'Rubbish',
'slug': 'rest-api-1',
'status': 'publish',
'content': 'random stuff',
'excerpt': 'lala',
'format': 'standard'
}
token = base64.standard_b64encode(data_sauth.encode())
headers = {'Authorization': 'Basic ' + token.decode('utf-8'), 'Content-Type': 'application/json'}
r = requests.post(url + '/posts', headers=headers, json=post)
print(r.status_code)
print(json.loads(r.content))
Now I get a 200 code. But I just get no post appearing and return of the posts. I cannot find where this might be going wrong. The API reference is here: https://developer.wordpress.org/rest-api/reference/posts/#create-a-post
On the WP side, I have installed the plugin named Application Passwords and ensured that the credentials match. No post appears, I get a 200 status code, and get a poll from the WP site of the existing posts, but no new post.
I know this is super old but I tried your code with my credentials and it worked perfectly, check that you're requesting to the right URL (some sites have different URLs for the API).

Sending a JSON string as a post request

rocksteady's solution worked
He did originally refer to dictionaries. But the following code to send the JSON string also worked wonders using requests:
import requests
headers = {
'Authorization': app_token
}
url = api_url + "/b2api/v1/b2_get_upload_url"
content = json.dumps({'bucketId': bucket_id})
r = requests.post(url, data = content, headers = headers)
I'm working with an API that requires me to send JSON as a POST request to get results. Problem is that Python 3 won't allow me to do this.
The following Python 2 code works fine, in fact it's the official sample:
request = urllib2.Request(
api_url +'/b2api/v1/b2_get_upload_url',
json.dumps({ 'bucketId' : bucket_id }),
headers = { 'Authorization': account_authorization_token }
)
response = urllib2.urlopen(request)
However, using this code in Python 3 only makes it complain about data being invalid:
import json
from urllib.request import Request, urlopen
from urllib.parse import urlencode
# -! Irrelevant code has been cut out !-
headers = {
'Authorization': app_token
}
url = api_url + "/b2api/v1/b2_get_upload_url"
# Tested both with encode and without
content = json.dumps({'bucketId': bucket_id}).encode('utf-8')
request = Request(
url=url,
data=content,
headers=headers
)
response = urlopen(req)
I've tried doing urlencode(), like you're supposed to. But this returns a 400 status code from the web server, because it's expecting pure JSON. Even if the pure JSON data is invalid, I need to somehow force Python into sending it.
EDIT: As requested, here are the errors I get. Since this is a flask application, here's a screenshot of the debugger:
Screenshot
Adding .encode('utf-8') gives me an "Expected string or buffer" error
EDIT 2: Screenshot of the debugger with .encode('utf-8') added
Since I have a similar application running, but the client still was missing, I tried it myself.
The server which is running is from the following exercise:
Miguel Grinberg - designing a restful API using Flask
That's why it uses authentication.
But the interesting part: Using requests you can leave the dictionary as it is.
Look at this:
username = 'miguel'
password = 'python'
import requests
content = {"title":"Read a book"}
request = requests.get("http://127.0.0.1:5000/api/v1.0/projects", auth=(username, password), params=content)
print request.text
It seems to work :)
Update 1:
POST requests are done using requests.post(...)
This here describes it well : python requests
Update 2:
In order to complete the answer:
requests.post("http://127.0.0.1:5000/api/v1.0/projects", json=content)
sends the json-string.
json is a valid parameter of the request and internally uses json.dumps()...

Categories