An open API service indexing awesome lists of open source software.

https://github.com/tdkorn/my-magento

Python Magento 2 REST API Wrapper
https://github.com/tdkorn/my-magento

api magento python wrapper

Last synced: about 1 year ago
JSON representation

Python Magento 2 REST API Wrapper

Awesome Lists containing this project

README

          

.. |.~.ACCESS_TOKEN| replace:: ``ACCESS_TOKEN``
.. _.~.ACCESS_TOKEN: https://my-magento.readthedocs.io/en/latest/clients.html#magento.clients.Client.ACCESS_TOKEN
.. |.~.APIResponse| replace:: ``APIResponse``
.. _.~.APIResponse: https://my-magento.readthedocs.io/en/latest/model.html#magento.models.model.APIResponse
.. |.~.Category| replace:: ``Category``
.. _.~.Category: https://my-magento.readthedocs.io/en/latest/category.html#magento.models.category.Category
.. |.~.CategorySearch| replace:: ``CategorySearch``
.. _.~.CategorySearch: https://my-magento.readthedocs.io/en/latest/search_module.html#magento.search.CategorySearch
.. |.~.Client| replace:: ``Client``
.. _.~.Client: https://my-magento.readthedocs.io/en/latest/clients.html#magento.clients.Client
.. |..Client.categories| replace:: ``Client.categories``
.. _..Client.categories: https://my-magento.readthedocs.io/en/latest/clients.html#magento.clients.Client.categories
.. |..Client.customers| replace:: ``Client.customers``
.. _..Client.customers: https://my-magento.readthedocs.io/en/latest/clients.html#magento.clients.Client.customers
.. |..Client.invoices| replace:: ``Client.invoices``
.. _..Client.invoices: https://my-magento.readthedocs.io/en/latest/clients.html#magento.clients.Client.invoices
.. |..Client.order_items| replace:: ``Client.order_items``
.. _..Client.order_items: https://my-magento.readthedocs.io/en/latest/clients.html#magento.clients.Client.order_items
.. |..Client.orders| replace:: ``Client.orders``
.. _..Client.orders: https://my-magento.readthedocs.io/en/latest/clients.html#magento.clients.Client.orders
.. |..Client.product_attributes| replace:: ``Client.product_attributes``
.. _..Client.product_attributes: https://my-magento.readthedocs.io/en/latest/clients.html#magento.clients.Client.product_attributes
.. |..Client.products| replace:: ``Client.products``
.. _..Client.products: https://my-magento.readthedocs.io/en/latest/clients.html#magento.clients.Client.products
.. |..Client.scope| replace:: ``Client.scope``
.. _..Client.scope: https://my-magento.readthedocs.io/en/latest/clients.html#magento.clients.Client.scope
.. |..Client.search| replace:: ``Client.search()``
.. _..Client.search: https://my-magento.readthedocs.io/en/latest/clients.html#magento.clients.Client.search
.. |..Client.url_for| replace:: ``Client.url_for()``
.. _..Client.url_for: https://my-magento.readthedocs.io/en/latest/clients.html#magento.clients.Client.url_for
.. |.~.Customer| replace:: ``Customer``
.. _.~.Customer: https://my-magento.readthedocs.io/en/latest/customer.html#magento.models.customer.Customer
.. |.~.CustomerSearch| replace:: ``CustomerSearch``
.. _.~.CustomerSearch: https://my-magento.readthedocs.io/en/latest/search_module.html#magento.search.CustomerSearch
.. |.~.Invoice| replace:: ``Invoice``
.. _.~.Invoice: https://my-magento.readthedocs.io/en/latest/invoice.html#magento.models.invoice.Invoice
.. |.~.InvoiceSearch| replace:: ``InvoiceSearch``
.. _.~.InvoiceSearch: https://my-magento.readthedocs.io/en/latest/search_module.html#magento.search.InvoiceSearch
.. |.~.MediaEntry| replace:: ``MediaEntry``
.. _.~.MediaEntry: https://my-magento.readthedocs.io/en/latest/product.html#magento.models.product.MediaEntry
.. |.~.Model| replace:: ``Model``
.. _.~.Model: https://my-magento.readthedocs.io/en/latest/model.html#magento.models.model.Model
.. |..Model.refresh| replace:: ``Model.refresh()``
.. _..Model.refresh: https://my-magento.readthedocs.io/en/latest/model.html#magento.models.model.Model.refresh
.. |.~.Order| replace:: ``Order``
.. _.~.Order: https://my-magento.readthedocs.io/en/latest/order.html#magento.models.order.Order
.. |.~.OrderItem| replace:: ``OrderItem``
.. _.~.OrderItem: https://my-magento.readthedocs.io/en/latest/order.html#magento.models.order.OrderItem
.. |.~.OrderItemSearch| replace:: ``OrderItemSearch``
.. _.~.OrderItemSearch: https://my-magento.readthedocs.io/en/latest/search_module.html#magento.search.OrderItemSearch
.. |.~.OrderSearch| replace:: ``OrderSearch``
.. _.~.OrderSearch: https://my-magento.readthedocs.io/en/latest/search_module.html#magento.search.OrderSearch
.. |.~.Product| replace:: ``Product``
.. _.~.Product: https://my-magento.readthedocs.io/en/latest/product.html#magento.models.product.Product
.. |.~.ProductAttribute| replace:: ``ProductAttribute``
.. _.~.ProductAttribute: https://my-magento.readthedocs.io/en/latest/product.html#magento.models.product.ProductAttribute
.. |.~.ProductAttributeSearch| replace:: ``ProductAttributeSearch``
.. _.~.ProductAttributeSearch: https://my-magento.readthedocs.io/en/latest/search_module.html#magento.search.ProductAttributeSearch
.. |.~.ProductSearch| replace:: ``ProductSearch``
.. _.~.ProductSearch: https://my-magento.readthedocs.io/en/latest/search_module.html#magento.search.ProductSearch
.. |.~.ProductSearch.by_sku| replace:: ``by_sku()``
.. _.~.ProductSearch.by_sku: https://my-magento.readthedocs.io/en/latest/search_module.html#magento.search.ProductSearch.by_sku
.. |.~.SearchQuery| replace:: ``SearchQuery``
.. _.~.SearchQuery: https://my-magento.readthedocs.io/en/latest/search_module.html#magento.search.SearchQuery
.. |.~.SearchQuery.by_id| replace:: ``by_id()``
.. _.~.SearchQuery.by_id: https://my-magento.readthedocs.io/en/latest/search_module.html#magento.search.SearchQuery.by_id
.. |.~.SearchQuery.by_list| replace:: ``by_list()``
.. _.~.SearchQuery.by_list: https://my-magento.readthedocs.io/en/latest/search_module.html#magento.search.SearchQuery.by_list
.. |.~.SearchQuery.result| replace:: ``result``
.. _.~.SearchQuery.result: https://my-magento.readthedocs.io/en/latest/search_module.html#magento.search.SearchQuery.result
.. |.~.USER_CREDENTIALS| replace:: ``USER_CREDENTIALS``
.. _.~.USER_CREDENTIALS: https://my-magento.readthedocs.io/en/latest/clients.html#magento.clients.Client.USER_CREDENTIALS
.. |.~.add_criteria| replace:: ``add_criteria()``
.. _.~.add_criteria: https://my-magento.readthedocs.io/en/latest/search_module.html#magento.search.SearchQuery.add_criteria
.. |.~.authenticate| replace:: ``authenticate()``
.. _.~.authenticate: https://my-magento.readthedocs.io/en/latest/clients.html#magento.clients.Client.authenticate
.. |.~.by_id| replace:: ``by_id()``
.. _.~.by_id: https://my-magento.readthedocs.io/en/latest/search_module.html#magento.search.SearchQuery.by_id
.. |.~.by_list| replace:: ``by_list()``
.. _.~.by_list: https://my-magento.readthedocs.io/en/latest/search_module.html#magento.search.SearchQuery.by_list
.. |.~.delete| replace:: ``delete()``
.. _.~.delete: https://my-magento.readthedocs.io/en/latest/clients.html#magento.clients.Client.delete
.. |.~.execute| replace:: ``execute()``
.. _.~.execute: https://my-magento.readthedocs.io/en/latest/search_module.html#magento.search.SearchQuery.execute
.. |.~.get| replace:: ``get()``
.. _.~.get: https://my-magento.readthedocs.io/en/latest/clients.html#magento.clients.Client.get
.. |..get_api| replace:: ``get_api()``
.. _..get_api: https://my-magento.readthedocs.io/en/latest/modules.html#magento.get_api
.. |.~.get_api| replace:: ``get_api()``
.. _.~.get_api: https://my-magento.readthedocs.io/en/latest/modules.html#magento.get_api
.. |.~.post| replace:: ``post()``
.. _.~.post: https://my-magento.readthedocs.io/en/latest/clients.html#magento.clients.Client.post
.. |.~.put| replace:: ``put()``
.. _.~.put: https://my-magento.readthedocs.io/en/latest/clients.html#magento.clients.Client.put
.. |.~.restrict_fields| replace:: ``restrict_fields()``
.. _.~.restrict_fields: https://my-magento.readthedocs.io/en/latest/search_module.html#magento.search.SearchQuery.restrict_fields
.. |.~.scope| replace:: ``scope``
.. _.~.scope: https://my-magento.readthedocs.io/en/latest/clients.html#magento.clients.Client.scope
.. |.~.search| replace:: ``search()``
.. _.~.search: https://my-magento.readthedocs.io/en/latest/clients.html#magento.clients.Client.search
.. |.~.since| replace:: ``since()``
.. _.~.since: https://my-magento.readthedocs.io/en/latest/search_module.html#magento.search.SearchQuery.since
.. |.~.until| replace:: ``until()``
.. _.~.until: https://my-magento.readthedocs.io/en/latest/search_module.html#magento.search.SearchQuery.until
.. |.~.url_for| replace:: ``url_for()``
.. _.~.url_for: https://my-magento.readthedocs.io/en/latest/clients.html#magento.clients.Client.url_for
.. |.~.views| replace:: ``views``
.. _.~.views: https://my-magento.readthedocs.io/en/latest/clients.html#magento.clients.Store.views

