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

问题描述 投票:0回答:2

我在将 AWS S3 存储桶中的 TOML 配置文件加载到 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 存储桶加载配置后直接访问设置对象的值(例如,settings.my_value)时出现问题。除非我之前迭代设置中的项目,否则这种直接访问会失败。

预期行为:我应该能够直接从设置对象访问一个值,而无需先遍历所有项目。

实际行为:直接访问失败并显示一条错误消息,指出请求的密钥不存在,除非我首先遍历设置中的项目。

这特别令人费解,因为如果我注释掉设置中项目的迭代,打印语句将失败,说明“my_value”不存在。但是,如果我保留迭代,打印语句就会成功。

知道为什么会这样吗?是否有关于 Dynaconf 如何加载或访问我在这里丢失的数据的内容?任何帮助将不胜感激!

更新: 更好的是,给我一个关于加载远程设置文件的正确方法的指南。

python amazon-s3 settings dynaconf
2个回答
0
投票

您在使用 Dynaconf 时遇到的问题可以通过在使用配置文件初始化设置对象后调用

load()
方法来解决。这可确保正确加载配置并可直接访问。

这是您的代码的更新版本,其中包括

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 等远程源加载配置。如果您的用例需要直接从远程源访问配置而不将其下载到临时文件,您也可以探索这些选项。


-1
投票

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)
© www.soinside.com 2019 - 2024. All rights reserved.