mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-02 21:13:36 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			538 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			TOML
		
	
	
	
	
	
			
		
		
	
	
			538 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			TOML
		
	
	
	
	
	
[project]
 | 
						|
name = "zulip-server"
 | 
						|
version = "0.1.0"
 | 
						|
requires-python = ">=3.10"
 | 
						|
 | 
						|
[dependency-groups]
 | 
						|
prod = [
 | 
						|
  # Django itself
 | 
						|
  "django[argon2]==5.2.*",
 | 
						|
  "asgiref",
 | 
						|
 | 
						|
  # needed for NotRequired, ParamSpec
 | 
						|
  "typing-extensions",
 | 
						|
 | 
						|
  # Needed for rendering backend templates
 | 
						|
  "jinja2",
 | 
						|
 | 
						|
  # Needed for Markdown processing
 | 
						|
  "markdown",
 | 
						|
  "pygments",
 | 
						|
  "jsx-lexer",
 | 
						|
  "uri-template",
 | 
						|
  "regex",
 | 
						|
 | 
						|
  # Needed for manage.py
 | 
						|
  "ipython",
 | 
						|
 | 
						|
  # Needed for image processing and thumbnailing
 | 
						|
  "pyvips",
 | 
						|
 | 
						|
  # Needed for building complex DB queries
 | 
						|
  "sqlalchemy==1.4.*",
 | 
						|
  "greenlet",
 | 
						|
 | 
						|
  # Needed for S3 file uploads and other AWS tools
 | 
						|
  "boto3",
 | 
						|
 | 
						|
  # The runtime-relevant part of boto3-stubs (see mypy.in)
 | 
						|
  "mypy-boto3-s3",
 | 
						|
  "mypy-boto3-ses",
 | 
						|
  "mypy-boto3-sns",
 | 
						|
  "mypy-boto3-sqs",
 | 
						|
 | 
						|
  # Needed for integrations
 | 
						|
  "defusedxml",
 | 
						|
 | 
						|
  # Needed for LDAP support
 | 
						|
  "python-ldap",
 | 
						|
  "django-auth-ldap",
 | 
						|
 | 
						|
  # Django extension providing bitfield support
 | 
						|
  "django-bitfield",
 | 
						|
 | 
						|
  # Needed for Android push notifications
 | 
						|
  "firebase-admin",
 | 
						|
 | 
						|
  # Needed for the email mirror
 | 
						|
  "html2text",
 | 
						|
  "talon-core",
 | 
						|
 | 
						|
  # Needed for inlining the CSS in emails
 | 
						|
  "css-inline",
 | 
						|
 | 
						|
  # Needed for JWT-based auth
 | 
						|
  "pyjwt",
 | 
						|
 | 
						|
  # Needed to access RabbitMQ
 | 
						|
  "pika",
 | 
						|
 | 
						|
  # Needed to access our database
 | 
						|
  "psycopg2",
 | 
						|
 | 
						|
  # Needed for memcached usage
 | 
						|
  "python-binary-memcached",
 | 
						|
 | 
						|
  # Needed for compression support in memcached via python-binary-memcached
 | 
						|
  "django-bmemcached",
 | 
						|
 | 
						|
  # Needed for zerver/tests/test_timestamp.py
 | 
						|
  "python-dateutil",
 | 
						|
 | 
						|
  # Needed for Redis
 | 
						|
  "redis",
 | 
						|
 | 
						|
  # Tornado used for server->client push system
 | 
						|
  "tornado",
 | 
						|
 | 
						|
  # Fast JSON parser
 | 
						|
  "orjson",
 | 
						|
 | 
						|
  # Needed for iOS push notifications
 | 
						|
  "aioapns",
 | 
						|
 | 
						|
  # To parse po files
 | 
						|
  "polib",
 | 
						|
 | 
						|
  # Needed for cloning virtual environments
 | 
						|
  "virtualenv-clone",
 | 
						|
 | 
						|
  # Needed for link preview
 | 
						|
  "beautifulsoup4",
 | 
						|
  "pyoembed",
 | 
						|
  "python-magic",
 | 
						|
 | 
						|
  # The Zulip API bindings, from its own repository.
 | 
						|
  "zulip",
 | 
						|
  "zulip-bots",
 | 
						|
 | 
						|
  # Used for Hesiod lookups, etc.
 | 
						|
  "dnspython",
 | 
						|
 | 
						|
  # Install Python Social Auth
 | 
						|
  "social-auth-app-django",
 | 
						|
  "social-auth-core[azuread,saml]",
 | 
						|
  "python3-saml",
 | 
						|
 | 
						|
  # For encrypting a login token to the desktop app
 | 
						|
  "cryptography",
 | 
						|
 | 
						|
  # Needed for messages' rendered content parsing in push notifications.
 | 
						|
  "lxml",
 | 
						|
 | 
						|
  # Needed for 2-factor authentication
 | 
						|
  "django-two-factor-auth[call,phonenumberslite,sms]",
 | 
						|
 | 
						|
  # Needed for processing payments (in corporate)
 | 
						|
  "stripe",
 | 
						|
 | 
						|
  # For checking whether email of the user is from a disposable email provider.
 | 
						|
  "disposable-email-domains",
 | 
						|
 | 
						|
  # Needed for parsing YAML with JSON references from the REST API spec files
 | 
						|
  "jsonref",
 | 
						|
 | 
						|
  # Needed for string matching in AlertWordProcessor
 | 
						|
  "pyahocorasick",
 | 
						|
 | 
						|
  # Needed for function decorators that don't break introspection.
 | 
						|
  # Used for rate limiting authentication.
 | 
						|
  "decorator",
 | 
						|
 | 
						|
  # For server-side enforcement of password strength
 | 
						|
  "zxcvbn",
 | 
						|
 | 
						|
  # Needed for sending HTTP requests
 | 
						|
  "requests[security]",
 | 
						|
  "requests-oauthlib",
 | 
						|
 | 
						|
  # For OpenAPI schema validation.
 | 
						|
  "openapi-core",
 | 
						|
  "werkzeug<3.1.2", # https://github.com/python-openapi/openapi-core/issues/938
 | 
						|
 | 
						|
  # For reporting errors to sentry.io
 | 
						|
  "sentry-sdk",
 | 
						|
 | 
						|
  # For detecting URLs to link
 | 
						|
  "tlds",
 | 
						|
 | 
						|
  # Unicode Collation Algorithm for sorting multilingual strings
 | 
						|
  "pyuca",
 | 
						|
 | 
						|
  # Handle connection retries with exponential backoff
 | 
						|
  "backoff",
 | 
						|
 | 
						|
  # Needed for reading bson files in rocketchat import tool
 | 
						|
  "pymongo",
 | 
						|
 | 
						|
  # Non-backtracking regular expressions
 | 
						|
  "google-re2",
 | 
						|
 | 
						|
  # For querying recursive group membership
 | 
						|
  "django-cte",
 | 
						|
 | 
						|
  # SCIM integration
 | 
						|
  "django-scim2",
 | 
						|
 | 
						|
  # Circuit-breaking for outgoing services
 | 
						|
  "circuitbreaker",
 | 
						|
 | 
						|
  # Runtime monkeypatching of django-stubs generics
 | 
						|
  "django-stubs-ext",
 | 
						|
 | 
						|
  # Structured data representation with parsing.
 | 
						|
  "pydantic",
 | 
						|
  "annotated-types",
 | 
						|
 | 
						|
  # For requesting LLM API endpoints.
 | 
						|
  "litellm",
 | 
						|
 | 
						|
  # Used for running the Zulip production Django server
 | 
						|
  "uwsgi",
 | 
						|
 | 
						|
  # Used for monitoring memcached
 | 
						|
  "prometheus-client",
 | 
						|
 | 
						|
  # For captchas on unauth'd pages which can generate emails
 | 
						|
  "altcha",
 | 
						|
 | 
						|
  # SMTP server for accepting incoming email
 | 
						|
  "aiosmtpd>=1.4.6",
 | 
						|
 | 
						|
  # For using Missing sentinel
 | 
						|
  "pydantic-partials",
 | 
						|
 | 
						|
  # For E2EE of push notifications
 | 
						|
  "pynacl",
 | 
						|
 | 
						|
  # Character set detection for text/plain
 | 
						|
  "chardet>=5.1.0",
 | 
						|
 | 
						|
  # Better compression than zlib
 | 
						|
  "zstd",
 | 
						|
]
 | 
						|