.. Title: MyMagento
.. Description: A Python package that wraps and extends the Magento 2 REST API
.. Author: TDKorn

.. meta::
:title: MyMagento
:description: A Python package that wraps and extends the Magento 2 REST API

.. |RTD| replace:: **Explore the docs Β»**
.. _RTD: https://my-magento.readthedocs.io/en/latest/
.. |api_endpoint| replace:: API endpoint
.. _api_endpoint: https://adobe-commerce.redoc.ly/2.3.7-admin/

.. raw:: html

.. image:: https://raw.githubusercontent.com/TDKorn/my-magento/v2.2.0/docs/source/_static/magento_orange.png
:alt: Logo for MyMagento: Python Magento 2 REST API Wrapper
:width: 15%

.. raw:: html

MyMagentoπŸ›’

A Python package that wraps and extends the Magento 2 REST API

|RTD|_

.. image:: https://img.shields.io/pypi/v/my-magento?color=eb5202
:target: https://pypi.org/project/my-magento/
:alt: PyPI Version

.. image:: https://img.shields.io/badge/GitHub-my--magento-4f1abc
:target: https://github.com/tdkorn/my-magento
:alt: GitHub Repository

.. image:: https://static.pepy.tech/personalized-badge/my-magento?period=total&units=none&left_color=grey&right_color=blue&left_text=Downloads
:target: https://pepy.tech/project/my-magento

