Skip to content

Commit 91a71e6

Browse files
wu-shengclaude
andcommitted
fix: update django/psycopg/httpx for Python 3.13/3.14 compatibility
django: - Add 5.1 for >=3.13 (4.2 doesn't support 3.13+) - Fix test services: replace removed django.conf.urls.url with django.urls.path (available since Django 2.0, works with 3.2+) - Verified locally: django==5.1 PASSED with span validation on 3.13 psycopg: - Add 3.2.* for >=3.13 (3.1.* has no cp313 binary wheels) - Verified locally: psycopg[binary]==3.2.* PASSED with span validation on 3.13 httpx: - Only test 0.23.* for >=3.13 (0.22.* can't install on 3.13+) Update plugin-test skill with proxy bypass guidance. Regenerate Plugins.md. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 06acd20 commit 91a71e6

7 files changed

Lines changed: 27 additions & 23 deletions

File tree

.claude/skills/plugin-test/SKILL.md

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -163,20 +163,22 @@ Plugin library failed to install in Docker. Check:
163163
- Docker compose command for the service
164164

165165
### Failure - Permanent 502 / Empty Segments
166-
If the consumer returns 502 indefinitely and no segments are collected:
166+
**IMPORTANT: Check your HTTP proxy first!** If `http_proxy` or `https_proxy` environment variables are set, ALL test HTTP requests (prepare, validate) go through the proxy instead of reaching Docker containers directly. This causes 502 responses and empty segment data.
167+
168+
```bash
169+
# Check for proxy
170+
echo $http_proxy $https_proxy
171+
172+
# Run tests without proxy
173+
export http_proxy="" https_proxy="" no_proxy="*" NO_PROXY="*"
174+
poetry run pytest -v tests/plugin/web/sw_flask/
175+
```
176+
177+
If still failing after clearing proxy:
167178
- Check container logs: `docker logs sw_<name>-consumer-1`
168-
- Look for whether Flask actually started (should see `* Running on http://`)
169-
- Common cause: `pip install -r requirements.txt` in the Docker container downgrades shared dependencies (urllib3, charset-normalizer) that break the Flask/agent startup
170-
- Run `docker exec sw_<name>-consumer-1 pip list` to check installed package versions
171-
- The Docker image has pre-installed packages from `make install`; test-specific `pip install` can create conflicts
172-
173-
### Local vs CI Differences
174-
- CI runs on Linux with native Docker — faster, more reliable networking
175-
- macOS Docker Desktop runs containers in a Linux VM — additional latency
176-
- Some tests may fail locally due to dependency conflicts in containers but pass in CI where the environment is cleaner
177-
- For authoritative span data verification, rely on CI results
178-
- Locally, verify: (1) Docker image builds, (2) agent loads all plugins (`docker run --rm <image> python3 -c "from skywalking.plugins import install"`)
179-
- To debug container issues locally: `docker compose -f <path>/docker-compose.yml up` (foreground) and watch logs
179+
- Look for whether the service actually started
180+
- Debug in foreground: `docker compose -f <path>/docker-compose.yml up`
181+
- Check ports: `lsof -i :9090 -i :9091 -i :12800`
180182

181183
## Plugin Name to Test Path Mapping
182184

