¿Cómo cargar imágenes usando wordpress REST api en python?

5 minutos de lectura

avatar de usuario
mi año de código

Creo que tengo este 90% de trabajo, pero termina ‘cargando’ una imagen transparente en blanco. Recibo una respuesta 201 después de la carga. Creo que probablemente sea un proxy para cuando WP encuentra una imagen faltante. No estoy seguro si estoy pasando la imagen incorrectamente (es decir, no sale de mi computadora) o si no la estoy etiquetando correctamente según el gusto de WP.

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

He visto una buena cantidad de respuestas en php o node.js, pero tengo problemas para entender la sintaxis en python. ¡Gracias por cualquier ayuda!

  • Lo he descubierto.

    – mi año de código

    8 de junio de 2017 a las 12:04

¡Lo he descubierto!

Con esta función, puedo cargar imágenes a través de la API REST de WP en mi sitio (Cazador de equipo fotográfico.) La función devuelve el ID de la imagen. Luego puede pasar esa identificación a una nueva llamada posterior y convertirla en la imagen destacada, o hacer lo que desee con ella.

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)

  • Gracias, por publicar la solución. Esto es realmente agradable. Funcionó para mí también.

    – Mukesh Kumar

    3 de septiembre de 2017 a las 7:26

  • ¿Existe una configuración alternativa para usar la autenticación basada en cookies (valor predeterminado de WP)?

    – gregturn

    20 de septiembre de 2017 a las 15:24

  • Me temo que no lo sé. Mi configuración se creó mucho antes de que siquiera pensara en usar una cookie.

    – mi año de código

    11 de agosto de 2018 a las 14:34

Una versión mejorada de manejar no ASCII en el nombre de archivo (letras griegas por ejemplo). Lo que hace es convertir todos los caracteres que no son ASCII en una secuencia de escape UTF-8. (Código original de @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)

Desde mi entendimiento un POST HEADER solo puede contener caracteres ASCII

Para especificar campos adicionales compatibles con la API, como texto alternativo, descripción, etc.:

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'))

gracias a @my Year Of Code.

mi código de trabajo final:

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,
    )

devolver 201 medio Created OK

respuesta json parece:

{
  "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"
  },
...

más detalles consulte mi publicación (en chino): 【已解决】用Python通过WordPress的REST API上传图片

Este es mi código de trabajo para cargar imágenes en WordPress desde una imagen local o desde una URL. Espero que alguien lo encuentre útil.

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("https://stackoverflow.com/")[-1] if len(imgPath.split("https://stackoverflow.com/")[-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'])

¿Ha sido útil esta solución?