Pydantic: как анализировать объекты, не являющиеся dict

Вводятся следующие данные

data = {
    'campaigns': [
        {
            'title': 'GBP',
            'geo_segment': 'WW',
            'ac_type': 'Value',
            'conversion': 'soft',
            'asset_type': 'ALL',
            'date': '22.04.21',
            'name': 'GBP_WW_1_core_22.04.21',
            'budget': '2000',
            'cpa': '1,00'
        }
    ],
    'stages': [
        'pre',
        'post'
    ],
    'language_mode': 'all_en'
}

Для разбора campaigns я использую метод parse_obj()

campaigns = parse_obj_as(List[CampaignData], data['campaigns'])

class CampaignData(BaseModel):
    title: NonEmptyString
    geo_segment: NonEmptyString
    ......

Оно работает.

Как проверить остальные данные (stages:List, language_mode:str), которые не относятся к типу dict?

class GoogleCheckCampaignStages(BaseModel):
    stages: List[str]
        
    
class GoogleCheckLanguageMode(BaseModel):
    language_mode: str

Если я побегу

stages = parse_obj_as(List[GoogleCheckCampaignStages], data['stages'])

возвращается

value is not a valid dict (type=type_error.dict)

Тот же результат с data['language_mode'].

Если я попробую методом parse_raw_as()

parse_raw_as(GoogleCheckLanguageMode, data['language_mode'])

возвращается

json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

Итак, как разобрать значения str и list?

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
60
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ошибка, с которой вы сталкиваетесь, связана с тем, что вы передаете data["stages"], который является просто списком/массивом. У него нет ключа с именем stages, и поэтому Pydantic не знает, как его назначить.

Предполагая, что NonEmptyString определено, как показано ниже, я бы предложил создать одну модель, которая обрабатывает весь объект data, например, так:

from pydantic import BaseModel, parse_obj_as, constr
from typing import List

NonEmptyString = constr(min_length=1)

class CampaignData(BaseModel):
    title: NonEmptyString
    geo_segment: NonEmptyString
    # and so on ...

class Data(BaseModel):
    campaigns: List[CampaignData]
    stages: List[str]
    language_mode: str

parsed_data = parse_obj_as(Data, data)
print(parsed_data)
# campaigns=[CampaignData(title='GBP', geo_segment='WW', ...)] stages=['pre', 'post'] language_mode='all_en'

Если вы хотите получить доступ только к определенным элементам, вы можете легко сделать это следующим образом:

print(parsed_data.stages)
# ['pre', 'post']

Другие вопросы по теме