Skip to content

Commit 7911b32

Browse files
committed
Merge branch 'master' into ivana/tox-script-12
2 parents a62a871 + 5a5a1cf commit 7911b32

File tree

21 files changed

+654
-176
lines changed

21 files changed

+654
-176
lines changed

.github/workflows/test-integrations-flags.yml

Lines changed: 5 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -22,78 +22,14 @@ env:
2222
CACHED_BUILD_PATHS: |
2323
${{ github.workspace }}/dist-serverless
2424
jobs:
25-
test-flags-latest:
26-
name: Flags (latest)
27-
timeout-minutes: 30
28-
runs-on: ${{ matrix.os }}
29-
strategy:
30-
fail-fast: false
31-
matrix:
32-
python-version: ["3.8","3.12","3.13"]
33-
# python3.6 reached EOL and is no longer being supported on
34-
# new versions of hosted runners on Github Actions
35-
# ubuntu-20.04 is the last version that supported python3.6
36-
# see https://github.com/actions/setup-python/issues/544#issuecomment-1332535877
37-
os: [ubuntu-20.04]
38-
steps:
39-
- uses: actions/[email protected]
40-
- uses: actions/setup-python@v5
41-
with:
42-
python-version: ${{ matrix.python-version }}
43-
allow-prereleases: true
44-
- name: Setup Test Env
45-
run: |
46-
pip install "coverage[toml]" tox
47-
- name: Erase coverage
48-
run: |
49-
coverage erase
50-
- name: Test launchdarkly latest
51-
run: |
52-
set -x # print commands that are executed
53-
./scripts/runtox.sh "py${{ matrix.python-version }}-launchdarkly-latest"
54-
- name: Test openfeature latest
55-
run: |
56-
set -x # print commands that are executed
57-
./scripts/runtox.sh "py${{ matrix.python-version }}-openfeature-latest"
58-
- name: Test unleash latest
59-
run: |
60-
set -x # print commands that are executed
61-
./scripts/runtox.sh "py${{ matrix.python-version }}-unleash-latest"
62-
- name: Generate coverage XML (Python 3.6)
63-
if: ${{ !cancelled() && matrix.python-version == '3.6' }}
64-
run: |
65-
export COVERAGE_RCFILE=.coveragerc36
66-
coverage combine .coverage-sentry-*
67-
coverage xml --ignore-errors
68-
- name: Generate coverage XML
69-
if: ${{ !cancelled() && matrix.python-version != '3.6' }}
70-
run: |
71-
coverage combine .coverage-sentry-*
72-
coverage xml
73-
- name: Upload coverage to Codecov
74-
if: ${{ !cancelled() }}
75-
uses: codecov/[email protected]
76-
with:
77-
token: ${{ secrets.CODECOV_TOKEN }}
78-
files: coverage.xml
79-
# make sure no plugins alter our coverage reports
80-
plugin: noop
81-
verbose: true
82-
- name: Upload test results to Codecov
83-
if: ${{ !cancelled() }}
84-
uses: codecov/test-results-action@v1
85-
with:
86-
token: ${{ secrets.CODECOV_TOKEN }}
87-
files: .junitxml
88-
verbose: true
8925
test-flags-pinned:
9026
name: Flags (pinned)
9127
timeout-minutes: 30
9228
runs-on: ${{ matrix.os }}
9329
strategy:
9430
fail-fast: false
9531
matrix:
96-
python-version: ["3.8","3.12","3.13"]
32+
python-version: ["3.7","3.8","3.9","3.12","3.13"]
9733
# python3.6 reached EOL and is no longer being supported on
9834
# new versions of hosted runners on Github Actions
9935
# ubuntu-20.04 is the last version that supported python3.6
@@ -119,6 +55,10 @@ jobs:
11955
run: |
12056
set -x # print commands that are executed
12157
./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-openfeature"
58+
- name: Test statsig pinned
59+
run: |
60+
set -x # print commands that are executed
61+
./scripts/runtox.sh --exclude-latest "py${{ matrix.python-version }}-statsig"
12262
- name: Test unleash pinned
12363
run: |
12464
set -x # print commands that are executed

