спасибо, за уроки, не забрасывай канал, материал топ) там где то были обещания это все дело в контейнере заранить и многое другое) еще бы интересно пайтест в связке с БД увидеть енивей дякую)
потрясающий разбор! единтвенное, добавил бы что name: str маловато, т.к. для платежных систем часто важно что имя именно двух или трех-словное иначе запрос не пройдет
Спасибо большое за инфу, очень полезно. Если прочитаешь, подскажи, пожалуйста, как можно решить такую проблему. Я отправляю GET-запрос с параметрами, и в зависимости от того, какие параметры отправляю, зависит ответ и длина json. Т.е., к примеру, мне нужно получить данные, допустим, название модели инструментов, которые продаются в магазине и выпущенных в 2022 году. Я отправляю запрос с параметром 'year'='2022', и мне приходит ответ вот в таком формате: {'mod1': 'пила', 'mod2': 'молоток'} и т.д. Ответ приходит всегда по одной схеме, т.е. 'какое-то поле': str, но кол-во моделей может меняться, соответственно, и длина джейсона и название полей разное, т.е. mod1, mod2, mod3, как можно в таком случае описать pydantic-схему?
Здорово! Спасибо. Правда кажется експирейшн не совсем корректно делать FutureDate с точки зрения бытового взгляда, потому что мы можем не успеть обновиться пока компьютер не поэкспайрится
Спасибо))) Я по-этому и указал 2040й год на всякий случай :D Но даже если у нас и будет идти что-то не по плану, всегда на помощь прийдут кастомные валидации для моделей)
Из коробки такое не предоставляется. Небольшое вступление по-поводу самой библиотеки: Сама по-себе библиотека изначально предназначалась для парсинга данных из объектов типа sqlalchemy, dict и т.д. Спустя время, все поняли, что это крутая штука не только для парсинга, а и для валидации данных и активно начали её форсить в связке с фреймворком fastapi, накрутили кучу фич и т.д. В этом же курсе, она исключительно для валидации данных. Теперь по-поводу вопроса: Я думал на этот счёт, что было бы весьма удобно один раз написать модель и использовать её ещё и как генератор, но пришёл к выводу, что это будут только лишние проблемы. 1. Зачем писать ещё один уровень абстракции по-верх базового класса, расширять его куда-то в сторону, не используя основной функционал. (Проще написать обычный билдер с нуля) 2. Управление полями которые ENUM. К примеру, мы генерируем новый тестовый объект, какое из значений присвоить для этого поля? Если дефолтное выбрать, то нужно будет в обязательном порядке менять его на другое в дальнейшем. Итог: Лучше создать простенький билдер используя faker, чем всю эту штуку переписывать и делать из неё прям монстра.
Спасибо за уроки, но я что-то не понимаю сути происходящего. У нас приходят какие-то данные с сервера/приложения в виде json и мы для проверки генерируем свои данные?
Привет)) Мы получаем данные с сервера и с помощью pydantic валидируем их. То-есть пытаемся сериализировать с помощью pydantic, что намного удобнее, чем использовать довольно популярную библиотеку для валидации данных jsonschema.
@@SolveMeChannel, ух оперативность) использую Pydantic в связке с SQLAlchemy для тестирования API Пользователь запрашивает данные пользователя и в зависимости от языка интерфейса . поля 'name' и 'department' соответственно подтягиваются с БД в нужной локализации. Я парсю JSON ответа ( User.parse_obj(response_json) ) и также парсю даннные со стороны Базы данных ( User.from_orm(UserDB) ) и уже на уровне Pydantic класса сравниваю response_json= { "name": "User", "userId": "Test userId", "department": "Test Dept" } модель Pydantic class User(BaseModel): user_id: str = Field(alias='userId') name: str department: str class Config: orm_mode = True allow_population_by_field_name = True в Базе данных модель юзера такая class UserDB(Base): __tablename__ = 'user' id = Column(Integer, primary_key=True) user_id = Column(String) user_nm_kr = Column(String) user_nm_en = Column(String) dept_nm_kr = Column(String) dept_nm_en = Column(String) UPD: пока писал, понял что скорее всего логика должна быть на стороне бека в подготовке объекта от Базы данных
Есть один вопросик, а именно как работает эта штука? У меня лично 2 догадки :) Вариант 1 Если нет обычного имени - возвращает kr Вариант 2 При запросе на сервер передают хедер accept-language с языком, если такой язык есть, в таком и возвращается имя и другие параметры (Судя по респонсу, скорей всего так и есть, так как первый вариант менее популярный). Если же языка нет или хедер не передали, то возвращают все доступные локализации и параметры к ним в отдельном обьекте. =========================== Для первого варианта: from sqlalchemy import func def get_user_data(lang="en"): data = session.query( tables.UserDB.user_id, func.coalesce(tables.UserDB.user_nm_en, tables.UserDB.user_nm_kr), func.coalesce(tables.UserDB.dept_nm_en, tables.UserDB.dept_nm_kr) ).first() return data Для второго варианта есть такой ход конём: Если ты знаешь какой язык сейчас нужно селектить из базы, то можно вот так поступить: def get_user_data(lang="en"): LANG_MAPPER = { "en": (tables.UserDB.user_id, tables.UserDB.user_nm_en, tables.UserDB.dept_nm_en) "kr": (tables.UserDB.user_id, tables.UserDB.user_nm_kr, tables.UserDB.dept_nm_kr) } data = session.query(LANG_MAPPER.get(lang)).first() return data PS: Надеюсь я правильно понял суть проблемы :)
Спасибо большое за уроки. Помогите разобраться с одним моментом. Есть один вопрос. Как правильно описать джисон если первый словарь идет как динамический - это айдишник, по которому и получается джисон с сервера. Проблема в том что он всегда разный и он по сути значение, а ключа нету. Я по разному пробовал но не получается. Спасибо заранее за помощь.
Добрый день. Спасибо за лекции, очень актуально! Есть вопрос - может ли pydantic работать с "плавающими" секциями в json. Например family, name, middlename. Бывает что отчества нет или оно не указано, и поле то есть, то его нет.
Добрый день, в таком случае можно использовать значение по-умолчанию, к примеру: class Human(BaseModel): name: str last_name: str surname: str = None human = Human.parse_obj({ "name": "Andrii", "last_name": "Shevchenko", "surname": "Sheva" }) print(human.surname) human = Human.parse_obj({ "name": "Andrii", "last_name": "Shevchenko" }) print(human.surname) Если имени не будет, то ничего не произойдёт и в значении surname будет None, если есть, то будет соответственно то, что было передано. surname: str = None - эта конструкция как-раз и позволяет работать с необязательными полями (принцип тот же, как при описании аргументов которые может принимать метод/функция на вход). Так же вместо None, там может быть что угодно (число, массив, строка и т.д.), не рекомендовал бы только использовать пустую строку, так как нельзя будет потом понять, вам пришла пустая строка или это значение по-умолчанию, а так, вы можете создать валидацию на это поле, проверить что оно не None и если это так, делать какие-то проверки.
@@SolveMeChannel а что делать если, например, поле зависит от какой-то логики? Например, поле surname показывается, если поле show_surname = true. У меня подобная ситуация сейчас. Думаю как решить. Не хочется все эти поля делать optional.
Alexander V. Привет :) Можно воспользоваться вот такой конструкцией: class Human(BaseModel): name: str last_name: str surname: str = None is_hide: bool @validator('is_hide') def validate_surname_showing(cls, hide_value, values): if hide_value is False and values.get('surname') is None: raise ValueError('Surname should be presented') return hide_value human = Human.parse_obj({ "name": "Andrii", "last_name": "Shevchenko", "is_hide": True }) Обязательно валидировать поле is_hide и в валидаторе дополнительно принимать все значения, после этого просто проверять значение поля is_hide и то, что было передано. Обрати внимание, что если мы например валидируем поле is_hide, то в параметр values попадут все значения которые в описании класса находятся выше него, если бы мы разместили surname ниже is_hide, то нам бы постоянно приходил None и валидатор бы фейлился. Это из-за того, что он валидирует всё построчно и параметры ниже валидируемого поля просто ещё не попали в обьект класса pydantic.
@@SolveMeChannel спасибо) Позволю себе задать еще вопрос: как ты организовал логирование ошибок с Pydantic в контексте получения отчетов в связке с allure? У меня тест помечается как broken, а не failed в случае каких-то ошибок в валидации. Спасибо заранее)
Добрый день, в этом видео ua-cam.com/video/6QjDW-p_F-o/v-deo.html показывал как с ней работать и уже в дальнейших видео показывал как работать с pydantic, так же , почему я отдаю предпочтение именно ему.
You hide your currently edited file names and it's hard to copy something from your code. You can push your changes for each lesson as a separate branch as this guy did for his 7hours tutorial. ua-cam.com/video/c708Nf0cHrs/v-deo.html Channel super except for this issues
Hello, thank you so much for your response. I've fixed the issue with displaying the current tab. The creation of separate branches for each lesson was as hard for me as it could be because all lessons have been published and it is almost impossible to copy symbol by symbol. One more thing about why I don't want to do that it is the main idea of the lessons project, I want to have some cookbook for our community in which they could find anything without searching the Internet for a quick start of automation.
Привет дружище, к сожалению, у меня были большие проблемы с расширением экрана и как следствие, его отображение в видео, каждое видео это логическая эволюция -___- В первом исправил консоль, теперь не видно табы, исправил табы, не видно консоль, поменял назад и делал так, чтобы было видно что я пишу в консольке, потом исправил размер шрифта и т.д. По этому, сорри, сейчас уже +- пришёл к чему-то адекватному, если что-то не видно или не получается, пиши, я постараюсь помочь)
@@SolveMeChannel о спасибо большое не думал что ответишь. Сам недавно начал изучать автомейшн. Иногда работаю на Постмане, вручную ароверяю. Работаю на мануал тестинг. Спасибо за твои видео, многому научил. Удачи тебе и самые лучшие пожелания
Ну наконец - нормальный пример с вложенными объектами/массивами. Спасибо! А то все пихнут 1 классик и больше не показывают ничего
спасибо, за уроки, не забрасывай канал, материал топ)
там где то были обещания это все дело в контейнере заранить и многое другое)
еще бы интересно пайтест в связке с БД увидеть
енивей дякую)
Спасибо большое :) Сделаем отдельное видео о работе с базой используя sqlalchemy.
потрясающий разбор!
единтвенное, добавил бы что name: str маловато, т.к. для платежных систем часто важно что имя именно двух или трех-словное иначе запрос не пройдет
Спасибо большое за видосы) Очень классно рассказываешь)
Спасибо большое :)
все очень круто! спасибо тебе
Очень полезные видео! Спасибо за такой ценный материал! На канале видео уже не было год...надеюсь, не заброшен?
братан контент огонь!
Спасибо большое за инфу, очень полезно. Если прочитаешь, подскажи, пожалуйста, как можно решить такую проблему. Я отправляю GET-запрос с параметрами, и в зависимости от того, какие параметры отправляю, зависит ответ и длина json. Т.е., к примеру, мне нужно получить данные, допустим, название модели инструментов, которые продаются в магазине и выпущенных в 2022 году. Я отправляю запрос с параметром 'year'='2022', и мне приходит ответ вот в таком формате: {'mod1': 'пила', 'mod2': 'молоток'} и т.д. Ответ приходит всегда по одной схеме, т.е. 'какое-то поле': str, но кол-во моделей может меняться, соответственно, и длина джейсона и название полей разное, т.е. mod1, mod2, mod3, как можно в таком случае описать pydantic-схему?
Здорово! Спасибо.
Правда кажется експирейшн не совсем корректно делать FutureDate с точки зрения бытового взгляда, потому что мы можем не успеть обновиться пока компьютер не поэкспайрится
Спасибо)))
Я по-этому и указал 2040й год на всякий случай :D Но даже если у нас и будет идти что-то не по плану, всегда на помощь прийдут кастомные валидации для моделей)
билдер на основе модели pydentic можно сделать ?
Из коробки такое не предоставляется.
Небольшое вступление по-поводу самой библиотеки:
Сама по-себе библиотека изначально предназначалась для парсинга данных из объектов типа sqlalchemy, dict и т.д. Спустя время, все поняли, что это крутая штука не только для парсинга, а и для валидации данных и активно начали её форсить в связке с фреймворком fastapi, накрутили кучу фич и т.д. В этом же курсе, она исключительно для валидации данных.
Теперь по-поводу вопроса:
Я думал на этот счёт, что было бы весьма удобно один раз написать модель и использовать её ещё и как генератор, но пришёл к выводу, что это будут только лишние проблемы.
1. Зачем писать ещё один уровень абстракции по-верх базового класса, расширять его куда-то в сторону, не используя основной функционал. (Проще написать обычный билдер с нуля)
2. Управление полями которые ENUM. К примеру, мы генерируем новый тестовый объект, какое из значений присвоить для этого поля? Если дефолтное выбрать, то нужно будет в обязательном порядке менять его на другое в дальнейшем.
Итог: Лучше создать простенький билдер используя faker, чем всю эту штуку переписывать и делать из неё прям монстра.
Спасибо за уроки, но я что-то не понимаю сути происходящего. У нас приходят какие-то данные с сервера/приложения в виде json и мы для проверки генерируем свои данные?
Привет))
Мы получаем данные с сервера и с помощью pydantic валидируем их. То-есть пытаемся сериализировать с помощью pydantic, что намного удобнее, чем использовать довольно популярную библиотеку для валидации данных jsonschema.
А де опублікований код?)
А как работать если некоторые поля меняются под локализацией? Например если поле "Name" имеет английский и корейский варианты?
Добрый вечер, можете пожалуйста скинуть пример JSON, подумаем на проблемой вместе))
@@SolveMeChannel, ух оперативность)
использую Pydantic в связке с SQLAlchemy для тестирования API
Пользователь запрашивает данные пользователя и в зависимости от языка интерфейса . поля 'name' и 'department' соответственно подтягиваются с БД в нужной локализации.
Я парсю JSON ответа ( User.parse_obj(response_json) ) и также парсю даннные со стороны Базы данных ( User.from_orm(UserDB) ) и уже на уровне Pydantic класса сравниваю
response_json= {
"name": "User",
"userId": "Test userId",
"department": "Test Dept"
}
модель Pydantic
class User(BaseModel):
user_id: str = Field(alias='userId')
name: str
department: str
class Config:
orm_mode = True
allow_population_by_field_name = True
в Базе данных модель юзера такая
class UserDB(Base):
__tablename__ = 'user'
id = Column(Integer, primary_key=True)
user_id = Column(String)
user_nm_kr = Column(String)
user_nm_en = Column(String)
dept_nm_kr = Column(String)
dept_nm_en = Column(String)
UPD: пока писал, понял что скорее всего логика должна быть на стороне бека в подготовке объекта от Базы данных
Есть один вопросик, а именно как работает эта штука? У меня лично 2 догадки :)
Вариант 1
Если нет обычного имени - возвращает kr
Вариант 2
При запросе на сервер передают хедер accept-language с языком, если такой язык есть, в таком и возвращается имя и другие параметры (Судя по респонсу, скорей всего так и есть, так как первый вариант менее популярный). Если же языка нет или хедер не передали, то возвращают все доступные локализации и параметры к ним в отдельном обьекте.
===========================
Для первого варианта:
from sqlalchemy import func
def get_user_data(lang="en"):
data = session.query(
tables.UserDB.user_id,
func.coalesce(tables.UserDB.user_nm_en, tables.UserDB.user_nm_kr),
func.coalesce(tables.UserDB.dept_nm_en, tables.UserDB.dept_nm_kr)
).first()
return data
Для второго варианта есть такой ход конём:
Если ты знаешь какой язык сейчас нужно селектить из базы, то можно вот так поступить:
def get_user_data(lang="en"):
LANG_MAPPER = {
"en": (tables.UserDB.user_id, tables.UserDB.user_nm_en, tables.UserDB.dept_nm_en)
"kr": (tables.UserDB.user_id, tables.UserDB.user_nm_kr, tables.UserDB.dept_nm_kr)
}
data = session.query(LANG_MAPPER.get(lang)).first()
return data
PS: Надеюсь я правильно понял суть проблемы :)
Спасибо большое за уроки.
Помогите разобраться с одним моментом. Есть один вопрос. Как правильно описать джисон если первый словарь идет как динамический - это айдишник, по которому и получается джисон с сервера. Проблема в том что он всегда разный и он по сути значение, а ключа нету. Я по разному пробовал но не получается. Спасибо заранее за помощь.
Доброго времени суток) Можете пожалуйста написать пример и попробуем решить проблему вместе ?)
@@SolveMeChannel Здравствуйте.
json = {'158023': {'prices': {'xbox': {'LCPrice': '217,000', 'LCPrice2': '218,000', 'LCPrice3': '218,000',
'LCPrice4': '219,000', 'LCPrice5': '220,000', 'updated': '5 mins ago',
'MinPrice': '24,250', 'MaxPrice': '460,000', 'PRP': '44'},
'ps': {'LCPrice': '276,000', 'LCPrice2': '278,000', 'LCPrice3': '280,000',
'LCPrice4': '280,000', 'LCPrice5': '280,000', 'updated': '5 mins ago',
'MinPrice': '30,000', 'MaxPrice': '550,000', 'PRP': '47'},
'pc': {'LCPrice': '362,000', 'LCPrice2': '365,000', 'LCPrice3': '366,000',
'LCPrice4': '369,000', 'LCPrice5': '369,000', 'updated': '11 mins ago',
'MinPrice': '38,500', 'MaxPrice': '750,000', 'PRP': '45'}}}}
интересует '158023' = это айдишники и они всегда разные
он получается динамический и я вовсе не понимаю как его описать. Заранее спасибо за любую помощь!
Можете пожалуйста написать мне этот пример на почту или в группу в телеграм? А то youtube удаляет комментарии некоторые :(
Добрый день. Спасибо за лекции, очень актуально!
Есть вопрос - может ли pydantic работать с "плавающими" секциями в json. Например family, name, middlename. Бывает что отчества нет или оно не указано, и поле то есть, то его нет.
Добрый день, в таком случае можно использовать значение по-умолчанию, к примеру:
class Human(BaseModel):
name: str
last_name: str
surname: str = None
human = Human.parse_obj({
"name": "Andrii",
"last_name": "Shevchenko",
"surname": "Sheva"
})
print(human.surname)
human = Human.parse_obj({
"name": "Andrii",
"last_name": "Shevchenko"
})
print(human.surname)
Если имени не будет, то ничего не произойдёт и в значении surname будет None, если есть, то будет соответственно то, что было передано. surname: str = None - эта конструкция как-раз и позволяет работать с необязательными полями (принцип тот же, как при описании аргументов которые может принимать метод/функция на вход). Так же вместо None, там может быть что угодно (число, массив, строка и т.д.), не рекомендовал бы только использовать пустую строку, так как нельзя будет потом понять, вам пришла пустая строка или это значение по-умолчанию, а так, вы можете создать валидацию на это поле, проверить что оно не None и если это так, делать какие-то проверки.
@@SolveMeChannel Спасибо за быстрый и развёрнутый ответ
@@SolveMeChannel а что делать если, например, поле зависит от какой-то логики? Например, поле surname показывается, если поле show_surname = true.
У меня подобная ситуация сейчас. Думаю как решить. Не хочется все эти поля делать optional.
Alexander V. Привет :)
Можно воспользоваться вот такой конструкцией:
class Human(BaseModel):
name: str
last_name: str
surname: str = None
is_hide: bool
@validator('is_hide')
def validate_surname_showing(cls, hide_value, values):
if hide_value is False and values.get('surname') is None:
raise ValueError('Surname should be presented')
return hide_value
human = Human.parse_obj({
"name": "Andrii",
"last_name": "Shevchenko",
"is_hide": True
})
Обязательно валидировать поле is_hide и в валидаторе дополнительно принимать все значения, после этого просто проверять значение поля is_hide и то, что было передано. Обрати внимание, что если мы например валидируем поле is_hide, то в параметр values попадут все значения которые в описании класса находятся выше него, если бы мы разместили surname ниже is_hide, то нам бы постоянно приходил None и валидатор бы фейлился. Это из-за того, что он валидирует всё построчно и параметры ниже валидируемого поля просто ещё не попали в обьект класса pydantic.
@@SolveMeChannel спасибо)
Позволю себе задать еще вопрос: как ты организовал логирование ошибок с Pydantic в контексте получения отчетов в связке с allure?
У меня тест помечается как broken, а не failed в случае каких-то ошибок в валидации.
Спасибо заранее)
Я не внимательно смотрел видео или правда обещанного сравнения как бы эта валидация выглядела с использованием json schema не было?
Добрый день, в этом видео ua-cam.com/video/6QjDW-p_F-o/v-deo.html показывал как с ней работать и уже в дальнейших видео показывал как работать с pydantic, так же , почему я отдаю предпочтение именно ему.
You hide your currently edited file names and it's hard to copy something from your code.
You can push your changes for each lesson as a separate branch as this guy did for his 7hours tutorial.
ua-cam.com/video/c708Nf0cHrs/v-deo.html
Channel super except for this issues
Hello, thank you so much for your response. I've fixed the issue with displaying the current tab. The creation of separate branches for each lesson was as hard for me as it could be because all lessons have been published and it is almost impossible to copy symbol by symbol.
One more thing about why I don't want to do that it is the main idea of the lessons project, I want to have some cookbook for our community in which they could find anything without searching the Internet for a quick start of automation.
Зачем постоянно меняешь фрейм? Не пойму, усложнять то зачем
Привет дружище, к сожалению, у меня были большие проблемы с расширением экрана и как следствие, его отображение в видео, каждое видео это логическая эволюция -___- В первом исправил консоль, теперь не видно табы, исправил табы, не видно консоль, поменял назад и делал так, чтобы было видно что я пишу в консольке, потом исправил размер шрифта и т.д.
По этому, сорри, сейчас уже +- пришёл к чему-то адекватному, если что-то не видно или не получается, пиши, я постараюсь помочь)
@@SolveMeChannel о спасибо большое не думал что ответишь. Сам недавно начал изучать автомейшн. Иногда работаю на Постмане, вручную ароверяю. Работаю на мануал тестинг. Спасибо за твои видео, многому научил. Удачи тебе и самые лучшие пожелания