ebanutsya
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -5,3 +5,4 @@ __pycache__/
|
||||
.git/
|
||||
.env
|
||||
test.*
|
||||
test/
|
||||
|
||||
10
app.py
10
app.py
@@ -1,4 +1,4 @@
|
||||
from flask import Flask
|
||||
from flask import Flask, request
|
||||
from flask_cors import CORS
|
||||
from flask_jwt_extended import JWTManager
|
||||
from flask_migrate import Migrate
|
||||
@@ -23,9 +23,15 @@ server_session = Session(app)
|
||||
CORS(app, supports_credentials=True)
|
||||
jwt = JWTManager(app)
|
||||
blueprints = [
|
||||
(routes.auth_blueprint, '/auth')
|
||||
(routes.auth_blueprint, '/auth'),
|
||||
(routes.orders_blueprint, '/orders'),
|
||||
(routes.barcode_blueprint, '/barcode'),
|
||||
]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
for blueprint, url_prefix in blueprints:
|
||||
app.register_blueprint(blueprint, url_prefix=url_prefix)
|
||||
|
||||
|
||||
12
assemblr.log
Normal file
12
assemblr.log
Normal file
@@ -0,0 +1,12 @@
|
||||
10-15 00:21 - assemblr - INFO - SiproClient successfully initialized
|
||||
10-15 00:31 - assemblr - INFO - SiproClient successfully initialized
|
||||
10-15 00:31 - assemblr - INFO - SiproClient successfully initialized
|
||||
10-15 00:31 - assemblr - INFO - SiproClient successfully initialized
|
||||
10-15 00:31 - assemblr - INFO - SiproClient successfully initialized
|
||||
10-27 03:01 - assemblr - INFO - SiproClient successfully initialized
|
||||
10-27 04:50 - assemblr - INFO - SiproClient successfully initialized
|
||||
10-27 04:51 - assemblr - INFO - SiproClient successfully initialized
|
||||
10-27 05:36 - assemblr - INFO - SiproClient successfully initialized
|
||||
10-27 05:37 - assemblr - INFO - SiproClient successfully initialized
|
||||
10-27 05:38 - assemblr - INFO - SiproClient successfully initialized
|
||||
10-27 05:57 - assemblr - INFO - SiproClient successfully initialized
|
||||
@@ -17,5 +17,5 @@ class FlaskConfig:
|
||||
SESSION_PERMANENT = False
|
||||
SESSION_USE_SIGNER = True
|
||||
SESSION_REDIS = redis.from_url('redis://127.0.0.1:6379')
|
||||
|
||||
JWT_ACCESS_TOKEN_EXPIRES = 86400
|
||||
# SQLALCHEMY_ECHO = True
|
||||
|
||||
9
constants.py
Normal file
9
constants.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from pathlib import Path
|
||||
import os
|
||||
import sys
|
||||
|
||||
APP_PATH = os.path.dirname(sys.executable) if getattr(sys, 'frozen', False) else os.path.dirname(__file__)
|
||||
|
||||
LOGGER_NAME = 'assemblr'
|
||||
LOG_FILE = Path(APP_PATH) / Path(f'{LOGGER_NAME}.log')
|
||||
MAX_LOG_FILE_SIZE_BYTES = 400 * 1024 ** 2
|
||||
@@ -13,6 +13,20 @@ class User(db.Model):
|
||||
sipro_id = db.Column(db.Integer, nullable=True, comment='ID пользователя в SIPRO')
|
||||
|
||||
|
||||
class Assembly(db.Model):
|
||||
__tablename__ = 'assemblies'
|
||||
id = db.Column(db.Integer, primary_key=True, comment='ID сборки')
|
||||
|
||||
created_at = db.Column(db.DateTime, nullable=False, comment='Дата и время начала сборки')
|
||||
ended_at = db.Column(db.DateTime, nullable=False, comment='Дата и время конца сборки')
|
||||
|
||||
user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
|
||||
user = db.relationship('User', backref='assemblies')
|
||||
|
||||
order_id = db.Column(db.Integer, nullable=False, comment='ID заказа в базе данных')
|
||||
|
||||
|
||||
|
||||
class Barcode(db.Model):
|
||||
__tablename__ = 'barcodes'
|
||||
id = db.Column(db.Integer, primary_key=True, comment='ID пользователя')
|
||||
|
||||
34
logger.py
Normal file
34
logger.py
Normal file
@@ -0,0 +1,34 @@
|
||||
from logging.handlers import RotatingFileHandler
|
||||
from singleton import Singleton
|
||||
|
||||
import logging
|
||||
import constants
|
||||
|
||||
|
||||
class Logger(metaclass=Singleton):
|
||||
def __init__(self):
|
||||
self.logger = logging.getLogger(constants.LOGGER_NAME)
|
||||
self.logger.setLevel(logging.DEBUG)
|
||||
|
||||
file_handler = RotatingFileHandler(constants.LOG_FILE,
|
||||
maxBytes=constants.MAX_LOG_FILE_SIZE_BYTES,
|
||||
encoding='UTF-8',
|
||||
backupCount=1)
|
||||
file_handler.setLevel(logging.DEBUG)
|
||||
|
||||
console_handler = logging.StreamHandler()
|
||||
console_handler.setLevel(logging.INFO)
|
||||
|
||||
formatter = logging.Formatter(fmt='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
||||
datefmt='%m-%d %H:%M')
|
||||
file_handler.setFormatter(formatter)
|
||||
console_handler.setFormatter(formatter)
|
||||
|
||||
self.logger.addHandler(file_handler)
|
||||
self.logger.addHandler(console_handler)
|
||||
|
||||
def get_logger(self):
|
||||
return self.logger
|
||||
|
||||
|
||||
logger_instance = Logger().get_logger()
|
||||
@@ -1 +1,3 @@
|
||||
from routes.auth import auth_blueprint
|
||||
from routes.orders import orders_blueprint
|
||||
from routes.barcode import barcode_blueprint
|
||||
|
||||
@@ -29,16 +29,9 @@ def login_endpoint():
|
||||
login = data.get('login')
|
||||
user = User.query.filter_by(login=login).first()
|
||||
if not user:
|
||||
return jsonify(ok=False), 401
|
||||
return jsonify(ok=False, accessToken=''), 401
|
||||
password = data.get('password')
|
||||
if not check_password_hash(user.password_hash, password):
|
||||
return jsonify(ok=False), 401
|
||||
return jsonify(ok=False, accessToken=''), 401
|
||||
access_token = create_access_token(identity=user.id)
|
||||
return jsonify(access_token=access_token)
|
||||
|
||||
|
||||
@auth_blueprint.get('/protected')
|
||||
@jwt_required()
|
||||
def protected_endpoint():
|
||||
print(type(get_jwt_identity()))
|
||||
return 'test'
|
||||
return jsonify(ok=True, accessToken=access_token)
|
||||
|
||||
12
routes/barcode.py
Normal file
12
routes/barcode.py
Normal file
@@ -0,0 +1,12 @@
|
||||
from flask import Blueprint, jsonify, request
|
||||
from routes.utils import jwt_protect_blueprint
|
||||
import sipro.api.barcode
|
||||
|
||||
barcode_blueprint = jwt_protect_blueprint(Blueprint('barcode', __name__))
|
||||
|
||||
|
||||
@barcode_blueprint.get('/searchProducts')
|
||||
def search_product():
|
||||
args = request.args
|
||||
barcode = args.get('barcode')
|
||||
return sipro.api.barcode.get_products_by_barcode(barcode)
|
||||
17
routes/orders.py
Normal file
17
routes/orders.py
Normal file
@@ -0,0 +1,17 @@
|
||||
from flask import Blueprint, jsonify, request
|
||||
from routes.utils import jwt_protect_blueprint
|
||||
import sipro.api.orders
|
||||
|
||||
orders_blueprint = jwt_protect_blueprint(Blueprint('orders', __name__))
|
||||
|
||||
|
||||
@orders_blueprint.get('/<int:order_id>')
|
||||
def get_order(order_id: int):
|
||||
return jsonify(id=order_id)
|
||||
|
||||
|
||||
@orders_blueprint.get('/getBySupplierProductId')
|
||||
def get_orders_by_supplier_product_id():
|
||||
args = request.args
|
||||
supplier_product_id = args.get('supplierProductId')
|
||||
return sipro.api.orders.get_orders_by_supplier_product_id(supplier_product_id)
|
||||
12
routes/utils.py
Normal file
12
routes/utils.py
Normal file
@@ -0,0 +1,12 @@
|
||||
from functools import wraps
|
||||
|
||||
from flask import Blueprint
|
||||
from flask_jwt_extended import verify_jwt_in_request
|
||||
|
||||
|
||||
def jwt_protect_blueprint(blueprint) -> Blueprint:
|
||||
@blueprint.before_request
|
||||
def require_token():
|
||||
verify_jwt_in_request()
|
||||
|
||||
return blueprint
|
||||
@@ -19,3 +19,7 @@ MY_HOST = os.environ.get('MY_HOST')
|
||||
|
||||
# Flask settings
|
||||
SECRET_KEY = os.environ.get('SECRET_KEY')
|
||||
|
||||
# Sipro settings
|
||||
SIPRO_API_URL = os.environ.get('SIPRO_API_URL')
|
||||
SIPRO_API_TOKEN = os.environ.get('SIPRO_API_TOKEN')
|
||||
|
||||
7
singleton.py
Normal file
7
singleton.py
Normal file
@@ -0,0 +1,7 @@
|
||||
class Singleton(type):
|
||||
_instances = {}
|
||||
|
||||
def __call__(cls, *args, **kwargs):
|
||||
if cls not in cls._instances:
|
||||
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
|
||||
return cls._instances[cls]
|
||||
1
sipro/__init__.py
Normal file
1
sipro/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from sipro import api
|
||||
0
sipro/api/__init__.py
Normal file
0
sipro/api/__init__.py
Normal file
10
sipro/api/barcode.py
Normal file
10
sipro/api/barcode.py
Normal file
@@ -0,0 +1,10 @@
|
||||
from sipro.api.client import get_client
|
||||
|
||||
client = get_client()
|
||||
router = '/barcode'
|
||||
|
||||
|
||||
def get_products_by_barcode(barcode: str) -> list[dict]:
|
||||
method = f'{router}/getProducts?barcode={barcode}'
|
||||
response = client.method('GET', method)
|
||||
return response
|
||||
39
sipro/api/client.py
Normal file
39
sipro/api/client.py
Normal file
@@ -0,0 +1,39 @@
|
||||
import requests
|
||||
|
||||
import settings
|
||||
from logger import logger_instance
|
||||
|
||||
|
||||
class SiproClient:
|
||||
_instance = None
|
||||
|
||||
def __new__(cls, *args, **kwargs):
|
||||
if not cls._instance:
|
||||
cls._instance = super(SiproClient, cls).__new__(cls)
|
||||
return cls._instance
|
||||
|
||||
def __init__(self, api_url: str, token: str):
|
||||
if not hasattr(self, 'initialized'):
|
||||
self.api_url = api_url
|
||||
self.token = token
|
||||
self.initialized = True
|
||||
logger_instance.info('SiproClient successfully initialized')
|
||||
|
||||
def method(self, http_method: str, method: str, data: dict = None):
|
||||
url = self.api_url + '/assemblr' + method
|
||||
headers = {'Authorization': self.token}
|
||||
return requests.request(http_method, url, headers=headers, json=data).json()
|
||||
|
||||
def ping(self) -> str:
|
||||
return self.method('GET', '/ping').get('response')
|
||||
|
||||
|
||||
sipro_config = {
|
||||
'api_url': settings.SIPRO_API_URL,
|
||||
'token': settings.SIPRO_API_TOKEN,
|
||||
}
|
||||
sipro_client = SiproClient(**sipro_config)
|
||||
|
||||
|
||||
def get_client() -> SiproClient:
|
||||
return sipro_client
|
||||
10
sipro/api/orders.py
Normal file
10
sipro/api/orders.py
Normal file
@@ -0,0 +1,10 @@
|
||||
from sipro.api.client import get_client
|
||||
|
||||
client = get_client()
|
||||
router = '/orders'
|
||||
|
||||
|
||||
def get_orders_by_supplier_product_id(supplier_product_id: str) -> list[dict]:
|
||||
method = f'{router}/getBySupplierProductId?supplierProductId={supplier_product_id}'
|
||||
response = client.method('GET', method)
|
||||
return response
|
||||
Reference in New Issue
Block a user