首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >一起使用Typer和Hydra

一起使用Typer和Hydra
EN

Stack Overflow用户
提问于 2022-01-22 09:44:14
回答 1查看 509关注 0票数 2

我有一个简单的https://typer.tiangolo.com/应用程序:

代码语言:javascript
复制
import typer

app = typer.Typer()

@app.command()
def say_hi():
    print("Hi")

@app.callback()
def main():
    pass

if __name__ == "__main__":
    app()

我想使用https://hydra.cc/docs/intro/来管理应用程序的配置,但是,我不知道如何做到这一点,而不会失去从CLI中覆盖配置的能力。

我的第一次尝试是:

代码语言:javascript
复制
import hydra
import typer
from omegaconf import DictConfig, OmegaConf

app = typer.Typer()

@app.command()
def say_hi():
    print("Hi")

@app.callback()
@hydra.main(config_path="conf", config_name="config")
def main(cfg: DictConfig) -> None:
    print(OmegaConf.to_yaml(cfg))

if __name__ == "__main__":
    app()

但我说错了:

代码语言:javascript
复制
RuntimeError: Type not yet supported: <class 'omegaconf.dictconfig.DictConfig'>

如果删除DictConfig类型注释,就会得到cfg丢失的错误。

我在Hydra中看到了允许在没有装饰器的情况下初始化配置的合成API

代码语言:javascript
复制
@app.callback()
def main() -> None:
    with initialize(config_path="conf", job_name="test_app"):
        cfg = compose(config_name="config")
        print(OmegaConf.to_yaml(cfg))

但在这种情况下,我似乎无法覆盖命令行中的配置,因为Typer应用程序无法识别这些值。

有什么建议可以解决吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-01-23 21:45:57

compose函数接受覆盖字符串的可选列表:

代码语言:javascript
复制
with initialize(config_path="conf", job_name="test_app"):
    cfg = compose(config_name="config", overrides=["db=mysql", "db.user=me"])

您需要从命令行获得一个覆盖字符串列表,然后将该列表传递给compose。下面是一个使用Typer的示例;类似的模式可以适用于例如an解析或单击。(免责声明:我不是打字专家)

代码语言:javascript
复制
from typing import List, Optional

import typer
from omegaconf import OmegaConf, DictConfig

from hydra import compose, initialize

app = typer.Typer()

def my_compose(overrides: Optional[List[str]]) -> DictConfig:
    with initialize(config_path="conf", job_name="test_app"):
        return compose(config_name="config", overrides=overrides)

@app.command()
def say_hi(overrides: Optional[List[str]] = typer.Argument(None)):
    print("HI!")
    print(f"Got {overrides=}")
    cfg = my_compose(overrides)
    print("\nHydra config:")
    print(OmegaConf.to_yaml(cfg))

@app.command()
def say_bye(overrides: Optional[List[str]] = typer.Argument(None)):
    cfg = my_compose(overrides)
    ...
    print("BYE!")

if __name__ == "__main__":
    app()
代码语言:javascript
复制
$ python my_app.py say-hi +foo=bar +baz=qux
HI!
Got overrides=('+foo=bar', '+baz=qux')

Hydra config:
foo: bar
baz: qux

$ python my_app.py say-bye
BYE!
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70811640

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档