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:
Hayden
2023-01-01 14:47:27 -08:00
committed by GitHub
parent e329e1cd15
commit 4d5550ad85
27 changed files with 173 additions and 135 deletions

View File

@@ -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,

View File

@@ -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()

View File

@@ -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:

View File

@@ -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()

View File

@@ -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

View File

@@ -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.

View File

@@ -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

View File

@@ -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()

View File

@@ -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.

View File

@@ -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

View File

@@ -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:

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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

View File

@@ -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()

View File

@@ -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():

View File

@@ -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.

View File

@@ -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

View File

@@ -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.

View 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

View File

@@ -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,

View File

@@ -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