Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 6 additions & 15 deletions main/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,13 @@
get_list_of_str,
get_string,
)
from main.middleware.cookie_tombstones import parse_cookie_tombstones
from main.sentry import init_sentry
from main.settings_celery import * # noqa: F403
from main.settings_course_etl import * # noqa: F403
from main.settings_pluggy import * # noqa: F403
from openapi.settings_spectacular import open_spectacular_settings

VERSION = "0.65.0"
VERSION = "2026.4.16.1"

log = logging.getLogger()

Expand Down Expand Up @@ -242,7 +241,6 @@
CSRF_COOKIE_SECURE = get_bool("CSRF_COOKIE_SECURE", True) # noqa: FBT003
CSRF_COOKIE_DOMAIN = get_string("CSRF_COOKIE_DOMAIN", None)
CSRF_COOKIE_NAME = get_string("CSRF_COOKIE_NAME", "csrftoken")
COOKIE_TOMBSTONES = parse_cookie_tombstones(get_string("COOKIE_TOMBSTONES", "[]"))

CSRF_HEADER_NAME = get_string("CSRF_HEADER_NAME", "HTTP_X_CSRFTOKEN")

Expand All @@ -251,10 +249,6 @@
SESSION_COOKIE_DOMAIN = get_string("SESSION_COOKIE_DOMAIN", None)
SESSION_COOKIE_NAME = get_string("SESSION_COOKIE_NAME", "sessionid")

if COOKIE_TOMBSTONES:
tombstone_middleware = "main.middleware.cookie_tombstones.CookieTombstoneMiddleware"
MIDDLEWARE = (tombstone_middleware, *MIDDLEWARE)

# enable the nplusone profiler only in debug mode
if DEBUG:
INSTALLED_APPS += ("nplusone.ext.django",)
Expand Down Expand Up @@ -792,13 +786,10 @@ def get_all_config_keys():
name="QDRANT_ENABLE_INDEXING_PLUGIN_HOOKS", default=False
)

QDRANT_API_KEY = get_string(name="QDRANT_API_KEY", default="")
QDRANT_HOST = get_string(name="QDRANT_HOST", default="http://qdrant:6333")
QDRANT_API_KEY = get_string(name="QDRANT_API_KEY_V2", default="")
QDRANT_HOST = get_string(name="QDRANT_HOST_V2", default="http://qdrant:6333")


# 1 week default query cache ttl
QDRANT_QUERY_EMBEDDING_CACHE_TTL = get_int(
name="QDRANT_QUERY_EMBEDDING_CACHE_TTL", default=60 * 60 * 24 * 7
)
QDRANT_BASE_COLLECTION_NAME = get_string(
name="QDRANT_COLLECTION_NAME", default="resource_embeddings"
)
Expand Down Expand Up @@ -831,10 +822,10 @@ def get_all_config_keys():
QDRANT_CLIENT_TIMEOUT = get_int(name="QDRANT_CLIENT_TIMEOUT", default=10)

VECTOR_HYBRID_SEARCH_PREFETCH_MULTIPLIER = get_int(
name="VECTOR_HYBRID_SEARCH_PREFETCH_MULTIPLIER", default=5
name="VECTOR_HYBRID_SEARCH_PREFETCH_MULTIPLIER", default=20
)
VECTOR_HYBRID_SEARCH_PREFETCH_MAX_LIMIT = get_int(
name="VECTOR_HYBRID_SEARCH_PREFETCH_MAX_LIMIT", default=500
name="VECTOR_HYBRID_SEARCH_PREFETCH_MAX_LIMIT", default=10000
)
# toggle to use requests (default for local) or webdriver which renders js elements
EMBEDDINGS_EXTERNAL_FETCH_USE_WEBDRIVER = get_bool(
Expand Down
63 changes: 10 additions & 53 deletions main/settings_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
"""

import importlib
import re
import sys
import tomllib
from unittest import mock

import pytest
import semantic_version
from django.conf import settings
from django.core import mail
from django.core.exceptions import ImproperlyConfigured
Expand Down Expand Up @@ -162,12 +163,14 @@ def test_opensearch_index_pr_build(self):
settings_vars = self.reload_settings()
assert settings_vars["OPENSEARCH_INDEX"] == index_name

@staticmethod
def test_semantic_version():
"""
Verify that we have a semantic compatible version.
"""
semantic_version.Version(settings.VERSION)
def test_bump_my_version_format(self):
"""Verify that VERSION matches the bump-my-version calver format."""
with open("pyproject.toml", "rb") as f: # noqa: PTH123
pyproject = tomllib.load(f)
version_pattern = pyproject["tool"]["bumpversion"]["parse"]
package_version = pyproject["project"]["version"]
assert package_version == settings.VERSION
assert re.fullmatch(version_pattern, settings.VERSION)

def test_required_settings(self):
"""
Expand Down Expand Up @@ -203,52 +206,6 @@ def test_server_side_cursors_enabled(self):
is False
)

def test_cookie_tombstone_middleware_enabled(self):
"""Cookie tombstone middleware should be enabled when tombstones are configured."""
with mock.patch.dict(
"os.environ",
{
**REQUIRED_SETTINGS,
"COOKIE_TOMBSTONES": (
'[{"name":"csrftoken","domain":".learn.mit.edu","path":"/"}]'
),
},
clear=True,
):
settings_vars = self.reload_settings()
assert (
"main.middleware.cookie_tombstones.CookieTombstoneMiddleware"
in (settings_vars["MIDDLEWARE"])
)

