Skip to content
Merged
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
4 changes: 2 additions & 2 deletions app/backend.dev.env
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@ ACTIVENESS_PROBES_ENABLED=1
# Experimentation (feature flags)
EXPERIMENTATION_ENABLED=0
EXPERIMENTATION_PASS_ALL_GATES=1
STATSIG_SERVER_SECRET_KEY=secret-...
STATSIG_ENVIRONMENT=development
GROWTHBOOK_API_HOST=https://gbapi.couchershq.org
GROWTHBOOK_CLIENT_KEY=sdk-cGmljeXu1BCzHffE

# Moderation auto-approval deadline in seconds (0 to disable)
MODERATION_AUTO_APPROVE_DEADLINE_SECONDS=10
Expand Down
4 changes: 2 additions & 2 deletions app/backend/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ dependencies = [
"stripe>=13.1.0",
"ua-parser>=1.0.1",
"user-agents>=2.2.0",
"statsig-python-core>=0.8.0",
"growthbook>=1.2.0",
]

[project.scripts]
Expand Down Expand Up @@ -136,7 +136,7 @@ module = ["couchers.migrations.versions.*"]
ignore_errors = true

[[tool.mypy.overrides]]
module = ["http_ece", "py_vapid", "luhn", "sqlalchemy_utils.*", "statsig_python_core", "user_agents"]
module = ["http_ece", "py_vapid", "luhn", "sqlalchemy_utils.*", "growthbook", "user_agents"]
# These libraries don't have type stubs or py.typed markers
ignore_missing_imports = true

Expand Down
2 changes: 0 additions & 2 deletions app/backend/src/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,6 @@ def main() -> None:
setup_tracing()

# Initialize the experimentation framework for feature flags in the main process.
# IMPORTANT: This MUST be called AFTER worker processes are spawned (above).
# The underlying SDK uses internal threading that doesn't survive fork().
# Worker processes initialize their own instance in _run_forever().
setup_experimentation()

Expand Down
12 changes: 6 additions & 6 deletions app/backend/src/couchers/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,13 +115,13 @@
("RECAPTHCA_SITE_KEY", str),
# Whether we're in test
("IN_TEST", bool, "0"),
# Experimentation (feature flags via Statsig)
# Experimentation (feature flags via GrowthBook)
("EXPERIMENTATION_ENABLED", bool, "0"),
# When enabled, all feature gates return True (useful for development/testing)
("EXPERIMENTATION_PASS_ALL_GATES", bool, "0"),
# Statsig SDK configuration
("STATSIG_SERVER_SECRET_KEY", str, ""),
("STATSIG_ENVIRONMENT", str, "development"),
# GrowthBook SDK configuration
("GROWTHBOOK_API_HOST", str, "https://cdn.growthbook.io"),
("GROWTHBOOK_CLIENT_KEY", str, ""),
# Moderation auto-approval deadline in seconds (0 to disable auto-approval)
("MODERATION_AUTO_APPROVE_DEADLINE_SECONDS", int),
# User ID of the bot user for automated moderation actions
Expand Down Expand Up @@ -171,8 +171,8 @@ def check_config(cfg: dict[str, Any]) -> None:
raise Exception("MyPostcard API credentials not configured but postal verification enabled")

if cfg["EXPERIMENTATION_ENABLED"]:
if not cfg["STATSIG_SERVER_SECRET_KEY"]:
raise Exception("No Statsig server secret key but experimentation enabled")
if not cfg["GROWTHBOOK_CLIENT_KEY"]:
raise Exception("No GrowthBook client key but experimentation enabled")


def make_config() -> dict[str, Any]:
Expand Down
6 changes: 5 additions & 1 deletion app/backend/src/couchers/context.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
from typing import NoReturn, cast
from typing import TYPE_CHECKING, NoReturn, cast

import grpc

from couchers.i18n import LocalizationContext

if TYPE_CHECKING:
from growthbook import GrowthBook


class NonInteractiveContextException(Exception):
"""If this exception is raised, it is a programming error"""
Expand Down Expand Up @@ -79,6 +82,7 @@ def __init__(
self.__is_interactive = is_interactive
self.__logged_in = self._user_id is not None
self.__cookies: list[str] = []
self._growthbook: GrowthBook | None = None

if self.__is_interactive:
if not self._grpc_context:
Expand Down
Loading
Loading