.. image:: https://readthedocs.org/projects/my-magento/badge/?version=latest
:target: https://my-magento.readthedocs.io/en/latest/?badge=latest
:alt: Documentation Status

.. raw:: html

|

About MyMagento
~~~~~~~~~~~~~~~~~~~~

.. raw:: html



πŸ“ What's MyMagento?

.. raw:: html


``MyMagento`` is a highly interconnected package that wraps and extends the Magento 2 REST API,
providing a more intuitive and user-friendly interface to access and update your store.

.. raw:: html


MyMagento simplifies interaction with the Magento 2 REST API
============================================================

If you've worked with the Magento 2 API, you'll know that not all endpoints are created equally.

``MyMagento`` aims to streamline your workflow by simplifying a
variety of commonly needed API operations.

...

Main Components
==================================

.. raw:: html



πŸ’» The |.~.Client|_

.. raw:: html


* Handles all API interactions
* Supports multiple store views
* Provides access to all other package components

.. raw:: html


.. raw:: html



πŸ” The |.~.SearchQuery|_ and Subclasses

.. raw:: html


* |.~.execute|_ a search query on any endpoint
* Intuitive interface for `Building Custom Search Queries `_
* All predefined methods retrieve data using only 1-2 API requests

.. raw:: html


.. raw:: html



