【问题标题】:Handling hardcoded URL's in a python package在 python 包中处理硬编码的 URL
【发布时间】:2021-09-04 02:21:30
【问题描述】:

我正在开发一个使用 API(使用 HTTP 协议)的 python 包。 在我的包中,我有一个 python 配置文件,其中包含 API URL(hardcoded)和其他设置。 API URL 保存在全局变量中,因此我可以导入它并在我的包模块中使用它。例如:

API_URL = "https://api-url.com"

配置文件是软件包的一部分,这意味着一旦用户安装了软件包,他还将获得包含硬编码 URL 的配置文件。 问题是,在未来的某个时候,API 的 URL 可能会发生变化,并且包的所有真实性都会被破坏,用户将不得不更新(例如 pip install 等)包。 处理包中硬编码 URL 的正确方法是什么?

【问题讨论】:

    标签: python python-packaging


    【解决方案1】:

    这里的常见模式是不对 URL 基础进行硬编码,而是提供一个 API 类,该类将使用相应的 URL 进行实例化。该类还可以获取额外的配置/配置文件:

    class MyAPI:
        def __init__(self, config_file: str = DEFAULT_CONFIG, **overrides):
            self.config = build_config(config_file, overrides)
            self.url = self.config.url
    
        @property
        def value(self):
            return requests.get(urljoin(self.url, "./value"))
    

    然后用户会像这样使用它:

    api = MyAPI()
    
    print(api.value)
    

    api = MyAPI(url="NEW_URL")
    
    print(api.value)
    

    这与prawwikipedia 使用的示例类似。

    如果有不同的 URL 可用于相同/非常相似的界面,这是一个特别好的主意。 (通常至少是现场产品 + 一个测试沙箱)

    【讨论】:

    • 感谢您的申请。 API URL不应该由用户提供(可能我不够清楚。包使用了幕后的API)。这种情况应该怎么办?
    • 即使您认为什么都不会改变,提供某种机制来覆盖您的硬编码 URL 仍然是一个好主意。通过直接在代码中传递 URL,或者通过读取 env var,或者通过其他方式。也许您或其他人确实想通过模拟您的服务来测试您的库。
    【解决方案2】:

    您可以设计您的 API,以便 URIs don't change。这可以使用版本控制来实现,例如在 https://api-url.com/v1 而不是 https://api-url.com 提供您的 API。在这种情况下,用户 无需更新或更改任何内容,因为对 API 的任何更改都不会影响它们,因为更改只会存在于https://api-url.com/v2 提供的 API 的较新版本中。

    另一个选项是强制库客户端传递他们想要使用的 URL。这将解决硬编码问题,但不会解决根本原因。 API 通常会发生变化,因为对域的理解发生了变化,这反过来意味着可能会有比单独的 URL 更多的变化(这无论如何都会破坏你的库)。

    如果您认为您可能只是想更改域名并且预计不会有任何其他可能影响客户端的更改,您可以使用从旧 URL 重定向到新 URL。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-08
      • 2011-02-28
      • 2012-05-28
      • 2011-05-03
      • 1970-01-01
      • 2013-10-17
      • 2016-05-13
      相关资源
      最近更新 更多