wrapture-instrumentation 1.0.0.dev8__tar.gz → 1.0.0.dev9__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/CHANGES.md +30 -4
- {wrapture_instrumentation-1.0.0.dev8/src/wrapture_instrumentation.egg-info → wrapture_instrumentation-1.0.0.dev9}/PKG-INFO +26 -9
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/README.md +25 -8
- wrapture_instrumentation-1.0.0.dev9/demo/framework_django.py +188 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/pyproject.toml +12 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/__init__.py +1 -1
- wrapture_instrumentation-1.0.0.dev9/src/wrapture_instrumentation/framework/django/README.md +137 -0
- wrapture_instrumentation-1.0.0.dev9/src/wrapture_instrumentation/framework/django/__init__.py +135 -0
- wrapture_instrumentation-1.0.0.dev9/src/wrapture_instrumentation/framework/django/common.py +59 -0
- wrapture_instrumentation-1.0.0.dev9/src/wrapture_instrumentation/framework/django/db.py +171 -0
- wrapture_instrumentation-1.0.0.dev9/src/wrapture_instrumentation/framework/django/dispatch.py +83 -0
- wrapture_instrumentation-1.0.0.dev9/src/wrapture_instrumentation/framework/django/exceptions.py +56 -0
- wrapture_instrumentation-1.0.0.dev9/src/wrapture_instrumentation/framework/django/handlers.py +130 -0
- wrapture_instrumentation-1.0.0.dev9/src/wrapture_instrumentation/framework/django/resolvers.py +111 -0
- wrapture_instrumentation-1.0.0.dev9/src/wrapture_instrumentation/framework/django/templates.py +76 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/framework/flask/templating.py +3 -1
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/template/jinja2/environment.py +8 -5
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9/src/wrapture_instrumentation.egg-info}/PKG-INFO +26 -9
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation.egg-info/SOURCES.txt +24 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation.egg-info/entry_points.txt +1 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/asgi.py +20 -8
- wrapture_instrumentation-1.0.0.dev9/tests/framework/django/conftest.py +81 -0
- wrapture_instrumentation-1.0.0.dev9/tests/framework/django/shop/__init__.py +23 -0
- wrapture_instrumentation-1.0.0.dev9/tests/framework/django/shop/models.py +12 -0
- wrapture_instrumentation-1.0.0.dev9/tests/framework/django/shop/urls.py +23 -0
- wrapture_instrumentation-1.0.0.dev9/tests/framework/django/shop/views.py +80 -0
- wrapture_instrumentation-1.0.0.dev9/tests/framework/django/templates/page.html +1 -0
- wrapture_instrumentation-1.0.0.dev9/tests/framework/django/test_apply_remove.py +101 -0
- wrapture_instrumentation-1.0.0.dev9/tests/framework/django/test_class.py +99 -0
- wrapture_instrumentation-1.0.0.dev9/tests/framework/django/test_database.py +163 -0
- wrapture_instrumentation-1.0.0.dev9/tests/framework/django/test_registration.py +76 -0
- wrapture_instrumentation-1.0.0.dev9/tests/framework/django/test_request_options.py +41 -0
- wrapture_instrumentation-1.0.0.dev9/tests/framework/django/test_templating.py +54 -0
- wrapture_instrumentation-1.0.0.dev9/tests/framework/django/test_tracing.py +232 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/framework/flask/test_templating.py +2 -0
- wrapture_instrumentation-1.0.0.dev9/tests/template/jinja2/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/template/jinja2/test_rendering.py +8 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/LICENSE +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/MANIFEST.in +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/TESTING.md +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/demo/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/demo/database_sqlalchemy.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/demo/database_sqlite3.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/demo/external_aiohttp.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/demo/external_http_client.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/demo/external_httpx.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/demo/external_requests.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/demo/external_urllib3.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/demo/external_urllib_request.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/demo/external_xmlrpc_client.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/demo/framework_fastapi.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/demo/framework_flask.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/demo/framework_starlette.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/demo/rpc_grpc.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/demo/server_aiohttp.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/demo/server_uvicorn.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/demo/server_werkzeug.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/demo/server_wsgiref.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/demo/server_xmlrpc.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/demo/template_jinja2.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/setup.cfg +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/database/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/database/sqlalchemy/README.md +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/database/sqlalchemy/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/database/sqlalchemy/dialects.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/database/sqlalchemy/engine_base.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/database/sqlalchemy/engine_default.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/database/sqlite3/README.md +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/database/sqlite3/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/database/sqlite3/dbapi2.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/external/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/external/aiohttp_client/README.md +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/external/aiohttp_client/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/external/aiohttp_client/client.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/external/http_client/README.md +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/external/http_client/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/external/http_client/client.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/external/httpx/README.md +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/external/httpx/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/external/httpx/_client.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/external/requests/README.md +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/external/requests/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/external/requests/sessions.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/external/urllib3/README.md +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/external/urllib3/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/external/urllib3/pools.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/external/urllib_request/README.md +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/external/urllib_request/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/external/urllib_request/request.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/external/xmlrpc_client/README.md +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/external/xmlrpc_client/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/external/xmlrpc_client/client.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/framework/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/framework/fastapi/README.md +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/framework/fastapi/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/framework/fastapi/applications.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/framework/fastapi/routing.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/framework/flask/README.md +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/framework/flask/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/framework/flask/app.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/framework/flask/blueprints.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/framework/flask/common.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/framework/flask/scaffold.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/framework/starlette/README.md +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/framework/starlette/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/framework/starlette/applications.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/framework/starlette/routing.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/py.typed +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/rpc/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/rpc/grpc/README.md +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/rpc/grpc/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/rpc/grpc/interceptors.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/server/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/server/aiohttp_web/README.md +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/server/aiohttp_web/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/server/aiohttp_web/web_app.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/server/aiohttp_web/web_urldispatcher.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/server/uvicorn/README.md +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/server/uvicorn/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/server/uvicorn/config.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/server/werkzeug_serving/README.md +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/server/werkzeug_serving/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/server/werkzeug_serving/serving.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/server/wsgiref_simple_server/README.md +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/server/wsgiref_simple_server/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/server/wsgiref_simple_server/simple_server.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/server/xmlrpc_server/README.md +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/server/xmlrpc_server/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/server/xmlrpc_server/server.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/template/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/template/jinja2/README.md +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/template/jinja2/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation.egg-info/dependency_links.txt +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation.egg-info/not-zip-safe +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation.egg-info/requires.txt +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation.egg-info/top_level.txt +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/conftest.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/database/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/database/sqlalchemy/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/database/sqlalchemy/conftest.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/database/sqlalchemy/test_apply_remove.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/database/sqlalchemy/test_class.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/database/sqlalchemy/test_composition.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/database/sqlalchemy/test_recording.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/database/sqlalchemy/test_registration.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/database/sqlite3/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/database/sqlite3/conftest.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/database/sqlite3/test_apply_remove.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/database/sqlite3/test_class.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/database/sqlite3/test_recording.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/database/sqlite3/test_registration.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/aiohttp_client/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/aiohttp_client/conftest.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/aiohttp_client/test_apply_remove.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/aiohttp_client/test_class.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/aiohttp_client/test_composition.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/aiohttp_client/test_propagation.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/aiohttp_client/test_recording.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/aiohttp_client/test_registration.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/http_client/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/http_client/conftest.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/http_client/test_apply_remove.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/http_client/test_class.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/http_client/test_layering.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/http_client/test_recording.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/http_client/test_registration.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/httpx/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/httpx/conftest.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/httpx/test_apply_remove.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/httpx/test_async.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/httpx/test_class.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/httpx/test_propagation.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/httpx/test_recording.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/httpx/test_registration.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/requests/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/requests/conftest.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/requests/test_apply_remove.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/requests/test_class.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/requests/test_propagation.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/requests/test_recording.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/requests/test_registration.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/urllib3/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/urllib3/conftest.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/urllib3/test_apply_remove.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/urllib3/test_class.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/urllib3/test_composition.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/urllib3/test_propagation.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/urllib3/test_recording.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/urllib3/test_registration.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/urllib_request/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/urllib_request/conftest.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/urllib_request/test_apply_remove.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/urllib_request/test_class.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/urllib_request/test_propagation.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/urllib_request/test_registration.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/urllib_request/test_requests.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/xmlrpc_client/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/xmlrpc_client/conftest.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/xmlrpc_client/test_apply_remove.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/xmlrpc_client/test_class.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/xmlrpc_client/test_propagation.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/xmlrpc_client/test_recording.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/xmlrpc_client/test_registration.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/framework/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8/tests/framework/fastapi → wrapture_instrumentation-1.0.0.dev9/tests/framework/django}/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8/tests/framework/flask → wrapture_instrumentation-1.0.0.dev9/tests/framework/fastapi}/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/framework/fastapi/conftest.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/framework/fastapi/shop.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/framework/fastapi/test_apply_remove.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/framework/fastapi/test_class.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/framework/fastapi/test_composition.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/framework/fastapi/test_registration.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/framework/fastapi/test_request_options.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/framework/fastapi/test_tracing.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8/tests/framework/starlette → wrapture_instrumentation-1.0.0.dev9/tests/framework/flask}/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/framework/flask/portal.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/framework/flask/shop.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/framework/flask/test_apply_remove.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/framework/flask/test_class.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/framework/flask/test_lifecycle.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/framework/flask/test_registration.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/framework/flask/test_request_options.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/framework/flask/test_tracing.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8/tests/rpc → wrapture_instrumentation-1.0.0.dev9/tests/framework/starlette}/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/framework/starlette/conftest.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/framework/starlette/shop.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/framework/starlette/test_apply_remove.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/framework/starlette/test_class.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/framework/starlette/test_composition.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/framework/starlette/test_registration.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/framework/starlette/test_request_options.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/framework/starlette/test_tracing.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/httpserver.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8/tests/rpc/grpc → wrapture_instrumentation-1.0.0.dev9/tests/rpc}/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8/tests/server → wrapture_instrumentation-1.0.0.dev9/tests/rpc/grpc}/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/rpc/grpc/conftest.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/rpc/grpc/service.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/rpc/grpc/test_apply_remove.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/rpc/grpc/test_class.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/rpc/grpc/test_propagation.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/rpc/grpc/test_recording.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/rpc/grpc/test_registration.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/rpc/grpc/test_server.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8/tests/server/aiohttp_web → wrapture_instrumentation-1.0.0.dev9/tests/server}/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8/tests/server/uvicorn → wrapture_instrumentation-1.0.0.dev9/tests/server/aiohttp_web}/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/aiohttp_web/conftest.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/aiohttp_web/shop.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/aiohttp_web/test_apply_remove.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/aiohttp_web/test_class.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/aiohttp_web/test_composition.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/aiohttp_web/test_join.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/aiohttp_web/test_recording.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/aiohttp_web/test_registration.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8/tests/server/werkzeug_serving → wrapture_instrumentation-1.0.0.dev9/tests/server/uvicorn}/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/uvicorn/conftest.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/uvicorn/test_apply_remove.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/uvicorn/test_class.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/uvicorn/test_composition.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/uvicorn/test_recording.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/uvicorn/test_registration.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8/tests/server/wsgiref_simple_server → wrapture_instrumentation-1.0.0.dev9/tests/server/werkzeug_serving}/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/werkzeug_serving/conftest.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/werkzeug_serving/test_apply_remove.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/werkzeug_serving/test_class.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/werkzeug_serving/test_composition.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/werkzeug_serving/test_recording.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/werkzeug_serving/test_registration.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8/tests/server/xmlrpc_server → wrapture_instrumentation-1.0.0.dev9/tests/server/wsgiref_simple_server}/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/wsgiref_simple_server/conftest.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/wsgiref_simple_server/test_apply_remove.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/wsgiref_simple_server/test_class.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/wsgiref_simple_server/test_composition.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/wsgiref_simple_server/test_recording.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/wsgiref_simple_server/test_registration.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8/tests/template → wrapture_instrumentation-1.0.0.dev9/tests/server/xmlrpc_server}/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/xmlrpc_server/conftest.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/xmlrpc_server/test_apply_remove.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/xmlrpc_server/test_class.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/xmlrpc_server/test_join.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/xmlrpc_server/test_recording.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/xmlrpc_server/test_registration.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8/tests/template/jinja2 → wrapture_instrumentation-1.0.0.dev9/tests/template}/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/template/jinja2/test_apply_remove.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/template/jinja2/test_class.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/template/jinja2/test_registration.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/template/jinja2/test_with_flask.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/test_asgi.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/test_package.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/test_wsgi.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/wsgi.py +0 -0
- {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/xmlrpcserver.py +0 -0
|
@@ -228,8 +228,9 @@ In development.
|
|
|
228
228
|
Supports httpx 0.27 and later, below 1.0.
|
|
229
229
|
|
|
230
230
|
- Jinja2 (`jinja2`, Jinja2 3.x): every render traced in all its
|
|
231
|
-
forms, sync, streamed and async, each
|
|
232
|
-
template's own name; the loading
|
|
231
|
+
forms, sync, streamed and async, each carrying the template
|
|
232
|
+
category and annotated with the template's own name; the loading
|
|
233
|
+
pipeline
|
|
233
234
|
(`Environment._load_template` on every get_template,
|
|
234
235
|
`Environment.compile` inside a cold load) beneath it, behind a
|
|
235
236
|
`loading` switch; every event named by its patched location as
|
|
@@ -247,8 +248,8 @@ In development.
|
|
|
247
248
|
are noted against the request, whether Flask answered 500 or a
|
|
248
249
|
registered handler absorbed a real exception (an `HTTPException`
|
|
249
250
|
is control flow and is not noted); and template rendering records
|
|
250
|
-
beneath the view that asked for it,
|
|
251
|
-
took (`flask:render_template` or
|
|
251
|
+
beneath the view that asked for it, carrying the template category,
|
|
252
|
+
named by the spelling the call took (`flask:render_template` or
|
|
252
253
|
`flask.templating:render_template`), capturing the template name
|
|
253
254
|
while the render context and output stay out of capture. Three
|
|
254
255
|
settings switch the optional layers, all on by default:
|
|
@@ -371,3 +372,28 @@ In development.
|
|
|
371
372
|
records its own. Three settings: `leaf` and `propagate`, both on
|
|
372
373
|
by default, and `redact`. Supports urllib3 1.26 and later, below
|
|
373
374
|
3.
|
|
375
|
+
|
|
376
|
+
- Django (`django`, Django 4.2+): one instrumentation whose events
|
|
377
|
+
span three categories. Every request records as one tree through
|
|
378
|
+
the recording WSGI or ASGI middleware wrapped around the handler's
|
|
379
|
+
own `__call__` (both transports covered from the shared
|
|
380
|
+
`BaseHandler` dispatch), carrying method, path, redacted query and
|
|
381
|
+
status, joining the trace a `traceparent` header carries, and
|
|
382
|
+
annotated with the matched route pattern (`archive/<int:year>/`,
|
|
383
|
+
exported as `http.route`) and view name, an unmatched 404 left
|
|
384
|
+
unannotated. Every view is observed at URL resolution
|
|
385
|
+
(`ResolverMatch` construction), labelled by its URL pattern name,
|
|
386
|
+
function, class-based and async views alike, one call event per
|
|
387
|
+
view. An unhandled exception is noted on the request beside its
|
|
388
|
+
500 at Django's own catch-all; `Http404` and friends are their
|
|
389
|
+
statuses, not failures. ORM queries record as database leaves at
|
|
390
|
+
the `CursorWrapper` seam every backend funnels through, carrying
|
|
391
|
+
system, operation, database and, for a server database, host and
|
|
392
|
+
port; commit and rollback record beside them; bound parameters are
|
|
393
|
+
never recorded and the SQL text only behind the `statement`
|
|
394
|
+
setting; `leaf` folds an instrumented driver (sqlite3) beneath a
|
|
395
|
+
query. DTL renders record as template events beneath their views,
|
|
396
|
+
named templates annotated, contexts never captured; Django's
|
|
397
|
+
Jinja2 backend composes with the jinja2 target instead. Six
|
|
398
|
+
settings: `ignore_paths`, `redact`, `queries`, `statement`, `leaf`
|
|
399
|
+
and `templates`. Supports Django 4.2 and later, below 7.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: wrapture-instrumentation
|
|
3
|
-
Version: 1.0.0.
|
|
3
|
+
Version: 1.0.0.dev9
|
|
4
4
|
Summary: Instrumentation for common Python packages, applied through wrapture.
|
|
5
5
|
Author-email: Graham Dumpleton <Graham.Dumpleton@gmail.com>
|
|
6
6
|
License-Expression: BSD-2-Clause
|
|
@@ -29,14 +29,16 @@ wrapture attaches bindings to arbitrary Python call sites without
|
|
|
29
29
|
modifying the code being observed, and its config layer can switch on
|
|
30
30
|
packaged instrumentation for a third-party package by name. This
|
|
31
31
|
project is the collection of that packaged instrumentation: one
|
|
32
|
-
`wrapture.Instrumentation` class per target package
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
`wrapture.Instrumentation` class per target package, each registered
|
|
33
|
+
under the bare target name, so that tracing a framework is one config
|
|
34
|
+
entry and no code.
|
|
35
35
|
|
|
36
36
|
> **Status: pre-alpha.** The package is being built target by target
|
|
37
37
|
> against wrapture's alpha series, with development releases published
|
|
38
|
-
> to [PyPI](https://pypi.org/project/wrapture-instrumentation/).
|
|
39
|
-
>
|
|
38
|
+
> to [PyPI](https://pypi.org/project/wrapture-instrumentation/). The
|
|
39
|
+
> table below lists what is covered so far, from web frameworks and
|
|
40
|
+
> the servers that carry them to HTTP clients, databases and template
|
|
41
|
+
> engines.
|
|
40
42
|
|
|
41
43
|
## Installation
|
|
42
44
|
|
|
@@ -70,8 +72,12 @@ $ python -m wrapture -m myapp
|
|
|
70
72
|
|
|
71
73
|
The same config works through
|
|
72
74
|
[autowrapt](https://github.com/GrahamDumpleton/autowrapt) injection
|
|
73
|
-
(`AUTOWRAPT_BOOTSTRAP=wrapture python myapp.py`)
|
|
74
|
-
|
|
75
|
+
(`AUTOWRAPT_BOOTSTRAP=wrapture python myapp.py`); through
|
|
76
|
+
[manual setup](https://wrapture.readthedocs.io/en/latest/manual-setup.html),
|
|
77
|
+
a few lines in the application's own startup applying the config
|
|
78
|
+
where wrapping the launch from outside is awkward (an embedded
|
|
79
|
+
interpreter, gunicorn and other multi-process managers); and, in a
|
|
80
|
+
test, through `wrapture.instrumentation("flask")` scoping the
|
|
75
81
|
instrumentation to a block. The
|
|
76
82
|
[ad-hoc tracing guide](https://wrapture.readthedocs.io/en/latest/ad-hoc-tracing.html)
|
|
77
83
|
covers the config file itself.
|
|
@@ -96,6 +102,7 @@ $ python -m wrapture.tools instrumentation --toml
|
|
|
96
102
|
| ------ | ------------------ | ------- | -------- |
|
|
97
103
|
| [`aiohttp.client`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/external/aiohttp_client/README.md) | aiohttp 3.10+ (3.x) | Every outbound request through a `ClientSession` (the verb helpers, `session.request`, a streamed `async with`) as one external leaf on `_request` carrying method, URL, host, port, path, query and status (an error status is a status, not an exception); a followed redirect one event resolved inside it; the trace identity propagated hop by hop; the query and any URL credentials masked, the body never recorded. | `leaf`, `propagate`, `redact` |
|
|
98
104
|
| [`aiohttp.web`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/server/aiohttp_web/README.md) | aiohttp 3.10+ (3.x) | Every request an aiohttp server handles as one `server`-categorised request boundary carrying method, path, scheme, peer and redacted query, annotated with the matched route pattern (a sub-application's prefix folded in, exported as `http.route`) and status (an `HTTPException` is its status, not a failure), joining the trace a `traceparent` header carries; every registered handler function observed as its route is built and recorded beneath the boundary, labelled by the route's name. | `ignore_paths`, `join`, `redact` |
|
|
105
|
+
| [`django`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/framework/django/README.md) | Django 4.2+ (below 7.0) | Every request as one tree through the recording WSGI or ASGI middleware on the handler's own `__call__`, annotated with the matched route pattern and view name (the pattern exported as `http.route`); every view observed at URL resolution and labelled by its URL name, function, class-based and async views alike; ORM queries and transaction ends as database leaves at the cursor seam carrying system, operation and database, bound parameters never recorded and the SQL text only behind a setting; DTL renders as template events beneath their views, contexts never captured; unhandled failures noted on the request beside the 500 (an `Http404` is its status, not a failure). | `ignore_paths`, `redact`, `queries`, `statement`, `leaf`, `templates` |
|
|
99
106
|
| [`fastapi`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/framework/fastapi/README.md) | fastapi 0.110+ (below 1.0) | Every request as one tree through the recording ASGI middleware on the application's own `__call__`, annotated with the matched route pattern (router prefixes folded in) and name, the pattern exported as `http.route`; every endpoint function observed as its `APIRoute` is built, labelled by the route's name, dependency injection and response models undisturbed; validation failures record as their 422, unhandled failures on the request event beside the 500. | `ignore_paths`, `redact` |
|
|
100
107
|
| [`flask`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/framework/flask/README.md) | Flask 3.x | Every request as one tree, annotated with route and endpoint; every view observed and labelled by endpoint; template renders beneath their views; handled and unhandled failures noted on the request. | `ignore_paths`, `redact`, `lifecycle`, `handled_errors`, `templates` |
|
|
101
108
|
| [`grpc`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/rpc/grpc/README.md) | grpcio 1.76+ (1.x) | Every RPC a channel makes, all four call shapes, as one external leaf through an injected client interceptor, carrying the rpc system, service and method, host, port and status code (an error code is a status, not an exception; a streamed response records the call, its consumption deliberately not tracked); every RPC a server handles as one `server` boundary through an injected server interceptor spanning the handler's run (a streaming handler's whole body), joining the trace the metadata carries; an abort is its code with the boundary clean, an escaped exception the failure it is; payloads and metadata never recorded. | `client`, `server`, `propagate`, `join` |
|
|
@@ -121,6 +128,15 @@ settings, and what is deliberately not traced. Settings, further
|
|
|
121
128
|
choke points and wider version ranges are being added target by
|
|
122
129
|
target.
|
|
123
130
|
|
|
131
|
+
This package deliberately covers only the standard library and
|
|
132
|
+
third-party packages that can be exercised in-process, with no
|
|
133
|
+
separate backend product or service needed to test against.
|
|
134
|
+
Instrumentation for targets that do need one (a real PostgreSQL,
|
|
135
|
+
MySQL or Redis to speak to, and their driver packages) will be
|
|
136
|
+
provided as separate self-contained packages, one per
|
|
137
|
+
product/service, each carrying its own test arrangements and release
|
|
138
|
+
cadence. No such packages exist yet; they are coming.
|
|
139
|
+
|
|
124
140
|
## Adding a target
|
|
125
141
|
|
|
126
142
|
Each target lives under `src/wrapture_instrumentation/` in a role
|
|
@@ -177,4 +193,5 @@ here covers the tests.
|
|
|
177
193
|
|
|
178
194
|
## License
|
|
179
195
|
|
|
180
|
-
BSD
|
|
196
|
+
BSD 2-Clause. See
|
|
197
|
+
[LICENSE](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/LICENSE).
|
|
@@ -7,14 +7,16 @@ wrapture attaches bindings to arbitrary Python call sites without
|
|
|
7
7
|
modifying the code being observed, and its config layer can switch on
|
|
8
8
|
packaged instrumentation for a third-party package by name. This
|
|
9
9
|
project is the collection of that packaged instrumentation: one
|
|
10
|
-
`wrapture.Instrumentation` class per target package
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
`wrapture.Instrumentation` class per target package, each registered
|
|
11
|
+
under the bare target name, so that tracing a framework is one config
|
|
12
|
+
entry and no code.
|
|
13
13
|
|
|
14
14
|
> **Status: pre-alpha.** The package is being built target by target
|
|
15
15
|
> against wrapture's alpha series, with development releases published
|
|
16
|
-
> to [PyPI](https://pypi.org/project/wrapture-instrumentation/).
|
|
17
|
-
>
|
|
16
|
+
> to [PyPI](https://pypi.org/project/wrapture-instrumentation/). The
|
|
17
|
+
> table below lists what is covered so far, from web frameworks and
|
|
18
|
+
> the servers that carry them to HTTP clients, databases and template
|
|
19
|
+
> engines.
|
|
18
20
|
|
|
19
21
|
## Installation
|
|
20
22
|
|
|
@@ -48,8 +50,12 @@ $ python -m wrapture -m myapp
|
|
|
48
50
|
|
|
49
51
|
The same config works through
|
|
50
52
|
[autowrapt](https://github.com/GrahamDumpleton/autowrapt) injection
|
|
51
|
-
(`AUTOWRAPT_BOOTSTRAP=wrapture python myapp.py`)
|
|
52
|
-
|
|
53
|
+
(`AUTOWRAPT_BOOTSTRAP=wrapture python myapp.py`); through
|
|
54
|
+
[manual setup](https://wrapture.readthedocs.io/en/latest/manual-setup.html),
|
|
55
|
+
a few lines in the application's own startup applying the config
|
|
56
|
+
where wrapping the launch from outside is awkward (an embedded
|
|
57
|
+
interpreter, gunicorn and other multi-process managers); and, in a
|
|
58
|
+
test, through `wrapture.instrumentation("flask")` scoping the
|
|
53
59
|
instrumentation to a block. The
|
|
54
60
|
[ad-hoc tracing guide](https://wrapture.readthedocs.io/en/latest/ad-hoc-tracing.html)
|
|
55
61
|
covers the config file itself.
|
|
@@ -74,6 +80,7 @@ $ python -m wrapture.tools instrumentation --toml
|
|
|
74
80
|
| ------ | ------------------ | ------- | -------- |
|
|
75
81
|
| [`aiohttp.client`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/external/aiohttp_client/README.md) | aiohttp 3.10+ (3.x) | Every outbound request through a `ClientSession` (the verb helpers, `session.request`, a streamed `async with`) as one external leaf on `_request` carrying method, URL, host, port, path, query and status (an error status is a status, not an exception); a followed redirect one event resolved inside it; the trace identity propagated hop by hop; the query and any URL credentials masked, the body never recorded. | `leaf`, `propagate`, `redact` |
|
|
76
82
|
| [`aiohttp.web`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/server/aiohttp_web/README.md) | aiohttp 3.10+ (3.x) | Every request an aiohttp server handles as one `server`-categorised request boundary carrying method, path, scheme, peer and redacted query, annotated with the matched route pattern (a sub-application's prefix folded in, exported as `http.route`) and status (an `HTTPException` is its status, not a failure), joining the trace a `traceparent` header carries; every registered handler function observed as its route is built and recorded beneath the boundary, labelled by the route's name. | `ignore_paths`, `join`, `redact` |
|
|
83
|
+
| [`django`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/framework/django/README.md) | Django 4.2+ (below 7.0) | Every request as one tree through the recording WSGI or ASGI middleware on the handler's own `__call__`, annotated with the matched route pattern and view name (the pattern exported as `http.route`); every view observed at URL resolution and labelled by its URL name, function, class-based and async views alike; ORM queries and transaction ends as database leaves at the cursor seam carrying system, operation and database, bound parameters never recorded and the SQL text only behind a setting; DTL renders as template events beneath their views, contexts never captured; unhandled failures noted on the request beside the 500 (an `Http404` is its status, not a failure). | `ignore_paths`, `redact`, `queries`, `statement`, `leaf`, `templates` |
|
|
77
84
|
| [`fastapi`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/framework/fastapi/README.md) | fastapi 0.110+ (below 1.0) | Every request as one tree through the recording ASGI middleware on the application's own `__call__`, annotated with the matched route pattern (router prefixes folded in) and name, the pattern exported as `http.route`; every endpoint function observed as its `APIRoute` is built, labelled by the route's name, dependency injection and response models undisturbed; validation failures record as their 422, unhandled failures on the request event beside the 500. | `ignore_paths`, `redact` |
|
|
78
85
|
| [`flask`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/framework/flask/README.md) | Flask 3.x | Every request as one tree, annotated with route and endpoint; every view observed and labelled by endpoint; template renders beneath their views; handled and unhandled failures noted on the request. | `ignore_paths`, `redact`, `lifecycle`, `handled_errors`, `templates` |
|
|
79
86
|
| [`grpc`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/rpc/grpc/README.md) | grpcio 1.76+ (1.x) | Every RPC a channel makes, all four call shapes, as one external leaf through an injected client interceptor, carrying the rpc system, service and method, host, port and status code (an error code is a status, not an exception; a streamed response records the call, its consumption deliberately not tracked); every RPC a server handles as one `server` boundary through an injected server interceptor spanning the handler's run (a streaming handler's whole body), joining the trace the metadata carries; an abort is its code with the boundary clean, an escaped exception the failure it is; payloads and metadata never recorded. | `client`, `server`, `propagate`, `join` |
|
|
@@ -99,6 +106,15 @@ settings, and what is deliberately not traced. Settings, further
|
|
|
99
106
|
choke points and wider version ranges are being added target by
|
|
100
107
|
target.
|
|
101
108
|
|
|
109
|
+
This package deliberately covers only the standard library and
|
|
110
|
+
third-party packages that can be exercised in-process, with no
|
|
111
|
+
separate backend product or service needed to test against.
|
|
112
|
+
Instrumentation for targets that do need one (a real PostgreSQL,
|
|
113
|
+
MySQL or Redis to speak to, and their driver packages) will be
|
|
114
|
+
provided as separate self-contained packages, one per
|
|
115
|
+
product/service, each carrying its own test arrangements and release
|
|
116
|
+
cadence. No such packages exist yet; they are coming.
|
|
117
|
+
|
|
102
118
|
## Adding a target
|
|
103
119
|
|
|
104
120
|
Each target lives under `src/wrapture_instrumentation/` in a role
|
|
@@ -155,4 +171,5 @@ here covers the tests.
|
|
|
155
171
|
|
|
156
172
|
## License
|
|
157
173
|
|
|
158
|
-
BSD
|
|
174
|
+
BSD 2-Clause. See
|
|
175
|
+
[LICENSE](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/LICENSE).
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
"""Drive a Django application with the django and sqlite3
|
|
2
|
+
instrumentations applied together.
|
|
3
|
+
|
|
4
|
+
The instrumentations are resolved by their entry point names, the way
|
|
5
|
+
a config file finds them, and the application is the tests' own shop
|
|
6
|
+
app, configured and imported only after the instrumentations apply,
|
|
7
|
+
the order the runner guarantees in real use. Applying both is the
|
|
8
|
+
point: with the django target's `leaf` on (the default) each ORM
|
|
9
|
+
query is a terminal node and the sqlite3 driver's events fold into
|
|
10
|
+
it, one database event per query.
|
|
11
|
+
|
|
12
|
+
The requests go through the real handlers, a WSGIHandler driven by
|
|
13
|
+
the tests' WSGI driver and then an ASGIHandler driven by the ASGI
|
|
14
|
+
one, covering every view shape: plain views, a route with an int
|
|
15
|
+
converter, a class-based view, an async view, views that query and
|
|
16
|
+
populate the database inside atomic(), a DTL render, a streaming
|
|
17
|
+
response, an Http404 (its status, no failure), a 404 that matched no
|
|
18
|
+
route, and a view that raises (Django answers 500 and the exception
|
|
19
|
+
is noted against the request event).
|
|
20
|
+
|
|
21
|
+
Two views of the run always print: the live stream, one line as each
|
|
22
|
+
operation begins and a closing line with its outcome, and the tidy
|
|
23
|
+
tree reconstructed afterwards with timings. With --otel the same
|
|
24
|
+
events also export as OpenTelemetry spans to a local OTLP endpoint
|
|
25
|
+
(http://localhost:4318 unless OTEL_EXPORTER_OTLP_ENDPOINT says
|
|
26
|
+
otherwise), for verifying the spans in a backend such as Jaeger:
|
|
27
|
+
|
|
28
|
+
docker run --rm -p 16686:16686 -p 4318:4318 jaegertracing/all-in-one
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
from __future__ import annotations
|
|
32
|
+
|
|
33
|
+
import argparse
|
|
34
|
+
import os
|
|
35
|
+
import sys
|
|
36
|
+
|
|
37
|
+
import wrapture
|
|
38
|
+
|
|
39
|
+
WSGI_REQUESTS: tuple[tuple[str, str, str], ...] = (
|
|
40
|
+
("GET", "/", ""),
|
|
41
|
+
("GET", "/quote/widget/", "token=hunter2&item=widget"),
|
|
42
|
+
("GET", "/archive/1999/", ""),
|
|
43
|
+
("GET", "/catalog/", ""),
|
|
44
|
+
("GET", "/restock/", ""),
|
|
45
|
+
("GET", "/stocked/", ""),
|
|
46
|
+
("GET", "/pricelist/", "person=pat"),
|
|
47
|
+
("GET", "/export/", ""),
|
|
48
|
+
("GET", "/missing/", ""),
|
|
49
|
+
("GET", "/nowhere", ""),
|
|
50
|
+
("GET", "/quote/missing/", ""),
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
ASGI_REQUESTS: tuple[tuple[str, str, str], ...] = (
|
|
54
|
+
("GET", "/motd/", ""),
|
|
55
|
+
("GET", "/", ""),
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def add_otel_sink() -> None:
|
|
60
|
+
"""Register the OpenTelemetry sink, exporting the run's events as
|
|
61
|
+
spans; exits with guidance when the optional dependencies are
|
|
62
|
+
missing."""
|
|
63
|
+
|
|
64
|
+
try:
|
|
65
|
+
import wrapture.otel
|
|
66
|
+
except ImportError as error:
|
|
67
|
+
raise SystemExit(
|
|
68
|
+
"the OpenTelemetry dependencies are not installed; run the"
|
|
69
|
+
" demo through `just demo-django --otel`, which overlays"
|
|
70
|
+
" wrapture[otel] for the run"
|
|
71
|
+
) from error
|
|
72
|
+
|
|
73
|
+
wrapture.add_sink(wrapture.otel.sink(service_name="wrapture-django-demo"))
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def configure_django() -> None:
|
|
77
|
+
"""Configure the minimum settings the shop app needs and set
|
|
78
|
+
Django up, the demo's stand-in for a project's settings module."""
|
|
79
|
+
|
|
80
|
+
from pathlib import Path
|
|
81
|
+
|
|
82
|
+
import django
|
|
83
|
+
from django.conf import settings
|
|
84
|
+
|
|
85
|
+
import tests.framework.django
|
|
86
|
+
|
|
87
|
+
settings.configure(
|
|
88
|
+
DEBUG=False,
|
|
89
|
+
SECRET_KEY="demo-only",
|
|
90
|
+
DATABASES={
|
|
91
|
+
"default": {
|
|
92
|
+
"ENGINE": "django.db.backends.sqlite3",
|
|
93
|
+
"NAME": ":memory:",
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
ROOT_URLCONF="tests.framework.django.shop.urls",
|
|
97
|
+
INSTALLED_APPS=["tests.framework.django.shop"],
|
|
98
|
+
TEMPLATES=[
|
|
99
|
+
{
|
|
100
|
+
"BACKEND": "django.template.backends.django.DjangoTemplates",
|
|
101
|
+
"DIRS": [
|
|
102
|
+
str(Path(tests.framework.django.__file__).parent / "templates")
|
|
103
|
+
],
|
|
104
|
+
"APP_DIRS": False,
|
|
105
|
+
"OPTIONS": {},
|
|
106
|
+
}
|
|
107
|
+
],
|
|
108
|
+
ALLOWED_HOSTS=["*"],
|
|
109
|
+
USE_TZ=True,
|
|
110
|
+
)
|
|
111
|
+
django.setup()
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def main(arguments: list[str] | None = None) -> None:
|
|
115
|
+
"""Run the demo: apply the instrumentations, drive the requests
|
|
116
|
+
through both handlers, print the live stream and the tree, and
|
|
117
|
+
flush any exporters."""
|
|
118
|
+
|
|
119
|
+
parser = argparse.ArgumentParser(
|
|
120
|
+
prog="demo.framework_django",
|
|
121
|
+
description="Drive a Django application with the django and"
|
|
122
|
+
" sqlite3 instrumentations applied, printing the live stream"
|
|
123
|
+
" and the tree.",
|
|
124
|
+
)
|
|
125
|
+
parser.add_argument(
|
|
126
|
+
"--otel",
|
|
127
|
+
action="store_true",
|
|
128
|
+
help="also export the events as OpenTelemetry spans over OTLP",
|
|
129
|
+
)
|
|
130
|
+
options = parser.parse_args(arguments)
|
|
131
|
+
|
|
132
|
+
# The exporting sink registers first, mirroring the config loader,
|
|
133
|
+
# which always puts the [otel] table's sink ahead of the [[sink]]
|
|
134
|
+
# list; the printer writes to stdout so the stream and the demo's
|
|
135
|
+
# own headings interleave in order.
|
|
136
|
+
|
|
137
|
+
if options.otel:
|
|
138
|
+
add_otel_sink()
|
|
139
|
+
|
|
140
|
+
wrapture.add_sink(wrapture.Printer(stream=sys.stdout))
|
|
141
|
+
|
|
142
|
+
print("== live stream ==")
|
|
143
|
+
|
|
144
|
+
with wrapture.instrumentation("django", "sqlite3"), wrapture.timeline() as tape:
|
|
145
|
+
configure_django()
|
|
146
|
+
|
|
147
|
+
from django.db import connection
|
|
148
|
+
|
|
149
|
+
from tests import asgi, wsgi
|
|
150
|
+
from tests.framework.django.shop import make_asgi_app, make_wsgi_app
|
|
151
|
+
from tests.framework.django.shop.models import Item
|
|
152
|
+
|
|
153
|
+
# The model's table, created without migrations; the schema
|
|
154
|
+
# editor's statements record like any other, an honest look
|
|
155
|
+
# at what setup costs.
|
|
156
|
+
|
|
157
|
+
with connection.schema_editor() as editor:
|
|
158
|
+
editor.create_model(Item)
|
|
159
|
+
|
|
160
|
+
app = make_wsgi_app()
|
|
161
|
+
for method, path, query in WSGI_REQUESTS:
|
|
162
|
+
wsgi.request(app, method, path, query=query)
|
|
163
|
+
|
|
164
|
+
aapp = make_asgi_app()
|
|
165
|
+
for method, path, query in ASGI_REQUESTS:
|
|
166
|
+
asgi.request(aapp, method, path, query=query)
|
|
167
|
+
|
|
168
|
+
print()
|
|
169
|
+
print("== tree ==")
|
|
170
|
+
print(tape.tree(times=True))
|
|
171
|
+
|
|
172
|
+
# Deliver everything owed: batched spans push to the exporter here
|
|
173
|
+
# rather than at interpreter exit, so the closing hint below is
|
|
174
|
+
# true by the time it prints.
|
|
175
|
+
|
|
176
|
+
wrapture.shutdown()
|
|
177
|
+
|
|
178
|
+
if options.otel:
|
|
179
|
+
endpoint = os.environ.get(
|
|
180
|
+
"OTEL_EXPORTER_OTLP_ENDPOINT", "http://localhost:4318"
|
|
181
|
+
)
|
|
182
|
+
print()
|
|
183
|
+
print("== otel ==")
|
|
184
|
+
print(f"spans flushed to {endpoint} as service wrapture-django-demo")
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
if __name__ == "__main__":
|
|
188
|
+
main()
|
|
@@ -41,6 +41,7 @@ Documentation = "https://wrapture.readthedocs.io"
|
|
|
41
41
|
[project.entry-points."wrapture.instrumentation"]
|
|
42
42
|
"aiohttp.client" = "wrapture_instrumentation.external.aiohttp_client:AiohttpClientInstrumentation"
|
|
43
43
|
"aiohttp.web" = "wrapture_instrumentation.server.aiohttp_web:AiohttpWebInstrumentation"
|
|
44
|
+
django = "wrapture_instrumentation.framework.django:DjangoInstrumentation"
|
|
44
45
|
fastapi = "wrapture_instrumentation.framework.fastapi:FastAPIInstrumentation"
|
|
45
46
|
flask = "wrapture_instrumentation.framework.flask:FlaskInstrumentation"
|
|
46
47
|
grpc = "wrapture_instrumentation.rpc.grpc:GRPCInstrumentation"
|
|
@@ -85,6 +86,7 @@ test = [
|
|
|
85
86
|
# without, and the sqlalchemy suite skips itself where the
|
|
86
87
|
# import fails.
|
|
87
88
|
"aiosqlite; python_version != '3.13'",
|
|
89
|
+
"django",
|
|
88
90
|
"fastapi",
|
|
89
91
|
"flask",
|
|
90
92
|
"httpx",
|
|
@@ -122,10 +124,20 @@ files = ["src/wrapture_instrumentation", "tests", "demo"]
|
|
|
122
124
|
module = ["grpc", "grpc.*"]
|
|
123
125
|
ignore_missing_imports = true
|
|
124
126
|
|
|
127
|
+
# Django ships no inline types either (django-stubs is a separate
|
|
128
|
+
# project); the patch modules import it lazily so most of it is Any
|
|
129
|
+
# already, and the test app's model and class-based view necessarily
|
|
130
|
+
# subclass its (Any-typed) bases.
|
|
131
|
+
[[tool.mypy.overrides]]
|
|
132
|
+
module = ["django", "django.*"]
|
|
133
|
+
ignore_missing_imports = true
|
|
134
|
+
|
|
125
135
|
[[tool.mypy.overrides]]
|
|
126
136
|
module = [
|
|
127
137
|
"wrapture_instrumentation.rpc.grpc.interceptors",
|
|
128
138
|
"tests.rpc.grpc.service",
|
|
139
|
+
"tests.framework.django.shop.models",
|
|
140
|
+
"tests.framework.django.shop.views",
|
|
129
141
|
]
|
|
130
142
|
disallow_subclassing_any = false
|
|
131
143
|
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# django instrumentation
|
|
2
|
+
|
|
3
|
+
Request, database and template tracing for
|
|
4
|
+
[Django](https://www.djangoproject.com/). Entry point name `django`,
|
|
5
|
+
the package it patches; supports Django 4.2 and later, below 7.0;
|
|
6
|
+
fully removable. One instrumentation whose events span three
|
|
7
|
+
categories: requests from the handler boundary, database events from
|
|
8
|
+
the ORM's cursor seam, template events from DTL rendering.
|
|
9
|
+
|
|
10
|
+
## Enabling it
|
|
11
|
+
|
|
12
|
+
An `[[instrument]]` entry in `wrapture.toml` (with at least one sink
|
|
13
|
+
to hear the events):
|
|
14
|
+
|
|
15
|
+
```toml
|
|
16
|
+
[[instrument]]
|
|
17
|
+
name = "django"
|
|
18
|
+
|
|
19
|
+
[[sink]]
|
|
20
|
+
type = "printer"
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
run under wrapture's runner or through autowrapt injection, so the
|
|
24
|
+
patches are in place before Django imports; in a test, the context
|
|
25
|
+
manager `wrapture.instrumentation("django")` scopes it to a block.
|
|
26
|
+
|
|
27
|
+
## What you see
|
|
28
|
+
|
|
29
|
+
One `request` event per request, WSGI and ASGI alike, with the
|
|
30
|
+
matched route on it, the view beneath it, and the view's queries and
|
|
31
|
+
template renders beneath that:
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
GET /quote/widget/ (django.core.handlers.wsgi:WSGIHandler.__call__) -> '200 OK'
|
|
35
|
+
quoted(...) -> <HttpResponse ...>
|
|
36
|
+
CursorWrapper.execute(...) -> ...
|
|
37
|
+
Template.render(...) -> '<27 chars>'
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
- The request boundary is wrapture's recording WSGI or ASGI
|
|
41
|
+
middleware, installed by decorating the handler's own `__call__`,
|
|
42
|
+
the callable a server actually invokes. Each event carries the
|
|
43
|
+
method, path, query (with the built-in sensitive names masked),
|
|
44
|
+
scheme and peer, and the status line as its result. A request
|
|
45
|
+
carrying a `traceparent` header joins the caller's trace.
|
|
46
|
+
|
|
47
|
+
- Once dispatch has resolved the URL, the request event is annotated
|
|
48
|
+
with the route pattern (`archive/<int:year>/`) and the view name
|
|
49
|
+
from `resolver_match`, the low-cardinality grouping key the raw
|
|
50
|
+
path is not; wrapture's OpenTelemetry export reads the pattern as
|
|
51
|
+
`http.route` and names the span by it. A request that matched no
|
|
52
|
+
route (a 404) records with its raw path and no route keys. A view
|
|
53
|
+
that raised still gets its route keys.
|
|
54
|
+
|
|
55
|
+
- Every view is observed as URL resolution constructs its
|
|
56
|
+
`ResolverMatch`, labelled by the URL pattern's name when it has
|
|
57
|
+
one, so it records as a call beneath its request under the name
|
|
58
|
+
Django knows it by; an unnamed pattern's view keeps its
|
|
59
|
+
module-qualified path as its identity. A class-based view records
|
|
60
|
+
as one event for the whole view (its `dispatch` and HTTP-method
|
|
61
|
+
methods run inside it), and an async view is still awaited: the
|
|
62
|
+
observed proxy reads as a coroutine function to Django's own
|
|
63
|
+
checks. The view's captured request argument reduces to its type
|
|
64
|
+
(its repr carries the raw query string); URL-derived arguments
|
|
65
|
+
pass. Two deliberate gaps: `resolve("/x/").func` compares equal
|
|
66
|
+
to the view but is not the same object under instrumentation, and
|
|
67
|
+
the 404/500 error-handler views resolve outside `ResolverMatch`
|
|
68
|
+
and are not observed.
|
|
69
|
+
|
|
70
|
+
- An unhandled exception is noted against the request event at
|
|
71
|
+
Django's own catch-all, so the request shows the failure beside
|
|
72
|
+
the 500 it answered; the failing view's own event carries the
|
|
73
|
+
exception directly. `Http404`, `PermissionDenied` and
|
|
74
|
+
`SuspiciousOperation` are control flow that carry a status
|
|
75
|
+
(404/403/400) and are never noted.
|
|
76
|
+
|
|
77
|
+
- Every ORM query, and raw SQL through a Django cursor, records as a
|
|
78
|
+
`database` event at the `CursorWrapper` seam every backend funnels
|
|
79
|
+
through (`DEBUG = True`'s debug cursor included), carrying
|
|
80
|
+
`system` (the connection's vendor: `sqlite`, `postgresql`,
|
|
81
|
+
`mysql`, `oracle`), `operation` (the SQL's leading keyword),
|
|
82
|
+
`database` and, for a server database, `host` and `port`. Commit
|
|
83
|
+
and rollback record the same way at the connection, showing the
|
|
84
|
+
real transaction boundaries `atomic()` creates; under plain
|
|
85
|
+
autocommit most statements never hit them. Bound parameters are
|
|
86
|
+
never recorded; the SQL text (with placeholders, not values) only
|
|
87
|
+
when the `statement` setting is on.
|
|
88
|
+
|
|
89
|
+
- Every DTL render records as a `template`-categorised event beneath
|
|
90
|
+
the view that asked for it, annotated with the template's name,
|
|
91
|
+
the render context masked wholesale and the output reduced to its
|
|
92
|
+
size. Included and extended templates nest beneath the render that
|
|
93
|
+
pulled them in.
|
|
94
|
+
|
|
95
|
+
## Composition
|
|
96
|
+
|
|
97
|
+
- Under an instrumented server (the `uvicorn` target, or any
|
|
98
|
+
recording middleware a server interposed), a request still records
|
|
99
|
+
as one tree: the outer middleware records and marks the scope, the
|
|
100
|
+
handler's own passes through, and the route annotation lands on
|
|
101
|
+
the one boundary.
|
|
102
|
+
|
|
103
|
+
- With the `sqlite3` target also applied and `leaf` on (the
|
|
104
|
+
default), each Django query is a terminal node and the driver's
|
|
105
|
+
own events beneath it are folded in, so a query records once; with
|
|
106
|
+
`leaf` off they nest beneath it instead. A future per-backend
|
|
107
|
+
driver package composes the same way.
|
|
108
|
+
|
|
109
|
+
- Django's Jinja2 template backend delegates to real Jinja2, so
|
|
110
|
+
those renders are the `jinja2` target's to record; this
|
|
111
|
+
instrumentation covers only DTL templates and the two never double
|
|
112
|
+
up.
|
|
113
|
+
|
|
114
|
+
## Settings
|
|
115
|
+
|
|
116
|
+
| Setting | Default | Controls |
|
|
117
|
+
| ------- | ------- | -------- |
|
|
118
|
+
| `ignore_paths` | `[]` | Request paths not to record, as path globs (`'/health'`, `'/static/*'`). An ignored request records nothing at all, its view, queries and template renders included. |
|
|
119
|
+
| `redact` | `[]` | Query string parameters to mask by name, on top of the built-in sensitive set (passwords, tokens, keys and session ids are always masked). The parameter still reaches the application; only the recording is masked. |
|
|
120
|
+
| `queries` | `true` | Record ORM statements and transaction ends as database events. |
|
|
121
|
+
| `statement` | `false` | Record the SQL text on each query event, as compiled with placeholders; bound parameters are never recorded regardless. |
|
|
122
|
+
| `leaf` | `true` | Record each query as a terminal node, folding an instrumented driver beneath it. |
|
|
123
|
+
| `templates` | `true` | Observe DTL template rendering beneath the view that asked for it. |
|
|
124
|
+
|
|
125
|
+
```toml
|
|
126
|
+
[[instrument]]
|
|
127
|
+
name = "django"
|
|
128
|
+
ignore_paths = ["/health"]
|
|
129
|
+
statement = true
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## How it patches
|
|
133
|
+
|
|
134
|
+
For the implementation detail see the module docstrings of
|
|
135
|
+
[handlers.py](handlers.py), [dispatch.py](dispatch.py),
|
|
136
|
+
[resolvers.py](resolvers.py), [exceptions.py](exceptions.py),
|
|
137
|
+
[db.py](db.py) and [templates.py](templates.py).
|