import atexit import logging import httpx from flask import Flask, jsonify from dotenv import load_dotenv from werkzeug.middleware.proxy_fix import ProxyFix from .binding import BindingService, SiteBindingRepository from .bitrix import BitrixAuthError, BitrixClient from .config import SiteConfig from .crypto import TokenCipher from .database import SiteDatabase from .routes import SiteInputError, create_blueprint logger = logging.getLogger(__name__) def create_app() -> Flask: load_dotenv() logging.getLogger("httpx").setLevel(logging.WARNING) logging.getLogger("httpcore").setLevel(logging.WARNING) config = SiteConfig.from_env() app = Flask(__name__) app.config["PUBLIC_BASE_URL"] = config.public_base_url if config.trust_proxy: # Используется конфигурация, при которой снаружи контейнера находится # обратный прокси nginx. app.wsgi_app = ProxyFix( app.wsgi_app, x_for=1, x_proto=1, x_host=1, ) database = SiteDatabase(config.database_url) database.open() bitrix = BitrixClient( config.bitrix_client_id, config.bitrix_client_secret, config.oauth_token_url, ) bindings = BindingService( SiteBindingRepository(database), TokenCipher(config.token_encryption_key), config.bot_username, config.binding_ttl_seconds, ) app.extensions["database"] = database app.register_blueprint(create_blueprint(bindings, bitrix)) atexit.register(database.close) atexit.register(bitrix.close) @app.errorhandler(SiteInputError) def input_error(error: SiteInputError): return jsonify(error=str(error)), 400 @app.errorhandler(BitrixAuthError) def auth_error(error: BitrixAuthError): return jsonify(error=str(error)), 403 @app.errorhandler(httpx.HTTPError) def bitrix_error(error: httpx.HTTPError): logger.exception("Bitrix request failed") return jsonify(error="Не удалось проверить пользователя Bitrix24"), 502 return app