[project] name = "notebooklm-py" version = "0.3.0" description = "Unofficial Python library for automating Google NotebookLM" dynamic = ["readme"] requires-python = ">=3.10" license = {text = "MIT"} authors = [ {name = "Teng Lin", email = "teng.lin@gmail.com"} ] keywords = ["notebooklm", "google", "ai", "automation", "rpc", "client", "api"] classifiers = [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.14", "Topic :: Software Development :: Libraries :: Python Modules", ] dependencies = [ "httpx>=0.27.0", "click>=8.0.0", "rich>=13.0.0", ] [project.urls] Homepage = "https://github.com/teng-lin/notebooklm-py" Repository = "https://github.com/teng-lin/notebooklm-py" Documentation = "https://github.com/teng-lin/notebooklm-py#readme" Issues = "https://github.com/teng-lin/notebooklm-py/issues" [project.optional-dependencies] browser = ["playwright>=1.40.0"] dev = [ "pytest>=8.0.0", "pytest-asyncio>=0.23.0", "pytest-httpx>=0.30.0", "pytest-cov>=4.0.0", "pytest-rerunfailures>=14.0", "python-dotenv>=1.0.0", "mypy>=1.0.0", "ruff>=0.4.0", "vcrpy>=6.0.0", ] all = ["notebooklm-py[browser,dev]"] [project.scripts] notebooklm = "notebooklm.notebooklm_cli:main" [build-system] requires = ["hatchling", "hatch-fancy-pypi-readme"] build-backend = "hatchling.build" [tool.hatch.metadata.hooks.fancy-pypi-readme] content-type = "text/markdown" [[tool.hatch.metadata.hooks.fancy-pypi-readme.fragments]] path = "README.md" # Convert relative doc links to version-tagged absolute URLs [[tool.hatch.metadata.hooks.fancy-pypi-readme.substitutions]] pattern = '\]\(docs/' replacement = '](https://github.com/teng-lin/notebooklm-py/blob/v$HFPR_VERSION/docs/' [[tool.hatch.metadata.hooks.fancy-pypi-readme.substitutions]] pattern = '\]\(CHANGELOG\.md\)' replacement = '](https://github.com/teng-lin/notebooklm-py/blob/v$HFPR_VERSION/CHANGELOG.md)' [[tool.hatch.metadata.hooks.fancy-pypi-readme.substitutions]] pattern = '\]\(SECURITY\.md\)' replacement = '](https://github.com/teng-lin/notebooklm-py/blob/v$HFPR_VERSION/SECURITY.md)' [[tool.hatch.metadata.hooks.fancy-pypi-readme.substitutions]] pattern = '\]\(LICENSE\)' replacement = '](https://github.com/teng-lin/notebooklm-py/blob/v$HFPR_VERSION/LICENSE)' [tool.hatch.build.targets.wheel] packages = ["src/notebooklm"] [tool.pytest.ini_options] testpaths = ["tests"] asyncio_mode = "auto" asyncio_default_fixture_loop_scope = "function" addopts = "--ignore=tests/e2e" markers = [ "e2e: end-to-end tests requiring authentication (run with pytest tests/e2e -m e2e)", "variants: parameter variant tests (skip to save quota)", "readonly: read-only tests against user's test notebook", "vcr: tests using VCR.py recorded cassettes (run with NOTEBOOKLM_VCR_RECORD=1 to record)", ] [tool.coverage.run] source = ["src/notebooklm"] branch = true [tool.coverage.report] show_missing = true fail_under = 70 [tool.mypy] python_version = "3.10" warn_return_any = false warn_unused_ignores = true disallow_untyped_defs = false check_untyped_defs = true ignore_missing_imports = true files = ["src/notebooklm"] exclude = ["tests/"] # Key check: catch attribute access on wrong types (would have caught our bugs) [[tool.mypy.overrides]] module = "notebooklm.cli.*" warn_return_any = false strict_optional = true [tool.ruff] target-version = "py310" line-length = 100 src = ["src", "tests"] [tool.ruff.lint] select = [ "E", # pycodestyle errors "W", # pycodestyle warnings "F", # pyflakes "I", # isort "B", # flake8-bugbear "C4", # flake8-comprehensions "UP", # pyupgrade "SIM", # flake8-simplify ] ignore = [ "E501", # line too long (handled by formatter) "B008", # function call in default argument (Click uses this) "SIM102", # nested ifs - kept for readability in complex data parsing "SIM105", # contextlib.suppress - explicit try/except clearer for data parsing ] per-file-ignores = {"src/notebooklm/__init__.py" = ["E402"]} [tool.ruff.lint.isort] known-first-party = ["notebooklm"] [tool.ruff.format] quote-style = "double" indent-style = "space"