🧠 The |.~.Model|_ Subclasses

.. raw:: html


* Wrap all API responses in the package
* Provide additional endpoint-specific methods to retrieve and update data

.. raw:: html


...

Available Endpoints
======================

``MyMagento`` is compatible with every |api_endpoint|_

Endpoints are wrapped with a |.~.Model|_ and |.~.SearchQuery|_ subclass as follows:

.. csv-table::
:header: "**Endpoint**", "**Client Shortcut**", "|.~.SearchQuery|_ **Subclass**", "|.~.Model|_ **Subclass**"

"``orders``", "|..Client.orders|_", "|.~.OrderSearch|_", "|.~.Order|_"
"``orders/items``", "|..Client.order_items|_", "|.~.OrderItemSearch|_", "|.~.OrderItem|_"
"``invoices``", "|..Client.invoices|_", "|.~.InvoiceSearch|_", "|.~.Invoice|_"
"``products``", "|..Client.products|_", "|.~.ProductSearch|_", "|.~.Product|_"
"``products/attributes``", "|..Client.product_attributes|_", "|.~.ProductAttributeSearch|_", "|.~.ProductAttribute|_"
"``categories``", "|..Client.categories|_", "|.~.CategorySearch|_", "|.~.Category|_"
"``customers``", "|..Client.customers|_", "|.~.CustomerSearch|_", "|.~.Customer|_"
"``endpoint``", "``Client.search('endpoint')``", "|.~.SearchQuery|_", "|.~.APIResponse|_"

...

βš™ Installing MyMagento
~~~~~~~~~~~~~~~~~~~~~~~~~~

To install using ``pip``::

pip install my-magento

Please note that ``MyMagento`` requires ``Python >= 3.10``

...

πŸ“š Documentation
~~~~~~~~~~~~~~~~~~

Full documentation can be found on `ReadTheDocs `_

|

QuickStart: Login with MyMagento
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

``MyMagento`` uses the |.~.Client|_ class to handle all interactions with the API.

.. raw:: html



πŸ’‘ Tip

.. raw:: html


See `Get a Magento 2 REST API Token With MyMagento `_ for full details on generating an access token

.. raw:: html


Setting the Login Credentials
===================================

To generate an |.~.ACCESS_TOKEN|_ you'll need to |.~.authenticate|_ your |.~.USER_CREDENTIALS|_.

Creating a |.~.Client|_ requires a ``domain``, ``username``, and ``password`` at minimum.

.. code-block:: python

>>> domain = 'website.com'
>>> username ='username'
>>> password = 'password'

If you're using a local installation of Magento you'll need to set ``local=True``. Your domain should look like this:

.. code-block:: python

>>> domain = '127.0.0.1/path/to/magento'

...

Getting a |.~.Client|_
=================================

Option 1: Initialize a |.~.Client|_ Directly
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. code-block:: python

from magento import Client

>>> api = Client(domain, username, password, **kwargs)

Option 2: Call |.~.get_api|_
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. code-block:: python

import magento

>>> api = magento.get_api(**kwargs)

|..get_api|_ takes the same keyword arguments as the |.~.Client|_

* If the ``domain``, ``username``, or ``password`` are missing,
it will attempt to use the following environment variables:

.. code-block:: python

import os

os.environ['MAGENTO_DOMAIN'] = domain
os.environ['MAGENTO_USERNAME']= username
os.environ['MAGENTO_PASSWORD']= password

...

Getting an |.~.ACCESS_TOKEN|_
=======================================

Unless you specify ``login=False``, the |.~.Client|_ will automatically call |.~.authenticate|_ once initialized:

.. code-block:: python

>> api.authenticate()

|[ MyMagento | website_username ]|: Authenticating username on website.com...
|[ MyMagento | website_username ]|: Logged in to username

|

Performing a |.~.search|_
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. |api_endpoints| replace:: API endpoint
.. _api_endpoints: https://adobe-commerce.redoc.ly/2.3.7-admin/

The |..Client.search|_ method lets you |.~.execute|_ a query on
any |api_endpoints|_

It creates a |.~.SearchQuery|_ for the endpoint,
allowing you to retrieve data about

* An individual item (ex. |.~.SearchQuery.by_id|_)
* A list of items (ex. |.~.SearchQuery.by_list|_)
* Any search criteria you desire (see `Building Custom Search Queries `_)

