Skip to content

Instantly share code, notes, and snippets.

@nyov
Last active August 15, 2021 12:57
Show Gist options
  • Star 16 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save nyov/5116258 to your computer and use it in GitHub Desktop.
Save nyov/5116258 to your computer and use it in GitHub Desktop.
A Magento REST API example with rauth as OAuth provider. For Magento 1
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from rauth.service import OAuth1Service
# Create consumer key & secret in your Magento Admin interface
# For an API Guideline see:
# http://www.magentocommerce.com/api/rest/authentication/oauth_authentication.html
#
# Short Magento setup explanation:
# 1. Magento Admin > System > Web Services > REST - OAuth Consumers:
# Add a new consumer for this script [maybe the OAuth1Service(name='') value]
# (This creates the consumer_key and consumer_secret token for you)
# 2. Possibly enable rewriting rules for the /api url in the Magento .htaccess
# 3. Magento Admin > System > Web Services > REST - Roles:
# Give the Customer account some access to stuff (using the customer authorize_url below)
# or create an Admin account for write access (using the admin authorize_url below)
# Give the Guest account some access for some basic functionality testing without authorization.
# 4. Magento Admin > System > Web Services > REST - Attributes:
# Configure ACL attributes access for the role/account configured in 3rd
# - The customer must have a (frontend) account to login to and authorize the script.
# - For any created Admin roles in 3rd, the role needs to be mapped to an admin user:
# 5. Magento Admin > System > Permissions > Users:
# Edit an admin user and under 'REST Role', tick the created Admin REST Role to map it to that account.
# This admin will get the authorize_url to authorize your script access in the browser.
MAGENTO_HOST = 'http://127.0.0.1'
MAGENTO_API_BASE = '%s/api/rest/' % MAGENTO_HOST
magento = OAuth1Service(
name = 'magento',
consumer_key = 'vygdq11yzaectqwbpn1h4zwlamsrpomi',
consumer_secret = '5x5idvqc8rh4vc8lrxeg4hvple0u63dt',
request_token_url = '%s/oauth/initiate' % MAGENTO_HOST,
access_token_url = '%s/oauth/token' % MAGENTO_HOST,
# Customer authorization
#authorize_url = '%s/oauth/authorize' % MAGENTO_HOST,
# Admin authorize url depending on admin url
authorize_url = '%s/admin/oauth_authorize' % MAGENTO_HOST,
base_url = MAGENTO_API_BASE
)
# get request token
request_token, request_token_secret = magento.get_request_token(method='POST', params={'oauth_callback': 'oob'})
# authorize us
authorize_url = magento.get_authorize_url(request_token)
print 'Visit this URL in your browser: ' + authorize_url
code = raw_input('Paste Code from browser: ')
session = magento.get_auth_session(request_token,
request_token_secret,
method='POST',
data={'oauth_verifier': code})
headers = {'Accept': 'application/json'}
r = session.get('products', headers=headers)
articles = r.json()
for i, product in articles.items():
id = product['sku'].encode('utf-8')
text = product['description'].encode('utf-8')
print '{0}. ArtNr: {1} - {2}'.format(i, id, text)
session.close()
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from rauth.service import OAuth1Service
import json
from urlparse import urljoin
# Create consumer key & secret in your Magento Admin interface
# For an API Guideline see:
# http://www.magentocommerce.com/api/rest/authentication/oauth_authentication.html
#
# Short Magento setup explanation:
# 1. Magento Admin > System > Web Services > REST - OAuth Consumers:
# Add a new consumer for this script [maybe the OAuth1Service(name='') value]
# (This creates the consumer_key and consumer_secret token for you)
# 2. Possibly enable rewriting rules for the /api url in the Magento .htaccess
# 3. Magento Admin > System > Web Services > REST - Roles:
# Give the Customer account some access to stuff (using the customer authorize_url below)
# or create an Admin account for write access (using the admin authorize_url below)
# Give the Guest account some access for some basic functionality testing without authorization.
# 4. Magento Admin > System > Web Services > REST - Attributes:
# Configure ACL attributes access for the role/account configured in 3rd
# - The customer must have a (frontend) account to login to and authorize the script.
# - For any created Admin roles in 3rd, the role needs to be mapped to an admin user:
# 5. Magento Admin > System > Permissions > Users:
# Edit an admin user and under 'REST Role', tick the created Admin REST Role to map it to that account.
# This admin will get the authorize_url to authorize your script access in the browser.
MAGENTO_HOST = 'http://127.0.0.1'
MAGENTO_API_BASE = '%s/api/rest/' % MAGENTO_HOST
magento = OAuth1Service(
name = 'magento',
consumer_key = 'vygdq11yzaectqwbpn1h4zwlamsrpomi',
consumer_secret = '5x5idvqc8rh4vc8lrxeg4hvple0u63dt',
request_token_url = '%s/oauth/initiate' % MAGENTO_HOST,
access_token_url = '%s/oauth/token' % MAGENTO_HOST,
# Customer authorization
#authorize_url = '%s/oauth/authorize' % MAGENTO_HOST,
# Admin authorize url depending on admin url
authorize_url = '%s/admin/oauth_authorize' % MAGENTO_HOST,
base_url = MAGENTO_API_BASE
)
"""
# get request token
request_token, request_token_secret = magento.get_request_token(method='POST', params={'oauth_callback': 'oob'})
print 'Our request token is: ' + request_token
print ' token secret is: ' + request_token_secret
print
# authorize us
authorize_url = magento.get_authorize_url(request_token)
print 'Visit this URL in your browser: ' + authorize_url
code = raw_input('Paste Code from browser: ')
#session = magento.get_auth_session(request_token, request_token_secret, method='POST', data=params)
#session = magento.get_auth_session(request_token, request_token_secret, method='GET', params=params)
# -- get access token
access_token, access_token_secret = magento.get_access_token(request_token=request_token,
request_token_secret=request_token_secret,
method='POST',
data={'oauth_verifier': code})
print 'Our access token is: ' + access_token
print ' token secret is: ' + access_token_secret
print
"""
access_token = '<save access_token here for reuse>'
access_token_secret = '<save access_token here for reuse>'
tok = access_token, access_token_secret
session = magento.get_session(token=tok, signature=None)
## example GET request
headers = {'Accept': 'application/json'}
#headers = {'Accept': 'application/xml'}
r = session.get(
'products',
#'products/1/categories',
#'customers',
#'stockitems',
#'products?filter[1][attribute]=entity_id&filter[1][gt]=4'
headers=headers,
#header_auth=True,
)
print r.request.headers
print r.json()
print
## example POST request
headers = {'Content-Type': 'application/json', 'Accept': 'application/json'}
# - create a product
product = """{
"type_id": "simple",
"attribute_set_id": "4",
"sku": "TestArticle1",
"name": "Test Article 70mm² M12",
"price": "3.5200",
"description": "This Product has the bare minimum required attributes to get inserted",
"short_description": "Test Article 70mm² M12",
"weight": "0.0000",
"status": "1",
"visibility": "4",
"tax_class_id": "2"
}"""
payload = json.loads(product)
r = session.post(
'products',
header_auth=True,
headers=headers,
data=json.dumps(payload),
)
# see if we have errors
if r.status_code != 200:
print 'Error!'
print r.text
quit()
else:
# catch the returned Location redirect to the new product
article_url = urljoin(MAGENTO_API_BASE, r.headers['location'])
print 'New product inserted as: %s' % (article_url)
# - assign new product to a category (so it will be visible in frontend)
# FIX THIS TO A CATEGORY ID WHICH EXISTS AND IS NOT ROOT
payload = json.dumps({'category_id': '2'})
r = session.post(
article_url + '/categories',
header_auth=True,
headers=headers,
data=payload,
)
# see if we have errors
if r.status_code != 200:
print 'Error!'
print r.text
quit()
else:
article_url = urljoin(MAGENTO_API_BASE, r.headers['location'])
print 'Success! Product added to category: %s' % (article_url)
print r.request.headers
session.close()
@madhurranjan
Copy link

