| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247 | from typing import Any, Optionalfrom urllib.parse import quote_plusfrom pydantic import Field, NonNegativeInt, PositiveFloat, PositiveInt, computed_fieldfrom pydantic_settings import BaseSettingsfrom configs.middleware.cache.redis_config import RedisConfigfrom configs.middleware.storage.aliyun_oss_storage_config import AliyunOSSStorageConfigfrom configs.middleware.storage.amazon_s3_storage_config import S3StorageConfigfrom configs.middleware.storage.azure_blob_storage_config import AzureBlobStorageConfigfrom configs.middleware.storage.baidu_obs_storage_config import BaiduOBSStorageConfigfrom configs.middleware.storage.google_cloud_storage_config import GoogleCloudStorageConfigfrom configs.middleware.storage.huawei_obs_storage_config import HuaweiCloudOBSStorageConfigfrom configs.middleware.storage.oci_storage_config import OCIStorageConfigfrom configs.middleware.storage.supabase_storage_config import SupabaseStorageConfigfrom configs.middleware.storage.tencent_cos_storage_config import TencentCloudCOSStorageConfigfrom configs.middleware.storage.volcengine_tos_storage_config import VolcengineTOSStorageConfigfrom configs.middleware.vdb.analyticdb_config import AnalyticdbConfigfrom configs.middleware.vdb.chroma_config import ChromaConfigfrom configs.middleware.vdb.elasticsearch_config import ElasticsearchConfigfrom configs.middleware.vdb.milvus_config import MilvusConfigfrom configs.middleware.vdb.myscale_config import MyScaleConfigfrom configs.middleware.vdb.opensearch_config import OpenSearchConfigfrom configs.middleware.vdb.oracle_config import OracleConfigfrom configs.middleware.vdb.pgvector_config import PGVectorConfigfrom configs.middleware.vdb.pgvectors_config import PGVectoRSConfigfrom configs.middleware.vdb.qdrant_config import QdrantConfigfrom configs.middleware.vdb.relyt_config import RelytConfigfrom configs.middleware.vdb.tencent_vector_config import TencentVectorDBConfigfrom configs.middleware.vdb.tidb_vector_config import TiDBVectorConfigfrom configs.middleware.vdb.weaviate_config import WeaviateConfigclass StorageConfig(BaseSettings):    STORAGE_TYPE: str = Field(        description="Type of storage to use."        " Options: 'local', 's3', 'azure-blob', 'aliyun-oss', 'google-storage'. Default is 'local'.",        default="local",    )    STORAGE_LOCAL_PATH: str = Field(        description="Path for local storage when STORAGE_TYPE is set to 'local'.",        default="storage",    )class VectorStoreConfig(BaseSettings):    VECTOR_STORE: Optional[str] = Field(        description="Type of vector store to use for efficient similarity search."        " Set to None if not using a vector store.",        default=None,    )class KeywordStoreConfig(BaseSettings):    KEYWORD_STORE: str = Field(        description="Method for keyword extraction and storage."        " Default is 'jieba', a Chinese text segmentation library.",        default="jieba",    )class DatabaseConfig:    DB_HOST: str = Field(        description="Hostname or IP address of the database server.",        default="localhost",    )    DB_PORT: PositiveInt = Field(        description="Port number for database connection.",        default=5432,    )    DB_USERNAME: str = Field(        description="Username for database authentication.",        default="postgres",    )    DB_PASSWORD: str = Field(        description="Password for database authentication.",        default="",    )    DB_DATABASE: str = Field(        description="Name of the database to connect to.",        default="dify",    )    DB_CHARSET: str = Field(        description="Character set for database connection.",        default="",    )    DB_EXTRAS: str = Field(        description="Additional database connection parameters. Example: 'keepalives_idle=60&keepalives=1'",        default="",    )    SQLALCHEMY_DATABASE_URI_SCHEME: str = Field(        description="Database URI scheme for SQLAlchemy connection.",        default="postgresql",    )    @computed_field    @property    def SQLALCHEMY_DATABASE_URI(self) -> str:        db_extras = (            f"{self.DB_EXTRAS}&client_encoding={self.DB_CHARSET}" if self.DB_CHARSET else self.DB_EXTRAS        ).strip("&")        db_extras = f"?{db_extras}" if db_extras else ""        return (            f"{self.SQLALCHEMY_DATABASE_URI_SCHEME}://"            f"{quote_plus(self.DB_USERNAME)}:{quote_plus(self.DB_PASSWORD)}@{self.DB_HOST}:{self.DB_PORT}/{self.DB_DATABASE}"            f"{db_extras}"        )    SQLALCHEMY_POOL_SIZE: NonNegativeInt = Field(        description="Maximum number of database connections in the pool.",        default=30,    )    SQLALCHEMY_MAX_OVERFLOW: NonNegativeInt = Field(        description="Maximum number of connections that can be created beyond the pool_size.",        default=10,    )    SQLALCHEMY_POOL_RECYCLE: NonNegativeInt = Field(        description="Number of seconds after which a connection is automatically recycled.",        default=3600,    )    SQLALCHEMY_POOL_PRE_PING: bool = Field(        description="If True, enables connection pool pre-ping feature to check connections.",        default=False,    )    SQLALCHEMY_ECHO: bool | str = Field(        description="If True, SQLAlchemy will log all SQL statements.",        default=False,    )    @computed_field    @property    def SQLALCHEMY_ENGINE_OPTIONS(self) -> dict[str, Any]:        return {            "pool_size": self.SQLALCHEMY_POOL_SIZE,            "max_overflow": self.SQLALCHEMY_MAX_OVERFLOW,            "pool_recycle": self.SQLALCHEMY_POOL_RECYCLE,            "pool_pre_ping": self.SQLALCHEMY_POOL_PRE_PING,            "connect_args": {"options": "-c timezone=UTC"},        }class CeleryConfig(DatabaseConfig):    CELERY_BACKEND: str = Field(        description="Backend for Celery task results. Options: 'database', 'redis'.",        default="database",    )    CELERY_BROKER_URL: Optional[str] = Field(        description="URL of the message broker for Celery tasks.",        default=None,    )    CELERY_USE_SENTINEL: Optional[bool] = Field(        description="Whether to use Redis Sentinel for high availability.",        default=False,    )    CELERY_SENTINEL_MASTER_NAME: Optional[str] = Field(        description="Name of the Redis Sentinel master.",        default=None,    )    CELERY_SENTINEL_SOCKET_TIMEOUT: Optional[PositiveFloat] = Field(        description="Timeout for Redis Sentinel socket operations in seconds.",        default=0.1,    )    @computed_field    @property    def CELERY_RESULT_BACKEND(self) -> str | None:        return (            "db+{}".format(self.SQLALCHEMY_DATABASE_URI)            if self.CELERY_BACKEND == "database"            else self.CELERY_BROKER_URL        )    @computed_field    @property    def BROKER_USE_SSL(self) -> bool:        return self.CELERY_BROKER_URL.startswith("rediss://") if self.CELERY_BROKER_URL else Falseclass InternalTestConfig(BaseSettings):    """    Configuration settings for Internal Test    """    AWS_SECRET_ACCESS_KEY: Optional[str] = Field(        description="Internal test AWS secret access key",        default=None,    )    AWS_ACCESS_KEY_ID: Optional[str] = Field(        description="Internal test AWS access key ID",        default=None,    )class MiddlewareConfig(    # place the configs in alphabet order    CeleryConfig,    DatabaseConfig,    KeywordStoreConfig,    RedisConfig,    # configs of storage and storage providers    StorageConfig,    AliyunOSSStorageConfig,    AzureBlobStorageConfig,    BaiduOBSStorageConfig,    GoogleCloudStorageConfig,    HuaweiCloudOBSStorageConfig,    OCIStorageConfig,    S3StorageConfig,    SupabaseStorageConfig,    TencentCloudCOSStorageConfig,    VolcengineTOSStorageConfig,    # configs of vdb and vdb providers    VectorStoreConfig,    AnalyticdbConfig,    ChromaConfig,    MilvusConfig,    MyScaleConfig,    OpenSearchConfig,    OracleConfig,    PGVectorConfig,    PGVectoRSConfig,    QdrantConfig,    RelytConfig,    TencentVectorDBConfig,    TiDBVectorConfig,    WeaviateConfig,    ElasticsearchConfig,    InternalTestConfig,):    pass
 |