def test_cookie_tombstone_middleware_disabled(self):
"""Cookie tombstone middleware should be disabled when tombstones are unset."""
with mock.patch.dict("os.environ", REQUIRED_SETTINGS, clear=True):
settings_vars = self.reload_settings()
assert (
"main.middleware.cookie_tombstones.CookieTombstoneMiddleware"
not in (settings_vars["MIDDLEWARE"])
)

def test_cookie_tombstone_middleware_ordering(self):
"""Cookie tombstone middleware should be first in the middleware stack."""
with mock.patch.dict(
"os.environ",
{
**REQUIRED_SETTINGS,
"COOKIE_TOMBSTONES": (
'[{"name":"csrftoken","domain":".learn.mit.edu","path":"/"}]'
),
},
clear=True,
):
settings_vars = self.reload_settings()
middleware = settings_vars["MIDDLEWARE"]
assert (
middleware[0]
== "main.middleware.cookie_tombstones.CookieTombstoneMiddleware"
)

def test_celery_beat_disabled(self):
"""Test that we can disable celery beat with an env var"""
with mock.patch.dict(
Expand Down
49 changes: 40 additions & 9 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "mit-learn"
version = "0.71.0"
version = "2026.4.16.1"
description = "Search index for use with other MIT applications."
authors = [{ name = "MIT ODL" }]
requires-python = ">=3.12,<3.13"
Expand All @@ -11,7 +11,7 @@ classifiers = [
"Programming Language :: Python :: 3.12",
]
dependencies = [
"Django==4.2.30",
"Django==4.2.29",
"attrs>=25.0.0,<26",
"base36>=0.1.1,<0.2",
"beautifulsoup4>=4.8.2,<5",
Expand All @@ -37,7 +37,7 @@ dependencies = [
"django-ipware>=7.0.0,<8",
"django-json-widget>=2.0.0,<3",
"django-oauth-toolkit>=3.0.0,<4",
"django-redis>=5.2.0,<7",
"django-redis>=5.2.0,<6",
"django-scim2>=0.19.1,<0.20",
"django-server-status>=0.7.0,<0.8",
"django-storages>=1.13.2,<2",
Expand All @@ -57,20 +57,19 @@ dependencies = [
"langchain>=0.3.11,<0.4",
"langchain-experimental>=0.3.4,<0.4",
"langchain-openai>=0.3.2,<0.4",
"litellm==1.83.7",
"litellm==1.81.13",
"llama-index>=0.14.0,<0.15",
"llama-index-llms-openai>=0.6.0,<0.7",
"lxml>=6.0.0,<7",
"markdown>=3.7,<4",
"markdown2>=2.4.8,<3",
"mitol-django-common>=2026.4.2,<2027",
"mitol-django-scim>=2026.4.2,<2027",
"mitol-django-scim>=2025.3.31,<2026",
"mitol-django-observability>=2026.1.0,<2027",
"named-enum>=1.4.0,<2",
"nested-lookup>=0.2.25,<0.3",
"nh3>=0.3.0,<0.4",
"ocw-data-parser>=0.35.1,<0.36",
"onnxruntime==1.24.4",
"onnxruntime==1.22.1",
"openai>=2.0.0,<3",
"opensearch-dsl>=2.0.0,<3",
"opensearch-py>=2.0.0,<3",
Expand Down Expand Up @@ -130,13 +129,12 @@ dev = [
"moto>=5.0.0,<6",
"nplusone>=1.0.0,<2",
"pdbpp>=0.11.6,<0.12",
"pytest>=9.0.3,<10",
"pytest>=8.0.0,<9",
"pytest-cov>=7.0.0,<8",
"pytest-django>=4.5.2,<5",
"pytest-env>=1.0.0,<2",
"pytest-freezegun>=0.4.2,<0.5",
"pytest-mock>=3.10.0,<4",
"pytest-repeat>=0.9.4",
"responses>=0.25.0,<0.26",
"ruff==0.14.14",
"safety>=3.0.0,<4",
Expand Down Expand Up @@ -263,3 +261,36 @@ inline-quotes = "double"
"*_test.py" = ["ARG001", "E501", "S101", "PLR2004"]
"test_*.py" = ["ARG001", "E501", "S101", "PLR2004"]
"**/migrations/**" = ["ARG001"]

[tool.bumpversion]
commit = false
tag = false
parse = "(?P<release>(?:[1-9][0-9]{3})\\.(?:1[0-2]|[1-9])\\.(?:3[0-1]|[12][0-9]|[1-9]))\\.(?P<build>\\d+)"
serialize = ["{release}.{build}"]

[tool.bumpversion.parts.release]
calver_format = "{YYYY}.{MM}.{DD}"

[tool.bumpversion.parts.build]
first_value = "1"

[[tool.bumpversion.files]]
filename = "main/settings.py"
search = 'VERSION = "{current_version}"'
replace = 'VERSION = "{new_version}"'

[[tool.bumpversion.files]]
filename = "pyproject.toml"
search = 'version = "{current_version}"'
replace = 'version = "{new_version}"'

[[tool.bumpversion.files]]
filename = "uv.lock"
search = """
name = "mit-learn"
version = "{current_version}"
source = {{ virtual = "." }}"""
replace = """
name = "mit-learn"
version = "{new_version}"
source = {{ virtual = "." }}"""
Loading
Loading