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

huangapple go评论66阅读模式
英文:

Dynaconf Object Access Fails After Loading Configuration from S3 Unless Iterated Over

问题

I'm encountering a strange issue while loading TOML configuration files from an AWS S3 bucket into a Dynaconf object in Python.

Here's a simplified version of the code I'm using:

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

The problem arises when I try to directly access a value from the settings object (for example, settings.my_value) after loading the configuration from the S3 bucket. This direct access fails unless I previously iterate over the items in settings.

Expected behavior: I should be able to directly access a value from the settings object without first iterating over all the items.

Actual behavior: Direct access fails with an error message stating that the requested key doesn't exist, unless I first iterate over the items in settings.

This is particularly puzzling because if I comment out the iteration over the items in settings, the print statement fails, stating that 'my_value' doesn't exist. But, if I leave the iteration in place, the print statement succeeds.

Any ideas why this might be happening? Is there something about how Dynaconf loads or accesses data that I'm missing here?

Update: even better, give me a guideline on what would be the proper way of loading a remote settings file.

英文:

I'm encountering a strange issue while loading TOML configuration files from an AWS S3 bucket into a Dynaconf object in Python.

Here's a simplified version of the code I'm using:

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

The problem arises when I try to directly access a value from the settings object (for example, settings.my_value) after loading the configuration from the S3 bucket. This direct access fails unless I previously iterate over the items in settings.

Expected behavior: I should be able to directly access a value from the settings object without first iterating over all the items.

Actual behavior: Direct access fails with an error message stating that the requested key doesn't exist, unless I first iterate over the items in settings.

This is particularly puzzling because if I comment out the iteration over the items in settings, the print statement fails, stating that 'my_value' doesn't exist. But, if I leave the iteration in place, the print statement succeeds.

Any ideas why this might be happening? Is there something about how Dynaconf loads or accesses data that I'm missing here? Any help would be greatly appreciated!

Update: even better, give me a guideline on what would be the proper way of loading a remote settings file.

答案1

得分: 1

Sure, here is the translated content:

首先,让我指出一些小问题。我认为您对 get_bucket 的使用不正确,因为在 boto3 文档 中另有说明。
其次,os.fdopen 是多余的。只需使用相同参数的 open。第三,无需将文件名包装在列表中。如 Dynaconf 文档 中所述,一个包含单个文件名的字符串就可以了。

至于您的问题,您将配置放在了一个作用域下,是吗?dynaconf 会延迟加载它们,并将作用域作为属性,而不是键。将配置放在作用域之外可以解决所有问题,例如:

my_value = 1

而不是

[default]
my_value = 1

如果您一定要使用作用域,请写成 settings.SCOPE_NAME.my_value。我不太清楚为什么迭代会有帮助,但这是解决方案。
如果有帮助,请点击上投票、接受和悬赏,谢谢!

英文:

To begin with, let me point out a few minor issues. I do not think your usage of get_bucket is correct as it states otherwise in boto3 docs.
Second, os.fdopen is redundent. Simply use open with the same parameters. Third, there is no need to wrap the file's name in a list. As in Dynaconf docs, a single string with a single filename is okay.

Now, as for your problem, you put the configuration under a scope, didn't you? dynaconf lazyloads those and put the SCOPES as properties and not the keys. Putting the configuration outside of a scope solves everything E.g.

my_value = 1

instead of

[default]
my_value=1

If you MUST use a scope, write settings.SCOPE_NAME.my_value. I don't really know why iterating helps but here is the solution.
If it helps, please click upvote&accept&bounty, thank you!

答案2

得分: -1

Dynaconf对象访问问题可能是由于延迟加载引起的。您可以使用Dynaconf的远程功能从S3加载设置并将其与现有设置合并。这样,您可以直接访问值,而无需首先迭代项目。我提供了下面的代码供您查看,请告诉我。

from dynaconf import Dynaconf

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

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

# 现在您可以在下面访问settings.my_value
print(settings.my_value)
英文:

Dynaconf object access issue might be due to lazy loading. You can use Dynaconf's remote function to load settings from S3 and merge them with your existing settings. This way, you can directly access the values without iterating over the items first. I've provided below code you can check and let me know.

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)

huangapple
  • 本文由 发表于 2023年5月11日 17:58:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/76226385.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定