mirror of
https://github.com/mealie-recipes/mealie.git
synced 2025-12-27 12:45:17 -05:00
chore: mypy, ruff, extract, openapi, and recipes-scraper updates (#1968)
* bump ruff and mypy * mypy fixes * bump and fix openapi * drop debug statement * bump extruct * bump recipes-scrapers
This commit is contained in:
@@ -113,7 +113,6 @@ def main():
|
||||
reload=True,
|
||||
reload_dirs=["mealie"],
|
||||
reload_delay=2,
|
||||
debug=True,
|
||||
log_level="info",
|
||||
use_colors=True,
|
||||
log_config=None,
|
||||
|
||||
@@ -18,7 +18,7 @@ class UserLockedOut(Exception):
|
||||
...
|
||||
|
||||
|
||||
def create_access_token(data: dict, expires_delta: timedelta = None) -> str:
|
||||
def create_access_token(data: dict, expires_delta: timedelta | None = None) -> str:
|
||||
settings = get_app_settings()
|
||||
|
||||
to_encode = data.copy()
|
||||
|
||||
@@ -23,7 +23,7 @@ class BaseMixins:
|
||||
self.__init__(*args, **kwarg)
|
||||
|
||||
@classmethod
|
||||
def get_ref(cls, match_value: str, match_attr: str = None, session: Session = None):
|
||||
def get_ref(cls, match_value: str, match_attr: str | None = None, session: Session | None = None):
|
||||
match_attr = match_attr or cls.Config.get_attr # type: ignore
|
||||
|
||||
if match_value is None or session is None:
|
||||
|
||||
@@ -136,12 +136,12 @@ class RecipeModel(SqlAlchemyBase, BaseMixins):
|
||||
def __init__(
|
||||
self,
|
||||
session,
|
||||
assets: list = None,
|
||||
notes: list[dict] = None,
|
||||
nutrition: dict = None,
|
||||
recipe_ingredient: list[dict] = None,
|
||||
recipe_instructions: list[dict] = None,
|
||||
settings: dict = None,
|
||||
assets: list | None = None,
|
||||
notes: list[dict] | None = None,
|
||||
nutrition: dict | None = None,
|
||||
recipe_ingredient: list[dict] | None = None,
|
||||
recipe_instructions: list[dict] | None = None,
|
||||
settings: dict | None = None,
|
||||
**_,
|
||||
) -> None:
|
||||
self.nutrition = Nutrition(**nutrition) if nutrition else Nutrition()
|
||||
|
||||
@@ -71,7 +71,7 @@ class User(SqlAlchemyBase, BaseMixins):
|
||||
}
|
||||
|
||||
@auto_init()
|
||||
def __init__(self, session, full_name, password, group: str = None, **kwargs) -> None:
|
||||
def __init__(self, session, full_name, password, group: str | None = None, **kwargs) -> None:
|
||||
if group is None:
|
||||
settings = get_app_settings()
|
||||
group = settings.DEFAULT_GROUP
|
||||
|
||||
@@ -35,7 +35,7 @@ class MinifierOptions:
|
||||
|
||||
|
||||
class ABCMinifier(ABC):
|
||||
def __init__(self, purge=False, opts: MinifierOptions = None, logger: Logger = None):
|
||||
def __init__(self, purge=False, opts: MinifierOptions | None = None, logger: Logger | None = None):
|
||||
self._purge = purge
|
||||
self._opts = opts or MinifierOptions()
|
||||
self._logger = logger or Logger("Minifier")
|
||||
@@ -60,7 +60,7 @@ class ABCMinifier(ABC):
|
||||
|
||||
class PillowMinifier(ABCMinifier):
|
||||
@staticmethod
|
||||
def to_webp(image_file: Path, dest: Path = None, quality: int = 100) -> Path:
|
||||
def to_webp(image_file: Path, dest: Path | None = None, quality: int = 100) -> Path:
|
||||
"""
|
||||
Converts an image to the webp format in-place. The original image is not
|
||||
removed By default, the quality is set to 100.
|
||||
|
||||
@@ -64,7 +64,12 @@ class RepositoryGeneric(Generic[Schema, Model]):
|
||||
return {**dct, **kwargs}
|
||||
|
||||
def get_all(
|
||||
self, limit: int = None, order_by: str = None, order_descending: bool = True, start=0, override=None
|
||||
self,
|
||||
limit: int | None = None,
|
||||
order_by: str | None = None,
|
||||
order_descending: bool = True,
|
||||
start=0,
|
||||
override=None,
|
||||
) -> list[Schema]:
|
||||
self.logger.warning('"get_all" method is deprecated; use "page_all" instead')
|
||||
|
||||
@@ -95,9 +100,9 @@ class RepositoryGeneric(Generic[Schema, Model]):
|
||||
self,
|
||||
query_by: dict[str, str | bool | int | UUID4],
|
||||
start=0,
|
||||
limit: int = None,
|
||||
limit: int | None = None,
|
||||
override_schema=None,
|
||||
order_by: str = None,
|
||||
order_by: str | None = None,
|
||||
) -> list[Schema]:
|
||||
# sourcery skip: remove-unnecessary-cast
|
||||
eff_schema = override_schema or self.schema
|
||||
@@ -112,7 +117,7 @@ class RepositoryGeneric(Generic[Schema, Model]):
|
||||
|
||||
return [eff_schema.from_orm(x) for x in q.offset(start).limit(limit).all()]
|
||||
|
||||
def _query_one(self, match_value: str | int | UUID4, match_key: str = None) -> Model:
|
||||
def _query_one(self, match_value: str | int | UUID4, match_key: str | None = None) -> Model:
|
||||
"""
|
||||
Query the sql database for one item an return the sql alchemy model
|
||||
object. If no match key is provided the primary_key attribute will be used.
|
||||
@@ -123,7 +128,9 @@ class RepositoryGeneric(Generic[Schema, Model]):
|
||||
fltr = self._filter_builder(**{match_key: match_value})
|
||||
return self._query().filter_by(**fltr).one()
|
||||
|
||||
def get_one(self, value: str | int | UUID4, key: str = None, any_case=False, override_schema=None) -> Schema | None:
|
||||
def get_one(
|
||||
self, value: str | int | UUID4, key: str | None = None, any_case=False, override_schema=None
|
||||
) -> Schema | None:
|
||||
key = key or self.primary_key
|
||||
|
||||
q = self.session.query(self.model)
|
||||
@@ -220,7 +227,7 @@ class RepositoryGeneric(Generic[Schema, Model]):
|
||||
def _count_attribute(
|
||||
self,
|
||||
attribute_name: str,
|
||||
attr_match: str = None,
|
||||
attr_match: str | None = None,
|
||||
count=True,
|
||||
override_schema=None,
|
||||
) -> int | list[Schema]: # sourcery skip: assign-if-exp
|
||||
|
||||
@@ -42,7 +42,7 @@ class RepositoryRecipes(RepositoryGeneric[Recipe, RecipeModel]):
|
||||
def by_group(self, group_id: UUID) -> "RepositoryRecipes":
|
||||
return super().by_group(group_id) # type: ignore
|
||||
|
||||
def get_all_public(self, limit: int = None, order_by: str = None, start=0, override_schema=None):
|
||||
def get_all_public(self, limit: int | None = None, order_by: str | None = None, start=0, override_schema=None):
|
||||
eff_schema = override_schema or self.schema
|
||||
|
||||
if order_by:
|
||||
@@ -69,7 +69,7 @@ class RepositoryRecipes(RepositoryGeneric[Recipe, RecipeModel]):
|
||||
.all()
|
||||
]
|
||||
|
||||
def update_image(self, slug: str, _: str = None) -> int:
|
||||
def update_image(self, slug: str, _: str | None = None) -> int:
|
||||
entry: RecipeModel = self._query_one(match_value=slug)
|
||||
entry.image = randint(0, 255)
|
||||
self.session.commit()
|
||||
|
||||
@@ -13,7 +13,7 @@ class AbstractSeeder(ABC):
|
||||
Abstract class for seeding data.
|
||||
"""
|
||||
|
||||
def __init__(self, db: AllRepositories, logger: Logger = None, group_id: UUID4 = None):
|
||||
def __init__(self, db: AllRepositories, logger: Logger | None = None, group_id: UUID4 | None = None):
|
||||
"""
|
||||
Initialize the abstract seeder.
|
||||
:param db_conn: Database connection.
|
||||
|
||||
@@ -36,7 +36,7 @@ def controller(router: APIRouter, *urls: str) -> Callable[[type[T]], type[T]]:
|
||||
return decorator
|
||||
|
||||
|
||||
def _cbv(router: APIRouter, cls: type[T], *urls: str, instance: Any = None) -> type[T]:
|
||||
def _cbv(router: APIRouter, cls: type[T], *urls: str, instance: Any | None = None) -> type[T]:
|
||||
"""
|
||||
Replaces any methods of the provided class `cls` that are endpoints of routes in `router` with updated
|
||||
function calls that will properly inject an instance of `cls`.
|
||||
@@ -46,7 +46,7 @@ def _cbv(router: APIRouter, cls: type[T], *urls: str, instance: Any = None) -> t
|
||||
return cls
|
||||
|
||||
|
||||
def _init_cbv(cls: type[Any], instance: Any = None) -> None:
|
||||
def _init_cbv(cls: type[Any], instance: Any | None = None) -> None:
|
||||
"""
|
||||
Idempotently modifies the provided `cls`, performing the following modifications:
|
||||
* The `__init__` function is updated to set any class-annotated dependencies as instance attributes
|
||||
|
||||
@@ -34,8 +34,8 @@ class HttpRepo(Generic[C, R, U]):
|
||||
self,
|
||||
repo: RepositoryGeneric,
|
||||
logger: Logger,
|
||||
exception_msgs: Callable[[type[Exception]], str] = None,
|
||||
default_message: str = None,
|
||||
exception_msgs: Callable[[type[Exception]], str] | None = None,
|
||||
default_message: str | None = None,
|
||||
) -> None:
|
||||
|
||||
self.repo = repo
|
||||
@@ -72,7 +72,7 @@ class HttpRepo(Generic[C, R, U]):
|
||||
|
||||
return item
|
||||
|
||||
def get_one(self, item_id: int | str | UUID4, key: str = None) -> R:
|
||||
def get_one(self, item_id: int | str | UUID4, key: str | None = None) -> R:
|
||||
item = self.repo.get_one(item_id, key)
|
||||
|
||||
if not item:
|
||||
|
||||
@@ -33,7 +33,7 @@ class GroupReportsController(BaseUserController):
|
||||
)
|
||||
|
||||
@router.get("", response_model=list[ReportSummary])
|
||||
def get_all(self, report_type: ReportCategory = None):
|
||||
def get_all(self, report_type: ReportCategory | None = None):
|
||||
return self.repo.multi_query({"group_id": self.group_id, "category": report_type}, limit=9999)
|
||||
|
||||
@router.get("/{item_id}", response_model=ReportOut)
|
||||
|
||||
@@ -22,7 +22,7 @@ class RecipeSharedController(BaseUserController):
|
||||
return HttpRepo[RecipeShareTokenSave, RecipeShareToken, RecipeShareTokenCreate](self.repo, self.logger)
|
||||
|
||||
@router.get("", response_model=list[RecipeShareTokenSummary])
|
||||
def get_all(self, recipe_id: UUID4 = None):
|
||||
def get_all(self, recipe_id: UUID4 | None = None):
|
||||
if recipe_id:
|
||||
return self.repo.multi_query({"recipe_id": recipe_id}, override_schema=RecipeShareTokenSummary)
|
||||
else:
|
||||
@@ -38,5 +38,5 @@ class RecipeSharedController(BaseUserController):
|
||||
return self.mixins.get_one(item_id)
|
||||
|
||||
@router.delete("/{item_id}")
|
||||
def delete_one(self, item_id: UUID4 = None) -> None:
|
||||
def delete_one(self, item_id: UUID4 | None = None) -> None:
|
||||
return self.mixins.delete_one(item_id)
|
||||
|
||||
@@ -37,5 +37,5 @@ class UserImageController(BaseUserController):
|
||||
|
||||
self.repos.users.patch(id, {"cache_key": cache.new_key()})
|
||||
|
||||
if not dest.is_file:
|
||||
if not dest.is_file():
|
||||
raise HTTPException(status.HTTP_500_INTERNAL_SERVER_ERROR)
|
||||
|
||||
@@ -14,7 +14,7 @@ class BackupSchemaMismatch(Exception):
|
||||
|
||||
|
||||
class BackupV2(BaseService):
|
||||
def __init__(self, db_url: str = None) -> None:
|
||||
def __init__(self, db_url: str | None = None) -> None:
|
||||
super().__init__()
|
||||
|
||||
# type - one of these has to be a string
|
||||
|
||||
@@ -28,7 +28,7 @@ class EmailTemplate(BaseModel):
|
||||
|
||||
|
||||
class EmailService(BaseService):
|
||||
def __init__(self, sender: ABCEmailSender = None) -> None:
|
||||
def __init__(self, sender: ABCEmailSender | None = None) -> None:
|
||||
self.templates_dir = CWD / "templates"
|
||||
self.default_template = self.templates_dir / "default.html"
|
||||
self.sender: ABCEmailSender = sender or DefaultEmailSender()
|
||||
|
||||
@@ -79,7 +79,7 @@ class ABCExporter(BaseService):
|
||||
zip (zipfile.ZipFile):
|
||||
"""
|
||||
|
||||
def func(source_dir: Path, dest_dir: str, ignore_ext: set[str] = None) -> None:
|
||||
def func(source_dir: Path, dest_dir: str, ignore_ext: set[str] | None = None) -> None:
|
||||
ignore_ext = ignore_ext or set()
|
||||
|
||||
for source_file in source_dir.iterdir():
|
||||
|
||||
@@ -51,7 +51,7 @@ class InvalidDomainError(Exception):
|
||||
class RecipeDataService(BaseService):
|
||||
minifier: img.ABCMinifier
|
||||
|
||||
def __init__(self, recipe_id: UUID4, group_id: UUID4 = None) -> None:
|
||||
def __init__(self, recipe_id: UUID4, group_id: UUID4 | None = None) -> None:
|
||||
"""
|
||||
RecipeDataService is a service that consolidates the reading/writing actions related
|
||||
to assets, and images for a recipe.
|
||||
|
||||
@@ -84,7 +84,7 @@ class RecipeService(BaseService):
|
||||
self.logger.info(f"Recipe Directory Removed: {recipe.slug}")
|
||||
|
||||
@staticmethod
|
||||
def _recipe_creation_factory(user: PrivateUser, name: str, additional_attrs: dict = None) -> Recipe:
|
||||
def _recipe_creation_factory(user: PrivateUser, name: str, additional_attrs: dict | None = None) -> Recipe:
|
||||
"""
|
||||
The main creation point for recipes. The factor method returns an instance of the
|
||||
Recipe Schema class with the appropriate defaults set. Recipes should not be created
|
||||
|
||||
@@ -96,7 +96,7 @@ class TemplateService(BaseService):
|
||||
|
||||
return save_path
|
||||
|
||||
def _render_jinja2(self, recipe: Recipe, j2_template: str = None) -> Path:
|
||||
def _render_jinja2(self, recipe: Recipe, j2_template: str | None = None) -> Path:
|
||||
"""
|
||||
Renders a Jinja2 Template in a temporary directory and returns
|
||||
the path to the file.
|
||||
|
||||
@@ -229,7 +229,7 @@ def _sanitize_instruction_text(line: str | dict) -> str:
|
||||
return clean_line
|
||||
|
||||
|
||||
def clean_ingredients(ingredients: list | str | None, default: list = None) -> list[str]:
|
||||
def clean_ingredients(ingredients: list | str | None, default: list | None = None) -> list[str]:
|
||||
"""
|
||||
ingredient attempts to parse the ingredients field from a recipe and return a list of
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ class RecipeScraper:
|
||||
# List of recipe scrapers. Note that order matters
|
||||
scrapers: list[type[ABCScraperStrategy]]
|
||||
|
||||
def __init__(self, scrapers: list[type[ABCScraperStrategy]] = None) -> None:
|
||||
def __init__(self, scrapers: list[type[ABCScraperStrategy]] | None = None) -> None:
|
||||
if scrapers is None:
|
||||
scrapers = [
|
||||
RecipeScraperPackage,
|
||||
|
||||
@@ -20,9 +20,6 @@ class BackgroundExecutor:
|
||||
self.repos = repos
|
||||
self.background_tasks = bg
|
||||
|
||||
def populate_item(self, _: int) -> ServerTask:
|
||||
pass
|
||||
|
||||
def dispatch(self, task_name: ServerTaskNames, func: Callable, *args: Any, **kwargs: Any) -> ServerTask:
|
||||
"""The dispatch function is a wrapper around the BackgroundTasks class in Starlett. It directly calls
|
||||
the add_task function and your task will be run in the background. This function all passes the id required
|
||||
|
||||
Reference in New Issue
Block a user