docs = [
 | 
						|
  # Needed to build RTD docs
 | 
						|
  "sphinx",
 | 
						|
  "sphinx-rtd-theme",
 | 
						|
  "sphinx-design",
 | 
						|
 | 
						|
  # Needed to build Markdown docs
 | 
						|
  "myst-parser",
 | 
						|
]
 | 
						|
dev = [
 | 
						|
  { include-group = "prod" },
 | 
						|
  { include-group = "docs" },
 | 
						|
 | 
						|
  # moto s3 mock
 | 
						|
  "moto[s3]",
 | 
						|
 | 
						|
  # For tools/run-dev
 | 
						|
  "aiohttp",
 | 
						|
 | 
						|
  # Needed for documentation links test
 | 
						|
  "scrapy",
 | 
						|
 | 
						|
  # Needed to compute test coverage
 | 
						|
  "coverage",
 | 
						|
 | 
						|
  # fake for LDAP testing
 | 
						|
  "fakeldap",
 | 
						|
 | 
						|
  # For testing mock http requests
 | 
						|
  "responses",
 | 
						|
 | 
						|
  # For doing highly usable Python profiling
 | 
						|
  "line-profiler",
 | 
						|
 | 
						|
  # Python reformatter
 | 
						|
  "black",
 | 
						|
 | 
						|
  # Python linter
 | 
						|
  "ruff",
 | 
						|
 | 
						|
  # Needed for watching file changes
 | 
						|
  "pyinotify",
 | 
						|
  "pyasyncore", # https://github.com/seb-m/pyinotify/issues/204
 | 
						|
 | 
						|
  # Needed to run tests in parallel
 | 
						|
  "tblib",
 | 
						|
 | 
						|
  # For linting Git commit messages
 | 
						|
  "gitlint-core",
 | 
						|
 | 
						|
  # Needed for visualising cProfile reports
 | 
						|
  "snakeviz",
 | 
						|
 | 
						|
  # Needed for creating DigitalOcean droplets
 | 
						|
  "python-digitalocean",
 | 
						|
 | 
						|
  # zulip's linting framework - zulint
 | 
						|
  "zulint",
 | 
						|
 | 
						|
  # For type checking
 | 
						|
  "mypy[faster-cache]",
 | 
						|
 | 
						|
  "boto3-stubs[s3,ses,sns,sqs]",
 | 
						|
  "django-stubs",
 | 
						|
  "google-re2-stubs",
 | 
						|
  "lxml-stubs",
 | 
						|
  "SQLAlchemy[mypy]",
 | 
						|
  "types-beautifulsoup4",
 | 
						|
  "types-boto",
 | 
						|
  "types-decorator",
 | 
						|
  "types-defusedxml",
 | 
						|
  "types-jsonschema",
 | 
						|
  "types-Markdown",
 | 
						|
  "types-oauthlib",
 | 
						|
  "types-polib",
 | 
						|
  "types-pika",
 | 
						|
  "types-psycopg2",
 | 
						|
  "types-Pygments",
 | 
						|
  "types-pyOpenSSL",
 | 
						|
  "types-python-dateutil",
 | 
						|
  "types-PyYAML",
 | 
						|
  "types-redis",
 | 
						|
  "types-regex",
 | 
						|
  "types-requests",
 | 
						|
  "types-requests-oauthlib",
 | 
						|
  "types-uwsgi",
 | 
						|
  "types-zstd",
 | 
						|
  "types-zxcvbn",
 | 
						|
 | 
						|
  # Needed for tools/check-thirdparty
 | 
						|
  "python-debian",
 | 
						|
 | 
						|
  # Pattern-based lint tool
 | 
						|
  "semgrep<1.80.0", # https://github.com/semgrep/semgrep/issues/10408
 | 
						|
 | 
						|
  # For sorting versions when uploading releases
 | 
						|
  "natsort",
 | 
						|
 | 
						|
  # For spell check linter
 | 
						|
  "codespell",
 | 
						|
 | 
						|
  # For mocking time
 | 
						|
  "time-machine",
 | 
						|
]
 | 
						|
 | 
						|