Hi ,

Thanks for the Gist but I could not get it working with Oauth1service. However, my final code that allowed me to get the products was this :

!/usr/bin/env python

from requests_oauthlib import OAuth1 as OAuth
import requests
consumer_key = ''
consumer_secret = ''
access_key = ''
access_secret = ''

oauth = OAuth(client_key=consumer_key, client_secret=consumer_secret, resource_owner_key=access_key, resource_owner_secret=access_secret)
h = {'Content-Type': 'application/json', 'Accept': 'application/json'}
r = requests.get(url='http://magentohost/api/rest/products', headers=h, auth=oauth)
print r
print r.content

However, the problem I'm facing is that I'm unable to make any POST requests. They are all returning 403. Can you help here please?

@nyov
Copy link
Author

nyov commented Jul 14, 2015

Hey @madhurranjan,
I didn't get a notice about your comment. Sorry, I haven't been using rauth or requests_oauthlib in ages, so I'm not having a clue about your issue.
It usually helps to figure out what's actually on the wire. I tend to use wireshark for debugging what the client really sends (missing Authorization headers or other strangeness).

One thing magento1 did strange, was not use Authorization headers but put stuff in the request body, IIRC. So maybe requests_oauthlib doesn't know how to handle that (there was a reason I went with rauth back in that day, even though I had to submit some patches along the way.)