...

Example: |.~.search|_ an endpoint |.~.by_id|_
=====================================================

.. code-block:: python

# Query the "invoices" endpoint (also: api.invoices)
>>> api.search("invoices").by_id(1)

for

Example: |.~.search|_ an endpoint |.~.by_list|_
=======================================================

.. code-block:: python

# Retrieve invoices from a list of invoice ids
>>> ids = list(range(1,101))
>>> api.invoices.by_list("entity_id", ids)

[ for , ...]

...

Search Results: The |.~.Model|_ Classes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. |the_models| replace:: the ``magento.models`` subpackage
.. _the_models: models.html

The |.~.SearchQuery.result|_ of any |.~.SearchQuery|_ will be parsed and wrapped by a
|.~.Model|_ class in |the_models|_.

These classes make the API response data easier to work with.

They also provide endpoint-specific methods to update store data and search for related items.

Example: Retrieving every |.~.Order|_ containing a |.~.Product|_
==========================================================================

Let's retrieve a |.~.Product|_ using |.~.ProductSearch.by_sku|_

.. code-block:: python

>>> product = api.products.by_sku("24-MB01")

We can search for orders containing this product in multiple ways:

.. code-block:: python

# Using the Product itself
>>> product.get_orders()

[, ... ]

# Using an OrderSearch
>>> api.orders.by_product(product)
>>> api.orders.by_product_id(product.id)
>>> api.orders.by_sku(product.sku)

[, ... ]

Example: Retrieving all |.~.Product|_\s and |.~.Invoice|_\s for a |.~.Category|_
===============================================================================================

.. code-block:: python

>>> category = api.categories.by_name("Watches")
>>> category.get_products()
>>> category.get_invoices()

[, , , ... ]
[ for , ... ]

Example: Updating the Thumbnail |.~.MediaEntry|_ of a |.~.Product|_
=============================================================================

.. code-block:: python

# Update product thumbnail label on specific store view
>>> product.thumbnail.set_alt_text("bonjour", scope="FR")
>>> print(product.thumbnail)

: bonjour>

...

.. raw:: html



πŸ’‘ Tip: Set the Store Scope

.. raw:: html


If you have multiple store views, a ``store_code`` can be specified when
retrieving/updating data

* The |..Client.scope|_ is used by default - simply change it to switch store |.~.views|_
* Passing the ``scope`` keyword argument to |..Client.url_for|_, |..Model.refresh|_,
and some Model update methods will temporarily override the Client scope

.. raw:: html


...

.. _Custom Queries:

Building Custom Search Queries
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

In addition to the predefined methods, you can also build your own queries

* Simply |.~.add_criteria|_, |.~.restrict_fields|_, and |.~.execute|_ the search
* The |.~.since|_ and |.~.until|_ methods allow you to further filter your query by date

.. raw:: html



πŸ“‹ Example: Retrieve Orders Over $50 Placed Since the Start of 2023

.. raw:: html


.. code-block:: python

>>> api.orders.add_criteria(
... field="grand_total",
... value="50",
... condition="gt"
... ).since("2023-01-01").execute()

[, ...]

.. raw:: html


...

Making Authorized Requests
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The |.~.Client|_ can be used to generate the |.~.url_for|_ any API endpoint,
including a store |.~.scope|_.

You can use this URL to make an authorized
|.~.get|_, |.~.post|_, |.~.put|_, or |.~.delete|_ request.

Example: Making a |.~.get|_ Request
=============================================

.. code-block:: python

# Request the data for credit memo with id 7
>>> url = api.url_for('creditmemo/7')
>>> response = api.get(url)
>>> print(response.json())

{'adjustment': 1.5, 'adjustment_negative': 0, 'adjustment_positive': 1.5, 'base_adjustment': 1.5, ... }

.. raw:: html



πŸ“ Note

.. raw:: html


A |.~.search|_ is simpler than making |.~.get|_ requests, as the result will
be wrapped by |.~.APIResponse|_ or other |.~.Model|_

.. code-block:: python

# Retrieve credit memo with id 7 using a search
>>> memo = api.search("creditmemo").by_id(7)
>>> print(memo.data)
>>> print(memo)

{'adjustment': 1.5, 'adjustment_negative': 0, 'adjustment_positive': 1.5, 'base_adjustment': 1.5, ... }

.. raw:: html