[tool.uv]
 | 
						|
no-binary-package = ["lxml", "xmlsec"]
 | 
						|
 | 
						|
[tool.uv.sources]
 | 
						|
# Forked to avoid pulling in scipy: https://github.com/mailgun/talon/pull/200
 | 
						|
# and chardet, cchardet: https://github.com/mailgun/talon/pull/239
 | 
						|
# and fix invalid escape sequences: https://github.com/mailgun/talon/pull/245
 | 
						|
talon-core = { url = "https://github.com/zulip/talon/archive/e87a64dccc3c5ee1b8ea157d4b6e15ecd46f2bed.zip", subdirectory = "talon-core" }
 | 
						|
 | 
						|
# We integrate with these tightly, including fetching content not included in
 | 
						|
# the official PyPI release tarballs, such as logos, assets and documentation
 | 
						|
# files that we render on our /integrations/ page. Therefore, we need to pin the
 | 
						|
# version from Git rather than a PyPI release. Keeping everything in one
 | 
						|
# repository simplifies the process of implementing and documenting new bots for
 | 
						|
# new contributors.
 | 
						|
zulip = { url = "https://github.com/zulip/python-zulip-api/archive/9e131ac626976b9c3da6c11b6365b4939656f7c3.zip", subdirectory = "zulip" }
 | 
						|
