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
- Host: GitHub
- URL: https://github.com/tdkorn/my-magento
- Owner: TDKorn
- License: mit
- Created: 2022-02-10T11:16:12.000Z (over 4 years ago)
- Default Branch: main
- Last Pushed: 2024-06-23T22:14:32.000Z (about 2 years ago)
- Last Synced: 2025-04-04T19:33:48.315Z (over 1 year ago)
- Topics: api, magento, python, wrapper
- Language: Python
- Homepage: https://my-magento.readthedocs.io
- Size: 3.45 MB
- Stars: 12
- Watchers: 4
- Forks: 3
- Open Issues: 3
-
Metadata Files:
- Readme: README.rst
- Changelog: changelog.rst
- License: LICENSE
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