Conversation
|
Я по началу попробовал поменять решение предыдущего задания, добавить новые поля к старым классам и т.п. Но получить потом нахаляву GraphQL type, просто наследовав новые классы от новых, у меня не получилось (либо это в принципе невозможно, либо я что-то не так делал). В итоге я создал просто отдельный файл для экспериментов с GraphQL -- файл |
| Перед тестированием установите: | ||
| `pip install email-validator` |
There was a problem hiding this comment.
посмотрите poetry - позволяет удобно разделять зависимости dev и prod
| @strawberry.type | ||
| class Date: | ||
| year: int | ||
| month: int | ||
| day: int |
There was a problem hiding this comment.
strawberry поддерживает datetime стандартный, так что можно было его просто использовать
| return list(filter(lambda u: u.additional_info.birth_date.year == year, [ | ||
| UserMeta( | ||
| "hello@world.ru", | ||
| "Mike", | ||
| AdditionalInfo( | ||
| "I am a hero", | ||
| Date(2001, 1, 1) | ||
| ) | ||
| ), | ||
| UserMeta( | ||
| "hi@world.ru", | ||
| "Pol", | ||
| AdditionalInfo( | ||
| "DevOps", | ||
| Date(1001, 1, 1) | ||
| ) | ||
| ), | ||
| ])) |
There was a problem hiding this comment.
как временное решение нормально, но дальновиднее было бы вынести в отдельную функцию, которая бы потом просто переписалась при появлении полноценной БД. Хотя в теории можно и здесь к БД стучаться прямо в лямбде, но лямбды дебажить иногда сложнее и нужно быть осторожным с именем переменной, т.к. скоуп может по невнимательности полететь.
|
|
||
| @validator('name') | ||
| def name_alphanumeric(cls, v): | ||
| assert v.isalnum(), 'must be alphanumeric' |
There was a problem hiding this comment.
assert, вообще говоря, не очень хорошо использовать в логике (в тестах - норм). линтеры проверяющие секьюрность на него ругаются, например вот, что думает об assert bandit
| def validate_new_password(pwd: SecretStr): | ||
| value = pwd.get_secret_value() | ||
| if re.search(r"[a-z]", value) is None: | ||
| raise ValueError("password must contain lowercase letter", r"[a-z]") | ||
| if re.search(r"[A-Z]", value) is None: | ||
| raise ValueError("password must contain uppercase letter", r"[A-Z]") | ||
| if re.search(r"[0-9]", value) is None: | ||
| raise ValueError("password must contain digit", r"[0-9]") | ||
| if re.search(r"[!@#_.]", value) is None: | ||
| raise ValueError("password must contain special character '!', '@', '#', '_' or '.'", r"[!@#_.]") | ||
| m = re.search(r"[^a-zA-Z0-9!@#_.]", value) | ||
| if m is not None: | ||
| raise ValueError("password contains forbidden character " + m.group(0), "wrong char") |
There was a problem hiding this comment.
В ситуации, когда регулярное выражение заранее известно, гораздо эффективнее его скомпилировать заранее, т.к. работают они довольно медленно.
Например, можно сделать так:
checkups = [
(re.compile(r"[a-z]"), "password must contain lowercase letter"),
...
]
def validate_new_password(pwd: SecretStr):
value = pwd.get_secret_value()
for checkup in checkups:
if checkup[0].search(value) is None:
raise ValueError(checkup[1])
...тут нужно подумать, как красивее сделать последнее условие, но глобально скомпилить их заранее лучше, чем делать это каждый раз
No description provided.