zulip-bots = { url = "https://github.com/zulip/python-zulip-api/archive/0.9.0.zip", subdirectory = "zulip_bots" }
 | 
						|
 | 
						|
# zulip's linting framework - zulint
 | 
						|
zulint = { url = "https://github.com/zulip/zulint/archive/448e36a1e50e79c82257ed3d65fcf5c8591cdb61.zip" }
 | 
						|
 | 
						|
[tool.black]
 | 
						|
line-length = 100
 | 
						|
target-version = ["py310"]
 | 
						|
 | 
						|
[tool.isort]
 | 
						|
src_paths = [".", "tools"]
 | 
						|
known_third_party = "zulip"
 | 
						|
profile = "black"
 | 
						|
line_length = 100
 | 
						|
 | 
						|
[tool.mypy]
 | 
						|
# Logistics of what code to check and how to handle the data.
 | 
						|
scripts_are_modules = true
 | 
						|
show_traceback = true
 | 
						|
# See https://zulip.readthedocs.io/en/latest/testing/mypy.html#mypy-stubs-for-third-party-modules
 | 
						|
# for notes on how we manage mypy stubs.
 | 
						|
mypy_path = "$MYPY_CONFIG_FILE_DIR/stubs"
 | 
						|
cache_dir = "$MYPY_CONFIG_FILE_DIR/var/mypy-cache"
 | 
						|
 | 
						|
# Enable strict mode, with some exceptions.
 | 
						|
strict = true
 | 
						|
disallow_subclassing_any = false
 | 
						|
disallow_untyped_calls = false
 | 
						|
disallow_untyped_decorators = false
 | 
						|
warn_return_any = false
 | 
						|
 | 
						|
# Enable optional errors.
 | 
						|
enable_error_code = [
 | 
						|
    "redundant-self",
 | 
						|
    "deprecated",
 | 
						|
    "redundant-expr",
 | 
						|
    "truthy-bool",
 | 
						|
    "truthy-iterable",
 | 
						|
    "ignore-without-code",
 | 
						|
    "unused-awaitable",
 | 
						|
    "explicit-override",
 | 
						|
    "exhaustive-match",
 | 
						|
]
 | 
						|
 | 
						|
# Display the codes needed for # type: ignore[code] annotations.
 | 
						|
show_error_codes = true
 | 
						|
 | 
						|
# Warn of unreachable or redundant code.
 | 
						|
warn_unreachable = true
 | 
						|
 | 
						|
# dmypy enables local_partial_types implicitly. We need mypy to align
 | 
						|
# with this behavior.
 | 
						|
local_partial_types = true
 | 
						|
 | 
						|
