Skip to content

Commit 0b4084c

Browse files
authored
Merge branch 'master' into 2684-traceparent-header
2 parents 415e9e7 + c361337 commit 0b4084c

36 files changed

+741
-278
lines changed

.github/CODEOWNERS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
* @getsentry/team-web-sdk-backend
1+
* @getsentry/owners-python-sdk

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jobs:
2020
steps:
2121
- name: Get auth token
2222
id: token
23-
uses: actions/create-github-app-token@d72941d797fd3113feb6b93fd0dec494b13a2547 # v1.12.0
23+
uses: actions/create-github-app-token@3ff1caaa28b64c9cc276ce0a02e2ff584f3900c5 # v2.0.2
2424
with:
2525
app-id: ${{ vars.SENTRY_RELEASE_BOT_CLIENT_ID }}
2626
private-key: ${{ secrets.SENTRY_RELEASE_BOT_PRIVATE_KEY }}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ jobs:
104104
strategy:
105105
fail-fast: false
106106
matrix:
107-
python-version: ["3.8","3.9","3.11","3.12"]
107+
python-version: ["3.8","3.9","3.10","3.11","3.12","3.13"]
108108
# python3.6 reached EOL and is no longer being supported on
109109
# new versions of hosted runners on Github Actions
110110
# ubuntu-20.04 is the last version that supported python3.6

.github/workflows/test-integrations-web-1.yml

Lines changed: 0 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -22,95 +22,6 @@ env:
2222
CACHED_BUILD_PATHS: |
2323
${{ github.workspace }}/dist-serverless
2424
jobs:
25-
test-web_1-latest:
26-
name: Web 1 (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-22.04]
38-
services:
39-
postgres:
40-
image: postgres
41-
env:
42-
POSTGRES_PASSWORD: sentry
43-
# Set health checks to wait until postgres has started
44-
options: >-
45-
--health-cmd pg_isready
46-
--health-interval 10s
47-
--health-timeout 5s
48-
--health-retries 5
49-
# Maps tcp port 5432 on service container to the host
50-
ports:
51-
- 5432:5432
52-
env:
53-
SENTRY_PYTHON_TEST_POSTGRES_HOST: ${{ matrix.python-version == '3.6' && 'postgres' || 'localhost' }}
54-
SENTRY_PYTHON_TEST_POSTGRES_USER: postgres
55-
SENTRY_PYTHON_TEST_POSTGRES_PASSWORD: sentry
56-
# Use Docker container only for Python 3.6
57-
container: ${{ matrix.python-version == '3.6' && 'python:3.6' || null }}
58-
steps:
59-
- uses: actions/[email protected]
60-
- uses: actions/setup-python@v5
61-
if: ${{ matrix.python-version != '3.6' }}
62-
with:
63-
python-version: ${{ matrix.python-version }}
64-
allow-prereleases: true
65-
- name: Setup Test Env
66-
run: |
67-
pip install "coverage[toml]" tox
68-
- name: Erase coverage
69-
run: |
70-
coverage erase
71-
- name: Test django latest
72-
run: |
73-
set -x # print commands that are executed
74-
./scripts/runtox.sh "py${{ matrix.python-version }}-django-latest"
75-
- name: Test flask latest
76-
run: |
77-
set -x # print commands that are executed
78-
./scripts/runtox.sh "py${{ matrix.python-version }}-flask-latest"
79-
- name: Test starlette latest
80-
run: |
81-
set -x # print commands that are executed
82-
./scripts/runtox.sh "py${{ matrix.python-version }}-starlette-latest"
83-
- name: Test fastapi latest
84-
run: |
85-
set -x # print commands that are executed
86-
./scripts/runtox.sh "py${{ matrix.python-version }}-fastapi-latest"
87-
- name: Generate coverage XML (Python 3.6)
88-
if: ${{ !cancelled() && matrix.python-version == '3.6' }}
89-
run: |
90-
export COVERAGE_RCFILE=.coveragerc36
91-
coverage combine .coverage-sentry-*
92-
coverage xml --ignore-errors
93-
- name: Generate coverage XML
94-
if: ${{ !cancelled() && matrix.python-version != '3.6' }}
95-
run: |
96-
coverage combine .coverage-sentry-*
97-
coverage xml
98-
- name: Upload coverage to Codecov
99-
if: ${{ !cancelled() }}
100-
uses: codecov/[email protected]
101-
with:
102-
token: ${{ secrets.CODECOV_TOKEN }}
103-
files: coverage.xml
104-
# make sure no plugins alter our coverage reports
105-
plugin: noop
106-
verbose: true
107-
- name: Upload test results to Codecov
108-
if: ${{ !cancelled() }}
109-
uses: codecov/test-results-action@v1
110-
with:
111-
token: ${{ secrets.CODECOV_TOKEN }}
112-
files: .junitxml
113-
verbose: true
11425
test-web_1-pinned:
11526
name: Web 1 (pinned)
11627
timeout-minutes: 30