@louistaylor424
Copy link

Hi,

Thank you for sharing good source. I have changed your source to create product like following.

headers = {'Accept': 'application/json',}

product = """{
"attribute_set_id":"4",
"type_id":"simple",
"sku":"wedding dress",
"name":"Dress_test",
"meta_title":"dress",
"meta_description":"a wedding dress",
"price":"2000.0000",
"weight":"0.5000",
"status":"1",
"visibility":"4",
"enable_googlecheckout":"1",
"tax_class_id":"1",
"description":"dress",
"meta_keyword":"dress, wedding"
}"""
payload = json.loads(product)

r = session.post(
'products',
header_auth=True,
headers=headers,

data=json.dumps(payload),

data = payload

)

see if we have errors

if r.status_code != 200:
print 'Error!'
print r.text
quit()
else:
# catch the returned Location redirect to the new product
article_url = ''#urljoin(MAGENTO_API_BASE, r.headers['location'])
print 'New product inserted as: %s' % (article_url)

But I have 400 Error.

Would you like to help me to resolve this issue?

@ispeakcomputer
Copy link

Awesome, thanks for sharing

@blob84
Copy link

blob84 commented Mar 8, 2019

Hello I get this error:

Traceback (most recent call last): File "magento_cli.py", line 44, in <module> request_token, request_token_secret = magento.get_request_token(method='POST', params={'oauth_callback': 'oob'}) File "/home/antonio/.local/lib/python2.7/site-packages/rauth/service.py", line 244, in get_request_token process_token_request(r, decoder, key_token, key_token_secret) File "/home/antonio/.local/lib/python2.7/site-packages/rauth/service.py", line 20, in process_token_request data = decoder(r.content) File "/home/antonio/.local/lib/python2.7/site-packages/rauth/utils.py", line 33, in parse_utf8_qsl v = v.decode('utf-8') File "/usr/lib/python2.7/encodings/utf_8.py", line 16, in decode return codecs.utf_8_decode(input, errors, True) UnicodeDecodeError: 'utf8' codec can't decode byte 0xe8 in position 597: invalid continuation byte
It seems that I have problem with the utf-8.

@nyov
Copy link
Author

nyov commented Nov 25, 2019

Hi guys, sorry I don't get notifies on gist comments, unless you @mention me.

Late comment: A 400 error probably meant the API wasn't enabled or credentials were wrong.

@blob84, your magento apparently returned some data that couldn't be decoded using utf-8.
I don't know why this happens, if the API is enabled I think that should happen.
Note this was built for the Magento 1 API.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment