This commit is contained in:
Hayden 2023-08-13 17:45:23 -05:00
parent e55258c5be
commit be372dbc51
No known key found for this signature in database
GPG Key ID: 17CF79474E257545
54 changed files with 438 additions and 437 deletions

View File

@ -1,7 +1,8 @@
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from pathlib import Path from pathlib import Path
from pydantic import BaseModel, BaseSettings, PostgresDsn from pydantic import BaseModel, PostgresDsn
from pydantic_settings import BaseSettings
class AbstractDBProvider(ABC): class AbstractDBProvider(ABC):

View File

@ -1,7 +1,8 @@
import secrets import secrets
from pathlib import Path from pathlib import Path
from pydantic import BaseSettings, NoneStr, validator from pydantic import field_validator
from pydantic_settings import BaseSettings, SettingsConfigDict
from .db_providers import AbstractDBProvider, db_provider_factory from .db_providers import AbstractDBProvider, db_provider_factory
@ -48,7 +49,8 @@ class AppSettings(BaseSettings):
SECURITY_USER_LOCKOUT_TIME: int = 24 SECURITY_USER_LOCKOUT_TIME: int = 24
"time in hours" "time in hours"
@validator("BASE_URL") @field_validator("BASE_URL")
@classmethod
def remove_trailing_slash(cls, v: str) -> str: def remove_trailing_slash(cls, v: str) -> str:
if v and v[-1] == "/": if v and v[-1] == "/":
return v[:-1] return v[:-1]
@ -127,15 +129,15 @@ class AppSettings(BaseSettings):
# LDAP Configuration # LDAP Configuration
LDAP_AUTH_ENABLED: bool = False LDAP_AUTH_ENABLED: bool = False
LDAP_SERVER_URL: NoneStr = None LDAP_SERVER_URL: None | str = None
LDAP_TLS_INSECURE: bool = False LDAP_TLS_INSECURE: bool = False
LDAP_TLS_CACERTFILE: NoneStr = None LDAP_TLS_CACERTFILE: None | str = None
LDAP_ENABLE_STARTTLS: bool = False LDAP_ENABLE_STARTTLS: bool = False
LDAP_BASE_DN: NoneStr = None LDAP_BASE_DN: None | str = None
LDAP_QUERY_BIND: NoneStr = None LDAP_QUERY_BIND: None | str = None
LDAP_QUERY_PASSWORD: NoneStr = None LDAP_QUERY_PASSWORD: None | str = None
LDAP_USER_FILTER: NoneStr = None LDAP_USER_FILTER: None | str = None
LDAP_ADMIN_FILTER: NoneStr = None LDAP_ADMIN_FILTER: None | str = None
LDAP_ID_ATTRIBUTE: str = "uid" LDAP_ID_ATTRIBUTE: str = "uid"
LDAP_MAIL_ATTRIBUTE: str = "mail" LDAP_MAIL_ATTRIBUTE: str = "mail"
LDAP_NAME_ATTRIBUTE: str = "name" LDAP_NAME_ATTRIBUTE: str = "name"
@ -157,9 +159,7 @@ class AppSettings(BaseSettings):
# Testing Config # Testing Config
TESTING: bool = False TESTING: bool = False
model_config = SettingsConfigDict(arbitrary_types_allowed=True)
class Config:
arbitrary_types_allowed = True
def app_settings_constructor(data_dir: Path, production: bool, env_file: Path, env_encoding="utf-8") -> AppSettings: def app_settings_constructor(data_dir: Path, production: bool, env_file: Path, env_encoding="utf-8") -> AppSettings:

View File

@ -2,6 +2,7 @@ from typing import TYPE_CHECKING, Optional
import sqlalchemy as sa import sqlalchemy as sa
import sqlalchemy.orm as orm import sqlalchemy.orm as orm
from pydantic import ConfigDict
from sqlalchemy import select from sqlalchemy import select
from sqlalchemy.orm import Mapped, mapped_column from sqlalchemy.orm import Mapped, mapped_column
from sqlalchemy.orm.session import Session from sqlalchemy.orm.session import Session
@ -78,18 +79,16 @@ class Group(SqlAlchemyBase, BaseMixins):
ingredient_foods: Mapped[list["IngredientFoodModel"]] = orm.relationship("IngredientFoodModel", **common_args) ingredient_foods: Mapped[list["IngredientFoodModel"]] = orm.relationship("IngredientFoodModel", **common_args)
tools: Mapped[list["Tool"]] = orm.relationship("Tool", **common_args) tools: Mapped[list["Tool"]] = orm.relationship("Tool", **common_args)
tags: Mapped[list["Tag"]] = orm.relationship("Tag", **common_args) tags: Mapped[list["Tag"]] = orm.relationship("Tag", **common_args)
model_config = ConfigDict(exclude={
class Config: "users",
exclude = { "webhooks",
"users", "shopping_lists",
"webhooks", "cookbooks",
"shopping_lists", "preferences",
"cookbooks", "invite_tokens",
"preferences", "mealplans",
"invite_tokens", "data_exports",
"mealplans", })
"data_exports",
}
@auto_init() @auto_init()
def __init__(self, **_) -> None: def __init__(self, **_) -> None:

View File

@ -1,6 +1,7 @@
from datetime import datetime from datetime import datetime
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from pydantic import ConfigDict
from sqlalchemy import ForeignKey, orm from sqlalchemy import ForeignKey, orm
from sqlalchemy.orm import Mapped, mapped_column from sqlalchemy.orm import Mapped, mapped_column
from sqlalchemy.sql.sqltypes import Boolean, DateTime, String from sqlalchemy.sql.sqltypes import Boolean, DateTime, String
@ -47,9 +48,7 @@ class ReportModel(SqlAlchemyBase, BaseMixins):
# Relationships # Relationships
group_id: Mapped[GUID] = mapped_column(GUID, ForeignKey("groups.id"), nullable=False, index=True) group_id: Mapped[GUID] = mapped_column(GUID, ForeignKey("groups.id"), nullable=False, index=True)
group: Mapped["Group"] = orm.relationship("Group", back_populates="group_reports", single_parent=True) group: Mapped["Group"] = orm.relationship("Group", back_populates="group_reports", single_parent=True)
model_config = ConfigDict(exclude=["entries"])
class Config:
exclude = ["entries"]
@auto_init() @auto_init()
def __init__(self, **_) -> None: def __init__(self, **_) -> None:

View File

@ -1,5 +1,6 @@
from typing import TYPE_CHECKING, Optional from typing import TYPE_CHECKING, Optional
from pydantic import ConfigDict
from sqlalchemy import Boolean, Float, ForeignKey, Integer, String, orm from sqlalchemy import Boolean, Float, ForeignKey, Integer, String, orm
from sqlalchemy.ext.orderinglist import ordering_list from sqlalchemy.ext.orderinglist import ordering_list
from sqlalchemy.orm import Mapped, mapped_column from sqlalchemy.orm import Mapped, mapped_column
@ -72,9 +73,7 @@ class ShoppingListItem(SqlAlchemyBase, BaseMixins):
recipe_references: Mapped[list[ShoppingListItemRecipeReference]] = orm.relationship( recipe_references: Mapped[list[ShoppingListItemRecipeReference]] = orm.relationship(
ShoppingListItemRecipeReference, cascade="all, delete, delete-orphan" ShoppingListItemRecipeReference, cascade="all, delete, delete-orphan"
) )
model_config = ConfigDict(exclude={"id", "label", "food", "unit"})
class Config:
exclude = {"id", "label", "food", "unit"}
@api_extras @api_extras
@auto_init() @auto_init()
@ -94,9 +93,7 @@ class ShoppingListRecipeReference(BaseMixins, SqlAlchemyBase):
) )
recipe_quantity: Mapped[float] = mapped_column(Float, nullable=False) recipe_quantity: Mapped[float] = mapped_column(Float, nullable=False)
model_config = ConfigDict(exclude={"id", "recipe"})
class Config:
exclude = {"id", "recipe"}
@auto_init() @auto_init()
def __init__(self, **_) -> None: def __init__(self, **_) -> None:
@ -114,9 +111,7 @@ class ShoppingListMultiPurposeLabel(SqlAlchemyBase, BaseMixins):
"MultiPurposeLabel", back_populates="shopping_lists_label_settings" "MultiPurposeLabel", back_populates="shopping_lists_label_settings"
) )
position: Mapped[int] = mapped_column(Integer, nullable=False, default=0) position: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
model_config = ConfigDict(exclude={"label"})
class Config:
exclude = {"label"}
@auto_init() @auto_init()
def __init__(self, **_) -> None: def __init__(self, **_) -> None:
@ -148,9 +143,7 @@ class ShoppingList(SqlAlchemyBase, BaseMixins):
collection_class=ordering_list("position"), collection_class=ordering_list("position"),
) )
extras: Mapped[list[ShoppingListExtras]] = orm.relationship("ShoppingListExtras", cascade="all, delete-orphan") extras: Mapped[list[ShoppingListExtras]] = orm.relationship("ShoppingListExtras", cascade="all, delete-orphan")
model_config = ConfigDict(exclude={"id", "list_items"})
class Config:
exclude = {"id", "list_items"}
@api_extras @api_extras
@auto_init() @auto_init()

View File

@ -1,3 +1,4 @@
from pydantic import ConfigDict
from sqlalchemy import ForeignKey, Integer, String, orm from sqlalchemy import ForeignKey, Integer, String, orm
from sqlalchemy.orm import Mapped, mapped_column from sqlalchemy.orm import Mapped, mapped_column
@ -28,12 +29,10 @@ class RecipeInstruction(SqlAlchemyBase):
ingredient_references: Mapped[list[RecipeIngredientRefLink]] = orm.relationship( ingredient_references: Mapped[list[RecipeIngredientRefLink]] = orm.relationship(
RecipeIngredientRefLink, cascade="all, delete-orphan" RecipeIngredientRefLink, cascade="all, delete-orphan"
) )
model_config = ConfigDict(exclude={
class Config: "id",
exclude = { "ingredient_references",
"id", })
"ingredient_references",
}
@auto_init() @auto_init()
def __init__(self, ingredient_references, session, **_) -> None: def __init__(self, ingredient_references, session, **_) -> None:

View File

@ -3,6 +3,7 @@ from typing import TYPE_CHECKING
import sqlalchemy as sa import sqlalchemy as sa
import sqlalchemy.orm as orm import sqlalchemy.orm as orm
from pydantic import ConfigDict
from sqlalchemy import event from sqlalchemy import event
from sqlalchemy.ext.orderinglist import ordering_list from sqlalchemy.ext.orderinglist import ordering_list
from sqlalchemy.orm import Mapped, mapped_column, validates from sqlalchemy.orm import Mapped, mapped_column, validates
@ -135,19 +136,16 @@ class RecipeModel(SqlAlchemyBase, BaseMixins):
# Automatically updated by sqlalchemy event, do not write to this manually # Automatically updated by sqlalchemy event, do not write to this manually
name_normalized: Mapped[str] = mapped_column(sa.String, nullable=False, index=True) name_normalized: Mapped[str] = mapped_column(sa.String, nullable=False, index=True)
description_normalized: Mapped[str | None] = mapped_column(sa.String, index=True) description_normalized: Mapped[str | None] = mapped_column(sa.String, index=True)
model_config = ConfigDict(get_attr="slug", exclude={
class Config: "assets",
get_attr = "slug" "notes",
exclude = { "nutrition",
"assets", "recipe_ingredient",
"notes", "recipe_instructions",
"nutrition", "settings",
"recipe_ingredient", "comments",
"recipe_instructions", "timeline_events",
"settings", })
"comments",
"timeline_events",
}
@validates("name") @validates("name")
def validate_name(self, _, name): def validate_name(self, _, name):

View File

@ -2,6 +2,7 @@ import enum
from datetime import datetime from datetime import datetime
from typing import TYPE_CHECKING, Optional from typing import TYPE_CHECKING, Optional
from pydantic import ConfigDict
from sqlalchemy import Boolean, DateTime, Enum, ForeignKey, Integer, String, orm from sqlalchemy import Boolean, DateTime, Enum, ForeignKey, Integer, String, orm
from sqlalchemy.orm import Mapped, mapped_column from sqlalchemy.orm import Mapped, mapped_column
@ -83,16 +84,14 @@ class User(SqlAlchemyBase, BaseMixins):
favorite_recipes: Mapped[list["RecipeModel"]] = orm.relationship( favorite_recipes: Mapped[list["RecipeModel"]] = orm.relationship(
"RecipeModel", secondary=users_to_favorites, back_populates="favorited_by" "RecipeModel", secondary=users_to_favorites, back_populates="favorited_by"
) )
model_config = ConfigDict(exclude={
class Config: "password",
exclude = { "admin",
"password", "can_manage",
"admin", "can_invite",
"can_manage", "can_organize",
"can_invite", "group",
"can_organize", })
"group",
}
@auto_init() @auto_init()
def __init__(self, session, full_name, password, group: str | None = None, **kwargs) -> None: def __init__(self, session, full_name, password, group: str | None = None, **kwargs) -> None:

View File

@ -60,7 +60,7 @@ class RepositoryRecipes(RepositoryGeneric[Recipe, RecipeModel]):
stmt = ( stmt = (
select(self.model) select(self.model)
.join(RecipeSettings) .join(RecipeSettings)
.filter(RecipeSettings.public == True) # noqa: 711 .filter(RecipeSettings.public is True) # noqa: 711
.order_by(order_attr.desc()) .order_by(order_attr.desc())
.offset(start) .offset(start)
.limit(limit) .limit(limit)
@ -70,7 +70,7 @@ class RepositoryRecipes(RepositoryGeneric[Recipe, RecipeModel]):
stmt = ( stmt = (
select(self.model) select(self.model)
.join(RecipeSettings) .join(RecipeSettings)
.filter(RecipeSettings.public == True) # noqa: 711 .filter(RecipeSettings.public is True) # noqa: 711
.offset(start) .offset(start)
.limit(limit) .limit(limit)
) )

View File

@ -2,7 +2,7 @@ from abc import ABC
from logging import Logger from logging import Logger
from fastapi import Depends from fastapi import Depends
from pydantic import UUID4 from pydantic import UUID4, ConfigDict
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from mealie.core.config import get_app_dirs, get_app_settings from mealie.core.config import get_app_dirs, get_app_settings
@ -57,9 +57,7 @@ class _BaseController(ABC):
if not self._folders: if not self._folders:
self._folders = get_app_dirs() self._folders = get_app_dirs()
return self._folders return self._folders
model_config = ConfigDict(arbitrary_types_allowed=True)
class Config:
arbitrary_types_allowed = True
class BasePublicController(_BaseController): class BasePublicController(_BaseController):

View File

@ -1,7 +1,7 @@
from functools import cached_property from functools import cached_property
from fastapi import APIRouter, Depends from fastapi import APIRouter, Depends
from pydantic import UUID4, BaseModel from pydantic import UUID4, BaseModel, ConfigDict
from mealie.routes._base import BaseCrudController, controller from mealie.routes._base import BaseCrudController, controller
from mealie.routes._base.mixins import HttpRepo from mealie.routes._base.mixins import HttpRepo
@ -20,9 +20,7 @@ class CategorySummary(BaseModel):
id: UUID4 id: UUID4
slug: str slug: str
name: str name: str
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True
@controller(router) @controller(router)

View File

@ -4,16 +4,14 @@ from collections.abc import Sequence
from typing import Protocol, TypeVar from typing import Protocol, TypeVar
from humps.main import camelize from humps.main import camelize
from pydantic import UUID4, BaseModel from pydantic import UUID4, BaseModel, ConfigDict
from sqlalchemy.orm.interfaces import LoaderOption from sqlalchemy.orm.interfaces import LoaderOption
T = TypeVar("T", bound=BaseModel) T = TypeVar("T", bound=BaseModel)
class MealieModel(BaseModel): class MealieModel(BaseModel):
class Config: model_config = ConfigDict(alias_generator=camelize, populate_by_name=True)
alias_generator = camelize
allow_population_by_field_name = True
def cast(self, cls: type[T], **kwargs) -> T: def cast(self, cls: type[T], **kwargs) -> T:
""" """

View File

@ -19,9 +19,9 @@ class ImportJob(BackupOptions):
class CreateBackup(BaseModel): class CreateBackup(BaseModel):
tag: str | None tag: str | None = None
options: BackupOptions options: BackupOptions
templates: list[str] | None templates: list[str] | None = None
class BackupFile(BaseModel): class BackupFile(BaseModel):

View File

@ -4,11 +4,11 @@ from pydantic.main import BaseModel
class ImportBase(BaseModel): class ImportBase(BaseModel):
name: str name: str
status: bool status: bool
exception: str | None exception: str | None = None
class RecipeImport(ImportBase): class RecipeImport(ImportBase):
slug: str | None slug: str | None = None
class CommentImport(ImportBase): class CommentImport(ImportBase):

View File

@ -1,4 +1,4 @@
from pydantic import validator from pydantic import ConfigDict, validator
from slugify import slugify from slugify import slugify
from mealie.schema._mealie import MealieModel from mealie.schema._mealie import MealieModel
@ -11,10 +11,10 @@ class CustomPageBase(MealieModel):
slug: str | None slug: str | None
position: int position: int
categories: list[RecipeCategoryResponse] = [] categories: list[RecipeCategoryResponse] = []
model_config = ConfigDict(from_attributes=True)
class Config: # TODO[pydantic]: We couldn't refactor the `validator`, please replace it by `field_validator` manually.
orm_mode = True # Check https://docs.pydantic.dev/dev-v2/migration/#changes-to-validators for more information.
@validator("slug", always=True, pre=True) @validator("slug", always=True, pre=True)
def validate_slug(slug: str, values): def validate_slug(slug: str, values):
name: str = values["name"] name: str = values["name"]
@ -28,6 +28,4 @@ class CustomPageBase(MealieModel):
class CustomPageOut(CustomPageBase): class CustomPageOut(CustomPageBase):
id: int id: int
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True

View File

@ -1,4 +1,4 @@
from pydantic import UUID4, validator from pydantic import UUID4, ConfigDict, validator
from slugify import slugify from slugify import slugify
from sqlalchemy.orm import joinedload from sqlalchemy.orm import joinedload
from sqlalchemy.orm.interfaces import LoaderOption from sqlalchemy.orm.interfaces import LoaderOption
@ -24,10 +24,14 @@ class CreateCookBook(MealieModel):
require_all_tags: bool = True require_all_tags: bool = True
require_all_tools: bool = True require_all_tools: bool = True
# TODO[pydantic]: We couldn't refactor the `validator`, please replace it by `field_validator` manually.
# Check https://docs.pydantic.dev/dev-v2/migration/#changes-to-validators for more information.
@validator("public", always=True, pre=True) @validator("public", always=True, pre=True)
def validate_public(public: bool | None, values: dict) -> bool: # type: ignore def validate_public(public: bool | None, values: dict) -> bool: # type: ignore
return False if public is None else public return False if public is None else public
# TODO[pydantic]: We couldn't refactor the `validator`, please replace it by `field_validator` manually.
# Check https://docs.pydantic.dev/dev-v2/migration/#changes-to-validators for more information.
@validator("slug", always=True, pre=True) @validator("slug", always=True, pre=True)
def validate_slug(slug: str, values): # type: ignore def validate_slug(slug: str, values): # type: ignore
name: str = values["name"] name: str = values["name"]
@ -50,9 +54,7 @@ class UpdateCookBook(SaveCookBook):
class ReadCookBook(UpdateCookBook): class ReadCookBook(UpdateCookBook):
group_id: UUID4 group_id: UUID4
categories: list[CategoryBase] = [] categories: list[CategoryBase] = []
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True
@classmethod @classmethod
def loader_options(cls) -> list[LoaderOption]: def loader_options(cls) -> list[LoaderOption]:
@ -66,6 +68,4 @@ class CookBookPagination(PaginationBase):
class RecipeCookBook(ReadCookBook): class RecipeCookBook(ReadCookBook):
group_id: UUID4 group_id: UUID4
recipes: list[RecipeSummary] recipes: list[RecipeSummary]
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True

View File

@ -1,4 +1,4 @@
from pydantic import UUID4, NoneStr from pydantic import UUID4, ConfigDict, NoneStr
from sqlalchemy.orm import joinedload from sqlalchemy.orm import joinedload
from sqlalchemy.orm.interfaces import LoaderOption from sqlalchemy.orm.interfaces import LoaderOption
@ -54,9 +54,7 @@ class GroupEventNotifierOptionsSave(GroupEventNotifierOptions):
class GroupEventNotifierOptionsOut(GroupEventNotifierOptions): class GroupEventNotifierOptionsOut(GroupEventNotifierOptions):
id: UUID4 id: UUID4
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True
# ======================================================================= # =======================================================================
@ -85,9 +83,7 @@ class GroupEventNotifierOut(MealieModel):
enabled: bool enabled: bool
group_id: UUID4 group_id: UUID4
options: GroupEventNotifierOptionsOut options: GroupEventNotifierOptionsOut
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True
@classmethod @classmethod
def loader_options(cls) -> list[LoaderOption]: def loader_options(cls) -> list[LoaderOption]:
@ -100,6 +96,4 @@ class GroupEventPagination(PaginationBase):
class GroupEventNotifierPrivate(GroupEventNotifierOut): class GroupEventNotifierPrivate(GroupEventNotifierOut):
apprise_url: str apprise_url: str
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True

View File

@ -1,6 +1,6 @@
from datetime import datetime from datetime import datetime
from pydantic import UUID4 from pydantic import UUID4, ConfigDict
from mealie.schema._mealie import MealieModel from mealie.schema._mealie import MealieModel
@ -13,6 +13,4 @@ class GroupDataExport(MealieModel):
path: str path: str
size: str size: str
expires: datetime expires: datetime
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True

View File

@ -1,6 +1,6 @@
from uuid import UUID from uuid import UUID
from pydantic import UUID4 from pydantic import UUID4, ConfigDict
from mealie.schema._mealie import MealieModel from mealie.schema._mealie import MealieModel
@ -24,6 +24,4 @@ class CreateGroupPreferences(UpdateGroupPreferences):
class ReadGroupPreferences(CreateGroupPreferences): class ReadGroupPreferences(CreateGroupPreferences):
id: UUID4 id: UUID4
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True

View File

@ -7,6 +7,8 @@ from mealie.schema._mealie.validators import validate_locale
class SeederConfig(MealieModel): class SeederConfig(MealieModel):
locale: str locale: str
# TODO[pydantic]: We couldn't refactor the `validator`, please replace it by `field_validator` manually.
# Check https://docs.pydantic.dev/dev-v2/migration/#changes-to-validators for more information.
@validator("locale") @validator("locale")
def valid_locale(cls, v, values, **kwargs): def valid_locale(cls, v, values, **kwargs):
if not validate_locale(v): if not validate_locale(v):

View File

@ -2,7 +2,7 @@ from __future__ import annotations
from datetime import datetime from datetime import datetime
from pydantic import UUID4, validator from pydantic import UUID4, ConfigDict, field_validator
from sqlalchemy.orm import joinedload, selectinload from sqlalchemy.orm import joinedload, selectinload
from sqlalchemy.orm.interfaces import LoaderOption from sqlalchemy.orm.interfaces import LoaderOption
@ -35,7 +35,8 @@ class ShoppingListItemRecipeRefCreate(MealieModel):
recipe_scale: NoneFloat = 1 recipe_scale: NoneFloat = 1
"""the number of times this recipe has been added""" """the number of times this recipe has been added"""
@validator("recipe_quantity", pre=True) @field_validator("recipe_quantity", mode="before")
@classmethod
def default_none_to_zero(cls, v): def default_none_to_zero(cls, v):
return 0 if v is None else v return 0 if v is None else v
@ -46,8 +47,7 @@ class ShoppingListItemRecipeRefUpdate(ShoppingListItemRecipeRefCreate):
class ShoppingListItemRecipeRefOut(ShoppingListItemRecipeRefUpdate): class ShoppingListItemRecipeRefOut(ShoppingListItemRecipeRefUpdate):
class Config: model_config = ConfigDict(from_attributes=True)
orm_mode = True
class ShoppingListItemBase(RecipeIngredientBase): class ShoppingListItemBase(RecipeIngredientBase):
@ -98,10 +98,9 @@ class ShoppingListItemOut(ShoppingListItemBase):
if (not self.label) and (self.food and self.food.label): if (not self.label) and (self.food and self.food.label):
self.label = self.food.label self.label = self.food.label
self.label_id = self.label.id self.label_id = self.label.id
# TODO[pydantic]: The following keys were removed: `getter_dict`.
class Config: # Check https://docs.pydantic.dev/dev-v2/migration/#changes-to-config for more information.
orm_mode = True model_config = ConfigDict(from_attributes=True, getter_dict=ExtrasGetterDict)
getter_dict = ExtrasGetterDict
@classmethod @classmethod
def loader_options(cls) -> list[LoaderOption]: def loader_options(cls) -> list[LoaderOption]:
@ -135,9 +134,7 @@ class ShoppingListMultiPurposeLabelUpdate(ShoppingListMultiPurposeLabelCreate):
class ShoppingListMultiPurposeLabelOut(ShoppingListMultiPurposeLabelUpdate): class ShoppingListMultiPurposeLabelOut(ShoppingListMultiPurposeLabelUpdate):
label: MultiPurposeLabelSummary label: MultiPurposeLabelSummary
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True
@classmethod @classmethod
def loader_options(cls) -> list[LoaderOption]: def loader_options(cls) -> list[LoaderOption]:
@ -164,9 +161,7 @@ class ShoppingListRecipeRefOut(MealieModel):
"""the number of times this recipe has been added""" """the number of times this recipe has been added"""
recipe: RecipeSummary recipe: RecipeSummary
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True
@classmethod @classmethod
def loader_options(cls) -> list[LoaderOption]: def loader_options(cls) -> list[LoaderOption]:
@ -185,10 +180,9 @@ class ShoppingListSummary(ShoppingListSave):
id: UUID4 id: UUID4
recipe_references: list[ShoppingListRecipeRefOut] recipe_references: list[ShoppingListRecipeRefOut]
label_settings: list[ShoppingListMultiPurposeLabelOut] label_settings: list[ShoppingListMultiPurposeLabelOut]
# TODO[pydantic]: The following keys were removed: `getter_dict`.
class Config: # Check https://docs.pydantic.dev/dev-v2/migration/#changes-to-config for more information.
orm_mode = True model_config = ConfigDict(from_attributes=True, getter_dict=ExtrasGetterDict)
getter_dict = ExtrasGetterDict
@classmethod @classmethod
def loader_options(cls) -> list[LoaderOption]: def loader_options(cls) -> list[LoaderOption]:
@ -219,10 +213,9 @@ class ShoppingListUpdate(ShoppingListSave):
class ShoppingListOut(ShoppingListUpdate): class ShoppingListOut(ShoppingListUpdate):
recipe_references: list[ShoppingListRecipeRefOut] recipe_references: list[ShoppingListRecipeRefOut]
label_settings: list[ShoppingListMultiPurposeLabelOut] label_settings: list[ShoppingListMultiPurposeLabelOut]
# TODO[pydantic]: The following keys were removed: `getter_dict`.
class Config: # Check https://docs.pydantic.dev/dev-v2/migration/#changes-to-config for more information.
orm_mode = True model_config = ConfigDict(from_attributes=True, getter_dict=ExtrasGetterDict)
getter_dict = ExtrasGetterDict
@classmethod @classmethod
def loader_options(cls) -> list[LoaderOption]: def loader_options(cls) -> list[LoaderOption]:

View File

@ -1,6 +1,6 @@
from uuid import UUID from uuid import UUID
from pydantic import NoneStr from pydantic import ConfigDict, NoneStr
from mealie.schema._mealie import MealieModel from mealie.schema._mealie import MealieModel
@ -19,9 +19,7 @@ class ReadInviteToken(MealieModel):
token: str token: str
uses_left: int uses_left: int
group_id: UUID group_id: UUID
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True
class EmailInvitation(MealieModel): class EmailInvitation(MealieModel):

View File

@ -3,7 +3,7 @@ import enum
from uuid import UUID from uuid import UUID
from isodate import parse_time from isodate import parse_time
from pydantic import UUID4, validator from pydantic import UUID4, ConfigDict, field_validator
from pydantic.datetime_parse import parse_datetime from pydantic.datetime_parse import parse_datetime
from mealie.schema._mealie import MealieModel from mealie.schema._mealie import MealieModel
@ -22,7 +22,8 @@ class CreateWebhook(MealieModel):
webhook_type: WebhookType = WebhookType.mealplan webhook_type: WebhookType = WebhookType.mealplan
scheduled_time: datetime.time scheduled_time: datetime.time
@validator("scheduled_time", pre=True) @field_validator("scheduled_time", mode="before")
@classmethod
@classmethod @classmethod
def validate_scheduled_time(cls, v): def validate_scheduled_time(cls, v):
""" """
@ -55,9 +56,7 @@ class SaveWebhook(CreateWebhook):
class ReadWebhook(SaveWebhook): class ReadWebhook(SaveWebhook):
id: UUID4 id: UUID4
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True
class WebhookPagination(PaginationBase): class WebhookPagination(PaginationBase):

View File

@ -1,6 +1,6 @@
from __future__ import annotations from __future__ import annotations
from pydantic import UUID4 from pydantic import UUID4, ConfigDict
from mealie.schema._mealie import MealieModel from mealie.schema._mealie import MealieModel
from mealie.schema.response.pagination import PaginationBase from mealie.schema.response.pagination import PaginationBase
@ -21,9 +21,7 @@ class MultiPurposeLabelUpdate(MultiPurposeLabelSave):
class MultiPurposeLabelSummary(MultiPurposeLabelUpdate): class MultiPurposeLabelSummary(MultiPurposeLabelUpdate):
pass pass
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True
class MultiPurposeLabelPagination(PaginationBase): class MultiPurposeLabelPagination(PaginationBase):
@ -31,11 +29,7 @@ class MultiPurposeLabelPagination(PaginationBase):
class MultiPurposeLabelOut(MultiPurposeLabelUpdate): class MultiPurposeLabelOut(MultiPurposeLabelUpdate):
# shopping_list_items: list[ShoppingListItemOut] = [] model_config = ConfigDict(from_attributes=True)
# foods: list[IngredientFood] = []
class Config:
orm_mode = True
# from mealie.schema.recipe.recipe_ingredient import IngredientFood # from mealie.schema.recipe.recipe_ingredient import IngredientFood

View File

@ -1,6 +1,6 @@
from datetime import date from datetime import date
from pydantic import validator from pydantic import ConfigDict, validator
from mealie.schema._mealie import MealieModel from mealie.schema._mealie import MealieModel
@ -9,24 +9,18 @@ class MealIn(MealieModel):
slug: str | None slug: str | None
name: str | None name: str | None
description: str | None description: str | None
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True
class MealDayIn(MealieModel): class MealDayIn(MealieModel):
date: date | None date: date | None
meals: list[MealIn] meals: list[MealIn]
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True
class MealDayOut(MealDayIn): class MealDayOut(MealDayIn):
id: int id: int
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True
class MealPlanIn(MealieModel): class MealPlanIn(MealieModel):
@ -35,19 +29,17 @@ class MealPlanIn(MealieModel):
end_date: date end_date: date
plan_days: list[MealDayIn] plan_days: list[MealDayIn]
# TODO[pydantic]: We couldn't refactor the `validator`, please replace it by `field_validator` manually.
# Check https://docs.pydantic.dev/dev-v2/migration/#changes-to-validators for more information.
@validator("end_date") @validator("end_date")
def end_date_after_start_date(v, values, config, field): def end_date_after_start_date(v, values, config, field):
if "start_date" in values and v < values["start_date"]: if "start_date" in values and v < values["start_date"]:
raise ValueError("EndDate should be greater than StartDate") raise ValueError("EndDate should be greater than StartDate")
return v return v
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True
class MealPlanOut(MealPlanIn): class MealPlanOut(MealPlanIn):
id: int id: int
shopping_list: int | None shopping_list: int | None
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True

View File

@ -2,7 +2,7 @@ from datetime import date
from enum import Enum from enum import Enum
from uuid import UUID from uuid import UUID
from pydantic import validator from pydantic import ConfigDict, validator
from sqlalchemy.orm import selectinload from sqlalchemy.orm import selectinload
from sqlalchemy.orm.interfaces import LoaderOption from sqlalchemy.orm.interfaces import LoaderOption
@ -32,6 +32,8 @@ class CreatePlanEntry(MealieModel):
text: str = "" text: str = ""
recipe_id: UUID | None recipe_id: UUID | None
# TODO[pydantic]: We couldn't refactor the `validator`, please replace it by `field_validator` manually.
# Check https://docs.pydantic.dev/dev-v2/migration/#changes-to-validators for more information.
@validator("recipe_id", always=True) @validator("recipe_id", always=True)
@classmethod @classmethod
def id_or_title(cls, value, values): def id_or_title(cls, value, values):
@ -50,16 +52,12 @@ class UpdatePlanEntry(CreatePlanEntry):
class SavePlanEntry(CreatePlanEntry): class SavePlanEntry(CreatePlanEntry):
group_id: UUID group_id: UUID
user_id: UUID | None user_id: UUID | None
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True
class ReadPlanEntry(UpdatePlanEntry): class ReadPlanEntry(UpdatePlanEntry):
recipe: RecipeSummary | None recipe: RecipeSummary | None
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True
@classmethod @classmethod
def loader_options(cls) -> list[LoaderOption]: def loader_options(cls) -> list[LoaderOption]:

View File

@ -1,7 +1,7 @@
import datetime import datetime
from enum import Enum from enum import Enum
from pydantic import UUID4 from pydantic import UUID4, ConfigDict
from sqlalchemy.orm import joinedload from sqlalchemy.orm import joinedload
from sqlalchemy.orm.interfaces import LoaderOption from sqlalchemy.orm.interfaces import LoaderOption
@ -14,14 +14,11 @@ class Category(MealieModel):
id: UUID4 id: UUID4
name: str name: str
slug: str slug: str
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True
class Tag(Category): class Tag(Category):
class Config: model_config = ConfigDict(from_attributes=True)
orm_mode = True
class PlanRulesDay(str, Enum): class PlanRulesDay(str, Enum):
@ -64,9 +61,7 @@ class PlanRulesSave(PlanRulesCreate):
class PlanRulesOut(PlanRulesSave): class PlanRulesOut(PlanRulesSave):
id: UUID4 id: UUID4
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True
@classmethod @classmethod
def loader_options(cls) -> list[LoaderOption]: def loader_options(cls) -> list[LoaderOption]:

View File

@ -1,3 +1,5 @@
from pydantic import ConfigDict
from mealie.schema._mealie import MealieModel from mealie.schema._mealie import MealieModel
from mealie.schema.getter_dict import GroupGetterDict from mealie.schema.getter_dict import GroupGetterDict
@ -7,9 +9,7 @@ class ListItem(MealieModel):
text: str = "" text: str = ""
quantity: int = 1 quantity: int = 1
checked: bool = False checked: bool = False
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True
class ShoppingListIn(MealieModel): class ShoppingListIn(MealieModel):
@ -20,7 +20,6 @@ class ShoppingListIn(MealieModel):
class ShoppingListOut(ShoppingListIn): class ShoppingListOut(ShoppingListIn):
id: int id: int
# TODO[pydantic]: The following keys were removed: `getter_dict`.
class Config: # Check https://docs.pydantic.dev/dev-v2/migration/#changes-to-config for more information.
orm_mode = True model_config = ConfigDict(from_attributes=True, getter_dict=GroupGetterDict)
getter_dict = GroupGetterDict

View File

@ -5,7 +5,7 @@ from pathlib import Path
from typing import Any from typing import Any
from uuid import uuid4 from uuid import uuid4
from pydantic import UUID4, BaseModel, Field, validator from pydantic import UUID4, BaseModel, ConfigDict, Field, validator
from slugify import slugify from slugify import slugify
from sqlalchemy.orm import joinedload, selectinload from sqlalchemy.orm import joinedload, selectinload
from sqlalchemy.orm.interfaces import LoaderOption from sqlalchemy.orm.interfaces import LoaderOption
@ -36,9 +36,7 @@ class RecipeTag(MealieModel):
id: UUID4 | None = None id: UUID4 | None = None
name: str name: str
slug: str slug: str
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True
class RecipeTagPagination(PaginationBase): class RecipeTagPagination(PaginationBase):
@ -105,9 +103,7 @@ class RecipeSummary(MealieModel):
created_at: datetime.datetime | None created_at: datetime.datetime | None
update_at: datetime.datetime | None update_at: datetime.datetime | None
last_made: datetime.datetime | None last_made: datetime.datetime | None
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True
class RecipePagination(PaginationBase): class RecipePagination(PaginationBase):
@ -171,10 +167,9 @@ class Recipe(RecipeSummary):
raise ValueError("Recipe has no ID") raise ValueError("Recipe has no ID")
return self.image_dir_from_id(self.id) return self.image_dir_from_id(self.id)
# TODO[pydantic]: The following keys were removed: `getter_dict`.
class Config: # Check https://docs.pydantic.dev/dev-v2/migration/#changes-to-config for more information.
orm_mode = True model_config = ConfigDict(from_attributes=True, getter_dict=ExtrasGetterDict)
getter_dict = ExtrasGetterDict
@classmethod @classmethod
def from_orm(cls, obj): def from_orm(cls, obj):
@ -195,6 +190,8 @@ class Recipe(RecipeSummary):
ingredient.is_food = not ingredient.disable_amount ingredient.is_food = not ingredient.disable_amount
ingredient.display = ingredient._format_display() ingredient.display = ingredient._format_display()
# TODO[pydantic]: We couldn't refactor the `validator`, please replace it by `field_validator` manually.
# Check https://docs.pydantic.dev/dev-v2/migration/#changes-to-validators for more information.
@validator("slug", always=True, pre=True, allow_reuse=True) @validator("slug", always=True, pre=True, allow_reuse=True)
def validate_slug(slug: str, values): # type: ignore def validate_slug(slug: str, values): # type: ignore
if not values.get("name"): if not values.get("name"):
@ -202,6 +199,8 @@ class Recipe(RecipeSummary):
return slugify(values["name"]) return slugify(values["name"])
# TODO[pydantic]: We couldn't refactor the `validator`, please replace it by `field_validator` manually.
# Check https://docs.pydantic.dev/dev-v2/migration/#changes-to-validators for more information.
@validator("recipe_ingredient", always=True, pre=True, allow_reuse=True) @validator("recipe_ingredient", always=True, pre=True, allow_reuse=True)
def validate_ingredients(recipe_ingredient, values): def validate_ingredients(recipe_ingredient, values):
if not recipe_ingredient or not isinstance(recipe_ingredient, list): if not recipe_ingredient or not isinstance(recipe_ingredient, list):
@ -212,24 +211,32 @@ class Recipe(RecipeSummary):
return recipe_ingredient return recipe_ingredient
# TODO[pydantic]: We couldn't refactor the `validator`, please replace it by `field_validator` manually.
# Check https://docs.pydantic.dev/dev-v2/migration/#changes-to-validators for more information.
@validator("tags", always=True, pre=True, allow_reuse=True) @validator("tags", always=True, pre=True, allow_reuse=True)
def validate_tags(cats: list[Any]): # type: ignore def validate_tags(cats: list[Any]): # type: ignore
if isinstance(cats, list) and cats and isinstance(cats[0], str): if isinstance(cats, list) and cats and isinstance(cats[0], str):
return [RecipeTag(id=uuid4(), name=c, slug=slugify(c)) for c in cats] return [RecipeTag(id=uuid4(), name=c, slug=slugify(c)) for c in cats]
return cats return cats
# TODO[pydantic]: We couldn't refactor the `validator`, please replace it by `field_validator` manually.
# Check https://docs.pydantic.dev/dev-v2/migration/#changes-to-validators for more information.
@validator("recipe_category", always=True, pre=True, allow_reuse=True) @validator("recipe_category", always=True, pre=True, allow_reuse=True)
def validate_categories(cats: list[Any]): # type: ignore def validate_categories(cats: list[Any]): # type: ignore
if isinstance(cats, list) and cats and isinstance(cats[0], str): if isinstance(cats, list) and cats and isinstance(cats[0], str):
return [RecipeCategory(id=uuid4(), name=c, slug=slugify(c)) for c in cats] return [RecipeCategory(id=uuid4(), name=c, slug=slugify(c)) for c in cats]
return cats return cats
# TODO[pydantic]: We couldn't refactor the `validator`, please replace it by `field_validator` manually.
# Check https://docs.pydantic.dev/dev-v2/migration/#changes-to-validators for more information.
@validator("group_id", always=True, pre=True, allow_reuse=True) @validator("group_id", always=True, pre=True, allow_reuse=True)
def validate_group_id(group_id: Any): def validate_group_id(group_id: Any):
if isinstance(group_id, int): if isinstance(group_id, int):
return uuid4() return uuid4()
return group_id return group_id
# TODO[pydantic]: We couldn't refactor the `validator`, please replace it by `field_validator` manually.
# Check https://docs.pydantic.dev/dev-v2/migration/#changes-to-validators for more information.
@validator("user_id", always=True, pre=True, allow_reuse=True) @validator("user_id", always=True, pre=True, allow_reuse=True)
def validate_user_id(user_id: Any): def validate_user_id(user_id: Any):
if isinstance(user_id, int): if isinstance(user_id, int):

View File

@ -1,3 +1,5 @@
from pydantic import ConfigDict
from mealie.schema._mealie import MealieModel from mealie.schema._mealie import MealieModel
@ -5,6 +7,4 @@ class RecipeAsset(MealieModel):
name: str name: str
icon: str icon: str
file_name: str | None file_name: str | None
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True

View File

@ -1,4 +1,4 @@
from pydantic import UUID4 from pydantic import UUID4, ConfigDict
from sqlalchemy.orm import selectinload from sqlalchemy.orm import selectinload
from sqlalchemy.orm.interfaces import LoaderOption from sqlalchemy.orm.interfaces import LoaderOption
@ -17,24 +17,18 @@ class CategorySave(CategoryIn):
class CategoryBase(CategoryIn): class CategoryBase(CategoryIn):
id: UUID4 id: UUID4
slug: str slug: str
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True
class CategoryOut(CategoryBase): class CategoryOut(CategoryBase):
slug: str slug: str
group_id: UUID4 group_id: UUID4
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True
class RecipeCategoryResponse(CategoryBase): class RecipeCategoryResponse(CategoryBase):
recipes: "list[RecipeSummary]" = [] recipes: "list[RecipeSummary]" = []
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True
class TagIn(CategoryIn): class TagIn(CategoryIn):
@ -52,9 +46,7 @@ class TagBase(CategoryBase):
class TagOut(TagSave): class TagOut(TagSave):
id: UUID4 id: UUID4
slug: str slug: str
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True
class RecipeTagResponse(RecipeCategoryResponse): class RecipeTagResponse(RecipeCategoryResponse):

View File

@ -1,6 +1,6 @@
from datetime import datetime from datetime import datetime
from pydantic import UUID4 from pydantic import UUID4, ConfigDict
from sqlalchemy.orm import joinedload from sqlalchemy.orm import joinedload
from sqlalchemy.orm.interfaces import LoaderOption from sqlalchemy.orm.interfaces import LoaderOption
@ -13,9 +13,7 @@ class UserBase(MealieModel):
id: UUID4 id: UUID4
username: str | None username: str | None
admin: bool admin: bool
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True
class RecipeCommentCreate(MealieModel): class RecipeCommentCreate(MealieModel):
@ -39,9 +37,7 @@ class RecipeCommentOut(RecipeCommentCreate):
update_at: datetime update_at: datetime
user_id: UUID4 user_id: UUID4
user: UserBase user: UserBase
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True
@classmethod @classmethod
def loader_options(cls) -> list[LoaderOption]: def loader_options(cls) -> list[LoaderOption]:

View File

@ -5,7 +5,7 @@ import enum
from fractions import Fraction from fractions import Fraction
from uuid import UUID, uuid4 from uuid import UUID, uuid4
from pydantic import UUID4, Field, validator from pydantic import UUID4, ConfigDict, Field, field_validator, validator
from sqlalchemy.orm import joinedload from sqlalchemy.orm import joinedload
from sqlalchemy.orm.interfaces import LoaderOption from sqlalchemy.orm.interfaces import LoaderOption
@ -49,10 +49,9 @@ class IngredientFood(CreateIngredientFood):
label: MultiPurposeLabelSummary | None = None label: MultiPurposeLabelSummary | None = None
created_at: datetime.datetime | None created_at: datetime.datetime | None
update_at: datetime.datetime | None update_at: datetime.datetime | None
# TODO[pydantic]: The following keys were removed: `getter_dict`.
class Config: # Check https://docs.pydantic.dev/dev-v2/migration/#changes-to-config for more information.
orm_mode = True model_config = ConfigDict(from_attributes=True, getter_dict=ExtrasGetterDict)
getter_dict = ExtrasGetterDict
@classmethod @classmethod
def loader_options(cls) -> list[LoaderOption]: def loader_options(cls) -> list[LoaderOption]:
@ -77,9 +76,7 @@ class IngredientUnit(CreateIngredientUnit):
id: UUID4 id: UUID4
created_at: datetime.datetime | None created_at: datetime.datetime | None
update_at: datetime.datetime | None update_at: datetime.datetime | None
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True
class RecipeIngredientBase(MealieModel): class RecipeIngredientBase(MealieModel):
@ -114,14 +111,16 @@ class RecipeIngredientBase(MealieModel):
if not self.display: if not self.display:
self.display = self._format_display() self.display = self._format_display()
@validator("unit", pre=True) @field_validator("unit", mode="before")
@classmethod
def validate_unit(cls, v): def validate_unit(cls, v):
if isinstance(v, str): if isinstance(v, str):
return CreateIngredientUnit(name=v) return CreateIngredientUnit(name=v)
else: else:
return v return v
@validator("food", pre=True) @field_validator("food", mode="before")
@classmethod
def validate_food(cls, v): def validate_food(cls, v):
if isinstance(v, str): if isinstance(v, str):
return CreateIngredientFood(name=v) return CreateIngredientFood(name=v)
@ -200,11 +199,10 @@ class RecipeIngredient(RecipeIngredientBase):
# It is required for the reorder and section titles to function properly because of how # It is required for the reorder and section titles to function properly because of how
# Vue handles reactivity. ref may serve another purpose in the future. # Vue handles reactivity. ref may serve another purpose in the future.
reference_id: UUID = Field(default_factory=uuid4) reference_id: UUID = Field(default_factory=uuid4)
model_config = ConfigDict(from_attributes=True)
class Config: @field_validator("quantity", mode="before")
orm_mode = True @classmethod
@validator("quantity", pre=True)
def validate_quantity(cls, value) -> NoneFloat: def validate_quantity(cls, value) -> NoneFloat:
""" """
Sometimes the frontend UI will provide an empty string as a "null" value because of the default Sometimes the frontend UI will provide an empty string as a "null" value because of the default
@ -226,6 +224,8 @@ class IngredientConfidence(MealieModel):
quantity: NoneFloat = None quantity: NoneFloat = None
food: NoneFloat = None food: NoneFloat = None
# TODO[pydantic]: We couldn't refactor the `validator`, please replace it by `field_validator` manually.
# Check https://docs.pydantic.dev/dev-v2/migration/#changes-to-validators for more information.
@validator("quantity", pre=True) @validator("quantity", pre=True)
@classmethod @classmethod
def validate_quantity(cls, value, values) -> NoneFloat: def validate_quantity(cls, value, values) -> NoneFloat:

View File

@ -1,9 +1,7 @@
from pydantic import BaseModel from pydantic import BaseModel, ConfigDict
class RecipeNote(BaseModel): class RecipeNote(BaseModel):
title: str title: str
text: str text: str
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True

View File

@ -1,3 +1,5 @@
from pydantic import ConfigDict
from mealie.schema._mealie import MealieModel from mealie.schema._mealie import MealieModel
@ -9,6 +11,4 @@ class Nutrition(MealieModel):
fiber_content: str | None fiber_content: str | None
sodium_content: str | None sodium_content: str | None
sugar_content: str | None sugar_content: str | None
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True

View File

@ -1,3 +1,5 @@
from pydantic import ConfigDict
from mealie.schema._mealie.mealie_model import MealieModel from mealie.schema._mealie.mealie_model import MealieModel
@ -8,11 +10,9 @@ class ScrapeRecipeTest(MealieModel):
class ScrapeRecipe(MealieModel): class ScrapeRecipe(MealieModel):
url: str url: str
include_tags: bool = False include_tags: bool = False
model_config = ConfigDict(json_schema_extra={
class Config: "example": {
schema_extra = { "url": "https://myfavoriterecipes.com/recipes",
"example": { "includeTags": True,
"url": "https://myfavoriterecipes.com/recipes", },
"includeTags": True, })
},
}

View File

@ -1,3 +1,5 @@
from pydantic import ConfigDict
from mealie.schema._mealie import MealieModel from mealie.schema._mealie import MealieModel
@ -9,6 +11,4 @@ class RecipeSettings(MealieModel):
disable_comments: bool = True disable_comments: bool = True
disable_amount: bool = True disable_amount: bool = True
locked: bool = False locked: bool = False
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True

View File

@ -1,6 +1,6 @@
from datetime import datetime, timedelta from datetime import datetime, timedelta
from pydantic import UUID4, Field from pydantic import UUID4, ConfigDict, Field
from sqlalchemy.orm import selectinload from sqlalchemy.orm import selectinload
from sqlalchemy.orm.interfaces import LoaderOption from sqlalchemy.orm.interfaces import LoaderOption
@ -26,16 +26,12 @@ class RecipeShareTokenSave(RecipeShareTokenCreate):
class RecipeShareTokenSummary(RecipeShareTokenSave): class RecipeShareTokenSummary(RecipeShareTokenSave):
id: UUID4 id: UUID4
created_at: datetime created_at: datetime
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True
class RecipeShareToken(RecipeShareTokenSummary): class RecipeShareToken(RecipeShareTokenSummary):
recipe: Recipe recipe: Recipe
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True
@classmethod @classmethod
def loader_options(cls) -> list[LoaderOption]: def loader_options(cls) -> list[LoaderOption]:

View File

@ -1,6 +1,6 @@
from uuid import UUID, uuid4 from uuid import UUID, uuid4
from pydantic import UUID4, Field from pydantic import UUID4, ConfigDict, Field
from mealie.schema._mealie import MealieModel from mealie.schema._mealie import MealieModel
@ -11,9 +11,7 @@ class IngredientReferences(MealieModel):
""" """
reference_id: UUID4 | None reference_id: UUID4 | None
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True
class RecipeStep(MealieModel): class RecipeStep(MealieModel):
@ -21,6 +19,4 @@ class RecipeStep(MealieModel):
title: str | None = "" title: str | None = ""
text: str text: str
ingredient_references: list[IngredientReferences] = [] ingredient_references: list[IngredientReferences] = []
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True

View File

@ -2,7 +2,7 @@ from datetime import datetime
from enum import Enum from enum import Enum
from pathlib import Path from pathlib import Path
from pydantic import UUID4, Field from pydantic import UUID4, ConfigDict, Field
from mealie.core.config import get_app_dirs from mealie.core.config import get_app_dirs
from mealie.schema._mealie.mealie_model import MealieModel from mealie.schema._mealie.mealie_model import MealieModel
@ -35,9 +35,7 @@ class RecipeTimelineEventIn(MealieModel):
image: TimelineEventImage | None = TimelineEventImage.does_not_have_image image: TimelineEventImage | None = TimelineEventImage.does_not_have_image
timestamp: datetime = datetime.now() timestamp: datetime = datetime.now()
model_config = ConfigDict(use_enum_values=True)
class Config:
use_enum_values = True
class RecipeTimelineEventCreate(RecipeTimelineEventIn): class RecipeTimelineEventCreate(RecipeTimelineEventIn):
@ -48,18 +46,14 @@ class RecipeTimelineEventUpdate(MealieModel):
subject: str subject: str
message: str | None = Field(alias="eventMessage") message: str | None = Field(alias="eventMessage")
image: TimelineEventImage | None = None image: TimelineEventImage | None = None
model_config = ConfigDict(use_enum_values=True)
class Config:
use_enum_values = True
class RecipeTimelineEventOut(RecipeTimelineEventCreate): class RecipeTimelineEventOut(RecipeTimelineEventCreate):
id: UUID4 id: UUID4
created_at: datetime created_at: datetime
update_at: datetime update_at: datetime
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True
@classmethod @classmethod
def image_dir_from_id(cls, recipe_id: UUID4 | str, timeline_event_id: UUID4 | str) -> Path: def image_dir_from_id(cls, recipe_id: UUID4 | str, timeline_event_id: UUID4 | str) -> Path:

View File

@ -1,4 +1,4 @@
from pydantic import UUID4 from pydantic import UUID4, ConfigDict
from sqlalchemy.orm import selectinload from sqlalchemy.orm import selectinload
from sqlalchemy.orm.interfaces import LoaderOption from sqlalchemy.orm.interfaces import LoaderOption
@ -19,16 +19,12 @@ class RecipeToolSave(RecipeToolCreate):
class RecipeToolOut(RecipeToolCreate): class RecipeToolOut(RecipeToolCreate):
id: UUID4 id: UUID4
slug: str slug: str
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True
class RecipeToolResponse(RecipeToolOut): class RecipeToolResponse(RecipeToolOut):
recipes: list["RecipeSummary"] = [] recipes: list["RecipeSummary"] = []
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True
@classmethod @classmethod
def loader_options(cls) -> list[LoaderOption]: def loader_options(cls) -> list[LoaderOption]:

View File

@ -1,4 +1,4 @@
from pydantic import BaseModel from pydantic import BaseModel, ConfigDict
from mealie.schema._mealie import MealieModel from mealie.schema._mealie import MealieModel
@ -10,8 +10,7 @@ class RecipeSlug(MealieModel):
class SlugResponse(BaseModel): class SlugResponse(BaseModel):
class Config: model_config = ConfigDict(json_schema_extra={"example": "adult-mac-and-cheese"})
schema_extra = {"example": "adult-mac-and-cheese"}
class UpdateImageResponse(BaseModel): class UpdateImageResponse(BaseModel):
@ -23,4 +22,4 @@ class RecipeZipTokenResponse(BaseModel):
class RecipeDuplicate(BaseModel): class RecipeDuplicate(BaseModel):
name: str | None name: str | None = None

View File

@ -1,7 +1,7 @@
import datetime import datetime
import enum import enum
from pydantic import Field from pydantic import ConfigDict, Field
from pydantic.types import UUID4 from pydantic.types import UUID4
from sqlalchemy.orm import joinedload from sqlalchemy.orm import joinedload
from sqlalchemy.orm.interfaces import LoaderOption from sqlalchemy.orm.interfaces import LoaderOption
@ -34,9 +34,7 @@ class ReportEntryCreate(MealieModel):
class ReportEntryOut(ReportEntryCreate): class ReportEntryOut(ReportEntryCreate):
id: UUID4 id: UUID4
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True
class ReportCreate(MealieModel): class ReportCreate(MealieModel):
@ -53,9 +51,7 @@ class ReportSummary(ReportCreate):
class ReportOut(ReportSummary): class ReportOut(ReportSummary):
entries: list[ReportEntryOut] = [] entries: list[ReportEntryOut] = []
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True
@classmethod @classmethod
def loader_options(cls) -> list[LoaderOption]: def loader_options(cls) -> list[LoaderOption]:

View File

@ -4,7 +4,6 @@ from urllib.parse import parse_qs, urlencode, urlsplit, urlunsplit
from humps import camelize from humps import camelize
from pydantic import UUID4, BaseModel, validator from pydantic import UUID4, BaseModel, validator
from pydantic.generics import GenericModel
from mealie.schema._mealie import MealieModel from mealie.schema._mealie import MealieModel
@ -34,6 +33,8 @@ class PaginationQuery(MealieModel):
query_filter: str | None = None query_filter: str | None = None
pagination_seed: str | None = None pagination_seed: str | None = None
# TODO[pydantic]: We couldn't refactor the `validator`, please replace it by `field_validator` manually.
# Check https://docs.pydantic.dev/dev-v2/migration/#changes-to-validators for more information.
@validator("pagination_seed", always=True, pre=True) @validator("pagination_seed", always=True, pre=True)
def validate_randseed(cls, pagination_seed, values): def validate_randseed(cls, pagination_seed, values):
if values.get("order_by") == "random" and not pagination_seed: if values.get("order_by") == "random" and not pagination_seed:
@ -41,7 +42,7 @@ class PaginationQuery(MealieModel):
return pagination_seed return pagination_seed
class PaginationBase(GenericModel, Generic[DataT]): class PaginationBase(BaseModel, Generic[DataT]):
page: int = 1 page: int = 1
per_page: int = 10 per_page: int = 10
total: int = 0 total: int = 0

View File

@ -2,7 +2,7 @@ import datetime
import enum import enum
from uuid import UUID from uuid import UUID
from pydantic import Field from pydantic import ConfigDict, Field
from mealie.schema._mealie import MealieModel from mealie.schema._mealie import MealieModel
from mealie.schema.response.pagination import PaginationBase from mealie.schema.response.pagination import PaginationBase
@ -43,9 +43,7 @@ class ServerTaskCreate(MealieModel):
class ServerTask(ServerTaskCreate): class ServerTask(ServerTaskCreate):
id: int id: int
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True
class ServerTaskPagination(PaginationBase): class ServerTaskPagination(PaginationBase):

View File

@ -1,5 +1,6 @@
from pydantic import UUID4, BaseModel from typing import Annotated
from pydantic.types import constr
from pydantic import UUID4, BaseModel, StringConstraints
from mealie.schema._mealie.mealie_model import MealieModel from mealie.schema._mealie.mealie_model import MealieModel
@ -10,8 +11,8 @@ class Token(BaseModel):
class TokenData(BaseModel): class TokenData(BaseModel):
user_id: UUID4 | None user_id: UUID4 | None = None
username: constr(to_lower=True, strip_whitespace=True) | None = None # type: ignore username: Annotated[str, StringConstraints(to_lower=True, strip_whitespace=True)] | None = None # type: ignore
class UnlockResults(MealieModel): class UnlockResults(MealieModel):

View File

@ -1,5 +1,7 @@
from pydantic import validator from typing import Annotated
from pydantic.types import NoneStr, constr
from pydantic import StringConstraints, validator
from pydantic.types import NoneStr
from mealie.schema._mealie import MealieModel from mealie.schema._mealie import MealieModel
from mealie.schema._mealie.validators import validate_locale from mealie.schema._mealie.validators import validate_locale
@ -8,8 +10,8 @@ from mealie.schema._mealie.validators import validate_locale
class CreateUserRegistration(MealieModel): class CreateUserRegistration(MealieModel):
group: NoneStr = None group: NoneStr = None
group_token: NoneStr = None group_token: NoneStr = None
email: constr(to_lower=True, strip_whitespace=True) # type: ignore email: Annotated[str, StringConstraints(to_lower=True, strip_whitespace=True)] # type: ignore
username: constr(to_lower=True, strip_whitespace=True) # type: ignore username: Annotated[str, StringConstraints(to_lower=True, strip_whitespace=True)] # type: ignore
password: str password: str
password_confirm: str password_confirm: str
advanced: bool = False advanced: bool = False
@ -18,12 +20,16 @@ class CreateUserRegistration(MealieModel):
seed_data: bool = False seed_data: bool = False
locale: str = "en-US" locale: str = "en-US"
# TODO[pydantic]: We couldn't refactor the `validator`, please replace it by `field_validator` manually.
# Check https://docs.pydantic.dev/dev-v2/migration/#changes-to-validators for more information.
@validator("locale") @validator("locale")
def valid_locale(cls, v, values, **kwargs): def valid_locale(cls, v, values, **kwargs):
if not validate_locale(v): if not validate_locale(v):
raise ValueError("invalid locale") raise ValueError("invalid locale")
return v return v
# TODO[pydantic]: We couldn't refactor the `validator`, please replace it by `field_validator` manually.
# Check https://docs.pydantic.dev/dev-v2/migration/#changes-to-validators for more information.
@validator("password_confirm") @validator("password_confirm")
@classmethod @classmethod
def passwords_match(cls, value, values): def passwords_match(cls, value, values):
@ -31,6 +37,8 @@ class CreateUserRegistration(MealieModel):
raise ValueError("passwords do not match") raise ValueError("passwords do not match")
return value return value
# TODO[pydantic]: We couldn't refactor the `validator`, please replace it by `field_validator` manually.
# Check https://docs.pydantic.dev/dev-v2/migration/#changes-to-validators for more information.
@validator("group_token", always=True) @validator("group_token", always=True)
@classmethod @classmethod
def group_or_token(cls, value, values): def group_or_token(cls, value, values):

View File

@ -1,10 +1,9 @@
from datetime import datetime, timedelta from datetime import datetime, timedelta
from pathlib import Path from pathlib import Path
from typing import Any from typing import Annotated, Any
from uuid import UUID from uuid import UUID
from pydantic import UUID4, Field, validator from pydantic import UUID4, ConfigDict, Field, StringConstraints, field_validator
from pydantic.types import constr
from sqlalchemy.orm import joinedload, selectinload from sqlalchemy.orm import joinedload, selectinload
from sqlalchemy.orm.interfaces import LoaderOption from sqlalchemy.orm.interfaces import LoaderOption
@ -35,24 +34,18 @@ class LongLiveTokenOut(MealieModel):
name: str name: str
id: int id: int
created_at: datetime | None created_at: datetime | None
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True
class CreateToken(LongLiveTokenIn): class CreateToken(LongLiveTokenIn):
user_id: UUID4 user_id: UUID4
token: str token: str
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True
class DeleteTokenResponse(MealieModel): class DeleteTokenResponse(MealieModel):
token_delete: str token_delete: str
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True
class ChangePassword(MealieModel): class ChangePassword(MealieModel):
@ -62,15 +55,13 @@ class ChangePassword(MealieModel):
class GroupBase(MealieModel): class GroupBase(MealieModel):
name: str name: str
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True
class UserBase(MealieModel): class UserBase(MealieModel):
username: str | None username: str | None
full_name: str | None = None full_name: str | None = None
email: constr(to_lower=True, strip_whitespace=True) # type: ignore email: Annotated[str, StringConstraints(to_lower=True, strip_whitespace=True)] # type: ignore
auth_method: AuthMethod = AuthMethod.MEALIE auth_method: AuthMethod = AuthMethod.MEALIE
admin: bool = False admin: bool = False
group: str | None group: str | None
@ -80,20 +71,17 @@ class UserBase(MealieModel):
can_invite: bool = False can_invite: bool = False
can_manage: bool = False can_manage: bool = False
can_organize: bool = False can_organize: bool = False
# TODO[pydantic]: The following keys were removed: `getter_dict`.
class Config: # Check https://docs.pydantic.dev/dev-v2/migration/#changes-to-config for more information.
orm_mode = True model_config = ConfigDict(from_attributes=True, getter_dict=GroupGetterDict, json_schema_extra={
getter_dict = GroupGetterDict "example": {
"username": "ChangeMe",
schema_extra = { "fullName": "Change Me",
"example": { "email": "changeme@email.com",
"username": "ChangeMe", "group": settings.DEFAULT_GROUP,
"fullName": "Change Me", "admin": "false",
"email": "changeme@email.com",
"group": settings.DEFAULT_GROUP,
"admin": "false",
}
} }
})
class UserIn(UserBase): class UserIn(UserBase):
@ -107,11 +95,9 @@ class UserOut(UserBase):
tokens: list[LongLiveTokenOut] | None tokens: list[LongLiveTokenOut] | None
cache_key: str cache_key: str
favorite_recipes: list[str] | None = [] favorite_recipes: list[str] | None = []
# TODO[pydantic]: The following keys were removed: `getter_dict`.
class Config: # Check https://docs.pydantic.dev/dev-v2/migration/#changes-to-config for more information.
orm_mode = True model_config = ConfigDict(from_attributes=True, getter_dict=UserGetterDict)
getter_dict = UserGetterDict
@property @property
def is_default_user(self) -> bool: def is_default_user(self) -> bool:
@ -128,10 +114,9 @@ class UserPagination(PaginationBase):
class UserFavorites(UserBase): class UserFavorites(UserBase):
favorite_recipes: list[RecipeSummary] = [] # type: ignore favorite_recipes: list[RecipeSummary] = [] # type: ignore
# TODO[pydantic]: The following keys were removed: `getter_dict`.
class Config: # Check https://docs.pydantic.dev/dev-v2/migration/#changes-to-config for more information.
orm_mode = True model_config = ConfigDict(from_attributes=True, getter_dict=GroupGetterDict)
getter_dict = GroupGetterDict
@classmethod @classmethod
def loader_options(cls) -> list[LoaderOption]: def loader_options(cls) -> list[LoaderOption]:
@ -148,11 +133,10 @@ class PrivateUser(UserOut):
group_id: UUID4 group_id: UUID4
login_attemps: int = 0 login_attemps: int = 0
locked_at: datetime | None = None locked_at: datetime | None = None
model_config = ConfigDict(from_attributes=True)
class Config: @field_validator("login_attemps", mode="before")
orm_mode = True @classmethod
@validator("login_attemps", pre=True)
def none_to_zero(cls, v): def none_to_zero(cls, v):
return 0 if v is None else v return 0 if v is None else v
@ -189,9 +173,7 @@ class UpdateGroup(GroupBase):
class GroupInDB(UpdateGroup): class GroupInDB(UpdateGroup):
users: list[UserOut] | None users: list[UserOut] | None
preferences: ReadGroupPreferences | None = None preferences: ReadGroupPreferences | None = None
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True
@staticmethod @staticmethod
def get_directory(id: UUID4) -> Path: def get_directory(id: UUID4) -> Path:
@ -232,6 +214,4 @@ class GroupPagination(PaginationBase):
class LongLiveTokenInDB(CreateToken): class LongLiveTokenInDB(CreateToken):
id: int id: int
user: PrivateUser user: PrivateUser
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True

View File

@ -1,4 +1,4 @@
from pydantic import UUID4 from pydantic import UUID4, ConfigDict
from sqlalchemy.orm import selectinload from sqlalchemy.orm import selectinload
from sqlalchemy.orm.interfaces import LoaderOption from sqlalchemy.orm.interfaces import LoaderOption
@ -33,9 +33,7 @@ class SavePasswordResetToken(MealieModel):
class PrivatePasswordResetToken(SavePasswordResetToken): class PrivatePasswordResetToken(SavePasswordResetToken):
user: PrivateUser user: PrivateUser
model_config = ConfigDict(from_attributes=True)
class Config:
orm_mode = True
@classmethod @classmethod
def loader_options(cls) -> list[LoaderOption]: def loader_options(cls) -> list[LoaderOption]:

View File

@ -177,8 +177,8 @@ class Event(MealieModel):
document_data: EventDocumentDataBase document_data: EventDocumentDataBase
# set at instantiation # set at instantiation
event_id: UUID4 | None event_id: UUID4 | None = None
timestamp: datetime | None timestamp: datetime | None = None
def __init__(self, *args, **kwargs) -> None: def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)

View File

@ -1,7 +1,7 @@
import string import string
import unicodedata import unicodedata
from pydantic import BaseModel from pydantic import BaseModel, ConfigDict
from .._helpers import check_char, move_parens_to_end from .._helpers import check_char, move_parens_to_end
@ -11,9 +11,7 @@ class BruteParsedIngredient(BaseModel):
note: str = "" note: str = ""
amount: float = 1.0 amount: float = 1.0
unit: str = "" unit: str = ""
model_config = ConfigDict(str_strip_whitespace=True)
class Config:
anystr_strip_whitespace = True
def parse_fraction(x): def parse_fraction(x):

View File

@ -31,6 +31,8 @@ class CRFIngredient(BaseModel):
unit: str = "" unit: str = ""
confidence: CRFConfidence confidence: CRFConfidence
# TODO[pydantic]: We couldn't refactor the `validator`, please replace it by `field_validator` manually.
# Check https://docs.pydantic.dev/dev-v2/migration/#changes-to-validators for more information.
@validator("qty", always=True, pre=True) @validator("qty", always=True, pre=True)
def validate_qty(qty, values): # sourcery skip: merge-nested-ifs def validate_qty(qty, values): # sourcery skip: merge-nested-ifs
if qty is None or qty == "": if qty is None or qty == "":

218
poetry.lock generated
View File

@ -44,6 +44,17 @@ files = [
[package.extras] [package.extras]
dev = ["black", "coverage", "isort", "pre-commit", "pyenchant", "pylint"] dev = ["black", "coverage", "isort", "pre-commit", "pyenchant", "pylint"]
[[package]]
name = "annotated-types"
version = "0.5.0"
description = "Reusable constraint types to use with typing.Annotated"
optional = false
python-versions = ">=3.7"
files = [
{file = "annotated_types-0.5.0-py3-none-any.whl", hash = "sha256:58da39888f92c276ad970249761ebea80ba544b77acddaa1a4d6cf78287d45fd"},
{file = "annotated_types-0.5.0.tar.gz", hash = "sha256:47cdc3490d9ac1506ce92c7aaa76c579dc3509ff11e098fc867e5130ab7be802"},
]
[[package]] [[package]]
name = "anyio" name = "anyio"
version = "3.6.2" version = "3.6.2"
@ -545,24 +556,22 @@ cli = ["requests"]
[[package]] [[package]]
name = "fastapi" name = "fastapi"
version = "0.95.0" version = "0.101.0"
description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production" description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
{file = "fastapi-0.95.0-py3-none-any.whl", hash = "sha256:daf73bbe844180200be7966f68e8ec9fd8be57079dff1bacb366db32729e6eb5"}, {file = "fastapi-0.101.0-py3-none-any.whl", hash = "sha256:494eb3494d89e8079c20859d7ca695f66eaccc40f46fe8c75ab6186d15f05ffd"},
{file = "fastapi-0.95.0.tar.gz", hash = "sha256:99d4fdb10e9dd9a24027ac1d0bd4b56702652056ca17a6c8721eec4ad2f14e18"}, {file = "fastapi-0.101.0.tar.gz", hash = "sha256:ca2ae65fe42f6a34b5cf6c994337149154b1b400c39809d7b2dccdceb5ae77af"},
] ]
[package.dependencies] [package.dependencies]
pydantic = ">=1.6.2,<1.7 || >1.7,<1.7.1 || >1.7.1,<1.7.2 || >1.7.2,<1.7.3 || >1.7.3,<1.8 || >1.8,<1.8.1 || >1.8.1,<2.0.0" pydantic = ">=1.7.4,<1.8 || >1.8,<1.8.1 || >1.8.1,<2.0.0 || >2.0.0,<2.0.1 || >2.0.1,<2.1.0 || >2.1.0,<3.0.0"
starlette = ">=0.26.1,<0.27.0" starlette = ">=0.27.0,<0.28.0"
typing-extensions = ">=4.5.0"
[package.extras] [package.extras]
all = ["email-validator (>=1.1.1)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=2.11.2)", "orjson (>=3.2.1)", "python-multipart (>=0.0.5)", "pyyaml (>=5.3.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0)", "uvicorn[standard] (>=0.12.0)"] all = ["email-validator (>=2.0.0)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=2.11.2)", "orjson (>=3.2.1)", "pydantic-extra-types (>=2.0.0)", "pydantic-settings (>=2.0.0)", "python-multipart (>=0.0.5)", "pyyaml (>=5.3.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0)", "uvicorn[standard] (>=0.12.0)"]
dev = ["pre-commit (>=2.17.0,<3.0.0)", "ruff (==0.0.138)", "uvicorn[standard] (>=0.12.0,<0.21.0)"]
doc = ["mdx-include (>=1.4.1,<2.0.0)", "mkdocs (>=1.1.2,<2.0.0)", "mkdocs-markdownextradata-plugin (>=0.1.7,<0.3.0)", "mkdocs-material (>=8.1.4,<9.0.0)", "pyyaml (>=5.3.1,<7.0.0)", "typer-cli (>=0.0.13,<0.0.14)", "typer[all] (>=0.6.1,<0.8.0)"]
test = ["anyio[trio] (>=3.2.1,<4.0.0)", "black (==23.1.0)", "coverage[toml] (>=6.5.0,<8.0)", "databases[sqlite] (>=0.3.2,<0.7.0)", "email-validator (>=1.1.1,<2.0.0)", "flask (>=1.1.2,<3.0.0)", "httpx (>=0.23.0,<0.24.0)", "isort (>=5.0.6,<6.0.0)", "mypy (==0.982)", "orjson (>=3.2.1,<4.0.0)", "passlib[bcrypt] (>=1.7.2,<2.0.0)", "peewee (>=3.13.3,<4.0.0)", "pytest (>=7.1.3,<8.0.0)", "python-jose[cryptography] (>=3.3.0,<4.0.0)", "python-multipart (>=0.0.5,<0.0.7)", "pyyaml (>=5.3.1,<7.0.0)", "ruff (==0.0.138)", "sqlalchemy (>=1.3.18,<1.4.43)", "types-orjson (==3.6.2)", "types-ujson (==5.7.0.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0,<6.0.0)"]
[[package]] [[package]]
name = "filelock" name = "filelock"
@ -1696,55 +1705,150 @@ pyasn1 = ">=0.4.6,<0.5.0"
[[package]] [[package]]
name = "pydantic" name = "pydantic"
version = "1.10.7" version = "2.1.1"
description = "Data validation and settings management using python type hints" description = "Data validation using Python type hints"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
{file = "pydantic-1.10.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e79e999e539872e903767c417c897e729e015872040e56b96e67968c3b918b2d"}, {file = "pydantic-2.1.1-py3-none-any.whl", hash = "sha256:43bdbf359d6304c57afda15c2b95797295b702948082d4c23851ce752f21da70"},
{file = "pydantic-1.10.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:01aea3a42c13f2602b7ecbbea484a98169fb568ebd9e247593ea05f01b884b2e"}, {file = "pydantic-2.1.1.tar.gz", hash = "sha256:22d63db5ce4831afd16e7c58b3192d3faf8f79154980d9397d9867254310ba4b"},
{file = "pydantic-1.10.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:516f1ed9bc2406a0467dd777afc636c7091d71f214d5e413d64fef45174cfc7a"},
{file = "pydantic-1.10.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae150a63564929c675d7f2303008d88426a0add46efd76c3fc797cd71cb1b46f"},
{file = "pydantic-1.10.7-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ecbbc51391248116c0a055899e6c3e7ffbb11fb5e2a4cd6f2d0b93272118a209"},
{file = "pydantic-1.10.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f4a2b50e2b03d5776e7f21af73e2070e1b5c0d0df255a827e7c632962f8315af"},
{file = "pydantic-1.10.7-cp310-cp310-win_amd64.whl", hash = "sha256:a7cd2251439988b413cb0a985c4ed82b6c6aac382dbaff53ae03c4b23a70e80a"},
{file = "pydantic-1.10.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:68792151e174a4aa9e9fc1b4e653e65a354a2fa0fed169f7b3d09902ad2cb6f1"},
{file = "pydantic-1.10.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dfe2507b8ef209da71b6fb5f4e597b50c5a34b78d7e857c4f8f3115effaef5fe"},
{file = "pydantic-1.10.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10a86d8c8db68086f1e30a530f7d5f83eb0685e632e411dbbcf2d5c0150e8dcd"},
{file = "pydantic-1.10.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d75ae19d2a3dbb146b6f324031c24f8a3f52ff5d6a9f22f0683694b3afcb16fb"},
{file = "pydantic-1.10.7-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:464855a7ff7f2cc2cf537ecc421291b9132aa9c79aef44e917ad711b4a93163b"},
{file = "pydantic-1.10.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:193924c563fae6ddcb71d3f06fa153866423ac1b793a47936656e806b64e24ca"},
{file = "pydantic-1.10.7-cp311-cp311-win_amd64.whl", hash = "sha256:b4a849d10f211389502059c33332e91327bc154acc1845f375a99eca3afa802d"},
{file = "pydantic-1.10.7-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:cc1dde4e50a5fc1336ee0581c1612215bc64ed6d28d2c7c6f25d2fe3e7c3e918"},
{file = "pydantic-1.10.7-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e0cfe895a504c060e5d36b287ee696e2fdad02d89e0d895f83037245218a87fe"},
{file = "pydantic-1.10.7-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:670bb4683ad1e48b0ecb06f0cfe2178dcf74ff27921cdf1606e527d2617a81ee"},
{file = "pydantic-1.10.7-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:950ce33857841f9a337ce07ddf46bc84e1c4946d2a3bba18f8280297157a3fd1"},
{file = "pydantic-1.10.7-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:c15582f9055fbc1bfe50266a19771bbbef33dd28c45e78afbe1996fd70966c2a"},
{file = "pydantic-1.10.7-cp37-cp37m-win_amd64.whl", hash = "sha256:82dffb306dd20bd5268fd6379bc4bfe75242a9c2b79fec58e1041fbbdb1f7914"},
{file = "pydantic-1.10.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8c7f51861d73e8b9ddcb9916ae7ac39fb52761d9ea0df41128e81e2ba42886cd"},
{file = "pydantic-1.10.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6434b49c0b03a51021ade5c4daa7d70c98f7a79e95b551201fff682fc1661245"},
{file = "pydantic-1.10.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64d34ab766fa056df49013bb6e79921a0265204c071984e75a09cbceacbbdd5d"},
{file = "pydantic-1.10.7-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:701daea9ffe9d26f97b52f1d157e0d4121644f0fcf80b443248434958fd03dc3"},
{file = "pydantic-1.10.7-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:cf135c46099ff3f919d2150a948ce94b9ce545598ef2c6c7bf55dca98a304b52"},
{file = "pydantic-1.10.7-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b0f85904f73161817b80781cc150f8b906d521fa11e3cdabae19a581c3606209"},
{file = "pydantic-1.10.7-cp38-cp38-win_amd64.whl", hash = "sha256:9f6f0fd68d73257ad6685419478c5aece46432f4bdd8d32c7345f1986496171e"},
{file = "pydantic-1.10.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c230c0d8a322276d6e7b88c3f7ce885f9ed16e0910354510e0bae84d54991143"},
{file = "pydantic-1.10.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:976cae77ba6a49d80f461fd8bba183ff7ba79f44aa5cfa82f1346b5626542f8e"},
{file = "pydantic-1.10.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7d45fc99d64af9aaf7e308054a0067fdcd87ffe974f2442312372dfa66e1001d"},
{file = "pydantic-1.10.7-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d2a5ebb48958754d386195fe9e9c5106f11275867051bf017a8059410e9abf1f"},
{file = "pydantic-1.10.7-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:abfb7d4a7cd5cc4e1d1887c43503a7c5dd608eadf8bc615413fc498d3e4645cd"},
{file = "pydantic-1.10.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:80b1fab4deb08a8292d15e43a6edccdffa5377a36a4597bb545b93e79c5ff0a5"},
{file = "pydantic-1.10.7-cp39-cp39-win_amd64.whl", hash = "sha256:d71e69699498b020ea198468e2480a2f1e7433e32a3a99760058c6520e2bea7e"},
{file = "pydantic-1.10.7-py3-none-any.whl", hash = "sha256:0cd181f1d0b1d00e2b705f1bf1ac7799a2d938cce3376b8007df62b29be3c2c6"},
{file = "pydantic-1.10.7.tar.gz", hash = "sha256:cfc83c0678b6ba51b0532bea66860617c4cd4251ecf76e9846fa5a9f3454e97e"},
] ]
[package.dependencies] [package.dependencies]
typing-extensions = ">=4.2.0" annotated-types = ">=0.4.0"
pydantic-core = "2.4.0"
typing-extensions = ">=4.6.1"
[package.extras] [package.extras]
dotenv = ["python-dotenv (>=0.10.4)"] email = ["email-validator (>=2.0.0)"]
email = ["email-validator (>=1.0.3)"]
[[package]]
name = "pydantic-core"
version = "2.4.0"
description = ""
optional = false
python-versions = ">=3.7"
files = [
{file = "pydantic_core-2.4.0-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:2ca4687dd996bde7f3c420def450797feeb20dcee2b9687023e3323c73fc14a2"},
{file = "pydantic_core-2.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:782fced7d61469fd1231b184a80e4f2fa7ad54cd7173834651a453f96f29d673"},
{file = "pydantic_core-2.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6213b471b68146af97b8551294e59e7392c2117e28ffad9c557c65087f4baee3"},
{file = "pydantic_core-2.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63797499a219d8e81eb4e0c42222d0a4c8ec896f5c76751d4258af95de41fdf1"},
{file = "pydantic_core-2.4.0-cp310-cp310-manylinux_2_24_armv7l.whl", hash = "sha256:0455876d575a35defc4da7e0a199596d6c773e20d3d42fa1fc29f6aa640369ed"},
{file = "pydantic_core-2.4.0-cp310-cp310-manylinux_2_24_ppc64le.whl", hash = "sha256:8c938c96294d983dcf419b54dba2d21056959c22911d41788efbf949a29ae30d"},
{file = "pydantic_core-2.4.0-cp310-cp310-manylinux_2_24_s390x.whl", hash = "sha256:878a5017d93e776c379af4e7b20f173c82594d94fa073059bcc546789ad50bf8"},
{file = "pydantic_core-2.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:69159afc2f2dc43285725f16143bc5df3c853bc1cb7df6021fce7ef1c69e8171"},
{file = "pydantic_core-2.4.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:54df7df399b777c1fd144f541c95d351b3aa110535a6810a6a569905d106b6f3"},
{file = "pydantic_core-2.4.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e412607ca89a0ced10758dfb8f9adcc365ce4c1c377e637c01989a75e9a9ec8a"},
{file = "pydantic_core-2.4.0-cp310-none-win32.whl", hash = "sha256:853f103e2b9a58832fdd08a587a51de8b552ae90e1a5d167f316b7eabf8d7dde"},
{file = "pydantic_core-2.4.0-cp310-none-win_amd64.whl", hash = "sha256:3ba2c9c94a9176f6321a879c8b864d7c5b12d34f549a4c216c72ce213d7d953c"},
{file = "pydantic_core-2.4.0-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:a8b7acd04896e8f161e1500dc5f218017db05c1d322f054e89cbd089ce5d0071"},
{file = "pydantic_core-2.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:16468bd074fa4567592d3255bf25528ed41e6b616d69bf07096bdb5b66f947d1"},
{file = "pydantic_core-2.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cba5ad5eef02c86a1f3da00544cbc59a510d596b27566479a7cd4d91c6187a11"},
{file = "pydantic_core-2.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b7206e41e04b443016e930e01685bab7a308113c0b251b3f906942c8d4b48fcb"},
{file = "pydantic_core-2.4.0-cp311-cp311-manylinux_2_24_armv7l.whl", hash = "sha256:c1375025f0bfc9155286ebae8eecc65e33e494c90025cda69e247c3ccd2bab00"},
{file = "pydantic_core-2.4.0-cp311-cp311-manylinux_2_24_ppc64le.whl", hash = "sha256:3534118289e33130ed3f1cc487002e8d09b9f359be48b02e9cd3de58ce58fba9"},
{file = "pydantic_core-2.4.0-cp311-cp311-manylinux_2_24_s390x.whl", hash = "sha256:94d2b36a74623caab262bf95f0e365c2c058396082bd9d6a9e825657d0c1e7fa"},
{file = "pydantic_core-2.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:af24ad4fbaa5e4a2000beae0c3b7fd1c78d7819ab90f9370a1cfd8998e3f8a3c"},
{file = "pydantic_core-2.4.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bf10963d8aed8bbe0165b41797c9463d4c5c8788ae6a77c68427569be6bead41"},
{file = "pydantic_core-2.4.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:68199ada7c310ddb8c76efbb606a0de656b40899388a7498954f423e03fc38be"},
{file = "pydantic_core-2.4.0-cp311-none-win32.whl", hash = "sha256:6f855bcc96ed3dd56da7373cfcc9dcbabbc2073cac7f65c185772d08884790ce"},
{file = "pydantic_core-2.4.0-cp311-none-win_amd64.whl", hash = "sha256:de39eb3bab93a99ddda1ac1b9aa331b944d8bcc4aa9141148f7fd8ee0299dafc"},
{file = "pydantic_core-2.4.0-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:f773b39780323a0499b53ebd91a28ad11cde6705605d98d999dfa08624caf064"},
{file = "pydantic_core-2.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a297c0d6c61963c5c3726840677b798ca5b7dfc71bc9c02b9a4af11d23236008"},
{file = "pydantic_core-2.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:546064c55264156b973b5e65e5fafbe5e62390902ce3cf6b4005765505e8ff56"},
{file = "pydantic_core-2.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:36ba9e728588588f0196deaf6751b9222492331b5552f865a8ff120869d372e0"},
{file = "pydantic_core-2.4.0-cp312-cp312-manylinux_2_24_armv7l.whl", hash = "sha256:57a53a75010c635b3ad6499e7721eaa3b450e03f6862afe2dbef9c8f66e46ec8"},
{file = "pydantic_core-2.4.0-cp312-cp312-manylinux_2_24_ppc64le.whl", hash = "sha256:4b262bbc13022f2097c48a21adcc360a81d83dc1d854c11b94953cd46d7d3c07"},
{file = "pydantic_core-2.4.0-cp312-cp312-manylinux_2_24_s390x.whl", hash = "sha256:01947ad728f426fa07fcb26457ebf90ce29320259938414bc0edd1476e75addb"},
{file = "pydantic_core-2.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b2799c2eaf182769889761d4fb4d78b82bc47dae833799fedbf69fc7de306faa"},
{file = "pydantic_core-2.4.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:a08fd490ba36d1fbb2cd5dcdcfb9f3892deb93bd53456724389135712b5fc735"},
{file = "pydantic_core-2.4.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1e8a7c62d15a5c4b307271e4252d76ebb981d6251c6ecea4daf203ef0179ea4f"},
{file = "pydantic_core-2.4.0-cp312-none-win32.whl", hash = "sha256:9206c14a67c38de7b916e486ae280017cf394fa4b1aa95cfe88621a4e1d79725"},
{file = "pydantic_core-2.4.0-cp312-none-win_amd64.whl", hash = "sha256:884235507549a6b2d3c4113fb1877ae263109e787d9e0eb25c35982ab28d0399"},
{file = "pydantic_core-2.4.0-cp37-cp37m-macosx_10_7_x86_64.whl", hash = "sha256:4cbe929efa77a806e8f1a97793f2dc3ea3475ae21a9ed0f37c21320fe93f6f50"},
{file = "pydantic_core-2.4.0-cp37-cp37m-macosx_11_0_arm64.whl", hash = "sha256:9137289de8fe845c246a8c3482dd0cb40338846ba683756d8f489a4bd8fddcae"},
{file = "pydantic_core-2.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5d8e764b5646623e57575f624f8ebb8f7a9f7fd1fae682ef87869ca5fec8dcf"},
{file = "pydantic_core-2.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8fba0aff4c407d0274e43697e785bcac155ad962be57518d1c711f45e72da70f"},
{file = "pydantic_core-2.4.0-cp37-cp37m-manylinux_2_24_armv7l.whl", hash = "sha256:30527d173e826f2f7651f91c821e337073df1555e3b5a0b7b1e2c39e26e50678"},
{file = "pydantic_core-2.4.0-cp37-cp37m-manylinux_2_24_ppc64le.whl", hash = "sha256:bd7d1dde70ff3e09e4bc7a1cbb91a7a538add291bfd5b3e70ef1e7b45192440f"},
{file = "pydantic_core-2.4.0-cp37-cp37m-manylinux_2_24_s390x.whl", hash = "sha256:72f1216ca8cef7b8adacd4c4c6b89c3b0c4f97503197f5284c80f36d6e4edd30"},
{file = "pydantic_core-2.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b013c7861a7c7bfcec48fd709513fea6f9f31727e7a0a93ca0dd12e056740717"},
{file = "pydantic_core-2.4.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:478f5f6d7e32bd4a04d102160efb2d389432ecf095fe87c555c0a6fc4adfc1a4"},
{file = "pydantic_core-2.4.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d9610b47b5fe4aacbbba6a9cb5f12cbe864eec99dbfed5710bd32ef5dd8a5d5b"},
{file = "pydantic_core-2.4.0-cp37-none-win32.whl", hash = "sha256:ff246c0111076c8022f9ba325c294f2cb5983403506989253e04dbae565e019b"},
{file = "pydantic_core-2.4.0-cp37-none-win_amd64.whl", hash = "sha256:d0c2b713464a8e263a243ae7980d81ce2de5ac59a9f798a282e44350b42dc516"},
{file = "pydantic_core-2.4.0-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:12ef6838245569fd60a179fade81ca4b90ae2fa0ef355d616f519f7bb27582db"},
{file = "pydantic_core-2.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:49db206eb8fdc4b4f30e6e3e410584146d813c151928f94ec0db06c4f2595538"},
{file = "pydantic_core-2.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a507d7fa44688bbac76af6521e488b3da93de155b9cba6f2c9b7833ce243d59"},
{file = "pydantic_core-2.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffe18407a4d000c568182ce5388bbbedeb099896904e43fc14eee76cfae6dec5"},
{file = "pydantic_core-2.4.0-cp38-cp38-manylinux_2_24_armv7l.whl", hash = "sha256:fa8e48001b39d54d97d7b380a0669fa99fc0feeb972e35a2d677ba59164a9a22"},
{file = "pydantic_core-2.4.0-cp38-cp38-manylinux_2_24_ppc64le.whl", hash = "sha256:394f12a2671ff8c4dfa2e85be6c08be0651ad85bc1e6aa9c77c21671baaf28cd"},
{file = "pydantic_core-2.4.0-cp38-cp38-manylinux_2_24_s390x.whl", hash = "sha256:2f9ea0355f90db2a76af530245fa42f04d98f752a1236ed7c6809ec484560d5b"},
{file = "pydantic_core-2.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:61d4e713f467abcdd59b47665d488bb898ad3dd47ce7446522a50e0cbd8e8279"},
{file = "pydantic_core-2.4.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:453862ab268f6326b01f067ed89cb3a527d34dc46f6f4eeec46a15bbc706d0da"},
{file = "pydantic_core-2.4.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:56a85fa0dab1567bd0cac10f0c3837b03e8a0d939e6a8061a3a420acd97e9421"},
{file = "pydantic_core-2.4.0-cp38-none-win32.whl", hash = "sha256:0d726108c1c0380b88b6dd4db559f0280e0ceda9e077f46ff90bc85cd4d03e77"},
{file = "pydantic_core-2.4.0-cp38-none-win_amd64.whl", hash = "sha256:047580388644c473b934d27849f8ed8dbe45df0adb72104e78b543e13bf69762"},
{file = "pydantic_core-2.4.0-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:867d3eea954bea807cabba83cfc939c889a18576d66d197c60025b15269d7cc0"},
{file = "pydantic_core-2.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:664402ef0c238a7f8a46efb101789d5f2275600fb18114446efec83cfadb5b66"},
{file = "pydantic_core-2.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:64e8012ad60a5f0da09ed48725e6e923d1be25f2f091a640af6079f874663813"},
{file = "pydantic_core-2.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac2b680de398f293b68183317432b3d67ab3faeba216aec18de0c395cb5e3060"},
{file = "pydantic_core-2.4.0-cp39-cp39-manylinux_2_24_armv7l.whl", hash = "sha256:8efc1be43b036c2b6bcfb1451df24ee0ddcf69c31351003daf2699ed93f5687b"},
{file = "pydantic_core-2.4.0-cp39-cp39-manylinux_2_24_ppc64le.whl", hash = "sha256:d93aedbc4614cc21b9ab0d0c4ccd7143354c1f7cffbbe96ae5216ad21d1b21b5"},
{file = "pydantic_core-2.4.0-cp39-cp39-manylinux_2_24_s390x.whl", hash = "sha256:af788b64e13d52fc3600a68b16d31fa8d8573e3ff2fc9a38f8a60b8d94d1f012"},
{file = "pydantic_core-2.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:97c6349c81cee2e69ef59eba6e6c08c5936e6b01c2d50b9e4ac152217845ae09"},
{file = "pydantic_core-2.4.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:cc086ddb6dc654a15deeed1d1f2bcb1cb924ebd70df9dca738af19f64229b06c"},
{file = "pydantic_core-2.4.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:e953353180bec330c3b830891d260b6f8e576e2d18db3c78d314e56bb2276066"},
{file = "pydantic_core-2.4.0-cp39-none-win32.whl", hash = "sha256:6feb4b64d11d5420e517910d60a907d08d846cacaf4e029668725cd21d16743c"},
{file = "pydantic_core-2.4.0-cp39-none-win_amd64.whl", hash = "sha256:153a61ac4030fa019b70b31fb7986461119230d3ba0ab661c757cfea652f4332"},
{file = "pydantic_core-2.4.0-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:3fcf529382b282a30b466bd7af05be28e22aa620e016135ac414f14e1ee6b9e1"},
{file = "pydantic_core-2.4.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2edef05b63d82568b877002dc4cb5cc18f8929b59077120192df1e03e0c633f8"},
{file = "pydantic_core-2.4.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da055a1b0bfa8041bb2ff586b2cb0353ed03944a3472186a02cc44a557a0e661"},
{file = "pydantic_core-2.4.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:77dadc764cf7c5405e04866181c5bd94a447372a9763e473abb63d1dfe9b7387"},
{file = "pydantic_core-2.4.0-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:a4ea23b07f29487a7bef2a869f68c7ee0e05424d81375ce3d3de829314c6b5ec"},
{file = "pydantic_core-2.4.0-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:382f0baa044d674ad59455a5eff83d7965572b745cc72df35c52c2ce8c731d37"},
{file = "pydantic_core-2.4.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:08f89697625e453421401c7f661b9d1eb4c9e4c0a12fd256eeb55b06994ac6af"},
{file = "pydantic_core-2.4.0-pp37-pypy37_pp73-macosx_10_7_x86_64.whl", hash = "sha256:43a405ce520b45941df9ff55d0cd09762017756a7b413bbad3a6e8178e64a2c2"},
{file = "pydantic_core-2.4.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:584a7a818c84767af16ce8bda5d4f7fedb37d3d231fc89928a192f567e4ef685"},
{file = "pydantic_core-2.4.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:04922fea7b13cd480586fa106345fe06e43220b8327358873c22d8dfa7a711c7"},
{file = "pydantic_core-2.4.0-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:17156abac20a9feed10feec867fddd91a80819a485b0107fe61f09f2117fe5f3"},
{file = "pydantic_core-2.4.0-pp37-pypy37_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:4e562cc63b04636cde361fd47569162f1daa94c759220ff202a8129902229114"},
{file = "pydantic_core-2.4.0-pp37-pypy37_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:90f3785146f701e053bb6b9e8f53acce2c919aca91df88bd4975be0cb926eb41"},
{file = "pydantic_core-2.4.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:e40b1e97edd3dc127aa53d8a5e539a3d0c227d71574d3f9ac1af02d58218a122"},
{file = "pydantic_core-2.4.0-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:b27f3e67f6e031f6620655741b7d0d6bebea8b25d415924b3e8bfef2dd7bd841"},
{file = "pydantic_core-2.4.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be86c2eb12fb0f846262ace9d8f032dc6978b8cb26a058920ecb723dbcb87d05"},
{file = "pydantic_core-2.4.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4665f7ed345012a8d2eddf4203ef145f5f56a291d010382d235b94e91813f88a"},
{file = "pydantic_core-2.4.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:79262be5a292d1df060f29b9a7cdd66934801f987a817632d7552534a172709a"},
{file = "pydantic_core-2.4.0-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:5fd905a69ac74eaba5041e21a1e8b1a479dab2b41c93bdcc4c1cede3c12a8d86"},
{file = "pydantic_core-2.4.0-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:2ad538b7e07343001934417cdc8584623b4d8823c5b8b258e75ec8d327cec969"},
{file = "pydantic_core-2.4.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:dd2429f7635ad4857b5881503f9c310be7761dc681c467a9d27787b674d1250a"},
{file = "pydantic_core-2.4.0-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:efff8b6761a1f6e45cebd1b7a6406eb2723d2d5710ff0d1b624fe11313693989"},
{file = "pydantic_core-2.4.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32a1e0352558cd7ccc014ffe818c7d87b15ec6145875e2cc5fa4bb7351a1033d"},
{file = "pydantic_core-2.4.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a027f41c5008571314861744d83aff75a34cf3a07022e0be32b214a5bc93f7f1"},
{file = "pydantic_core-2.4.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1927f0e15d190f11f0b8344373731e28fd774c6d676d8a6cfadc95c77214a48b"},
{file = "pydantic_core-2.4.0-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:7aa82d483d5fb867d4fb10a138ffd57b0f1644e99f2f4f336e48790ada9ada5e"},
{file = "pydantic_core-2.4.0-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:b85778308bf945e9b33ac604e6793df9b07933108d20bdf53811bc7c2798a4af"},
{file = "pydantic_core-2.4.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:3ded19dcaefe2f6706d81e0db787b59095f4ad0fbadce1edffdf092294c8a23f"},
{file = "pydantic_core-2.4.0.tar.gz", hash = "sha256:ec3473c9789cc00c7260d840c3db2c16dbfc816ca70ec87a00cddfa3e1a1cdd5"},
]
[package.dependencies]
typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0"
[[package]]
name = "pydantic-settings"
version = "2.0.2"
description = "Settings management using Pydantic"
optional = false
python-versions = ">=3.7"
files = [
{file = "pydantic_settings-2.0.2-py3-none-any.whl", hash = "sha256:6183a2abeab465d5a3ab69758e9a22d38b0cc2ba193f0b85f6971a252ea630f6"},
{file = "pydantic_settings-2.0.2.tar.gz", hash = "sha256:342337fff50b23585e807a86dec85037900972364435c55c2fc00d16ff080539"},
]
[package.dependencies]
pydantic = ">=2.0.1"
python-dotenv = ">=0.21.0"
[[package]] [[package]]
name = "pydantic-to-typescript" name = "pydantic-to-typescript"
@ -2453,13 +2557,13 @@ sqlcipher = ["sqlcipher3-binary"]
[[package]] [[package]]
name = "starlette" name = "starlette"
version = "0.26.1" version = "0.27.0"
description = "The little ASGI library that shines." description = "The little ASGI library that shines."
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
{file = "starlette-0.26.1-py3-none-any.whl", hash = "sha256:e87fce5d7cbdde34b76f0ac69013fd9d190d581d80681493016666e6f96c6d5e"}, {file = "starlette-0.27.0-py3-none-any.whl", hash = "sha256:918416370e846586541235ccd38a474c08b80443ed31c578a418e2209b3eef91"},
{file = "starlette-0.26.1.tar.gz", hash = "sha256:41da799057ea8620e4667a3e69a5b1923ebd32b1819c8fa75634bbe8d8bea9bd"}, {file = "starlette-0.27.0.tar.gz", hash = "sha256:6a6b0d042acb8d469a01eba54e9cda6cbd24ac602c4cd016723117d6a7e73b75"},
] ]
[package.dependencies] [package.dependencies]
@ -2561,13 +2665,13 @@ files = [
[[package]] [[package]]
name = "typing-extensions" name = "typing-extensions"
version = "4.4.0" version = "4.7.1"
description = "Backported and Experimental Type Hints for Python 3.7+" description = "Backported and Experimental Type Hints for Python 3.7+"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
{file = "typing_extensions-4.4.0-py3-none-any.whl", hash = "sha256:16fa4864408f655d35ec496218b85f79b3437c829e93320c7c9215ccfd92489e"}, {file = "typing_extensions-4.7.1-py3-none-any.whl", hash = "sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36"},
{file = "typing_extensions-4.4.0.tar.gz", hash = "sha256:1511434bb92bf8dd198c12b1cc812e800d4181cfcb867674e0f8279cc93087aa"}, {file = "typing_extensions-4.7.1.tar.gz", hash = "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2"},
] ]
[[package]] [[package]]
@ -2935,4 +3039,4 @@ pgsql = ["psycopg2-binary"]
[metadata] [metadata]
lock-version = "2.0" lock-version = "2.0"
python-versions = "^3.10" python-versions = "^3.10"
content-hash = "6ec46a82cad73c78013d1729df179a3fb5c4e12eb2a11ca04b2412d6b8e5b25f" content-hash = "86c45be1f77b9a37fe0933536a5ca4dda9e8bfafd94ce008db9070e870c9cbd1"