docs/en/setup/Plugins.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ or a limitation of SkyWalking auto-instrumentation (welcome to contribute!)
2121
| [bottle](http://bottlepy.org/docs/dev/) | Python >=3.13 - ['0.13']; Python >=3.10 - ['0.12.23']; | `sw_bottle` |
2222
| [celery](https://docs.celeryq.dev) | Python >=3.7 - ['5.1']; | `sw_celery` |
2323
| [confluent_kafka](https://www.confluent.io/) | Python >=3.7 - ['1.5.0', '1.7.0', '1.8.2']; | `sw_confluent_kafka` |
24-
| [django](https://www.djangoproject.com/) | Python >=3.13 - ['4.2']; Python >=3.10 - ['3.2']; | `sw_django` |
24+
| [django](https://www.djangoproject.com/) | Python >=3.13 - ['5.1']; Python >=3.10 - ['3.2']; | `sw_django` |
2525
| [elasticsearch](https://github.com/elastic/elasticsearch-py) | Python >=3.7 - ['7.13', '7.14', '7.15']; | `sw_elasticsearch` |
2626
| [hug](https://falcon.readthedocs.io/en/stable/) | Python >=3.11 - NOT SUPPORTED YET; Python >=3.10 - ['2.5', '2.6']; Python >=3.7 - ['2.4.1', '2.5', '2.6']; | `sw_falcon` |
2727
| [fastapi](https://fastapi.tiangolo.com) | Python >=3.7 - ['0.89.*', '0.88.*']; | `sw_fastapi` |
@@ -30,12 +30,12 @@ or a limitation of SkyWalking auto-instrumentation (welcome to contribute!)
3030
| [happybase](https://happybase.readthedocs.io) | Python >=3.12 - ['1.3.0']; Python >=3.10 - ['1.2.0']; | `sw_happybase` |
3131
| [http_server](https://docs.python.org/3/library/http.server.html) | Python >=3.7 - ['*']; | `sw_http_server` |
3232
| [werkzeug](https://werkzeug.palletsprojects.com/) | Python >=3.7 - ['1.0.1', '2.0']; | `sw_http_server` |
33-
| [httpx](https://www.python-httpx.org/) | Python >=3.7 - ['0.23.*', '0.22.*']; | `sw_httpx` |
33+
| [httpx](https://www.python-httpx.org/) | Python >=3.13 - ['0.23.*']; Python >=3.10 - ['0.23.*', '0.22.*']; | `sw_httpx` |
3434
| [kafka-python](https://kafka-python.readthedocs.io) | Python >=3.12 - ['2.3']; Python >=3.10 - ['2.0']; | `sw_kafka` |
3535
| [loguru](https://pypi.org/project/loguru/) | Python >=3.7 - ['0.6.0', '0.7.0']; | `sw_loguru` |
3636
| [mysqlclient](https://mysqlclient.readthedocs.io/) | Python >=3.7 - ['2.1.*']; | `sw_mysqlclient` |
3737
| [neo4j](https://neo4j.com/docs/python-manual/5/) | Python >=3.7 - ['5.*']; | `sw_neo4j` |
38-
| [psycopg[binary]](https://www.psycopg.org/) | Python >=3.11 - ['3.1.*']; Python >=3.7 - ['3.0.18', '3.1.*']; | `sw_psycopg` |
38+
| [psycopg[binary]](https://www.psycopg.org/) | Python >=3.13 - ['3.2.*']; Python >=3.11 - ['3.1.*']; Python >=3.10 - ['3.0.18', '3.1.*']; | `sw_psycopg` |
3939
| [psycopg2-binary](https://www.psycopg.org/) | Python >=3.10 - NOT SUPPORTED YET; Python >=3.7 - ['2.9']; | `sw_psycopg2` |
4040
| [pulsar-client](https://github.com/apache/pulsar-client-python) | Python >=3.12 - ['3.9.0']; Python >=3.10 - ['3.3.0']; | `sw_pulsar` |
4141
| [pymongo](https://pymongo.readthedocs.io) | Python >=3.7 - ['3.11.*']; | `sw_pymongo` |

skywalking/plugins/sw_django.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
link_vector = ['https://www.djangoproject.com/']
2525
support_matrix = {
2626
'django': {
27-
'>=3.13': ['4.2'],
27+
'>=3.13': ['5.1'],
2828
'>=3.10': ['3.2'],
2929
}
3030
}

skywalking/plugins/sw_httpx.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@
2323
link_vector = ['https://www.python-httpx.org/']
2424
support_matrix = {
2525
'httpx': {
26-
'>=3.7': ['0.23.*', '0.22.*']
26+
'>=3.13': ['0.23.*'],
27+
'>=3.10': ['0.23.*', '0.22.*'],
2728
}
2829
}
2930
note = """"""

skywalking/plugins/sw_psycopg.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,9 @@
2222
link_vector = ['https://www.psycopg.org/']
2323
support_matrix = {
2424
'psycopg[binary]': {
25+
'>=3.13': ['3.2.*'],
2526
'>=3.11': ['3.1.*'], # 3.11 support begins 3.1
26-
'>=3.7': ['3.0.18', '3.1.*'] # psycopg is psycopg3
27+
'>=3.10': ['3.0.18', '3.1.*'],
2728
}
2829
}
2930
note = """"""

tests/plugin/web/sw_django/services/consumer.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
import requests
2121
from django.conf import settings
22-
from django.conf.urls import url
22+
from django.urls import path
2323
from django.http import JsonResponse
2424

2525
settings.configure(
@@ -35,7 +35,7 @@ def index(request):
3535

3636

3737
urlpatterns = (
38-
url('users', index),
38+
path('users', index),
3939
)
4040

4141

tests/plugin/web/sw_django/services/provider.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
import time
2020

2121
from django.conf import settings
22-
from django.conf.urls import url
22+
from django.urls import path
2323
from django.http import JsonResponse
2424

2525
settings.configure(
@@ -35,7 +35,7 @@ def index(request):
3535

3636

3737
urlpatterns = (
38-
url('users', index),
38+
path('users', index),
3939
)
4040

4141

0 commit comments

Comments
 (0)