plugins = [
 | 
						|
    "mypy_django_plugin.main",
 | 
						|
    "pydantic.mypy",
 | 
						|
]
 | 
						|
 | 
						|
[[tool.mypy.overrides]]
 | 
						|
module = [
 | 
						|
    "ahocorasick.*",
 | 
						|
    "bitfield.*",
 | 
						|
    "bmemcached.*",
 | 
						|
    "circuitbreaker.*",
 | 
						|
    "digitalocean.*",
 | 
						|
    "django_auth_ldap.*",
 | 
						|
    "django_bmemcached.*",
 | 
						|
    "django_cte.*",
 | 
						|
    "django_otp.*",
 | 
						|
    "django_scim.*",
 | 
						|
    "fakeldap.*",
 | 
						|
    "firebase_admin.*",
 | 
						|
    "gitlint.*",
 | 
						|
    "integrations.*",
 | 
						|
    "jsonref.*",
 | 
						|
    "ldap.*", # https://github.com/python-ldap/python-ldap/issues/368
 | 
						|
    "onelogin.*",
 | 
						|
    "pyinotify.*",
 | 
						|
    "pyoembed.*",
 | 
						|
    "pyuca.*",
 | 
						|
    "pyvips.*",
 | 
						|
    "scim2_filter_parser.attr_paths",
 | 
						|
    "social_django.*",
 | 
						|
    "talon_core.*",
 | 
						|
    "tlds.*",
 | 
						|
    "two_factor.*",
 | 
						|
]
 | 
						|
ignore_missing_imports = true
 | 
						|
 | 
						|
[tool.django-stubs]
 | 
						|
django_settings_module = "zproject.settings"
 | 
						|
 | 
						|
[tool.pydantic-mypy]
 | 
						|
# See https://docs.pydantic.dev/latest/integrations/mypy/#mypy-plugin-capabilities for the effects of these options.
 | 
						|
init_forbid_extra = true
 | 
						|
init_typed = true
 | 
						|
warn_required_dynamic_aliases = true
 | 
						|
 | 
						|
[tool.ruff]
 | 
						|
line-length = 100
 | 
						|
src = [".", "tools"]
 | 
						|
target-version = "py310"
 | 
						|
 | 
						|
[tool.ruff.lint]
 | 
						|
# See https://github.com/astral-sh/ruff#rules for error code definitions.
 | 
						|
select = [
 | 
						|
    "ANN", # annotations
 | 
						|
    "B", # bugbear
 | 
						|
    "C4", # comprehensions
 | 
						|
    "COM", # trailing comma
 | 
						|
    "DJ", # Django
 | 
						|
    "DTZ", # naive datetime
 | 
						|
    "E", # style errors
 | 
						|
    "EXE", # shebang
 | 
						|
    "F", # flakes
 | 
						|
    "FLY", # string formatting
 | 
						|
    "FURB", # refurbishing
 | 
						|
    "G", # logging format
 | 
						|
    "I", # import sorting
 | 
						|
    "INT", # gettext
 | 
						|
    "ISC", # string concatenation
 | 
						|
    "LOG", # logging
 | 
						|
    "N", # naming
 | 
						|
    "PERF", # performance
 | 
						|
    "PGH", # pygrep-hooks
 | 
						|
    "PIE", # miscellaneous
 | 
						|
    "PL", # pylint
 | 
						|
    "PYI", # typing stubs
 | 
						|
    "Q", # quotes
 | 
						|
    "RSE", # raise
 | 
						|
    "RUF", # Ruff
 | 
						|
    "S", # security
 | 
						|
    "SLOT", # __slots__
 | 
						|
    "SIM", # simplify
 | 
						|
    "T10", # debugger
 | 
						|
    "TC", # type-checking
 | 
						|
    "TID", # tidy imports
 | 
						|
    "UP", # upgrade
 | 
						|
    "W", # style warnings
 | 
						|
    "YTT", # sys.version
 | 
						|
]
 | 
						|
