| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269 |
- # See PEP 518 for the spec of this file
- # https://www.python.org/dev/peps/pep-0518/
- [build-system]
- requires = ["hatchling>=1.27", "packaging"]
- build-backend = "hatchling.build"
- [project]
- name = "netbox"
- dynamic = ["version", "dependencies"]
- requires-python = ">=3.12"
- description = "The premier source of truth powering network automation."
- readme = "README.md"
- license = "Apache-2.0"
- license-files = ["LICENSE.txt"]
- authors = [{ name = "NetBox Community" }]
- classifiers = [
- "Development Status :: 5 - Production/Stable",
- "Framework :: Django",
- "Natural Language :: English",
- "Programming Language :: Python",
- "Programming Language :: Python :: 3 :: Only",
- "Programming Language :: Python :: 3.12",
- "Programming Language :: Python :: 3.13",
- "Programming Language :: Python :: 3.14",
- ]
- [project.optional-dependencies]
- ldap = ["django-auth-ldap"]
- saml2 = ["python3-saml"]
- remote-auth = ["django-auth-ldap", "python3-saml"]
- sentry = ["sentry-sdk"]
- swift = ["django-storage-swift"]
- s3 = ["boto3"]
- git = ["dulwich"]
- # NetBox Labs plugins (proprietary, opt-in). Minor-bounded to the tested series.
- branching = ["netboxlabs-netbox-branching>=1.1.0,<1.2.0"]
- custom-objects = ["netboxlabs-netbox-custom-objects>=0.5.0,<0.6.0"]
- # Convenience aggregate of the recommended NetBox Labs plugins (NOT a catch-all of every extra).
- # The component pins are duplicated literally, as remote-auth duplicates ldap and saml2;
- # scripts/verify_wheel_metadata.py verifies in CI that this aggregate equals the union of the
- # branching and custom-objects extras, guarding the duplication against drift.
- recommended-plugins = [
- "netboxlabs-netbox-branching>=1.1.0,<1.2.0",
- "netboxlabs-netbox-custom-objects>=0.5.0,<0.6.0",
- ]
- dev = [
- "build",
- "coverage",
- "packaging",
- "pre-commit",
- "ruff==0.15.10",
- "tblib",
- "twine",
- "uv",
- ]
- [project.scripts]
- netbox = "netbox.cli:main"
- [project.urls]
- Homepage = "https://netboxlabs.com/products/netbox/"
- Documentation = "https://netboxlabs.com/docs/netbox/"
- Source = "https://github.com/netbox-community/netbox"
- Issues = "https://github.com/netbox-community/netbox/issues"
- [tool.coverage.run]
- source = ["netbox/"]
- concurrency = ["multiprocessing"]
- parallel = true
- sigterm = true
- [tool.coverage.report]
- skip_covered = true
- fail_under = 91
- omit = [
- "*/migrations/*",
- "*/tests/*",
- # Non-application code (no testable logic / not part of the app)
- "netbox/scripts/*", # SCRIPTS_ROOT: user/generated scripts
- "*/netbox/configuration*.py", # settings/config files (template, testing, local)
- "*/netbox/wsgi.py", # WSGI entrypoint
- "*/netbox/__main__.py", # `python -m netbox` entry point
- "*/generate_secret_key.py", # standalone CLI helper
- "*/utilities/debug.py", # debug-toolbar hook, active only when DEBUG=True
- "*/extras/management/commands/housekeeping.py", # deprecated; will not be tested
- ]
- [tool.hatch.metadata.hooks.custom]
- # Implemented in scripts/packaging/hatch_metadata.py; computes a PEP 440 version from
- # netbox/release.yaml (version + optional designation) and runtime deps from requirements.txt.
- path = "scripts/packaging/hatch_metadata.py"
- [tool.hatch.build.targets.wheel]
- sources = ["netbox"]
- packages = [
- "netbox/account",
- "netbox/circuits",
- "netbox/core",
- "netbox/dcim",
- "netbox/extras",
- "netbox/ipam",
- "netbox/netbox",
- "netbox/tenancy",
- "netbox/users",
- "netbox/utilities",
- "netbox/virtualization",
- "netbox/vpn",
- "netbox/wireless",
- ]
- # Never ship a live or local configuration file: configuration.py holds SECRET_KEY
- # and database credentials, ldap_config.py holds LDAP bind credentials, and developers
- # often keep ad-hoc configuration*.py copies in this directory. Exclude both sets, then
- # re-include only the two tracked templates. (verify_wheel_contents.py enforces this in CI.)
- exclude = [
- "netbox/netbox/configuration*.py",
- "netbox/netbox/ldap_config*.py",
- ]
- # Bundle runtime data inside the installed netbox package at netbox/_data/.
- # Destinations carry an extra leading "netbox/" because the wheel `sources`
- # setting above strips one "netbox/" prefix from every path (including these
- # force-include targets); after stripping they resolve to netbox/_data/...
- [tool.hatch.build.targets.wheel.force-include]
- "netbox/templates" = "netbox/netbox/_data/templates"
- "netbox/translations" = "netbox/netbox/_data/translations"
- "netbox/project-static/dist" = "netbox/netbox/_data/project-static/dist"
- "netbox/project-static/img" = "netbox/netbox/_data/project-static/img"
- "netbox/project-static/js" = "netbox/netbox/_data/project-static/js"
- "netbox/release.yaml" = "netbox/netbox/_data/release.yaml"
- "contrib/gunicorn.py" = "netbox/netbox/_data/examples/gunicorn.py"
- # The canonical contrib files are bundled as-is; `netbox setup` adapts the systemd units for
- # a pip install at render time (see _PIP_TRANSFORMS in netbox/netbox/scaffold.py).
- "contrib/netbox.service" = "netbox/netbox/_data/examples/netbox.service"
- "contrib/netbox-rq.service" = "netbox/netbox/_data/examples/netbox-rq.service"
- "contrib/nginx.conf" = "netbox/netbox/_data/examples/nginx.conf"
- "contrib/apache.conf" = "netbox/netbox/_data/examples/apache.conf"
- "contrib/netbox.env" = "netbox/netbox/_data/examples/netbox.env"
- # Force the two tracked config templates in over the configuration*.py exclude above.
- "netbox/netbox/configuration_example.py" = "netbox/netbox/configuration_example.py"
- "netbox/netbox/configuration_testing.py" = "netbox/netbox/configuration_testing.py"
- [tool.hatch.build.targets.sdist]
- include = [
- "/.github/workflows/release.yml",
- "/CHANGELOG.md",
- "/LICENSE.txt",
- "/README.md",
- "/base_requirements.txt",
- "/contrib",
- "/docs",
- "/mkdocs.yml",
- "/netbox",
- "/pyproject.toml",
- "/requirements.txt",
- "/scripts",
- "/upgrade.sh",
- ]
- # Keep live/local configuration*.py and ldap_config*.py out of the sdist (same rule as the
- # wheel, keeping only the two tracked templates), and drop the local netbox/configuration.py
- # symlink that otherwise breaks `python -m build --sdist` with an AbsoluteLinkError.
- exclude = [
- "netbox/netbox/configuration*.py",
- "netbox/netbox/ldap_config*.py",
- "netbox/configuration.py",
- "netbox/ldap_config.py",
- ]
- [tool.hatch.build.targets.sdist.force-include]
- # Force the two tracked config templates in over the configuration*.py exclude above.
- "netbox/netbox/configuration_example.py" = "netbox/netbox/configuration_example.py"
- "netbox/netbox/configuration_testing.py" = "netbox/netbox/configuration_testing.py"
- [tool.pyright]
- include = ["netbox"]
- exclude = [
- "**/node_modules",
- "**/__pycache__",
- ]
- reportMissingImports = true
- reportMissingTypeStubs = false
- [tool.ruff]
- exclude = [
- ".eggs",
- ".git",
- ".pyenv",
- ".pytest_cache",
- ".ruff_cache",
- ".venv",
- ".vscode",
- "__pypackages__",
- "_build",
- "build",
- "dist",
- "netbox/project-static/**",
- "node_modules",
- "site-packages",
- "venv",
- ]
- # Enforce line length and indent-width
- line-length = 120
- indent-width = 4
- # Ignores anything in .gitignore
- respect-gitignore = true
- # Always generate Python 3.12-compatible code
- target-version = "py312"
- [tool.ruff.lint]
- # Pin the effective default rule set used with `preview = true` to match Ruff 0.15.1.
- # Ruff 0.15.2 changed the preview defaults, see https://github.com/astral-sh/ruff/releases/tag/0.15.2
- # Keeping this explicit makes ruff deterministic.
- select = ["E4", "E7", "E9", "F"]
- extend-select = [
- "E1", # pycodestyle errors: indentation-related (e.g., unexpected/missing indent)
- "E2", # pycodestyle errors: whitespace-related (e.g., missing whitespace, extra spaces)
- "E3", # pycodestyle errors: blank lines / spacing around definitions
- "E501", # pycodestyle: line too long (enforced with `line-length` above)
- "W", # pycodestyle warnings (various style warnings, often whitespace/newlines)
- "I", # import sorting (isort-equivalent)
- "RET", # return semantics (flake8-return family: consistent/explicit returns; remove redundant else/assign before return)
- "UP", # pyupgrade: modernize syntax for your target Python (e.g., f-strings, built-in generics, newer stdlib idioms)
- "RUF022", # ruff: enforce sorted `__all__` lists
- ]
- # If you add a rule to `ignore`, please also update the "Linter Exceptions" section in
- # docs/development/style-guide.md.
- ignore = [
- "F403", # pyflakes: `from ... import *` used; unable to detect undefined names
- "F405", # pyflakes: name may be undefined or defined from star imports
- "RET504", # return: unnecessary assignment before `return` (e.g., `x = expr; return x` -> `return expr`)
- "UP032", # pyupgrade: prefer f-strings over `str.format(...)`
- ]
- preview = true
- [tool.ruff.lint.isort]
- known-first-party = [
- "account",
- "circuits",
- "core",
- "dcim",
- "extras",
- "ipam",
- "netbox",
- "tenancy",
- "users",
- "utilities",
- "virtualization",
- "vpn",
- "wireless",
- ]
- [tool.ruff.lint.per-file-ignores]
- "template_code.py" = ["E501"]
- "netbox/netbox/graphql/filter_lookups.py" = ["UP046"] # Strawberry typing: keep `Generic[T]` for now
- "netbox/netbox/graphql/scalars.py" = ["UP007"] # Strawberry scalar typing: `Union[...]` required
- [tool.ruff.format]
- # Use single quotes for strings.
- quote-style = "single"
- # Indent with spaces, rather than tabs.
- indent-style = "space"
- # Enforce UNIX line ending
- line-ending = "lf"
|