python 从S3加载配置后Dynaconf对象访问失败,除非迭代

bf1o4zei  于 2023-05-16  发布在  Python
关注(0)|答案(2)|浏览(206)

bounty还有5天到期。回答此问题可获得+500声望奖励。Shlomi Schwartz希望引起更多关注这个问题。

我在将TOML配置文件从AWS S3存储桶加载到Python中的Dynaconf对象时遇到了一个奇怪的问题。
下面是我使用的代码的简化版本:

import os
import boto3
from dynaconf import Dynaconf

def load_settings(template_name: str) -> Dynaconf:
    s3 = boto3.client("s3")
    key = f"{template_name}.toml"
    obj = s3.get_object(Bucket="my_bucket", Key=key)
    toml_str = obj["Body"].read().decode("utf-8")

    temp_file = f"{template_name}.toml"

    # Write the TOML string to the temporary file

    with os.fdopen(fd, "w") as file:
        file.write(toml_str)

    settings = Dynaconf(
        envvar_prefix="DYNACONF",
        environments=True,
        settings_files=[temp_file]
    )
    
    # Iterating over the items
    for k, v in settings.items():
        print(k, v)

    # Now I can access the values
    print(settings.my_value)

    os.remove(temp_file)
    return settings

在从S3存储桶加载配置后,当我试图直接从设置对象(例如,www.example.com _value)访问值时,就会出现问题settings.my。这种直接访问会失败,除非我之前遍历了设置中的项。
预期行为:我应该能够直接从设置对象中访问一个值,而不需要首先迭代所有项。
实际行为:直接访问失败,并显示一条错误消息,指出所请求的键不存在,除非我首先遍历设置中的项。
这特别令人困惑,因为如果我注解掉settings中的项上的迭代,print语句就会失败,声明'my_value'不存在。但是,如果我保留迭代,print语句就会成功。
你知道为什么会这样吗Dynaconf如何加载或访问数据,我在这里遗漏了什么?任何帮助将不胜感激!

**更新:**甚至更好,给予我一个关于加载远程设置文件的正确方法的指导方针。

ovfsdjhp

ovfsdjhp1#

使用配置文件初始化设置对象后,通过调用设置对象上的load()方法可以解决Dynaconf遇到的问题。这可确保配置正确加载并可直接访问。
下面是包含load()方法的代码的更新版本:

import os
import boto3
from dynaconf import Dynaconf

def load_settings(template_name: str) -> Dynaconf:
    s3 = boto3.client("s3")
    key = f"{template_name}.toml"
    obj = s3.get_object(Bucket="my_bucket", Key=key)
    toml_str = obj["Body"].read().decode("utf-8")

    temp_file = f"{template_name}.toml"

    # Write the TOML string to the temporary file
    with open(temp_file, "w") as file:
        file.write(toml_str)

    settings = Dynaconf(
        envvar_prefix="DYNACONF",
        environments=True,
        settings_files=[temp_file]
    )

    # Load the configuration from the file
    settings.load()

    # Now you can directly access the values
    print(settings.my_value)

    os.remove(temp_file)
    return settings

load()方法触发从指定文件加载配置数据,使其可直接访问。如果不调用此方法,配置数据可能无法完全加载到设置对象中,从而在尝试直接访问值时导致错误。
另外,我对代码做了一个小修改,直接使用open()编写临时文件。在这个场景中,您可以简单地使用open()而不是os.fdopen()
此更新的代码应可解决此问题,并允许您直接访问Dynaconf设置对象中的值,而无需事先迭代这些项。
关于加载远程设置文件,您所采用的方法,即从S3下载配置文件,然后用Dynaconf加载它,是一种有效的方法。但是,值得注意的是,Dynaconf还支持从Redis或Vault等远程源加载配置。如果您的用例需要直接从远程源访问配置,而不需要将其下载到临时文件中,那么您也可以探索这些选项。

ztyzrc3y

ztyzrc3y2#

Dynaconf对象访问问题可能是由于延迟加载。您可以使用Dynaconf的远程功能从S3加载设置并将其与现有设置合并。这样,您就可以直接访问这些值,而无需先迭代这些项。我已经提供了下面的代码,你可以检查,让我知道。

from dynaconf import Dynaconf

settings = Dynaconf(
    envvar_prefix="DYNACONF",
    environments=True,
)

settings.load_remote("s3://my-bucket/my-settings.toml")

# Now you can access the settings.my_value below
print(settings.my_value)

相关问题