new common config loading from .env

This commit is contained in:
yanyongyu 2021-01-27 11:39:34 +08:00
parent 2e75671d56
commit 5e3f1b5435
4 changed files with 37 additions and 2 deletions

View File

@ -13,11 +13,14 @@
NoneBot 在启动时将会从系统环境变量或者 `.env` 文件中寻找变量 `ENVIRONMENT` (大小写不敏感),默认值为 `prod` NoneBot 在启动时将会从系统环境变量或者 `.env` 文件中寻找变量 `ENVIRONMENT` (大小写不敏感),默认值为 `prod`
这将引导 NoneBot 从系统环境变量或者 `.env.{ENVIRONMENT}` 文件中进一步加载具体配置。 这将引导 NoneBot 从系统环境变量或者 `.env.{ENVIRONMENT}` 文件中进一步加载具体配置。
`.env` 文件是基础环境配置文件,该文件中的配置项在不同环境下都会被加载,但会被 `.env.{ENVIRONMENT}` 文件中的配置所覆盖。
现在,我们在 `.env` 文件中写入当前环境信息: 现在,我们在 `.env` 文件中写入当前环境信息:
```bash ```bash
# .env # .env
ENVIRONMENT=dev ENVIRONMENT=dev
CUSTOM_CONFIG=common config # 这个配置项在任何环境中都会被加载
``` ```
如你所想,之后 NoneBot 就会从 `.env.dev` 文件中加载环境变量。 如你所想,之后 NoneBot 就会从 `.env.dev` 文件中加载环境变量。
@ -26,7 +29,7 @@ ENVIRONMENT=dev
NoneBot 使用 [pydantic](https://pydantic-docs.helpmanual.io/) 进行配置管理,会从 `.env.{ENVIRONMENT}` 文件中获悉环境配置。 NoneBot 使用 [pydantic](https://pydantic-docs.helpmanual.io/) 进行配置管理,会从 `.env.{ENVIRONMENT}` 文件中获悉环境配置。
可以在 NoneBot 初始化时指定加载某个环境配置文件: `nonebot.init(_env_file=".env.dev")`,这将忽略你在 `.env` 中设置的环境信息 可以在 NoneBot 初始化时指定加载某个环境配置文件: `nonebot.init(_env_file=".env.dev")`,这将忽略你在 `.env` 中设置的 `ENVIRONMENT`
:::warning 提示 :::warning 提示
由于 `pydantic` 使用 JSON 解析配置项,请确保配置项值为 JSON 格式的数据。如: 由于 `pydantic` 使用 JSON 解析配置项,请确保配置项值为 JSON 格式的数据。如:

View File

@ -175,6 +175,7 @@ def init(*, _env_file: Optional[str] = None, **kwargs):
logger.opt( logger.opt(
colors=True).info(f"Current <y><b>Env: {env.environment}</b></y>") colors=True).info(f"Current <y><b>Env: {env.environment}</b></y>")
config = Config(**kwargs, config = Config(**kwargs,
_common_config=env.dict(),
_env_file=_env_file or f".env.{env.environment}") _env_file=_env_file or f".env.{env.environment}")
default_filter.level = "DEBUG" if config.debug else "INFO" default_filter.level = "DEBUG" if config.debug else "INFO"

View File

@ -20,12 +20,41 @@ from datetime import timedelta
from ipaddress import IPv4Address from ipaddress import IPv4Address
from typing import Any, Set, Dict, Union, Mapping, Optional from typing import Any, Set, Dict, Union, Mapping, Optional
from pydantic.utils import deep_update
from pydantic import BaseSettings, IPvAnyAddress from pydantic import BaseSettings, IPvAnyAddress
from pydantic.env_settings import SettingsError, env_file_sentinel, read_env_file from pydantic.env_settings import SettingsError, env_file_sentinel, read_env_file
class BaseConfig(BaseSettings): class BaseConfig(BaseSettings):
def __init__(
__pydantic_self__, # type: ignore
_common_config: Optional[Dict[Any, Any]] = None,
_env_file: Union[Path, str, None] = env_file_sentinel,
_env_file_encoding: Optional[str] = None,
_secrets_dir: Union[Path, str, None] = None,
**values: Any) -> None:
super(BaseSettings,
__pydantic_self__).__init__(**__pydantic_self__._build_values(
values,
_common_config=_common_config,
_env_file=_env_file,
_env_file_encoding=_env_file_encoding,
_secrets_dir=_secrets_dir))
def _build_values(
self,
init_kwargs: Dict[str, Any],
_common_config: Optional[Dict[Any, Any]] = None,
_env_file: Union[Path, str, None] = None,
_env_file_encoding: Optional[str] = None,
_secrets_dir: Union[Path, str, None] = None,
) -> Dict[str, Any]:
return deep_update(self._build_secrets_files(_secrets_dir),
_common_config or {},
self._build_environ(_env_file,
_env_file_encoding), init_kwargs)
def _build_environ( def _build_environ(
self, self,
_env_file: Union[Path, str, None] = None, _env_file: Union[Path, str, None] = None,
@ -92,7 +121,7 @@ class BaseConfig(BaseSettings):
return self.__dict__.get(name) return self.__dict__.get(name)
class Env(BaseSettings): class Env(BaseConfig):
""" """
运行环境配置大小写不敏感 运行环境配置大小写不敏感
@ -109,6 +138,7 @@ class Env(BaseSettings):
""" """
class Config: class Config:
extra = "allow"
env_file = ".env" env_file = ".env"

View File

@ -1 +1,2 @@
ENVIRONMENT=dev ENVIRONMENT=dev
CUSTOM_CONFIG=common