diff --git a/api/configs/__init__.py b/api/configs/__init__.py index 47dcedcb85..c0e28c34e1 100644 --- a/api/configs/__init__.py +++ b/api/configs/__init__.py @@ -1,4 +1,3 @@ - from .app_config import DifyConfig dify_config = DifyConfig() \ No newline at end of file diff --git a/api/configs/app_config.py b/api/configs/app_config.py index 38921affd9..d1099a9036 100644 --- a/api/configs/app_config.py +++ b/api/configs/app_config.py @@ -1,5 +1,5 @@ -from pydantic import computed_field -from pydantic_settings import BaseSettings, SettingsConfigDict +from pydantic import Field, computed_field +from pydantic_settings import SettingsConfigDict from configs.deploy import DeploymentConfig from configs.enterprise import EnterpriseFeatureConfig @@ -9,13 +9,7 @@ from configs.middleware import MiddlewareConfig from configs.packaging import PackagingInfo -# TODO: Both `BaseModel` and `BaseSettings` has `model_config` attribute but they are in different types. -# This inheritance is depends on the order of the classes. -# It is better to use `BaseSettings` as the base class. class DifyConfig( - # based on pydantic-settings - BaseSettings, - # Packaging info PackagingInfo, @@ -35,11 +29,13 @@ class DifyConfig( # **Before using, please contact business@dify.ai by email to inquire about licensing matters.** EnterpriseFeatureConfig, ): + DEBUG: bool = Field(default=False, description='whether to enable debug mode.') model_config = SettingsConfigDict( # read from dotenv format config file env_file='.env', env_file_encoding='utf-8', + frozen=True, # ignore extra attributes extra='ignore', diff --git a/api/configs/deploy/__init__.py b/api/configs/deploy/__init__.py index a4e042a34a..219b315784 100644 --- a/api/configs/deploy/__init__.py +++ b/api/configs/deploy/__init__.py @@ -1,7 +1,8 @@ -from pydantic import BaseModel, Field +from pydantic import Field +from pydantic_settings import BaseSettings -class DeploymentConfig(BaseModel): +class DeploymentConfig(BaseSettings): """ Deployment configs """ diff --git a/api/configs/enterprise/__init__.py b/api/configs/enterprise/__init__.py index 39983036eb..b5d884e10e 100644 --- a/api/configs/enterprise/__init__.py +++ b/api/configs/enterprise/__init__.py @@ -1,7 +1,8 @@ -from pydantic import BaseModel, Field +from pydantic import Field +from pydantic_settings import BaseSettings -class EnterpriseFeatureConfig(BaseModel): +class EnterpriseFeatureConfig(BaseSettings): """ Enterprise feature configs. **Before using, please contact business@dify.ai by email to inquire about licensing matters.** diff --git a/api/configs/extra/__init__.py b/api/configs/extra/__init__.py index 358c12d63a..4543b5389d 100644 --- a/api/configs/extra/__init__.py +++ b/api/configs/extra/__init__.py @@ -1,5 +1,3 @@ -from pydantic import BaseModel - from configs.extra.notion_config import NotionConfig from configs.extra.sentry_config import SentryConfig diff --git a/api/configs/extra/notion_config.py b/api/configs/extra/notion_config.py index f8df28cefd..b77e8adaae 100644 --- a/api/configs/extra/notion_config.py +++ b/api/configs/extra/notion_config.py @@ -1,9 +1,10 @@ from typing import Optional -from pydantic import BaseModel, Field +from pydantic import Field +from pydantic_settings import BaseSettings -class NotionConfig(BaseModel): +class NotionConfig(BaseSettings): """ Notion integration configs """ diff --git a/api/configs/extra/sentry_config.py b/api/configs/extra/sentry_config.py index 8cdb8cf45a..e6517f730a 100644 --- a/api/configs/extra/sentry_config.py +++ b/api/configs/extra/sentry_config.py @@ -1,9 +1,10 @@ from typing import Optional -from pydantic import BaseModel, Field, NonNegativeFloat +from pydantic import Field, NonNegativeFloat +from pydantic_settings import BaseSettings -class SentryConfig(BaseModel): +class SentryConfig(BaseSettings): """ Sentry configs """ diff --git a/api/configs/feature/__init__.py b/api/configs/feature/__init__.py index 7c86df0507..bd0ef983c4 100644 --- a/api/configs/feature/__init__.py +++ b/api/configs/feature/__init__.py @@ -1,11 +1,12 @@ from typing import Optional -from pydantic import AliasChoices, BaseModel, Field, NonNegativeInt, PositiveInt, computed_field +from pydantic import AliasChoices, Field, NonNegativeInt, PositiveInt, computed_field +from pydantic_settings import BaseSettings from configs.feature.hosted_service import HostedServiceConfig -class SecurityConfig(BaseModel): +class SecurityConfig(BaseSettings): """ Secret Key configs """ @@ -22,7 +23,7 @@ class SecurityConfig(BaseModel): default=24, ) -class AppExecutionConfig(BaseModel): +class AppExecutionConfig(BaseSettings): """ App Execution configs """ @@ -32,7 +33,7 @@ class AppExecutionConfig(BaseModel): ) -class CodeExecutionSandboxConfig(BaseModel): +class CodeExecutionSandboxConfig(BaseSettings): """ Code Execution Sandbox configs """ @@ -47,7 +48,7 @@ class CodeExecutionSandboxConfig(BaseModel): ) -class EndpointConfig(BaseModel): +class EndpointConfig(BaseSettings): """ Module URL configs """ @@ -76,7 +77,7 @@ class EndpointConfig(BaseModel): ) -class FileAccessConfig(BaseModel): +class FileAccessConfig(BaseSettings): """ File Access configs """ @@ -95,7 +96,7 @@ class FileAccessConfig(BaseModel): ) -class FileUploadConfig(BaseModel): +class FileUploadConfig(BaseSettings): """ File Uploading configs """ @@ -120,7 +121,7 @@ class FileUploadConfig(BaseModel): ) -class HttpConfig(BaseModel): +class HttpConfig(BaseSettings): """ HTTP configs """ @@ -152,7 +153,7 @@ class HttpConfig(BaseModel): return self.inner_WEB_API_CORS_ALLOW_ORIGINS.split(',') -class InnerAPIConfig(BaseModel): +class InnerAPIConfig(BaseSettings): """ Inner API configs """ @@ -167,7 +168,7 @@ class InnerAPIConfig(BaseModel): ) -class LoggingConfig(BaseModel): +class LoggingConfig(BaseSettings): """ Logging configs """ @@ -199,7 +200,7 @@ class LoggingConfig(BaseModel): ) -class ModelLoadBalanceConfig(BaseModel): +class ModelLoadBalanceConfig(BaseSettings): """ Model load balance configs """ @@ -209,7 +210,7 @@ class ModelLoadBalanceConfig(BaseModel): ) -class BillingConfig(BaseModel): +class BillingConfig(BaseSettings): """ Platform Billing Configurations """ @@ -219,7 +220,7 @@ class BillingConfig(BaseModel): ) -class UpdateConfig(BaseModel): +class UpdateConfig(BaseSettings): """ Update configs """ @@ -229,7 +230,7 @@ class UpdateConfig(BaseModel): ) -class WorkflowConfig(BaseModel): +class WorkflowConfig(BaseSettings): """ Workflow feature configs """ @@ -250,7 +251,7 @@ class WorkflowConfig(BaseModel): ) -class OAuthConfig(BaseModel): +class OAuthConfig(BaseSettings): """ oauth configs """ @@ -280,7 +281,7 @@ class OAuthConfig(BaseModel): ) -class ModerationConfig(BaseModel): +class ModerationConfig(BaseSettings): """ Moderation in app configs. """ @@ -292,7 +293,7 @@ class ModerationConfig(BaseModel): ) -class ToolConfig(BaseModel): +class ToolConfig(BaseSettings): """ Tool configs """ @@ -303,7 +304,7 @@ class ToolConfig(BaseModel): ) -class MailConfig(BaseModel): +class MailConfig(BaseSettings): """ Mail Configurations """ @@ -359,7 +360,7 @@ class MailConfig(BaseModel): ) -class RagEtlConfig(BaseModel): +class RagEtlConfig(BaseSettings): """ RAG ETL Configurations. """ @@ -385,7 +386,7 @@ class RagEtlConfig(BaseModel): ) -class DataSetConfig(BaseModel): +class DataSetConfig(BaseSettings): """ Dataset configs """ @@ -396,7 +397,7 @@ class DataSetConfig(BaseModel): ) -class WorkspaceConfig(BaseModel): +class WorkspaceConfig(BaseSettings): """ Workspace configs """ @@ -407,7 +408,7 @@ class WorkspaceConfig(BaseModel): ) -class IndexingConfig(BaseModel): +class IndexingConfig(BaseSettings): """ Indexing configs. """ @@ -418,7 +419,7 @@ class IndexingConfig(BaseModel): ) -class ImageFormatConfig(BaseModel): +class ImageFormatConfig(BaseSettings): MULTIMODAL_SEND_IMAGE_FORMAT: str = Field( description='multi model send image format, support base64, url, default is base64', default='base64', diff --git a/api/configs/feature/hosted_service/__init__.py b/api/configs/feature/hosted_service/__init__.py index b09b6fd041..209d46bb76 100644 --- a/api/configs/feature/hosted_service/__init__.py +++ b/api/configs/feature/hosted_service/__init__.py @@ -1,9 +1,10 @@ from typing import Optional -from pydantic import BaseModel, Field, NonNegativeInt +from pydantic import Field, NonNegativeInt +from pydantic_settings import BaseSettings -class HostedOpenAiConfig(BaseModel): +class HostedOpenAiConfig(BaseSettings): """ Hosted OpenAI service config """ @@ -68,7 +69,7 @@ class HostedOpenAiConfig(BaseModel): ) -class HostedAzureOpenAiConfig(BaseModel): +class HostedAzureOpenAiConfig(BaseSettings): """ Hosted OpenAI service config """ @@ -94,7 +95,7 @@ class HostedAzureOpenAiConfig(BaseModel): ) -class HostedAnthropicConfig(BaseModel): +class HostedAnthropicConfig(BaseSettings): """ Hosted Azure OpenAI service config """ @@ -125,7 +126,7 @@ class HostedAnthropicConfig(BaseModel): ) -class HostedMinmaxConfig(BaseModel): +class HostedMinmaxConfig(BaseSettings): """ Hosted Minmax service config """ @@ -136,7 +137,7 @@ class HostedMinmaxConfig(BaseModel): ) -class HostedSparkConfig(BaseModel): +class HostedSparkConfig(BaseSettings): """ Hosted Spark service config """ @@ -147,7 +148,7 @@ class HostedSparkConfig(BaseModel): ) -class HostedZhipuAIConfig(BaseModel): +class HostedZhipuAIConfig(BaseSettings): """ Hosted Minmax service config """ @@ -158,7 +159,7 @@ class HostedZhipuAIConfig(BaseModel): ) -class HostedModerationConfig(BaseModel): +class HostedModerationConfig(BaseSettings): """ Hosted Moderation service config """ @@ -174,7 +175,7 @@ class HostedModerationConfig(BaseModel): ) -class HostedFetchAppTemplateConfig(BaseModel): +class HostedFetchAppTemplateConfig(BaseSettings): """ Hosted Moderation service config """ diff --git a/api/configs/middleware/__init__.py b/api/configs/middleware/__init__.py index 1bf9650af9..d8a2fe683a 100644 --- a/api/configs/middleware/__init__.py +++ b/api/configs/middleware/__init__.py @@ -1,6 +1,7 @@ from typing import Any, Optional -from pydantic import BaseModel, Field, NonNegativeInt, PositiveInt, computed_field +from pydantic import Field, NonNegativeInt, PositiveInt, computed_field +from pydantic_settings import BaseSettings from configs.middleware.cache.redis_config import RedisConfig from configs.middleware.storage.aliyun_oss_storage_config import AliyunOSSStorageConfig @@ -22,7 +23,7 @@ from configs.middleware.vdb.tidb_vector_config import TiDBVectorConfig from configs.middleware.vdb.weaviate_config import WeaviateConfig -class StorageConfig(BaseModel): +class StorageConfig(BaseSettings): STORAGE_TYPE: str = Field( description='storage type,' ' default to `local`,' @@ -36,14 +37,14 @@ class StorageConfig(BaseModel): ) -class VectorStoreConfig(BaseModel): +class VectorStoreConfig(BaseSettings): VECTOR_STORE: Optional[str] = Field( description='vector store type', default=None, ) -class KeywordStoreConfig(BaseModel): +class KeywordStoreConfig(BaseSettings): KEYWORD_STORE: str = Field( description='keyword store type', default='jieba', diff --git a/api/configs/middleware/cache/redis_config.py b/api/configs/middleware/cache/redis_config.py index 4cc40bbe6d..436ba5d4c0 100644 --- a/api/configs/middleware/cache/redis_config.py +++ b/api/configs/middleware/cache/redis_config.py @@ -1,9 +1,10 @@ from typing import Optional -from pydantic import BaseModel, Field, NonNegativeInt, PositiveInt +from pydantic import Field, NonNegativeInt, PositiveInt +from pydantic_settings import BaseSettings -class RedisConfig(BaseModel): +class RedisConfig(BaseSettings): """ Redis configs """ diff --git a/api/configs/middleware/storage/aliyun_oss_storage_config.py b/api/configs/middleware/storage/aliyun_oss_storage_config.py index a468f28ea0..19e6cafb12 100644 --- a/api/configs/middleware/storage/aliyun_oss_storage_config.py +++ b/api/configs/middleware/storage/aliyun_oss_storage_config.py @@ -1,9 +1,10 @@ from typing import Optional -from pydantic import BaseModel, Field +from pydantic import Field +from pydantic_settings import BaseSettings -class AliyunOSSStorageConfig(BaseModel): +class AliyunOSSStorageConfig(BaseSettings): """ Aliyun storage configs """ diff --git a/api/configs/middleware/storage/amazon_s3_storage_config.py b/api/configs/middleware/storage/amazon_s3_storage_config.py index 21fe425fa8..2566fbd5da 100644 --- a/api/configs/middleware/storage/amazon_s3_storage_config.py +++ b/api/configs/middleware/storage/amazon_s3_storage_config.py @@ -1,9 +1,10 @@ from typing import Optional -from pydantic import BaseModel, Field +from pydantic import Field +from pydantic_settings import BaseSettings -class S3StorageConfig(BaseModel): +class S3StorageConfig(BaseSettings): """ S3 storage configs """ diff --git a/api/configs/middleware/storage/azure_blob_storage_config.py b/api/configs/middleware/storage/azure_blob_storage_config.py index 2fcb0ea3bd..26e441c89b 100644 --- a/api/configs/middleware/storage/azure_blob_storage_config.py +++ b/api/configs/middleware/storage/azure_blob_storage_config.py @@ -1,9 +1,10 @@ from typing import Optional -from pydantic import BaseModel, Field +from pydantic import Field +from pydantic_settings import BaseSettings -class AzureBlobStorageConfig(BaseModel): +class AzureBlobStorageConfig(BaseSettings): """ Azure Blob storage configs """ diff --git a/api/configs/middleware/storage/google_cloud_storage_config.py b/api/configs/middleware/storage/google_cloud_storage_config.py index 1f4d9f9883..e1b0e34e0c 100644 --- a/api/configs/middleware/storage/google_cloud_storage_config.py +++ b/api/configs/middleware/storage/google_cloud_storage_config.py @@ -1,9 +1,10 @@ from typing import Optional -from pydantic import BaseModel, Field +from pydantic import Field +from pydantic_settings import BaseSettings -class GoogleCloudStorageConfig(BaseModel): +class GoogleCloudStorageConfig(BaseSettings): """ Google Cloud storage configs """ diff --git a/api/configs/middleware/storage/oci_storage_config.py b/api/configs/middleware/storage/oci_storage_config.py index 5fd99c6d1e..6c0c067469 100644 --- a/api/configs/middleware/storage/oci_storage_config.py +++ b/api/configs/middleware/storage/oci_storage_config.py @@ -1,9 +1,10 @@ from typing import Optional -from pydantic import BaseModel, Field +from pydantic import Field +from pydantic_settings import BaseSettings -class OCIStorageConfig(BaseModel): +class OCIStorageConfig(BaseSettings): """ OCI storage configs """ diff --git a/api/configs/middleware/storage/tencent_cos_storage_config.py b/api/configs/middleware/storage/tencent_cos_storage_config.py index 1bcc4b7b44..1060c7b93e 100644 --- a/api/configs/middleware/storage/tencent_cos_storage_config.py +++ b/api/configs/middleware/storage/tencent_cos_storage_config.py @@ -1,9 +1,10 @@ from typing import Optional -from pydantic import BaseModel, Field +from pydantic import Field +from pydantic_settings import BaseSettings -class TencentCloudCOSStorageConfig(BaseModel): +class TencentCloudCOSStorageConfig(BaseSettings): """ Tencent Cloud COS storage configs """ diff --git a/api/configs/middleware/vdb/chroma_config.py b/api/configs/middleware/vdb/chroma_config.py index a764ddc796..f365879efb 100644 --- a/api/configs/middleware/vdb/chroma_config.py +++ b/api/configs/middleware/vdb/chroma_config.py @@ -1,9 +1,10 @@ from typing import Optional -from pydantic import BaseModel, Field, PositiveInt +from pydantic import Field, PositiveInt +from pydantic_settings import BaseSettings -class ChromaConfig(BaseModel): +class ChromaConfig(BaseSettings): """ Chroma configs """ diff --git a/api/configs/middleware/vdb/milvus_config.py b/api/configs/middleware/vdb/milvus_config.py index 6c1cda5ee9..01502d4590 100644 --- a/api/configs/middleware/vdb/milvus_config.py +++ b/api/configs/middleware/vdb/milvus_config.py @@ -1,9 +1,10 @@ from typing import Optional -from pydantic import BaseModel, Field, PositiveInt +from pydantic import Field, PositiveInt +from pydantic_settings import BaseSettings -class MilvusConfig(BaseModel): +class MilvusConfig(BaseSettings): """ Milvus configs """ diff --git a/api/configs/middleware/vdb/opensearch_config.py b/api/configs/middleware/vdb/opensearch_config.py index 4d77e7be94..15d6f5b6a9 100644 --- a/api/configs/middleware/vdb/opensearch_config.py +++ b/api/configs/middleware/vdb/opensearch_config.py @@ -1,9 +1,10 @@ from typing import Optional -from pydantic import BaseModel, Field, PositiveInt +from pydantic import Field, PositiveInt +from pydantic_settings import BaseSettings -class OpenSearchConfig(BaseModel): +class OpenSearchConfig(BaseSettings): """ OpenSearch configs """ diff --git a/api/configs/middleware/vdb/oracle_config.py b/api/configs/middleware/vdb/oracle_config.py index 941d63cb77..888fc19492 100644 --- a/api/configs/middleware/vdb/oracle_config.py +++ b/api/configs/middleware/vdb/oracle_config.py @@ -1,9 +1,10 @@ from typing import Optional -from pydantic import BaseModel, Field, PositiveInt +from pydantic import Field, PositiveInt +from pydantic_settings import BaseSettings -class OracleConfig(BaseModel): +class OracleConfig(BaseSettings): """ ORACLE configs """ diff --git a/api/configs/middleware/vdb/pgvector_config.py b/api/configs/middleware/vdb/pgvector_config.py index ff288c6246..8a677f60a3 100644 --- a/api/configs/middleware/vdb/pgvector_config.py +++ b/api/configs/middleware/vdb/pgvector_config.py @@ -1,9 +1,10 @@ from typing import Optional -from pydantic import BaseModel, Field, PositiveInt +from pydantic import Field, PositiveInt +from pydantic_settings import BaseSettings -class PGVectorConfig(BaseModel): +class PGVectorConfig(BaseSettings): """ PGVector configs """ diff --git a/api/configs/middleware/vdb/pgvectors_config.py b/api/configs/middleware/vdb/pgvectors_config.py index a7a1ea5b45..39f52f22ff 100644 --- a/api/configs/middleware/vdb/pgvectors_config.py +++ b/api/configs/middleware/vdb/pgvectors_config.py @@ -1,9 +1,10 @@ from typing import Optional -from pydantic import BaseModel, Field, PositiveInt +from pydantic import Field, PositiveInt +from pydantic_settings import BaseSettings -class PGVectoRSConfig(BaseModel): +class PGVectoRSConfig(BaseSettings): """ PGVectoRS configs """ diff --git a/api/configs/middleware/vdb/qdrant_config.py b/api/configs/middleware/vdb/qdrant_config.py index f0223ffa1c..c85bf9c7dc 100644 --- a/api/configs/middleware/vdb/qdrant_config.py +++ b/api/configs/middleware/vdb/qdrant_config.py @@ -1,9 +1,10 @@ from typing import Optional -from pydantic import BaseModel, Field, NonNegativeInt, PositiveInt +from pydantic import Field, NonNegativeInt, PositiveInt +from pydantic_settings import BaseSettings -class QdrantConfig(BaseModel): +class QdrantConfig(BaseSettings): """ Qdrant configs """ diff --git a/api/configs/middleware/vdb/relyt_config.py b/api/configs/middleware/vdb/relyt_config.py index b550fa8e00..be93185f3c 100644 --- a/api/configs/middleware/vdb/relyt_config.py +++ b/api/configs/middleware/vdb/relyt_config.py @@ -1,9 +1,10 @@ from typing import Optional -from pydantic import BaseModel, Field, PositiveInt +from pydantic import Field, PositiveInt +from pydantic_settings import BaseSettings -class RelytConfig(BaseModel): +class RelytConfig(BaseSettings): """ Relyt configs """ diff --git a/api/configs/middleware/vdb/tencent_vector_config.py b/api/configs/middleware/vdb/tencent_vector_config.py index 340ebfc705..531ec84068 100644 --- a/api/configs/middleware/vdb/tencent_vector_config.py +++ b/api/configs/middleware/vdb/tencent_vector_config.py @@ -1,9 +1,10 @@ from typing import Optional -from pydantic import BaseModel, Field, NonNegativeInt, PositiveInt +from pydantic import Field, NonNegativeInt, PositiveInt +from pydantic_settings import BaseSettings -class TencentVectorDBConfig(BaseModel): +class TencentVectorDBConfig(BaseSettings): """ Tencent Vector configs """ diff --git a/api/configs/middleware/vdb/tidb_vector_config.py b/api/configs/middleware/vdb/tidb_vector_config.py index 1360dfd7fc..8d459691a8 100644 --- a/api/configs/middleware/vdb/tidb_vector_config.py +++ b/api/configs/middleware/vdb/tidb_vector_config.py @@ -1,9 +1,10 @@ from typing import Optional -from pydantic import BaseModel, Field, PositiveInt +from pydantic import Field, PositiveInt +from pydantic_settings import BaseSettings -class TiDBVectorConfig(BaseModel): +class TiDBVectorConfig(BaseSettings): """ TiDB Vector configs """ diff --git a/api/configs/middleware/vdb/weaviate_config.py b/api/configs/middleware/vdb/weaviate_config.py index d1c9f5b5be..b985ecea12 100644 --- a/api/configs/middleware/vdb/weaviate_config.py +++ b/api/configs/middleware/vdb/weaviate_config.py @@ -1,9 +1,10 @@ from typing import Optional -from pydantic import BaseModel, Field, PositiveInt +from pydantic import Field, PositiveInt +from pydantic_settings import BaseSettings -class WeaviateConfig(BaseModel): +class WeaviateConfig(BaseSettings): """ Weaviate configs """ diff --git a/api/configs/packaging/__init__.py b/api/configs/packaging/__init__.py index e9b389df8d..dc812a15be 100644 --- a/api/configs/packaging/__init__.py +++ b/api/configs/packaging/__init__.py @@ -1,7 +1,8 @@ -from pydantic import BaseModel, Field +from pydantic import Field +from pydantic_settings import BaseSettings -class PackagingInfo(BaseModel): +class PackagingInfo(BaseSettings): """ Packaging build information """ diff --git a/api/tests/unit_tests/configs/test_dify_config.py b/api/tests/unit_tests/configs/test_dify_config.py index fd43e69bb3..50bb2b75ac 100644 --- a/api/tests/unit_tests/configs/test_dify_config.py +++ b/api/tests/unit_tests/configs/test_dify_config.py @@ -21,6 +21,7 @@ def example_env_file(tmp_path, monkeypatch) -> str: def test_dify_config_undefined_entry(example_env_file): + # NOTE: See https://github.com/microsoft/pylance-release/issues/6099 for more details about this type error. # load dotenv file with pydantic-settings config = DifyConfig(_env_file=example_env_file) @@ -43,6 +44,8 @@ def test_dify_config(example_env_file): assert config.SENTRY_TRACES_SAMPLE_RATE == 1.0 +# NOTE: If there is a `.env` file in your Workspace, this test might not succeed as expected. +# This is due to `pymilvus` loading all the variables from the `.env` file into `os.environ`. def test_flask_configs(example_env_file): flask_app = Flask('app') flask_app.config.from_mapping(DifyConfig(_env_file=example_env_file).model_dump())