ignore = [
 | 
						|
    "ANN401", # Dynamically typed expressions (typing.Any) are disallowed
 | 
						|
    "B007", # Loop control variable not used within the loop body
 | 
						|
    "B904", # Within an except clause, raise exceptions with raise ... from err or raise ... from None to distinguish them from errors in exception handling
 | 
						|
    "C408", # Unnecessary `dict` call (rewrite as a literal)
 | 
						|
    "COM812", # Trailing comma missing
 | 
						|
    "DJ001", # Avoid using `null=True` on string-based fields
 | 
						|
    "DJ008", # Model does not define `__str__` method
 | 
						|
    "E402", # Module level import not at top of file
 | 
						|
    "E501", # Line too long
 | 
						|
    "E731", # Do not assign a lambda expression, use a def
 | 
						|
    "LOG015", # `error()` call on root logger
 | 
						|
    "N802", # Function name should be lowercase
 | 
						|
    "N806", # Variable in function should be lowercase
 | 
						|
    "PERF203", # `try`-`except` within a loop incurs performance overhead
 | 
						|
    "PLC0414", # Import alias does not rename original package
 | 
						|
    "PLC0415", # `import` should be at the top-level of a file
 | 
						|
    "PLC1901", # `s == ""` can be simplified to `not s` as an empty string is falsey
 | 
						|
    "PLR0911", # Too many return statements
 | 
						|
    "PLR0912", # Too many branches
 | 
						|
    "PLR0913", # Too many arguments to function call
 | 
						|
    "PLR0915", # Too many statements
 | 
						|
    "PLR2004", # Magic value used in comparison
 | 
						|
    "PLR5501", # Consider using `elif` instead of `else` then `if` to remove one indentation level
 | 
						|
    "PLW0603", # Using the global statement is discouraged
 | 
						|
    "PLW2901", # Outer for loop variable overwritten by inner for loop target
 | 
						|
    "RUF001", # String contains ambiguous unicode character
 | 
						|
    "RUF002", # Docstring contains ambiguous unicode character
 | 
						|
    "RUF003", # Comment contains ambiguous unicode character
 | 
						|
    "RUF012", # Mutable class attributes should be annotated with `typing.ClassVar`
 | 
						|
    "S101", # Use of `assert` detected
 | 
						|
    "S105", # Possible hardcoded password
 | 
						|
    "S106", # Possible hardcoded password
 | 
						|
    "S107", # Possible hardcoded password
 | 
						|
    "S110", # `try`-`except`-`pass` detected, consider logging the exception
 | 
						|
    "S113", # Probable use of requests call without timeout
 | 
						|
    "S310", # Audit URL open for permitted schemes. Allowing use of `file:` or custom schemes is often unexpected.
 | 
						|
    "S311", # Standard pseudo-random generators are not suitable for cryptographic purposes
 | 
						|
    "S324", # Probable use of insecure hash functions in `hashlib`
 | 
						|
    "S603", # `subprocess` call: check for execution of untrusted input
 | 
						|
    "S606", # Starting a process without a shell
 | 
						|
    "S607", # Starting a process with a partial executable path
 | 
						|
    "SIM103", # Return the condition directly
 | 
						|
    "SIM108", # Use ternary operator `action = "[commented]" if action == "created" else f"{action} a [comment]"` instead of if-else-block
 | 
						|
    "SIM114", # Combine `if` branches using logical `or` operator
 | 
						|
    "SIM401", # Use `d.get(key, default)` instead of an `if` block
 | 
						|
    "TC001", # Move application import into a type-checking block
 | 
						|
    "TC002", # Move third-party import into a type-checking block
 | 
						|
    "TC003", # Move standard library import into a type-checking block
 | 
						|
    "TC006", # Add quotes to type expression in `typing.cast()`
 | 
						|
]
 | 
						|
 | 
						|
[tool.ruff.lint.flake8-bandit]
 | 
						|
allowed-markup-calls = ["bs4.BeautifulSoup.decode", "lxml.html.tostring"]
 | 
						|
 | 
						|
[tool.ruff.lint.flake8-gettext]
 | 
						|
extend-function-names = ["gettext_lazy"]
 | 
						|
 | 
						|
[tool.ruff.lint.isort]
 | 
						|
known-third-party = ["zulip"]
 | 
						|
split-on-trailing-comma = false
 |