| import os |
|
|
| if os.environ.get("DEBUG", "false").lower() != "true": |
| from gevent import monkey |
|
|
| monkey.patch_all() |
|
|
| import grpc.experimental.gevent |
|
|
| grpc.experimental.gevent.init_gevent() |
|
|
| import json |
|
|
| from flask import Flask, Response, request |
| from flask_cors import CORS |
| from werkzeug.exceptions import Unauthorized |
|
|
| import contexts |
| from commands import register_commands |
| from configs import dify_config |
| from extensions import ( |
| ext_celery, |
| ext_code_based_extension, |
| ext_compress, |
| ext_database, |
| ext_hosting_provider, |
| ext_logging, |
| ext_login, |
| ext_mail, |
| ext_migrate, |
| ext_proxy_fix, |
| ext_redis, |
| ext_sentry, |
| ext_storage, |
| ) |
| from extensions.ext_database import db |
| from extensions.ext_login import login_manager |
| from libs.passport import PassportService |
| from services.account_service import AccountService |
| from flask_migrate import Migrate |
|
|
|
|
| class DifyApp(Flask): |
| pass |
|
|
|
|
| |
| |
| |
| def create_flask_app_with_configs() -> Flask: |
| """ |
| create a raw flask app |
| with configs loaded from .env file |
| """ |
| dify_app = DifyApp(__name__) |
| dify_app.config.from_mapping(dify_config.model_dump()) |
|
|
| |
| for key, value in dify_app.config.items(): |
| if isinstance(value, str): |
| os.environ[key] = value |
| elif isinstance(value, int | float | bool): |
| os.environ[key] = str(value) |
| elif value is None: |
| os.environ[key] = "" |
|
|
| return dify_app |
|
|
|
|
| def create_app() -> Flask: |
| app = create_flask_app_with_configs() |
| app.secret_key = dify_config.SECRET_KEY |
| initialize_extensions(app) |
| register_blueprints(app) |
| register_commands(app) |
|
|
| return app |
|
|
|
|
| def initialize_extensions(app): |
| |
| |
| ext_logging.init_app(app) |
| ext_compress.init_app(app) |
| ext_code_based_extension.init() |
| ext_database.init_app(app) |
| ext_migrate.init(app, ext_database.db) |
| ext_redis.init_app(app) |
| ext_storage.init_app(app) |
| ext_celery.init_app(app) |
| ext_login.init_app(app) |
| ext_mail.init_app(app) |
| ext_hosting_provider.init_app(app) |
| ext_sentry.init_app(app) |
| ext_proxy_fix.init_app(app) |
|
|
|
|
| |
| @login_manager.request_loader |
| def load_user_from_request(request_from_flask_login): |
| """Load user based on the request.""" |
| if request.blueprint not in {"console", "inner_api"}: |
| return None |
| |
| auth_header = request.headers.get("Authorization", "") |
| if not auth_header: |
| auth_token = request.args.get("_token") |
| if not auth_token: |
| raise Unauthorized("Invalid Authorization token.") |
| else: |
| if " " not in auth_header: |
| raise Unauthorized("Invalid Authorization header format. Expected 'Bearer <api-key>' format.") |
| auth_scheme, auth_token = auth_header.split(None, 1) |
| auth_scheme = auth_scheme.lower() |
| if auth_scheme != "bearer": |
| raise Unauthorized("Invalid Authorization header format. Expected 'Bearer <api-key>' format.") |
|
|
| decoded = PassportService().verify(auth_token) |
| user_id = decoded.get("user_id") |
|
|
| logged_in_account = AccountService.load_logged_in_account(account_id=user_id) |
| if logged_in_account: |
| contexts.tenant_id.set(logged_in_account.current_tenant_id) |
| return logged_in_account |
|
|
|
|
| @login_manager.unauthorized_handler |
| def unauthorized_handler(): |
| """Handle unauthorized requests.""" |
| return Response( |
| json.dumps({"code": "unauthorized", "message": "Unauthorized."}), |
| status=401, |
| content_type="application/json", |
| ) |
|
|
|
|
| |
| def register_blueprints(app): |
| from controllers.console import bp as console_app_bp |
| from controllers.files import bp as files_bp |
| from controllers.inner_api import bp as inner_api_bp |
| from controllers.service_api import bp as service_api_bp |
| from controllers.web import bp as web_bp |
|
|
| CORS( |
| service_api_bp, |
| allow_headers=["Content-Type", "Authorization", "X-App-Code"], |
| methods=["GET", "PUT", "POST", "DELETE", "OPTIONS", "PATCH"], |
| ) |
| app.register_blueprint(service_api_bp) |
|
|
| CORS( |
| web_bp, |
| resources={r"/*": {"origins": dify_config.WEB_API_CORS_ALLOW_ORIGINS}}, |
| supports_credentials=True, |
| allow_headers=["Content-Type", "Authorization", "X-App-Code"], |
| methods=["GET", "PUT", "POST", "DELETE", "OPTIONS", "PATCH"], |
| expose_headers=["X-Version", "X-Env"], |
| ) |
|
|
| app.register_blueprint(web_bp) |
|
|
| CORS( |
| console_app_bp, |
| resources={r"/*": {"origins": dify_config.CONSOLE_CORS_ALLOW_ORIGINS}}, |
| supports_credentials=True, |
| allow_headers=["Content-Type", "Authorization"], |
| methods=["GET", "PUT", "POST", "DELETE", "OPTIONS", "PATCH"], |
| expose_headers=["X-Version", "X-Env"], |
| ) |
|
|
| app.register_blueprint(console_app_bp) |
|
|
| CORS(files_bp, allow_headers=["Content-Type"], methods=["GET", "PUT", "POST", "DELETE", "OPTIONS", "PATCH"]) |
| app.register_blueprint(files_bp) |
|
|
| app.register_blueprint(inner_api_bp) |
|
|