CHANGELOG.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,36 @@
11
# Changelog
22

3+
## 2.26.1
4+
5+
### Various fixes & improvements
6+
7+
- fix(threading): Data leak in ThreadingIntegration between threads (#4281) by @antonpirker
8+
- fix(logging): Clarify separate warnings case is for Python <3.11 (#4296) by @szokeasaurusrex
9+
- fix(logging): Add formatted message to log events (#4292) by @szokeasaurusrex
10+
- fix(logging): Send raw logging parameters (#4291) by @szokeasaurusrex
11+
- fix: Revert "chore: Deprecate `same_process_as_parent` (#4244)" (#4290) by @sentrivana
12+
13+
## 2.26.0
14+
15+
### Various fixes & improvements
16+
17+
- fix(debug): Do not consider parent loggers for debug logging (#4286) by @szokeasaurusrex
18+
- test(tracing): Simplify static/classmethod tracing tests (#4278) by @szokeasaurusrex
19+
- feat(transport): Add a timeout (#4252) by @sentrivana
20+
- meta: Change CODEOWNERS back to Python SDK owners (#4269) by @sentrivana
21+
- feat(logs): Add sdk name and version as log attributes (#4262) by @AbhiPrasad
22+
- feat(logs): Add server.address to logs (#4257) by @AbhiPrasad
23+
- chore: Deprecate `same_process_as_parent` (#4244) by @sentrivana
24+
- feat(logs): Add sentry.origin attribute for log handler (#4250) by @AbhiPrasad
25+
- feat(tests): Add optional cutoff to toxgen (#4243) by @sentrivana
26+
- toxgen: Retry & fail if we fail to fetch PyPI data (#4251) by @sentrivana
27+
- build(deps): bump actions/create-github-app-token from 1.12.0 to 2.0.2 (#4248) by @dependabot
28+
- Trying to prevent the grpc setup from being flaky (#4233) by @antonpirker
29+
- feat(breadcrumbs): add `_meta` information for truncation of breadcrumbs (#4007) by @shellmayr
30+
- tests: Move django under toxgen (#4238) by @sentrivana
31+
- fix: Handle JSONDecodeError gracefully in StarletteRequestExtractor (#4226) by @moodix
32+
- fix(asyncio): Remove shutdown handler (#4237) by @sentrivana
33+
334
## 2.25.1
435

536
### Various fixes & improvements

docs/conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
copyright = "2019-{}, Sentry Team and Contributors".format(datetime.now().year)
3232
author = "Sentry Team and Contributors"
3333

34-
release = "2.25.1"
34+
release = "2.26.1"
3535
version = ".".join(release.split(".")[:2]) # The short X.Y version.
3636

3737

scripts/populate_tox/config.py

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@
2929
"clickhouse_driver": {
3030
"package": "clickhouse-driver",
3131
},
32+
"cohere": {
33+
"package": "cohere",
34+
"python": ">=3.9",
35+
},
3236
"django": {
3337
"package": "django",
3438
"deps": {
@@ -55,6 +59,27 @@
5559
"package": "falcon",
5660
"python": "<3.13",
5761
},
62+
"fastapi": {
63+
"package": "fastapi",
64+
"deps": {
65+
"*": [
66+
"httpx",
67+
"pytest-asyncio",
68+
"python-multipart",
69+
"requests",
70+
"anyio<4",
71+
],
72+
# There's an incompatibility between FastAPI's TestClient, which is
73+
# actually Starlette's TestClient, which is actually httpx's Client.
74+
# httpx dropped a deprecated Client argument in 0.28.0, Starlette
75+
# dropped it from its TestClient in 0.37.2, and FastAPI only pinned
76+
# Starlette>=0.37.2 from version 0.110.1 onwards -- so for older
77+
# FastAPI versions we use older httpx which still supports the
78+
# deprecated argument.
79+
"<0.110.1": ["httpx<0.28.0"],
80+
"py3.6": ["aiocontextvars"],
81+
},
82+
},
5883
"flask": {
5984
"package": "flask",
6085
"deps": {
@@ -137,7 +162,8 @@
137162
"jinja2",
138163
"httpx",
139164
],
140-
"<0.37": ["httpx<0.28.0"],
165+
# See the comment on FastAPI's httpx bound for more info
166+
"<0.37.2": ["httpx<0.28.0"],
141167
"<0.15": ["jinja2<3.1"],
142168
"py3.6": ["aiocontextvars"],
143169
},

scripts/populate_tox/populate_tox.py

Lines changed: 51 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import time
1010
from bisect import bisect_left
1111
from collections import defaultdict
12-
from datetime import datetime, timezone
12+
from datetime import datetime, timedelta, timezone # noqa: F401
1313
from importlib.metadata import metadata
1414
from packaging.specifiers import SpecifierSet
1515
from packaging.version import Version
@@ -29,13 +29,19 @@
2929
from split_tox_gh_actions.split_tox_gh_actions import GROUPS
3030

3131

32+
# Set CUTOFF this to a datetime to ignore packages older than CUTOFF
33+
CUTOFF = None
34+
# CUTOFF = datetime.now(tz=timezone.utc) - timedelta(days=365 * 5)
35+
3236
TOX_FILE = Path(__file__).resolve().parent.parent.parent / "tox.ini"
3337
ENV = Environment(
3438
loader=FileSystemLoader(Path(__file__).resolve().parent),
3539
trim_blocks=True,
3640
lstrip_blocks=True,
3741
)
3842

43+
PYPI_COOLDOWN = 0.15 # seconds to wait between requests to PyPI
44+
3945
PYPI_PROJECT_URL = "https://pypi.python.org/pypi/{project}/json"
4046
PYPI_VERSION_URL = "https://pypi.python.org/pypi/{project}/{version}/json"
4147
CLASSIFIER_PREFIX = "Programming Language :: Python :: "
@@ -68,12 +74,8 @@
6874
"beam",
6975
"boto3",
7076
"chalice",
71-
"cohere",
72-
"fastapi",
7377
"gcp",
7478
"httpx",
75-
"huey",
76-
"huggingface_hub",
7779
"langchain",
7880
"langchain_notiktoken",
7981
"openai",
@@ -88,27 +90,34 @@
8890
}
8991

9092

91-
@functools.cache
92-
def fetch_package(package: str) -> dict:
93-
"""Fetch package metadata from PyPI."""
94-
url = PYPI_PROJECT_URL.format(project=package)
95-
pypi_data = requests.get(url)
93+
def fetch_url(url: str) -> Optional[dict]:
94+
for attempt in range(3):
95+
pypi_data = requests.get(url)
96+
97+
if pypi_data.status_code == 200:
98+
return pypi_data.json()
9699

97-
if pypi_data.status_code != 200:
98-
print(f"{package} not found")
100+
backoff = PYPI_COOLDOWN * 2**attempt
101+
print(
102+
f"{url} returned an error: {pypi_data.status_code}. Attempt {attempt + 1}/3. Waiting {backoff}s"
103+
)
104+
time.sleep(backoff)
99105

100-
return pypi_data.json()
106+
return None
101107

102108

103109
@functools.cache
104-
def fetch_release(package: str, version: Version) -> dict:
105-
url = PYPI_VERSION_URL.format(project=package, version=version)
106-
pypi_data = requests.get(url)
110+
def fetch_package(package: str) -> Optional[dict]:
111+
"""Fetch package metadata from PyPI."""
112+
url = PYPI_PROJECT_URL.format(project=package)
113+
return fetch_url(url)
107114

108-
if pypi_data.status_code != 200:
109-
print(f"{package} not found")
110115

111-
return pypi_data.json()
116+
@functools.cache
117+
def fetch_release(package: str, version: Version) -> Optional[dict]:
118+
"""Fetch release metadata from PyPI."""
119+
url = PYPI_VERSION_URL.format(project=package, version=version)
120+
return fetch_url(url)
112121

113122

114123
def _prefilter_releases(
@@ -153,9 +162,13 @@ def _prefilter_releases(
153162
if meta["yanked"]:
154163
continue
155164

156-
if older_than is not None:
157-
if datetime.fromisoformat(meta["upload_time_iso_8601"]) > older_than:
158-
continue
165+
uploaded = datetime.fromisoformat(meta["upload_time_iso_8601"])
166+
167+
if older_than is not None and uploaded > older_than:
168+
continue
169+
170+
if CUTOFF is not None and uploaded < CUTOFF:
171+
continue
159172

160173
version = Version(release)
161174

@@ -221,16 +234,15 @@ def get_supported_releases(
221234
integration, pypi_data["releases"], older_than
222235
)
223236

224-
# Determine Python support
225-
expected_python_versions = TEST_SUITE_CONFIG[integration].get("python")
226-
if expected_python_versions:
227-
expected_python_versions = SpecifierSet(expected_python_versions)
228-
else:
229-
expected_python_versions = SpecifierSet(f">={MIN_PYTHON_VERSION}")
230-
231237
def _supports_lowest(release: Version) -> bool:
232-
time.sleep(0.1) # don't DoS PYPI
233-
py_versions = determine_python_versions(fetch_release(package, release))
238+
time.sleep(PYPI_COOLDOWN) # don't DoS PYPI
239+
240+
pypi_data = fetch_release(package, release)
241+
if pypi_data is None:
242+
print("Failed to fetch necessary data from PyPI. Aborting.")
243+
sys.exit(1)
244+
245+
py_versions = determine_python_versions(pypi_data)
234246
target_python_versions = TEST_SUITE_CONFIG[integration].get("python")
235247
if target_python_versions:
236248
target_python_versions = SpecifierSet(target_python_versions)
@@ -499,7 +511,11 @@ def _add_python_versions_to_release(
499511
integration: str, package: str, release: Version
500512
) -> None:
501513
release_pypi_data = fetch_release(package, release)
502-
time.sleep(0.1) # give PYPI some breathing room
514+
if release_pypi_data is None:
515+
print("Failed to fetch necessary data from PyPI. Aborting.")
516+
sys.exit(1)
517+
518+
time.sleep(PYPI_COOLDOWN) # give PYPI some breathing room
503519

504520
target_python_versions = TEST_SUITE_CONFIG[integration].get("python")
505521
if target_python_versions:
@@ -592,6 +608,9 @@ def main(fail_on_changes: bool = False) -> None:
592608

593609
# Fetch data for the main package
594610
pypi_data = fetch_package(package)
611+
if pypi_data is None:
612+
print("Failed to fetch necessary data from PyPI. Aborting.")
613+
sys.exit(1)
595614

596615
# Get the list of all supported releases
597616

0 commit comments

Comments
 (0)