View File

@ -20,14 +20,14 @@ appdirs = "1.4.4"
apprise = "^1.2.0" apprise = "^1.2.0"
bcrypt = "^4.0.1" bcrypt = "^4.0.1"
extruct = "^0.14.0" extruct = "^0.14.0"
fastapi = "^0.95.0" fastapi = "^0.101.0"
gunicorn = "^20.1.0" gunicorn = "^20.1.0"
httpx = "^0.23.1" httpx = "^0.23.1"
lxml = "^4.7.1" lxml = "^4.7.1"
orjson = "^3.8.0" orjson = "^3.8.0"
passlib = "^1.7.4" passlib = "^1.7.4"
psycopg2-binary = {version = "^2.9.1", optional = true} psycopg2-binary = {version = "^2.9.1", optional = true}
pydantic = "^1.10.4" pydantic = "^2.1.1"
pyhumps = "^3.5.3" pyhumps = "^3.5.3"
pytesseract = "^0.3.9" pytesseract = "^0.3.9"
python = "^3.10" python = "^3.10"
@ -43,6 +43,7 @@ tzdata = "^2022.7"
uvicorn = {extras = ["standard"], version = "^0.21.0"} uvicorn = {extras = ["standard"], version = "^0.21.0"}
beautifulsoup4 = "^4.11.2" beautifulsoup4 = "^4.11.2"
isodate = "^0.6.1" isodate = "^0.6.1"
pydantic-settings = "^2.0.2"
[tool.poetry.group.dev.dependencies] [tool.poetry.group.dev.dependencies]
black = "^23.1.0" black = "^23.1.0"