Skip to content

Commit

Permalink
add make_endpoint script
Browse files Browse the repository at this point in the history
  • Loading branch information
saleweaver committed Dec 24, 2021
1 parent f8331cc commit 43fb310
Show file tree
Hide file tree
Showing 10 changed files with 203 additions and 175 deletions.
1 change: 1 addition & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ exclude_lines =
if __name__ == .__main__.:
(.*)return self\._request(.*)
raise KeyError(\"AWS Access Key ID and Secret Access Key are required\")
(.*)super\(SellingApi(.*)
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,16 @@ Documentation is available [here](https://sp-api-docs.saleweaver.com/?utm_source
[![Documentation Status](https://img.shields.io/readthedocs/python-amazon-sp-api?style=for-the-badge)](https://sp-api-docs.saleweaver.com/?utm_source=github&utm_medium=repo&utm_term=badge)


### New endpoints

You can create a new endpoint file by running `make_endpoint <model_json_url>`

```bash
make_endpoint https://raw.githubusercontent.com/amzn/selling-partner-api-models/main/models/listings-restrictions-api-model/listingsRestrictions_2021-08-01.json
```

This creates a ready to use client. Please consider creating a pull request with the new code.

### DISCLAIMER

We are not affiliated with Amazon
Expand Down
178 changes: 178 additions & 0 deletions make_endpoint/make_endpoint
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
#!/usr/bin/env python

import argparse
import os
import pprint
import re

import jinja2
import requests


def parse_args():
parser = argparse.ArgumentParser(description='Create new endpoint.')
parser.add_argument('model_url', type=str,
help='The endpoint definition file provided by Amazon')
args = parser.parse_args()
return args


def get_model(url):
res = requests.get(url).json()
return res


def make_query(p):
r = r'{.*}'
try:
return re.sub(r, '{}', p), p[p.index('{') + 1:p.index('}')], True
except ValueError:
return re.sub(r, '{}', p), None, False


def make_py(endpoint, operations, description, directory):
context = {
'endpoint': endpoint,
'operations': operations,
'description': description
}
loader = jinja2.FileSystemLoader(searchpath="./make_endpoint")
env = jinja2.Environment(loader=loader)
file = "template.py.jinja2"
template = env.get_template(file)
out = template.render(context)

with open(os.path.join(directory, f'{sub(endpoint)}.py'), 'w+') as f:
f.write(out)
f.close()


def sub(e):
return re.sub(r'([A-Z])', lambda match: r'_{}'.format(match.group(1).lower()), e[0].lower() + e[1:])


def make_endpoint_name(s):
return re.sub(r'-([a-zA-Z])', lambda match: r'{}'.format(match.group(1).upper()), s[0].upper() + s[1:])


def make_directory(endpoint):
directory = f'./sp_api/api/{sub(endpoint)}'
if os.path.exists(directory):
raise Exception('Directory exists')
os.mkdir(directory)
open(os.path.join(directory, '__init__.py'), 'a').close()
return directory


def make_params(params, model):
if not params:
return []
new_params = []
for param in params:
if param.get('in') == 'body':
body = model.get('definitions').get(param.get('schema').get('$ref')[param.get('schema').get('$ref').rindex('/') + 1:])
body_example = pprint.pformat(body, width=250, compact=False)
param.update({'description': body_example})
new_params.append(param)
return new_params


def add_to_init(endpoint):
e = sub(endpoint)
import_template = f'''##### DO NOT DELETE ########## INSERT IMPORT HERE #######
from .{e}.{e} import {endpoint}
'''
append_template = f'''##### DO NOT DELETE ########## INSERT TITLE HERE #######
"{endpoint}",
'''
with open('./sp_api/api/__init__.py', 'r') as f:
content = f.read()
content = import_template.join(content.split('##### DO NOT DELETE ########## INSERT IMPORT HERE #######'))
content = append_template.join(content.split('##### DO NOT DELETE ########## INSERT TITLE HERE #######'))
f.close()
with open('./sp_api/api/__init__.py', 'w+') as f1:
f1.write(content)
f1.close()


def add_to_setup_py(endpoint):
package = f"'sp_api.api.{sub(endpoint)}'"
append_template = f"""##### DO NOT DELETE ########## INSERT PACKAGE HERE #######
{package},
"""
with open('../setup.py', 'r') as f:
content = f.read()
content = append_template.join(content.split('##### DO NOT DELETE ########## INSERT PACKAGE HERE #######'))
f.close()
with open('./setup.py', 'w+') as f1:
f1.write(content)
f1.close()


def create_endpoint_file(model_json):
model = get_model(model_json)
endpoint = get_endpoint_from_url(model_json)
directory = make_directory(endpoint)
operations = []
for k, v in model.get('paths').items():
for method, val in v.items():
if method == 'parameters':
continue
uri, param, has_query_params = make_query(k)
operation = {
'uri': uri,
'method': method.upper(),
'has_query_params': has_query_params,
'query_param': param,
'params_or_data': 'params' if method == 'get' else 'data',
'title': sub(val.get('operationId')),
'description': val.get('description'),
'params': make_params(val.get('parameters'), model)
}
operations.append(operation)

make_py(endpoint, operations, model.get('info').get('description'), directory)
# add_to_init(endpoint)
# add_to_setup_py(endpoint)


def get_endpoint_from_url(url):
n = url.split('/')[-2][:-10]
return make_endpoint_name(n)


if __name__ == '__main__':
args = parse_args()

create_endpoint_file(args.model_url)
# for model_json_url in [
# # 'https://raw.githubusercontent.com/amzn/selling-partner-api-models/main/models/fulfillment-outbound-api-model/fulfillmentOutbound_2020-07-01.json',
# # 'https://raw.githubusercontent.com/amzn/selling-partner-api-models/main/models/aplus-content-api-model/aplusContent_2020-11-01.json',
# # 'https://raw.githubusercontent.com/amzn/selling-partner-api-models/main/models/authorization-api-model/authorization.json',
# # 'https://raw.githubusercontent.com/amzn/selling-partner-api-models/main/models/fba-inbound-eligibility-api-model/fbaInbound.json',
# # 'https://raw.githubusercontent.com/amzn/selling-partner-api-models/main/models/fba-small-and-light-api-model/fbaSmallandLight.json',
# # 'https://raw.githubusercontent.com/amzn/selling-partner-api-models/main/models/services-api-model/services.json',
# # 'https://raw.githubusercontent.com/amzn/selling-partner-api-models/main/models/shipping-api-model/shipping.json',
# # 'https://raw.githubusercontent.com/amzn/selling-partner-api-models/main/models/solicitations-api-model/solicitations.json',
# # 'https://raw.githubusercontent.com/amzn/selling-partner-api-models/main/models/tokens-api-model/tokens_2021-03-01.json',
# # 'https://raw.githubusercontent.com/amzn/selling-partner-api-models/main/models/vendor-direct-fulfillment-inventory-api-model/vendorDirectFulfillmentInventoryV1.json',
# # 'https://raw.githubusercontent.com/amzn/selling-partner-api-models/main/models/vendor-direct-fulfillment-orders-api-model/vendorDirectFulfillmentOrdersV1.json',
# # 'https://raw.githubusercontent.com/amzn/selling-partner-api-models/main/models/vendor-direct-fulfillment-payments-api-model/vendorDirectFulfillmentPaymentsV1.json',
# # 'https://raw.githubusercontent.com/amzn/selling-partner-api-models/main/models/vendor-direct-fulfillment-shipping-api-model/vendorDirectFulfillmentShippingV1.json',
# # 'https://raw.githubusercontent.com/amzn/selling-partner-api-models/main/models/vendor-direct-fulfillment-transactions-api-model/vendorDirectFulfillmentTransactionsV1.json',
# # 'https://raw.githubusercontent.com/amzn/selling-partner-api-models/main/models/vendor-invoices-api-model/vendorInvoices.json',
# # 'https://raw.githubusercontent.com/amzn/selling-partner-api-models/main/models/vendor-orders-api-model/vendorOrders.json',
# # 'https://raw.githubusercontent.com/amzn/selling-partner-api-models/main/models/vendor-shipments-api-model/vendorShipments.json',
# # 'https://raw.githubusercontent.com/amzn/selling-partner-api-models/main/models/vendor-transaction-status-api-model/vendorTransactionStatus.json'
# # 'https://raw.githubusercontent.com/amzn/selling-partner-api-models/main/models/listings-items-api-model/listingsItems_2020-09-01.json',
# # 'https://raw.githubusercontent.com/amzn/selling-partner-api-models/main/models/product-type-definitions-api-model/definitionsProductTypes_2020-09-01.json',
# # 'https://raw.githubusercontent.com/amzn/selling-partner-api-models/main/models/catalog-items-api-model/catalogItems_2020-12-01.json'
# # 'https://raw.githubusercontent.com/amzn/selling-partner-api-models/main/models/messaging-api-model/messaging.json'
# # 'https://raw.githubusercontent.com/amzn/selling-partner-api-models/main/models/reports-api-model/reports_2021-06-30.json'
# # 'https://raw.githubusercontent.com/amzn/selling-partner-api-models/main/models/feeds-api-model/feeds_2021-06-30.json'
# # 'https://raw.githubusercontent.com/amzn/selling-partner-api-models/main/models/listings-restrictions-api-model/listingsRestrictions_2021-08-01.json'
# ]:
# try:
# create_endpoint_file(model_json_url)
# except Exception as e:
# print(e)
165 changes: 0 additions & 165 deletions make_endpoint/make_endpoint.py

This file was deleted.

4 changes: 2 additions & 2 deletions make_endpoint/template.py.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ class {{ endpoint }}(Client):

{{ operation.description }}

Args:
Args:
{% for arg in operation.params %}
{{ 'key ' if arg['in'] == 'query' else ''}}{{ arg.name }}:{{ arg.type }} | {{ '* REQUIRED' if arg.required else '' }} {{ arg.description }}
{% endfor %}

Returns:
Returns:
ApiResponse:
"""
{% if operation.has_query_params %}
Expand Down
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

setup(
name='python-amazon-sp-api',
version='0.10.4',
version='0.11.0',
install_requires=[
"requests",
"six>=1.15,<2",
Expand Down Expand Up @@ -59,6 +59,7 @@
'sp_api.api.aplus_content',
'sp_api.api.fulfillment_outbound',
],
scripts=['make_endpoint/make_endpoint'],
url='https://github.com/saleweaver/python-amazon-sp-api',
license='MIT',
author='Michael',
Expand Down
Loading

0 comments on commit 43fb310

Please sign in to comment.