【问题标题】:Parse multiple APIs in Python and match values that have different keys在 Python 中解析多个 API 并匹配具有不同键的值
【发布时间】:2021-12-26 14:37:06
【问题描述】:

在 Python 中,我正在编写一本异国食谱的网络版本,从各种 API 中获取食谱,以便将其发布到新网站。

如何将大约 100 个不同的 JSON 结构映射到我的?

我是否必须像我在本示例中展示的那样使用“get_content_from_api_1”、“...2”等手动操作,还是有更好的方法?

与原生 PostgreSql 相比,sqlAlchemy 有没有办法让事情变得更容易?

我面临的限制:

  • 各种 API 根本不共享相同的结构
  • 某些 API 将具有非扁平结构
  • 将有大约 100 种不同的 API,因此有 100 种不同的结构和键名

我拥有的代码的工作示例:

from dataclasses import dataclass
import requests


@dataclass
class MyCookingData:
    chocolate: str
    cucumber: str = None
    loaf: str = None


sample_obj_1 = {
    "chocolate": "dark",
    "cucumber": "long and green",
    "loaf": "2 pounds",
}

sample_obj_2 = {
    "choco": "milk",
    "cuc": "5",
    "meatloaf": "juicy",
}


def fetch_the_api(url):
    '''Fetch a public url, but return sample objects for the example'''
    '''
    try:
        response = requests.get(url, timeout=5)
    except requests.exceptions.HTTPError as err:
        print(err)
    '''
    response = url # sample_obj_ 1 and 2 for the example
    return response

def get_content_from_api_1(url):
    '''Get url or sample object 1'''
    api_data = fetch_the_api(url)
    new_data = MyCookingData(
        chocolate=api_data['chocolate'],
        cucumber=api_data['cucumber'],
        loaf=api_data['loaf'],
    )
    populate_db(new_data)

def get_content_from_api_2(url):
    '''Get url or sample object 2'''
    api_data = fetch_the_api(url)
    new_data = MyCookingData(
        chocolate=api_data['choco'],
        cucumber=api_data['cuc'],
        loaf=api_data['meatloaf'],
    )
    populate_db(new_data)

def populate_db(data):
    '''Store in db, but print for example'''
    # print(data.__dict__)
    for each_elem in data.__dict__:
        print(each_elem, '=>', data.__dict__[each_elem])


def main():
    print('Get content from API 1:')
    get_content_from_api_1(sample_obj_1)
    print('************')
    print('Get content from API 2:')
    get_content_from_api_2(sample_obj_2)
    print('************')


main()

我运行这段代码得到的结果是:

Get content from API 1:
chocolate => dark
cucumber => long and green
loaf => 2 pounds
************
Get content from API 2:
chocolate => milk
cucumber => 5
loaf => juicy
************

【问题讨论】:

    标签: python json api python-dataclasses


    【解决方案1】:

    您也许可以提供更多背景信息,也许还可以提供一些您尝试过但遇到问题的代码 - 查看 SO 指南

    话虽如此,您最好还是查看pydantic 而不是数据类(或者可能是 pydantic 的数据类版本)。

    数据类本身不会为解析输入做任何事情(尽管有可以在数据类中构建的模块来做到这一点),它们也不会做任何事情来验证类型等。相比之下,Pydantic 将为你做所有这些事情,如果你需要。

    【讨论】:

    • 感谢您的回答,我会检查 pydantic 数据类。我还添加了我必须使用的 100 个左右的功能中的 2 个。这对我来说似乎是多余的,我相信必须有更好的方法。背景信息是我正在编写一本异国情调的食谱并获取成分和食谱 API,以便在新网站上发布。
    • 谢谢 rv.kvetch ,我改写了我的问题并提供了经过测试的 MRE。希望我能更好地解释自己。
    • @paulavan 看起来您可能需要使用字段别名,例如 pydantic 提供的别名。例如,您想将chocolate 之类的公共字段映射到每个 API 中不同名称的字段,例如chocochoc?如果是这种情况,并且如果每个 API 本质上具有相同的架构(但不确定是否是这种情况),那么应该可以定义一个模型类,尽管有多个别名映射到每个字段。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-27
    • 2016-03-26
    • 2021-07-14
    • 2018-08-02
    • 2014-04-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多