[tool.poetry] authors = ["Hayden "] description = "A Recipe Manager" license = "AGPL" name = "mealie" version = "1.12.0" [tool.poetry.scripts] start = "mealie.app:main" [tool.poetry.dependencies] Jinja2 = "^3.1.2" Pillow = "^10.0.1" PyYAML = "^6.0.1" SQLAlchemy = "^2" aiofiles = "^24.0.0" alembic = "^1.11.3" aniso8601 = "9.0.1" appdirs = "1.4.4" apprise = "^1.4.5" bcrypt = "^4.0.1" extruct = "^0.17.0" fastapi = "^0.115.0" httpx = "^0.27.0" lxml = "^5.0.0" orjson = "^3.8.0" psycopg2-binary = { version = "^2.9.1", optional = true } pydantic = "^2.6.1" pyhumps = "^3.5.3" python = "^3.10" python-dateutil = "^2.8.2" python-dotenv = "^1.0.0" python-ldap = "^3.3.1" python-multipart = "^0.0.12" python-slugify = "^8.0.0" recipe-scrapers = "^15.0.0" requests = "^2.31.0" tzdata = "^2024.1" uvicorn = { extras = ["standard"], version = "^0.31.0" } beautifulsoup4 = "^4.11.2" isodate = "^0.6.1" text-unidecode = "^1.3" rapidfuzz = "^3.2.0" authlib = "^1.3.0" html2text = "^2024.0.0" paho-mqtt = "^1.6.1" pydantic-settings = "^2.1.0" pillow-heif = "^0.18.0" pyjwt = "^2.8.0" openai = "^1.27.0" typing-extensions = "^4.12.2" [tool.poetry.group.postgres.dependencies] psycopg2-binary = { version = "^2.9.1" } [tool.poetry.group.dev.dependencies] coverage = "^7.0" coveragepy-lcov = "^0.1.1" mkdocs-material = "^9.0.0" mypy = "^1.5.1" pre-commit = "^3.3.3" pylint = "^3.0.0" pytest = "^8.0.0" pytest-asyncio = "^0.24.0" rich = "^13.5.2" ruff = "^0.6.0" types-PyYAML = "^6.0.4" types-python-dateutil = "^2.8.18" types-python-slugify = "^6.0.0" types-requests = "^2.27.12" types-urllib3 = "^1.26.11" pydantic-to-typescript2 = "^1.0.4" [build-system] build-backend = "poetry.core.masonry.api" requires = ["poetry-core>=1.0.0"] [tool.vulture] exclude = ["**/models/**/*.py", "dir/"] ignore_decorators = ["@*router.*", "@app.on_event", "@field_validator", "@controller"] make_whitelist = true min_confidence = 60 paths = ["mealie"] sort_by_size = true [tool.pytest.ini_options] addopts = "-ra -q" minversion = "6.0" python_classes = '*Tests' python_files = 'test_*' python_functions = 'test_*' testpaths = ["tests"] [tool.coverage.report] skip_empty = true [tool.poetry.extras] pgsql = ["psycopg2-binary"] [tool.mypy] follow_imports = "skip" ignore_missing_imports = true plugins = "pydantic.mypy" python_version = "3.10" strict_optional = true [tool.ruff] line-length = 120 output-format = "concise" # Exclude a variety of commonly ignored directories. exclude = [ ".bzr", ".direnv", ".eggs", ".git", ".hg", ".mypy_cache", ".nox", ".pants.d", ".ruff_cache", ".svn", ".tox", ".venv", "__pypackages__", "_build", "buck-out", "build", "dist", "node_modules", "venv", ] # Assume Python 3.10. target-version = "py310" [tool.ruff.lint] # Enable Pyflakes `E` and `F` codes by default. ignore = ["F403", "TID252", "B008"] select = [ "B", # flake8-bugbear "C4", # McCabe complexity "C90", # flake8-comprehensions "DTZ", # flake8-datetimez "E", # pycodestyles "F", # pyflakes "I", # isort "T", # flake8-print "UP", # pyupgrade # "ANN", # flake8-annotations # "BLE", # blind-except # "RUF", # Ruff specific ] [tool.ruff.lint.per-file-ignores] "__init__.py" = ["E402", "E501"] "alembic/versions/2022*" = ["E501"] "alembic/versions/2023*" = ["E501"] "dev/scripts/all_recipes_stress_test.py" = ["E501"] "ldap_provider.py" = ["UP032"] "tests/conftest.py" = ["E402"] "tests/utils/routes/__init__.py" = ["F401"] [tool.ruff.lint.mccabe] # Unlike Flake8, default to a complexity level of 10. max-complexity = 24 # Default is 10.