CHANGELOG.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
- Set level based on status code for HTTP client breadcrumbs (#4004) by @sentrivana
1818
- Don't set transaction status to error on `sys.exit(0)` (#4025) by @sentrivana
1919
- Continuous profiling sample rate (#4002) by @Zylphrex
20+
21+
Set `profile_session_sample_rate=1.0` in your `init()` to collect continuous profiles for 100% of profile sessions. See https://docs.sentry.io/platforms/python/profiling/#enable-continuous-profiling for more information.
2022
- Track and report spans that were dropped (#4005) by @constantinius
2123
- Change continuous profile buffer size (#3987) by @Zylphrex
2224
- Handle `MultiPartParserError` to avoid internal sentry crash (#4001) by @orhanhenrik
@@ -40,7 +42,7 @@
4042
## 2.20.0
4143

4244
- **New integration:** Add [Typer](https://typer.tiangolo.com/) integration (#3869) by @patrick91
43-
45+
4446
For more information, see the documentation for the [TyperIntegration](https://docs.sentry.io/platforms/python/integrations/typer/).
4547

4648
- **New integration:** Add [Unleash](https://www.getunleash.io/) feature flagging integration (#3888) by @aliu39
@@ -122,7 +124,7 @@
122124
### Various fixes & improvements
123125

124126
- **New integration:** Add [LaunchDarkly](https://launchdarkly.com/) integration (#3648) by @cmanallen
125-
127+
126128
For more information, see the documentation for the [LaunchDarklyIntegration](https://docs.sentry.io/platforms/python/integrations/launchdarkly/).
127129

128130
- **New integration:** Add [OpenFeature](https://openfeature.dev/) feature flagging integration (#3648) by @cmanallen

requirements-linting.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@ flake8-bugbear
1515
pep8-naming
1616
pre-commit # local linting
1717
httpcore
18-
openfeature-sdk
1918
launchdarkly-server-sdk
19+
openfeature-sdk
20+
statsig
2021
UnleashClient
2122
typer
2223
strawberry-graphql

scripts/populate_tox/config.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,21 @@
2323
"py3.6": ["aiocontextvars"],
2424
},
2525
},
26+
"launchdarkly": {
27+
"package": "launchdarkly-server-sdk",
28+
},
2629
"loguru": {
2730
"package": "loguru",
2831
},
32+
"openfeature": {
33+
"package": "openfeature-sdk",
34+
},
35+
"statsig": {
36+
"package": "statsig",
37+
"deps": {
38+
"*": ["typing_extensions"],
39+
},
40+
},
2941
"strawberry": {
3042
"package": "strawberry-graphql[fastapi,flask]",
3143
"deps": {
@@ -42,4 +54,7 @@
4254
"typer": {
4355
"package": "typer",
4456
},
57+
"unleash": {
58+
"package": "UnleashClient",
59+
},
4560
}

scripts/populate_tox/populate_tox.py

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"""
2-
This script populates tox.ini automatically using release data from PYPI.
2+
This script populates tox.ini automatically using release data from PyPI.
33
"""
44

55
import functools
@@ -8,7 +8,6 @@
88
import time
99
from bisect import bisect_left
1010
from collections import defaultdict
11-
from datetime import datetime, timedelta
1211
from importlib.metadata import metadata
1312
from packaging.specifiers import SpecifierSet
1413
from packaging.version import Version
@@ -27,9 +26,6 @@
2726
from split_tox_gh_actions.split_tox_gh_actions import GROUPS
2827

2928

30-
# Only consider package versions going back this far
31-
CUTOFF = datetime.now() - timedelta(days=365 * 5)
32-
3329
TOX_FILE = Path(__file__).resolve().parent.parent.parent / "tox.ini"
3430
ENV = Environment(
3531
loader=FileSystemLoader(Path(__file__).resolve().parent),
@@ -81,11 +77,9 @@
8177
"huggingface_hub",
8278
"langchain",
8379
"langchain_notiktoken",
84-
"launchdarkly",
8580
"litestar",
8681
"openai",
8782
"openai_notiktoken",
88-
"openfeature",
8983
"pure_eval",
9084
"pymongo",
9185
"pyramid",
@@ -102,7 +96,6 @@
10296
"sqlalchemy",
10397
"tornado",
10498
"trytond",
105-
"unleash",
10699
}
107100

108101

@@ -154,8 +147,6 @@ def _prefilter_releases(integration: str, releases: dict[str, dict]) -> list[Ver
154147
continue
155148

156149
meta = data[0]
157-
if datetime.fromisoformat(meta["upload_time"]) < CUTOFF:
158-
continue
159150

160151
if meta["yanked"]:
161152
continue

scripts/populate_tox/tox.jinja

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -163,10 +163,6 @@ envlist =
163163
{py3.9,py3.11,py3.12}-langchain-latest
164164
{py3.9,py3.11,py3.12}-langchain-notiktoken
165165

166-
# LaunchDarkly
167-
{py3.8,py3.12,py3.13}-launchdarkly-v9.8.0
168-
{py3.8,py3.12,py3.13}-launchdarkly-latest
169-
170166
# Litestar
171167
{py3.8,py3.11}-litestar-v{2.0}
172168
{py3.8,py3.11,py3.12}-litestar-v{2.6}
@@ -180,10 +176,6 @@ envlist =
180176
{py3.9,py3.11,py3.12}-openai-latest
181177
{py3.9,py3.11,py3.12}-openai-notiktoken
182178

183-
# OpenFeature
184-
{py3.8,py3.12,py3.13}-openfeature-v0.7
185-
{py3.8,py3.12,py3.13}-openfeature-latest
186-
187179
# OpenTelemetry (OTel)
188180
{py3.7,py3.9,py3.12,py3.13}-opentelemetry
189181

@@ -272,10 +264,6 @@ envlist =
272264
{py3.8,py3.11,py3.12}-trytond-v{7}
273265
{py3.8,py3.12,py3.13}-trytond-latest
274266

275-
# Unleash
276-
{py3.8,py3.12,py3.13}-unleash-v6.0.1
277-
{py3.8,py3.12,py3.13}-unleash-latest
278-
279267
# === Integrations - Auto-generated ===
280268
# These come from the populate_tox.py script. Eventually we should move all
281269
# integration tests there.
@@ -541,18 +529,6 @@ deps =
541529
openai-latest: tiktoken~=0.6.0
542530
openai-notiktoken: openai
543531
544-
# OpenFeature
545-
openfeature-v0.7: openfeature-sdk~=0.7.1
546-
openfeature-latest: openfeature-sdk
547-
548-
# LaunchDarkly
549-
launchdarkly-v9.8.0: launchdarkly-server-sdk~=9.8.0
550-
launchdarkly-latest: launchdarkly-server-sdk
551-
552-
# Unleash
553-
unleash-v6.0.1: UnleashClient~=6.0.1
554-
unleash-latest: UnleashClient
555-
556532
# OpenTelemetry (OTel)
557533
opentelemetry: opentelemetry-distro
558534
@@ -778,9 +754,10 @@ setenv =
778754
rq: TESTPATH=tests/integrations/rq
779755
sanic: TESTPATH=tests/integrations/sanic
780756
spark: TESTPATH=tests/integrations/spark
757+
sqlalchemy: TESTPATH=tests/integrations/sqlalchemy
781758
starlette: TESTPATH=tests/integrations/starlette
782759
starlite: TESTPATH=tests/integrations/starlite
783-
sqlalchemy: TESTPATH=tests/integrations/sqlalchemy
760+
statsig: TESTPATH=tests/integrations/statsig
784761
strawberry: TESTPATH=tests/integrations/strawberry
785762
tornado: TESTPATH=tests/integrations/tornado
786763
trytond: TESTPATH=tests/integrations/trytond

scripts/split_tox_gh_actions/split_tox_gh_actions.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@
8787
"Flags": [
8888
"launchdarkly",
8989
"openfeature",
90+
"statsig",
9091
"unleash",
9192
],
9293
"Gevent": [

sentry_sdk/consts.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ class CompressionAlgo(Enum):
3838
from typing import Any
3939
from typing import Sequence
4040
from typing import Tuple
41+
from typing_extensions import Literal
4142
from typing_extensions import TypedDict
4243

4344
from sentry_sdk._types import (
@@ -528,6 +529,7 @@ def __init__(
528529
profiles_sample_rate=None, # type: Optional[float]
529530
profiles_sampler=None, # type: Optional[TracesSampler]
530531
profiler_mode=None, # type: Optional[ProfilerMode]
532+
profile_lifecycle="manual", # type: Literal["manual", "trace"]
531533
profile_session_sample_rate=None, # type: Optional[float]
532534
auto_enabling_integrations=True, # type: bool
533535
disabled_integrations=None, # type: Optional[Sequence[sentry_sdk.integrations.Integration]]

sentry_sdk/integrations/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ def iter_default_integrations(with_auto_enabling_integrations):
151151
"sanic": (0, 8),
152152
"sqlalchemy": (1, 2),
153153
"starlite": (1, 48),
154+
"statsig": (0, 55, 3),
154155
"strawberry": (0, 209, 5),
155156
"tornado": (6, 0),
156157
"typer": (0, 15),

sentry_sdk/integrations/statsig.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
from functools import wraps
2+
from typing import Any, TYPE_CHECKING
3+
4+
from sentry_sdk.feature_flags import add_feature_flag
5+
from sentry_sdk.integrations import Integration, DidNotEnable, _check_minimum_version
6+
from sentry_sdk.utils import parse_version
7+
8+
try:
9+
from statsig import statsig as statsig_module
10+
from statsig.version import __version__ as STATSIG_VERSION
11+
except ImportError:
12+
raise DidNotEnable("statsig is not installed")
13+
14+
if TYPE_CHECKING:
15+
from statsig.statsig_user import StatsigUser
16+
17+
18+
class StatsigIntegration(Integration):
19+
identifier = "statsig"
20+
21+
@staticmethod
22+
def setup_once():
23+
# type: () -> None
24+
version = parse_version(STATSIG_VERSION)
25+
_check_minimum_version(StatsigIntegration, version, "statsig")
26+
27+
# Wrap and patch evaluation method(s) in the statsig module
28+
old_check_gate = statsig_module.check_gate
29+
30+
@wraps(old_check_gate)
31+
def sentry_check_gate(user, gate, *args, **kwargs):
32+
# type: (StatsigUser, str, *Any, **Any) -> Any
33+
enabled = old_check_gate(user, gate, *args, **kwargs)
34+
add_feature_flag(gate, enabled)
35+
return enabled
36+
37+
statsig_module.check_gate = sentry_check_gate

0 commit comments

Comments
 (0)