Obtenga todos los pedidos de Woocommerce a través de la API de Python

3 minutos de lectura

Estoy buscando exportar todos los pedidos de la API de WooCommerce a través de un script de python.

he seguido el

proceso de autenticación

y he estado usando el método para obtener pedidos descritos
aquí. Mi código se parece a lo siguiente:

wcapi = API(
        url = "url",
        consumer_key = consumerkey,
        consumer_secret = consumersecret
)
r = wcapi.get('orders')
r = r.json()
r = r['orders']
print(len(r))        # output: 8

Esto genera los 8 pedidos más recientes, pero me gustaría acceder a todos ellos. Hay más de 200 pedidos realizados a través de WooCommerce en este momento. ¿Cómo accedo a todos los pedidos?

Por favor, dime que hay algo simple que me estoy perdiendo. Mi objetivo final es extraer estos pedidos automáticamente, transformarlos y luego subirlos a una herramienta de visualización. Todos los aportes son apreciados.

Primero: Inicialice su API (como lo hizo).

wcapi = API(
        url=eshop.url,
        consumer_key=eshop.consumer_key,
        consumer_secret=eshop.consumer_secret,
        wp_api=True,
        version="wc/v2",
        query_string_auth=True,
        verify_ssl = True,
        timeout=10
    )

Segundo: Obtenga los pedidos de su solicitud (como lo hizo).

 r=wcapi.get("orders")

Tercero: Obtener el total de páginas.

total_pages = int(r.headers['X-WP-TotalPages'])

Adelante: para cada página, capture el json y acceda a los datos a través de la API.

for i in range(1,total_pages+1):
     r=wcapi.get("orders?&page="+str(i)).json()
     ...

  • usar los encabezados para obtener el recuento total de páginas es muy útil. Gracias @gtopal

    – Timoteo Dalton

    3 de marzo a las 9:11

Los parámetros relevantes encontrados en el correspondiente documentación son page y per_page. El per_page El parámetro define cuántos pedidos se deben recuperar en cada solicitud. El page El parámetro define la página actual de la colección de pedidos.

Por ejemplo, la solicitud enviada por wcapi.get('orders/per_page=5&page=2') devolverá los pedidos del 5 al 10.

Sin embargo, como el valor predeterminado de per_page es 10, no está claro por qué recibe solo 8 pedidos.

avatar de usuario de autopoietic
autopoiético

Encontré el mismo problema con la respuesta paginada para productos.

Me basé en el mismo enfoque descrito por @gtopal, por el cual el X-WP-TotalPages El encabezado devuelto por WooCommerce se usa para iterar a través de cada página de resultados.

Sabía que probablemente me encontraría con el mismo problema para otras solicitudes de la API de WooCommerce (como los pedidos), y no quería tener que confundir mi código realizando un bucle repetidamente cuando solicitaba un conjunto de resultados paginados.

Para evitar esto, utilicé un decorador para abstraer la lógica de paginación, de modo que get_all_wc_orders puede centrarse sólo en la solicitud.

Espero que el decorador a continuación pueda ser útil para otra persona (esencia)

from woocommerce import API

WC_MAX_API_RESULT_COUNT = 100

wcapi = API(
    url=url,
    consumer_key=key,
    consumer_secret=secret,
    version="wc/v3",
    timeout=300,
)

def wcapi_aggregate_paginated_response(func):
    """
    Decorator that repeat calls a decorated function to get 
    all pages of WooCommerce API response.

    Combines the response data into a single list.

    Decorated function must accept parameters:
        - wcapi object
        - page number
    """
    def wrapper(wcapi, page=0, *args, **kwargs):
        items = []
        page = 0
        num_pages = WC_MAX_API_RESULT_COUNT

        while page < num_pages:
            page += 1
            log.debug(f"{page=}")

            response = func(wcapi, page=page, *args, **kwargs)

            items.extend(response.json())
            num_pages = int(response.headers["X-WP-TotalPages"])
            num_products = int(response.headers["X-WP-Total"])

        log.debug(f"{num_products=}, {len(items)=}")
        return items
    return wrapper


@wcapi_aggregate_paginated_response
def get_all_wc_orders(wcapi, page=1):
    """
    Query WooCommerce rest api for all products
    """
    response = wcapi.get(
        "orders",
        params={
            "per_page": WC_MAX_API_RESULT_COUNT,
            "page": page,
        },
    )
    response.raise_for_status()
    return response

orders = get_all_wc_orders(wcapi)

¿Ha sido útil esta solución?