mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-02 04:53:36 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			529 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			TOML
		
	
	
	
	
	
			
		
		
	
	
			529 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", # https://github.com/django/asgiref/pull/494
 | |
| 
 | |
|   # 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]", # https://github.com/python-social-auth/social-core/pull/1025
 | |
|   "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>=2.0.0.dev20250610173146", # https://github.com/dimagi/django-cte/pull/116
 | |
| 
 | |
|   # 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",
 | |
| ]
 | |
| 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]~=1.15.0",  # https://github.com/typeddjango/django-stubs/issues/2696
 | |
| 
 | |
|   "boto3-stubs[s3,ses,sns,sqs]",
 | |
|   "django-stubs",
 | |
|   "lxml-stubs",
 | |
|   "SQLAlchemy[mypy]",
 | |
|   "types-beautifulsoup4",
 | |
|   "types-boto",
 | |
|   "types-chardet",
 | |
|   "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-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]
 | |
| # https://github.com/django/asgiref/pull/494
 | |
| asgiref = { url = "https://github.com/andersk/asgiref/archive/8a2717c14bce1b8dd37371c675ee3728e66c3fe3.zip" }
 | |
| 
 | |
| # 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/9be0a32bf75a9d8738b005f0b880567fff64e943.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",
 | |
|     "redundant-expr",
 | |
|     "truthy-bool",
 | |
|     "truthy-iterable",
 | |
|     "ignore-without-code",
 | |
|     "unused-awaitable",
 | |
|     "explicit-override",
 | |
| ]
 | |
| 
 | |
| # 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.*",
 | |
|     "re2.*",
 | |
|     "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
 | |
|     "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 = ["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
 |