content: ### Build ###
  [build-system]
  requires = ["hatchling", "hatch-vcs"]
  build-backend = "hatchling.build"
  
  [tool.hatch.build.targets.wheel]
  packages = [
      "src/_nebari",
      "src/nebari",
  ]
  
  [tool.hatch.version]
  source = "vcs"
  
  [tool.hatch.build.hooks.vcs]
  version-file = "src/_nebari/_version.py"
  local_scheme = "node-and-timestamp"
  
  
  ### Project ###
  [project]
  name = "nebari"
  dynamic = ["version"]
  description = "A Jupyter and Dask-powered open source data science platform."
  readme = "README.md"
  requires-python = ">=3.10"
  license = "BSD-3-Clause"
  authors = [
      { name = "Nebari development team", email = "internal-it@quansight.com" },
  ]
  keywords = [
      "aws",
      "gcp",
      "do",
      "azure",
      "nebari",
      "dask",
      "jupyter",
  ]
  classifiers = [
      "Development Status :: 5 - Production/Stable",
      "Intended Audience :: Developers",
      "Topic :: Software Development :: Build Tools",
      "Programming Language :: Python :: 3",
      "Programming Language :: Python :: 3.10",
      "Programming Language :: Python :: 3.11",
      "Programming Language :: Python :: 3.12",
      "Programming Language :: Python :: 3.13",
      "Intended Audience :: Developers",
      "Intended Audience :: Education",
      "Intended Audience :: Information Technology",
      "Intended Audience :: Science/Research",
      "Intended Audience :: System Administrators",
      "Framework :: Jupyter :: JupyterLab",
  ]
  
  dependencies = [
      "auth0-python==4.7.1",
      "azure-identity==1.16.1",
      "azure-mgmt-containerservice==26.0.0",
      "azure-mgmt-resource==23.0.1",
      "bcrypt==4.0.1",
      "boto3==1.34.63",
      "click<8.2.0",      # Pinning click temporarily while https://github.com/fastapi/typer/discussions/1215 is resolved
      "cloudflare==2.11.7",
      "google-auth>=2.31.0,<3.0.0",
      "google-cloud-compute==1.19.1",
      "google-cloud-container==2.49.0",
      "google-cloud-iam==2.15.1",
      "google-cloud-storage==2.18.0",
      "grpc-google-iam-v1==0.13.1",
      "jinja2",
      "kubernetes==27.2.0",
      "pluggy==1.3.0",
      "prompt-toolkit==3.0.36",
      "pydantic>=2.9.2,<3.0.0",
      "pynacl==1.5.0",
      "python-keycloak>=3.9.0,<4.0.0",
      "questionary==2.0.0",
      "requests-toolbelt==1.0.0",
      "rich>=13.5.1,<14",
      "ruamel.yaml==0.18.6",
      "typer==0.9.0",
      "packaging==23.2",
      "typing-extensions>=4.11.0",
  ]
  
  [project.optional-dependencies]
  dev = [
      "black==22.3.0",
      "coverage[toml]",
      "dask-gateway",
      "escapism",
      "mypy==1.6.1",
      "paramiko",
      "pre-commit",
      "pytest-cov",
      "pytest-playwright",
      "pytest-timeout",
      "pytest",
      "python-dotenv",
      "python-hcl2",
      "setuptools==63.4.3",
      "tqdm",
  ]
  docs = [
      "sphinx",
      "sphinx_click",
  ]
  
  [project.urls]
  Documentation = "https://www.nebari.dev/docs/welcome"
  Source = "https://github.com/nebari-dev/nebari"
  
  [project.scripts]
  nebari = "nebari.__main__:main"
  
  [tool.mypy]
  warn_return_any = true
  warn_unused_configs = true
  files = [
      "src/_nebari",
      "src/nebari",
  ]
  exclude = [
      "src/_nebari/stages/kubernetes_services/template" # skip traitlets configuration files
  ]
  
  [[tool.mypy.overrides]]
  module = [
      "auth0.authentication",
      "auth0.management",
      "CloudFlare",
      "kubernetes",
      "kubernetes.client",
      "kubernetes.config",
      "kubernetes.client.rest",
      "kubernetes.client.exceptions",
      "keycloak",
      "keycloak.exceptions",
      "boto3",
      "botocore.exceptions",
  ]
  ignore_missing_imports = true
  
  [tool.ruff]
  extend-exclude = [
      "src/_nebari/template",
      "home",
      "__pycache__"
  ]
  
  [tool.ruff.lint]
  select = [
      "E",  # E: pycodestyle rules
      "F",  # F: pyflakes rules
      "PTH",  # PTH: flake8-use-pathlib rules
  ]
  ignore = [
      "E501", # Line too long
      "F821", # Undefined name
      "PTH123", # open() should be replaced by Path.open()
  ]
  
  [tool.coverage.run]
  branch = true
  
  [tool.coverage.report]
  # Regexes for lines to exclude from consideration
  exclude_also = [
      # Don't complain about missing debug-only code:
      "def __repr__",
      "if self\\.debug",
  
      # Don't complain if tests don't hit defensive assertion code:
      "raise AssertionError",
      "raise NotImplementedError",
  
      # Don't complain if non-runnable code isn't run:
      "if 0:",
      "if __name__ == .__main__.:",
  
      # Don't complain about abstract methods, they aren't run:
      "@(abc\\.)?abstractmethod",
      ]
  ignore_errors = false
  
  [tool.typos]
  files.extend-exclude = ["_build", "*/build/*", "*/node_modules/*", "nebari.egg-info", "*.git", "*.js", "*.json", "*.yaml", "*.yml", "pre-commit-config.yaml"]
  default.extend-ignore-re = ["(?Rm)^.*(#|//)\\s*typos: ignore$"]
  default.extend-ignore-words-re = ["aks", "AKS"]
  default.check-filename = true
  
  [tool.codespell]
  # Ref: https://github.com/codespell-project/codespell#using-a-config-file
  skip = '_build,*/build/*,*/node_modules/*,nebari.egg-info,*.git,package-lock.json,*.lock'
  check-hidden = true
  ignore-regex = '^\s*"image/\S+": ".*'
  ignore-words-list = 'aks'
  