add FastAPI
This commit is contained in:
0
service/__init__.py
Normal file
0
service/__init__.py
Normal file
72
service/auth_service.py
Normal file
72
service/auth_service.py
Normal file
@@ -0,0 +1,72 @@
|
||||
import logging as log
|
||||
from typing import Type
|
||||
import requests
|
||||
from sqlalchemy.orm import Session
|
||||
from sqlalchemy import select, desc
|
||||
|
||||
import constants
|
||||
from db.helpers import get_engine
|
||||
from db.models import ApiToken
|
||||
from constants import *
|
||||
|
||||
|
||||
def generate_token(persist=False):
|
||||
body = {
|
||||
"consumer_key": api_consumer_key,
|
||||
"consumer_secret": api_consumer_secret,
|
||||
"code": api_code
|
||||
}
|
||||
response = requests.post(f"{constants.api_url}/auth", json=body)
|
||||
|
||||
if response.status_code in [201, 200]:
|
||||
log.info('Generated tray access token: %s', response.json())
|
||||
|
||||
if persist:
|
||||
log.info('Persisting token')
|
||||
persist_auth_token(response.json())
|
||||
|
||||
return response
|
||||
|
||||
|
||||
def refresh_access_token():
|
||||
generate_token(persist=True)
|
||||
token = get_last_api_token()
|
||||
|
||||
log.info('Refreshing token')
|
||||
response = requests.get(f"{api_url}/auth?refresh_token={token.refresh_token}").json()
|
||||
|
||||
try:
|
||||
persist_auth_token(response)
|
||||
return response['access_token']
|
||||
except Exception as e:
|
||||
log.error(e)
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def persist_auth_token(api_token):
|
||||
with Session(get_engine()) as session:
|
||||
token = ApiToken(message=api_token["message"],
|
||||
code=api_token["code"],
|
||||
access_token=api_token["access_token"],
|
||||
refresh_token=api_token["refresh_token"],
|
||||
date_expiration_access_token=api_token["date_expiration_access_token"],
|
||||
date_expiration_refresh_token=api_token["date_expiration_refresh_token"],
|
||||
date_activated=api_token["date_activated"],
|
||||
api_host=api_token["api_host"],
|
||||
store_id=api_token["store_id"])
|
||||
|
||||
session.add(token)
|
||||
session.commit()
|
||||
|
||||
|
||||
def delete_token(token):
|
||||
with Session(get_engine()) as session:
|
||||
log.info('Deleting token %s', token.id)
|
||||
session.delete(token)
|
||||
session.commit()
|
||||
|
||||
|
||||
def get_last_api_token() -> Type[ApiToken] | None:
|
||||
with Session(get_engine()) as session:
|
||||
return session.query(ApiToken).order_by(desc(ApiToken.id)).first()
|
||||
58
service/helper.py
Normal file
58
service/helper.py
Normal file
@@ -0,0 +1,58 @@
|
||||
import json
|
||||
from datetime import datetime, timedelta
|
||||
import logging as log
|
||||
|
||||
import requests
|
||||
from pyrate_limiter import Duration, Rate, Limiter, InMemoryBucket
|
||||
|
||||
from constants import api_url
|
||||
|
||||
|
||||
def get_tray_url(path):
|
||||
return f"{api_url}/{path}"
|
||||
|
||||
|
||||
def parse_date(str_date, str_format=None):
|
||||
if str_date == '0000-00-00' or str_date == '':
|
||||
return None
|
||||
else:
|
||||
try:
|
||||
return datetime.strptime(str_date, str_format if str_format is not None else '%Y-%m-%d').date()
|
||||
except Exception as e:
|
||||
log.error(e)
|
||||
return None
|
||||
|
||||
|
||||
def get_paged_data(path, data_key, limiter, max_pages=None, params=None):
|
||||
all_data = []
|
||||
current_page = 1
|
||||
|
||||
url = get_tray_url(path)
|
||||
|
||||
if params is None:
|
||||
params = {}
|
||||
|
||||
while True:
|
||||
limiter.try_acquire(url, weight=1)
|
||||
|
||||
params['page'] = current_page
|
||||
response = requests.get(url, params=params)
|
||||
response.raise_for_status()
|
||||
json_data = response.json()
|
||||
|
||||
if response.status_code in [200, 201]:
|
||||
all_data.extend(json_data[data_key])
|
||||
paging_info = json_data['paging']
|
||||
total_items = paging_info['total']
|
||||
|
||||
if max_pages is not None and max_pages <= current_page:
|
||||
log.debug('Reached max pages: %s', max_pages)
|
||||
break
|
||||
|
||||
if len(all_data) >= total_items:
|
||||
break
|
||||
|
||||
current_page = current_page + 1
|
||||
|
||||
log.debug('Total items fetched: %i', len(all_data))
|
||||
return all_data
|
||||
109
service/order_service.py
Normal file
109
service/order_service.py
Normal file
@@ -0,0 +1,109 @@
|
||||
from datetime import datetime
|
||||
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
|
||||
from db.helpers import get_engine
|
||||
from db.models import Order, OrderStatus, OrderProductsSold # , ProductsSold
|
||||
from service.helper import parse_date, get_paged_data
|
||||
|
||||
|
||||
class OrderService:
|
||||
session = None
|
||||
access_token = None
|
||||
limiter = None
|
||||
|
||||
def __init__(self, access_token, limiter):
|
||||
self.access_token = access_token
|
||||
Session = sessionmaker(bind=get_engine())
|
||||
self.session = Session()
|
||||
self.limiter = limiter
|
||||
|
||||
|
||||
def save_all_orders(self):
|
||||
params = {
|
||||
'access_token': self.access_token
|
||||
}
|
||||
json_orders = get_paged_data('orders', 'Orders', self.limiter, max_pages=None, params=params)
|
||||
self.save_orders(json_orders)
|
||||
|
||||
def parse_order(self, json_order):
|
||||
return Order(
|
||||
id=int(json_order['id']),
|
||||
status=json_order['status'],
|
||||
date=parse_date(json_order['date']),
|
||||
customer_id=int(json_order['customer_id']),
|
||||
partial_total=float(json_order['partial_total']),
|
||||
taxes=float(json_order['taxes']),
|
||||
discount=float(json_order['discount']),
|
||||
point_sale=json_order['point_sale'],
|
||||
shipment=json_order['shipment'],
|
||||
shipment_value=float(json_order['shipment_value']),
|
||||
shipment_date=parse_date(json_order['shipment_date']),
|
||||
store_note=json_order['store_note'],
|
||||
discount_coupon=json_order['discount_coupon'],
|
||||
payment_method_rate=float(json_order['payment_method_rate']),
|
||||
value_1=float(json_order['value_1']),
|
||||
payment_form=json_order['payment_form'],
|
||||
sending_code=json_order['sending_code'],
|
||||
session_id=json_order['session_id'],
|
||||
total=float(json_order['total']),
|
||||
payment_date=parse_date(json_order['payment_date']),
|
||||
access_code=json_order['access_code'],
|
||||
progressive_discount=float(json_order['progressive_discount']),
|
||||
shipping_progressive_discount=float(json_order['shipping_progressive_discount']),
|
||||
shipment_integrator=json_order['shipment_integrator'],
|
||||
modified=datetime.strptime(json_order['modified'], '%Y-%m-%d %H:%M:%S'),
|
||||
printed=bool(json_order['printed']),
|
||||
interest=float(json_order['interest']),
|
||||
cart_additional_values_discount=float(json_order['cart_additional_values_discount']),
|
||||
cart_additional_values_increase=float(json_order['cart_additional_values_increase']),
|
||||
id_quotation=json_order['id_quotation'],
|
||||
estimated_delivery_date=parse_date(json_order['estimated_delivery_date']),
|
||||
external_code=json_order['external_code'],
|
||||
tracking_url=json_order['tracking_url'],
|
||||
has_payment=bool(int(json_order['has_payment'])),
|
||||
has_shipment=bool(int(json_order['has_shipment'])),
|
||||
has_invoice=bool(int(json_order['has_invoice'])),
|
||||
total_comission_user=float(json_order['total_comission_user']),
|
||||
total_comission=float(json_order['total_comission']),
|
||||
is_traceable=bool(json_order['is_traceable']),
|
||||
order_status_id=int(json_order['OrderStatus']['id'])
|
||||
)
|
||||
|
||||
def parse_order_status(self, json_order_status):
|
||||
return OrderStatus(
|
||||
id=int(json_order_status['id']),
|
||||
default=bool(int(json_order_status['default'])),
|
||||
type=json_order_status['type'],
|
||||
show_backoffice=bool(int(json_order_status['show_backoffice'])),
|
||||
allow_edit_order=bool(int(json_order_status['allow_edit_order'])),
|
||||
status=json_order_status['status'],
|
||||
description=json_order_status['description'],
|
||||
background=json_order_status['background']
|
||||
)
|
||||
|
||||
def parse_order_products_sold(self, json_order_ps, order_id):
|
||||
return OrderProductsSold(
|
||||
order_id=order_id,
|
||||
products_sold_id=json_order_ps['id']
|
||||
)
|
||||
|
||||
def save_orders(self, orders):
|
||||
for json_order in orders:
|
||||
json_order = json_order['Order']
|
||||
|
||||
order = self.parse_order(json_order)
|
||||
|
||||
if 'OrderStatus' in json_order:
|
||||
json_order_status = json_order['OrderStatus']
|
||||
order_status = self.parse_order_status(json_order_status)
|
||||
self.session.merge(order_status)
|
||||
|
||||
if 'ProductsSold' in json_order:
|
||||
for json_ps in json_order['ProductsSold']:
|
||||
order_products_sold = self.parse_order_products_sold(json_ps, order.id)
|
||||
self.session.merge(order_products_sold)
|
||||
|
||||
self.session.merge(order)
|
||||
|
||||
self.session.commit()
|
||||
144
service/product_service.py
Normal file
144
service/product_service.py
Normal file
@@ -0,0 +1,144 @@
|
||||
from datetime import datetime
|
||||
|
||||
import requests
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
|
||||
from service.helper import get_tray_url, parse_date, get_paged_data
|
||||
from db.helpers import get_engine
|
||||
from db.models import Product, Category, ProductsSold
|
||||
|
||||
|
||||
class ProductService():
|
||||
access_token = None
|
||||
session = None
|
||||
limiter = None
|
||||
|
||||
def __init__(self, access_token, limiter):
|
||||
self.access_token = access_token
|
||||
Session = sessionmaker(bind=get_engine())
|
||||
self.session = Session()
|
||||
self.limiter = limiter
|
||||
|
||||
def save_all_products(self):
|
||||
params = {
|
||||
'access_token': self.access_token
|
||||
}
|
||||
json_products = get_paged_data('products', 'Products', self.limiter, max_pages=None, params=params)
|
||||
self.save_products(json_products)
|
||||
|
||||
def save_all_products_sold(self):
|
||||
params = {
|
||||
'access_token': self.access_token
|
||||
}
|
||||
json_products_sold = get_paged_data('products_solds', 'ProductsSolds', self.limiter, max_pages=None, params=params)
|
||||
self.save_products_sold(json_products_sold)
|
||||
|
||||
def save_all_categories(self):
|
||||
params = {
|
||||
'access_token': self.access_token
|
||||
}
|
||||
json_categories = get_paged_data('categories', 'Categories', self.limiter, max_pages=None, params=params)
|
||||
self.save_categories(json_categories)
|
||||
|
||||
def parse_product(self, json_product):
|
||||
return Product(
|
||||
id=int(json_product['id']),
|
||||
modified=datetime.strptime(json_product['modified'], '%Y-%m-%d %H:%M:%S'),
|
||||
ean=json_product['ean'],
|
||||
is_kit=bool(json_product['is_kit']),
|
||||
slug=json_product['slug'],
|
||||
ncm=json_product['ncm'],
|
||||
activation_date=parse_date(json_product['activation_date']),
|
||||
deactivation_date=parse_date(json_product['deactivation_date']),
|
||||
name=json_product['name'],
|
||||
price=float(json_product['price']),
|
||||
cost_price=float(json_product['cost_price']),
|
||||
dollar_cost_price=float(json_product['dollar_cost_price']),
|
||||
promotional_price=float(json_product['promotional_price']),
|
||||
start_promotion=parse_date(json_product['start_promotion']),
|
||||
end_promotion=parse_date(json_product['end_promotion']),
|
||||
brand=json_product['brand'],
|
||||
brand_id=json_product['brand_id'],
|
||||
model=json_product['model'],
|
||||
weight=float(json_product['weight']),
|
||||
length=float(json_product['length']),
|
||||
width=float(json_product['width']),
|
||||
height=float(json_product['height']),
|
||||
stock=int(json_product['stock']),
|
||||
category_id=int(json_product['category_id']),
|
||||
available=bool(json_product['available']),
|
||||
availability=str(json_product['availability']),
|
||||
reference=str(json_product['reference']),
|
||||
hot=bool(json_product['hot']),
|
||||
release=bool(json_product['release']),
|
||||
additional_button=bool(json_product['additional_button']),
|
||||
has_variation=bool(json_product['has_variation']),
|
||||
rating=float(json_product['rating']),
|
||||
count_rating=int(json_product['count_rating']),
|
||||
quantity_sold=int(json_product['quantity_sold']),
|
||||
url=json_product['url'],
|
||||
created=datetime.strptime(json_product['created'], '%Y-%m-%d %H:%M:%S'),
|
||||
payment_option=str(json_product['payment_option']),
|
||||
payment_option_details=json_product['payment_option_details'],
|
||||
related_categories=json_product['related_categories'],
|
||||
release_date=parse_date(json_product['release_date']),
|
||||
shortcut=json_product['shortcut'],
|
||||
virtual_product=bool(json_product['virtual_product']),
|
||||
minimum_stock=int(json_product['minimum_stock']),
|
||||
minimum_stock_alert=bool(int(json_product['minimum_stock_alert'])),
|
||||
free_shipping=bool(json_product['free_shipping']),
|
||||
video=json_product['video'],
|
||||
metatag=json_product['metatag'],
|
||||
payment_option_html=json_product['payment_option_html'],
|
||||
upon_request=bool(json_product['upon_request']),
|
||||
available_for_purchase=bool(json_product['available_for_purchase']),
|
||||
# all_categories=json_product['all_categories'], #Todo
|
||||
all_categories=None,
|
||||
product_image=json_product['product_image'] if 'product_image' in json_product else None,
|
||||
variant=json_product['variant'] if 'variant' in json_product else None,
|
||||
additional_infos=json_product['additional_infos'] if 'additional_infos' in json_product else None,
|
||||
)
|
||||
|
||||
def parse_category(self, json_category):
|
||||
return Category(
|
||||
id=int(json_category['id']),
|
||||
parent_id=int(json_category['parent_id']) if json_category['parent_id'] in json_category else None,
|
||||
name=json_category['name'],
|
||||
small_description=json_category['small_description'],
|
||||
images=json_category['Images']
|
||||
)
|
||||
|
||||
def parse_products_sold(self, json_products_sold):
|
||||
return ProductsSold(
|
||||
id=int(json_products_sold['id']),
|
||||
product_id=int(json_products_sold['product_id']),
|
||||
order_id=int(json_products_sold['order_id']),
|
||||
name=json_products_sold['name'],
|
||||
price=float(json_products_sold['price']),
|
||||
original_price=float(json_products_sold['original_price']),
|
||||
quantity=int(json_products_sold['quantity']),
|
||||
model=json_products_sold['model'],
|
||||
reference=json_products_sold['reference'],
|
||||
variant_id=int(json_products_sold['variant_id']),
|
||||
additional_information=json_products_sold['additional_information'],
|
||||
)
|
||||
|
||||
def save_products_sold(self, json_products_sold):
|
||||
for json_ps in json_products_sold:
|
||||
products_sold = self.parse_products_sold(json_ps['ProductsSold'])
|
||||
self.session.merge(products_sold)
|
||||
self.session.commit()
|
||||
|
||||
def save_categories(self, json_categories):
|
||||
for json_category in json_categories:
|
||||
category = self.parse_category(json_category['Category'])
|
||||
self.session.merge(category)
|
||||
|
||||
self.session.commit()
|
||||
|
||||
def save_products(self, json_products):
|
||||
for json_product in json_products:
|
||||
product = self.parse_product(json_product['Product'])
|
||||
self.session.merge(product)
|
||||
|
||||
self.session.commit()
|
||||
Reference in New Issue
Block a user