The following data is input
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'
}
To parse campaigns
, I use the parse_obj()
method
campaigns = parse_obj_as(List[CampaignData], data['campaigns'])
class CampaignData(BaseModel):
title: NonEmptyString
geo_segment: NonEmptyString
......
It works.
How to validate the rest of the data (stages
: List
, language_mode
: str
), which is not of type dict
?
class GoogleCheckCampaignStages(BaseModel):
stages: List[str]
class GoogleCheckLanguageMode(BaseModel):
language_mode: str
If I run
stages = parse_obj_as(List[GoogleCheckCampaignStages], data['stages'])
returns
value is not a valid dict (type=type_error.dict)
Same result with data['language_mode']
.
If I try with parse_raw_as()
method
parse_raw_as(GoogleCheckLanguageMode, data['language_mode'])
returns
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
So how to parse str
and list
values?
CodePudding user response:
The error you are encountering is because you are passing in data["stages"]
which is just a list/array. It has no key called stages
and therefore Pydantic doesn't know how to assign it.
Assuming that NonEmptyString
is defined as below, I would suggest creating one model that processes the whole data
object, for example like this:
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'
If you'd like to access only specific elements, you can easily do it like this:
print(parsed_data.stages)
# ['pre', 'post']