trytonpsk-sale_web_channel/endpoints_rappi.py

274 lines
12 KiB
Python

import requests
import json
from datetime import datetime
from collections import namedtuple
from . import endpoints_rappi
URL_AUTH_DEV = 'https://rests-integrations-dev.auth0.com/oauth/token'
URL_AUTH_PRODUCTION = 'https://rests-integrations.auth0.com/oauth/token'
URL_ENV = 'https://microservices.dev.rappi.com/api/v2/restaurants-integrations-public-api'
AUDIENCE = 'https://int-public-api-v2/api'
HEADERS = {
'Accept': 'application/json',
'Content-type': 'application/json'
}
ChannelRappi = namedtuple('Channel', [
'seller_id', 'app_id', 'store_integration_id',
'secret_key', 'host_name', 'api_key', 'creation_time'])
channel = ChannelRappi(
seller_id='iJB9UvxChNgjmvXGgPCbIzUYaYzCf7PJ',
app_id='900152684',
store_integration_id='900152684',
secret_key='Qi-FvBNKoSkxRQn4R-Xf-TLNURZH08FXrPj2XSTvVKSccO2pyQBdn4x1XJhSgr5F',
host_name='',
api_key='',
creation_time=''
)
class RappiAPI:
def __init__(self, channel):
# self.api_key = channel.api_key
# self.url_base = 'https://microservices.dev.rappi.com/api/v2/restaurants-integrations-public-api'
# self.url_auth = URL_AUTH_DEV
# self.session = requests.Session()
# self.session.headers.update({'x-authorization': self.api_key})
# self.session.headers.update({'Content-Type': 'application/json'})
# self.store_name = channel.shop.name
self.seller_id = channel.seller_id
self.app_id = channel.app_id
self.store_integration_id = channel.app_id
self.url_base = 'https://microservices.dev.rappi.com/api/v2/restaurants-integrations-public-api'
self.url_auth = URL_AUTH_DEV
self.token = channel.access_token if channel.access_token else ''
self.session = requests.Session()
self.session.headers.update({
'x-authorization': 'bearer ' + self.token
})
self.session.headers.update({'Content-Type': 'application/json'})
def _send_request(self, endpoint=None, method='GET', data: dict = None, auth: bool = False):
if auth:
url = self.url_auth
else:
url = self.url_base + endpoint
try:
if method == 'GET':
response = self.session.get(url, timeout=10)
elif method == 'POST':
response = self.session.post(url, data=json.dumps(data), timeout=10)
elif method == 'PUT':
response = self.session.put(url, data=json.dumps(data), timeout=10)
elif method == 'DELETE':
response = self.session.delete(url, timeout=10)
else:
raise ValueError(f'Method {method} not supported')
content_type = response.headers.get('Content-Type', '')
# if response.status_code == 200:
if content_type.startswith('application/json'):
print(response.json())
return response.json()
else:
print(response.text)
return response.text
# else:
# if content_type.startswith('application/json'):
# return response.json()
# else:
# raise RuntimeError(f'Error {response.status_code}: {response.text}')
except requests.exceptions.RequestException as e:
raise RuntimeError(f'Request error: {str(e)}')
def get_token_access(self, client_id: str, client_secret: str):
data = {
"client_id": client_id,
"client_secret": client_secret,
"audience": AUDIENCE,
"grant_type": "client_credentials"
}
return self._send_request(method='POST', data=data, auth=True)
def get_info_store(self):
"""Get information store
integrationId: It is the id of the store that you assign in the integration.
rappiId: It is the id of the store assigned by Rappi.
name: It is the name of the store.
"""
endpoint = 'stores-pa'
return self._send_request(endpoint=endpoint)
def get_check_in_code(self, store_id):
"""
Use the endpoint to obtain the following information from the check-in code assigned to your store.
store_id It is the id of the consulted store.
code It is the store check-in code assigned by Rappi.
created_at It is the creation date of the check-in code assigned for the store.
updated_at It is the update date of the check-in code assigned to the store.
expired_at It is the expiration date of the check-in code assigned to the store
"""
endpoint = f'/stores-pa/{store_id}/check-in-code'
return self._send_request(endpoint=endpoint)
def get_info_menu_current(self, rappiId):
"""
Products
id This is Rappi id from the product.
name Product name.
price Product price.
toppings Toppings from the product.
Toppings
id This is Rappi id from the topping.
name This is name from the Topping.
price This is price from the Topping.
category This is category information from the Topping.
Topping Category
id This is Rappi id from the topping category.
name Topping category name.
"""
endpoint = f'/store/{rappiId}/menu/current'
return self._send_request(endpoint=endpoint)
def get_menu(self):
"""
"""
endpoint = '/menu'
return self._send_request(endpoint=endpoint)
def get_last_menu_store(self, store_id):
endpoint = f'/menu/rappi/{store_id}'
return self._send_request(endpoint=endpoint)
def get_menu_approved(self, store_id):
endpoint = f'/menu/approved/{store_id}'
return self._send_request(endpoint=endpoint)
def create_menu_store(self, items):
"""
NOTE: If menu don't created return response message dict {message: 'reason'}
"""
endpoint = '/menu'
data = {
'storeId': self.store_integration_id,
'items': items,
}
return self._send_request(endpoint=endpoint, method='POST', data=data)
def get_items_status(self, item_ids: list):
"""
Get item status avalability
Item SKU: This is the SKU you provided for the item to the Rappi
when uploading to the menu.
Item ID: This is the identifier that Rappi provided you when
uploading to the menu.
"""
endpoint = '/availability/items/status'
data = {
'storeId': self.storeId,
'item_ids': item_ids,
}
return self._send_request(endpoint=endpoint, method='POST', data=data)
def set_items_status(self, items_on: list, items_off: list):
"""
Set item status avalability
Item SKU: This is the SKU you provided for the item to the Rappi
when uploading to the menu.
Item ID: This is the identifier that Rappi provided you when
uploading to the menu.
"""
endpoint = '/availability/items/status'
data = {
'store_integration_id': self.store_integration_id,
'items': {
'turn_on': items_on,
'turn_off': items_off
},
}
return self._send_request(endpoint=endpoint, method='PUT', data=data)
# def cancel_order(self, order_id, cancel_reason):
# endpoint = f'/orders/{order_id}/cancel'
# data = {'reason': cancel_reason}
# return self._send_request(endpoint, method='PUT', data=data)
def get_orders(self):
endpoint = '/orders'
# params = {}
params = {'storeId': channel.app_id}
return self._send_request(endpoint=endpoint, method='GET', data=params)
def take_order(self, order_id, cookingTime=None):
endpoint = f'/orders/{order_id}/take/{cookingTime}'
return self._send_request(endpoint, method='PUT')
def reject_order(self, order_id, reason):
# reason optional
# cancel_type
#["ITEM_WRONG_PRICE", "ITEM_NOT_FOUND", "ITEM_OUT_OF_STOCK", "ORDER_MISSING_INFORMATION", "ORDER_MISSING_ADDRESS_INFORMATION", "ORDER_TOTAL_INCORRECT"]
endpoint = f'/orders/{order_id}/reject'
data = {'reason': reason}
return self._send_request(endpoint, method='PUT', data=data)
def ready_order(self, order_id):
endpoint = f'/orders/{order_id}/ready-for-pickup'
return self._send_request(endpoint, method='POST')
def get_order_events(self, order_id):
endpoint = f'/orders/{order_id}/events'
return self._send_request(endpoint)
def get_orders_status_sent(self):
endpoint = '/orders/status/sent'
return self._send_request(endpoint)
# Ejemplo de uso
# print(channel.seller_id, 'this is objetc')
# token = {
# 'access_token': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL3Jlc3RzLWludGVncmF0aW9ucy1kZXYuYXV0aDAuY29tLyIsInN1YiI6ImlKQjlVdnhDaE5nam12WEdnUENiSXpVWWFZekNmN1BKQGNsaWVudHMiLCJhdWQiOiJodHRwczovL2ludC1wdWJsaWMtYXBpLXYyL2FwaSIsImlhdCI6MTY5MzAxNzExNCwiZXhwIjoxNjkzNjIxOTEyLCJhenAiOiJpSkI5VXZ4Q2hOZ2ptdlhHZ1BDYkl6VVlhWXpDZjdQSiIsInNjb3BlIjoidXBkYXRlOmF2YWlsYWJpbGl0eV9zdG9yZXMgdXBkYXRlOmF2YWlsYWJpbGl0eV9zdG9yZXNfaXRlbXMgdXBkYXRlOmF2YWlsYWJpbGl0eV9zdG9yZXNfaXRlbXNfcmFwcGkgcmVhZDptZW51X3RoaXJkcGFydHkgdXBkYXRlOm1lbnUgcmVhZDptZW51X3JhcHBpIHVwZGF0ZTpvcmRlcnNfcmVhZHlfZm9yX3BpY2t1cCByZWFkOm1lbnVzX3JhcHBpIHJlYWQ6Y29uZmlnIGNyZWF0ZTpjb25maWcgdXBkYXRlOmNvbmZpZyBkZWxldGU6Y29uZmlnIHJlYWQ6b3JkZXJzIHBpY2t1cDpvcmRlciByZWplY3Q6b3JkZXIgdGFrZTpvcmRlciByZWFkOnN0b3JlcyByZWFkOmFwcF9jbGllbnRzIGNyZWF0ZTphcHBfY2xpZW50cyBkZWxldGU6YXBwX2NsaWVudHMgY3JlYXRlOmFwcF9jbGllbnRzX3N0b3JlcyByZWFkOm9yZGVyX2V2ZW50cyBkZWxldGU6YXBwX2NsaWVudHNfc3RvcmVzIGNyZWF0ZTpjbGllbnRzIHJlYWQ6bWVudV9zdGF0dXNfcmFwcGkgcmVhZDphdmFpbGFiaWxpdHlfc3RvcmVzX2l0ZW1zIHJlYWQ6d2ViaG9vayBjcmVhdGU6d2ViaG9vayB1cGRhdGU6d2ViaG9vayBkZWxldGU6d2ViaG9vayB1cGRhdGU6d2ViaG9va19zZWNyZXQiLCJndHkiOiJjbGllbnQtY3JlZGVudGlhbHMifQ.Loh_g9qB3jNhOHxXPVrWgDJQAr7n9DzB6jWbPD_vUDQ',
# 'scope': 'update:availability_stores update:availability_stores_items update:availability_stores_items_rappi read:menu_thirdparty update:menu read:menu_rappi update:orders_ready_for_pickup read:menus_rappi read:config create:config update:config delete:config read:orders pickup:order reject:order take:order read:stores read:app_clients create:app_clients delete:app_clients create:app_clients_stores read:order_events delete:app_clients_stores create:clients read:menu_status_rappi read:availability_stores_items read:webhook create:webhook update:webhook delete:webhook update:webhook_secret', 'expires_in': 604798, 'token_type': 'Bearer'}
# channel = channel._replace(api_key=token['access_token'], creation_time=datetime.now())
# rappi = RappiAPI(f'Bearer {channel.api_key}', URL_ENV, URL_AUTH_DEV)
# get token
# token = rappi.get_token_access(channel.seller_id, channel.secret_key, 'https://int-public-api-v2/api')
# print(token, 'validate token')
# # get menu
# menu = rappi.get_menu()
# print(menu, 'menu in rappi')
# # get menu approved
# menu_approved = rappi.get_menu_approved(store_id=channel.app_id)
# print(menu_approved, 'menu approved')
# # get last menu store
# last_menu = rappi.get_last_menu_store(store_id=channel.app_id)
# print(last_menu, 'last menu')
# create menu
# NOTE: If menu don't created return response message json {message: 'reason'}
# items = []
# menu_created = rappi.create_menu_store(store_id=channel.app_id, items=items)
# print(menu_created, 'menu created')
# Order options to call enpoints to manage order client
# get_orders, take_order or reject_order, ready_order
# # Get orders
# orders = rappi.get_orders()
# print(orders, 'list_orders')