Reputation: 423
I think I've got this 90% working, but it ends up 'uploading' a blank transparent image. I get a 201 response after the upload. I think that's probably a proxy for when WP finds a missing image. I'm unsure if i'm passing the image incorrectly (ie it doesn't leave my computer) or if I'm not tagging it properly to WP's liking.
from base64 import b64encode
import json
import requests
def imgUploadREST(imgPath):
url = 'https://www.XXXXXXXXXX.com/wp-json/wp/v2/media'
auth = b64encode('{}:{}'.format('USERNAME','PASS'))
payload = {
'type': 'image/jpeg', # mimetype
'title': 'title',
"Content":"content",
"excerpt":"Excerpt",
}
headers = {
'post_content':'post_content',
'Content':'content',
'Content-Disposition' : 'attachment; filename=image_20170510.jpg',
'Authorization': 'Basic {}'.format(auth),
}
with open(imgPath, "rb") as image_file:
files = {'field_name': image_file}
r = requests.post(url, files=files, headers=headers, data=payload)
print r
response = json.loads(r.content)
print response
return response
I've seen a fair number of answers in php or node.js, but I'm having trouble understanding the syntax in python. Thank you for any help!
Upvotes: 8
Views: 16275
Reputation: 13
An improved version to handle non-ASCII in the filename (Greek, Cyrillic etc. letters for example). What it does is convert all non-ASCII characters to a UTF-8 escape sequence. (Original code from @my Year Of Code)
def uploadImage(filePath):
data = open(filePath, 'rb').read()
fileName = os.path.basename(filePath)
espSequence = bytes(fileName, "utf-8").decode("unicode_escape")
# Convert all non ASCII characters to UTF-8 escape sequence
res = requests.post(url='http://xxxxxxxxxxxxx.com/wp-json/wp/v2/media',
data=data,
headers={'Content-Type': 'image/jpeg',
'Content-Disposition': 'attachment; filename=%s' % espSequence,
},
auth=('authname', 'authpass'))
newDict=res.json()
newID= newDict.get('id')
link = newDict.get('guid').get("rendered")
print newID, link
return (newID, link)
From my understading a POST HEADER can only contain ASCII characters
Upvotes: 1
Reputation: 11
import base64
import os
import requests
def rest_image_upload(image_path):
message = '<user_name>' + ":" + '<application password>'
message_bytes = message.encode('ascii')
base64_bytes = base64.b64encode(message_bytes)
base64_message = base64_bytes.decode('ascii')
# print(base64_message)
data = open(image_path, 'rb').read()
file_name = os.path.basename(image_path)
res = requests.post(url='https://<example.com>/wp-json/wp/v2/media',
data=data,
headers={'Content-Type': 'image/jpg',
'Content-Disposition': 'attachment; filename=%s' % file_name,
'Authorization': 'Basic ' + base64_message})
new_dict = res.json()
new_id = new_dict.get('id')
link = new_dict.get('guid').get("rendered")
# print(new_id, link)
return new_id, link
Upvotes: -1
Reputation: 144
This is my working code for uploading image into WordPress from local image or from url. hope someone find it useful.
import requests, json, os, base64
def wp_upload_image(domain, user, app_pass, imgPath):
# imgPath can be local image path or can be url
url = 'https://'+ domain + '/wp-json/wp/v2/media'
filename = imgPath.split('/')[-1] if len(imgPath.split('/')[-1])>1 else imgPath.split('\\')[-1]
extension = imgPath[imgPath.rfind('.')+1 : len(imgPath)]
if imgPath.find('http') == -1:
try: data = open(imgPath, 'rb').read()
except:
print('image local path not exits')
return None
else:
rs = requests.get(imgPath)
if rs.status_code == 200:
data = rs.content
else:
print('url get request failed')
return None
headers = { "Content-Disposition": f"attachment; filename={filename}" , "Content-Type": str("image/" + extension)}
rs = requests.post(url, auth=(user, app_pass), headers=headers, data=data)
print(rs)
return (rs.json()['source_url'], rs.json()['id'])
Upvotes: 0
Reputation: 20571
To specify additional fields supported by the api such as alt text, description ect:
from requests_toolbelt.multipart.encoder import MultipartEncoder
import requests
import os
fileName = os.path.basename(imgPath)
multipart_data = MultipartEncoder(
fields={
# a file upload field
'file': (fileName, open(imgPath, 'rb'), 'image/jpg'),
# plain text fields
'alt_text': 'alt test',
'caption': 'caption test',
'description': 'description test'
}
)
response = requests.post('http://example/wp-json/wp/v2/media', data=multipart_data,
headers={'Content-Type': multipart_data.content_type},
auth=('user', 'pass'))
Upvotes: 2
Reputation: 14328
thanks to @my Year Of Code
.
my final working code:
import
HOST = "https://www.crifan.com"
API_MEDIA = HOST + "/wp-json/wp/v2/media"
JWT_TOKEN = "eyJxxxxxxxxjLYB4"
imgMime = gImageSuffixToMime[imgSuffix] # 'image/png'
imgeFilename = "%s.%s" % (processedGuid, imgSuffix) # 'f6956c30ef0b475fa2b99c2f49622e35.png'
authValue = "Bearer %s" % JWT_TOKEN
curHeaders = {
"Authorization": authValue,
"Content-Type": imgMime,
'Content-Disposition': 'attachment; filename=%s' % imgeFilename,
}
# curHeaders={'Authorization': 'Bearer eyJ0xxxyyy.zzzB4', 'Content-Type': 'image/png', 'Content-Disposition': 'attachment; filename=f6956c30ef0b475fa2b99c2f49622e35.png'}
uploadImgUrl = API_MEDIA
resp = requests.post(
uploadImgUrl,
# proxies=cfgProxies,
headers=curHeaders,
data=imgBytes,
)
return 201
means Created OK
response json look like:
{
"id": 70393,
"date": "2020-03-07T18:43:47",
"date_gmt": "2020-03-07T10:43:47",
"guid": {
"rendered": "https://www.crifan.com/files/pic/uploads/2020/03/f6956c30ef0b475fa2b99c2f49622e35.png",
"raw": "https://www.crifan.com/files/pic/uploads/2020/03/f6956c30ef0b475fa2b99c2f49622e35.png"
},
...
more details refer my (Chinese) post: 【已解决】用Python通过WordPress的REST API上传图片
Upvotes: 0
Reputation: 423
I've figured it out!
With this function I'm able to upload images via the WP REST api to my site (Photo Gear Hunter.) The function returns the ID of the image. You can then pass that id to a new post call and make it the featured image, or do whatever you wish with it.
def restImgUL(imgPath):
url='http://xxxxxxxxxxxx.com/wp-json/wp/v2/media'
data = open(imgPath, 'rb').read()
fileName = os.path.basename(imgPath)
res = requests.post(url='http://xxxxxxxxxxxxx.com/wp-json/wp/v2/media',
data=data,
headers={ 'Content-Type': 'image/jpg','Content-Disposition' : 'attachment; filename=%s'% fileName},
auth=('authname', 'authpass'))
# pp = pprint.PrettyPrinter(indent=4) ## print it pretty.
# pp.pprint(res.json()) #this is nice when you need it
newDict=res.json()
newID= newDict.get('id')
link = newDict.get('guid').get("rendered")
print newID, link
return (newID, link)
Upvotes: 21