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.
Files changed (293) hide show
  1. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/CHANGES.md +30 -4
  2. {wrapture_instrumentation-1.0.0.dev8/src/wrapture_instrumentation.egg-info → wrapture_instrumentation-1.0.0.dev9}/PKG-INFO +26 -9
  3. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/README.md +25 -8
  4. wrapture_instrumentation-1.0.0.dev9/demo/framework_django.py +188 -0
  5. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/pyproject.toml +12 -0
  6. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/__init__.py +1 -1
  7. wrapture_instrumentation-1.0.0.dev9/src/wrapture_instrumentation/framework/django/README.md +137 -0
  8. wrapture_instrumentation-1.0.0.dev9/src/wrapture_instrumentation/framework/django/__init__.py +135 -0
  9. wrapture_instrumentation-1.0.0.dev9/src/wrapture_instrumentation/framework/django/common.py +59 -0
  10. wrapture_instrumentation-1.0.0.dev9/src/wrapture_instrumentation/framework/django/db.py +171 -0
  11. wrapture_instrumentation-1.0.0.dev9/src/wrapture_instrumentation/framework/django/dispatch.py +83 -0
  12. wrapture_instrumentation-1.0.0.dev9/src/wrapture_instrumentation/framework/django/exceptions.py +56 -0
  13. wrapture_instrumentation-1.0.0.dev9/src/wrapture_instrumentation/framework/django/handlers.py +130 -0
  14. wrapture_instrumentation-1.0.0.dev9/src/wrapture_instrumentation/framework/django/resolvers.py +111 -0
  15. wrapture_instrumentation-1.0.0.dev9/src/wrapture_instrumentation/framework/django/templates.py +76 -0
  16. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/framework/flask/templating.py +3 -1
  17. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/template/jinja2/environment.py +8 -5
  18. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9/src/wrapture_instrumentation.egg-info}/PKG-INFO +26 -9
  19. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation.egg-info/SOURCES.txt +24 -0
  20. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation.egg-info/entry_points.txt +1 -0
  21. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/asgi.py +20 -8
  22. wrapture_instrumentation-1.0.0.dev9/tests/framework/django/conftest.py +81 -0
  23. wrapture_instrumentation-1.0.0.dev9/tests/framework/django/shop/__init__.py +23 -0
  24. wrapture_instrumentation-1.0.0.dev9/tests/framework/django/shop/models.py +12 -0
  25. wrapture_instrumentation-1.0.0.dev9/tests/framework/django/shop/urls.py +23 -0
  26. wrapture_instrumentation-1.0.0.dev9/tests/framework/django/shop/views.py +80 -0
  27. wrapture_instrumentation-1.0.0.dev9/tests/framework/django/templates/page.html +1 -0
  28. wrapture_instrumentation-1.0.0.dev9/tests/framework/django/test_apply_remove.py +101 -0
  29. wrapture_instrumentation-1.0.0.dev9/tests/framework/django/test_class.py +99 -0
  30. wrapture_instrumentation-1.0.0.dev9/tests/framework/django/test_database.py +163 -0
  31. wrapture_instrumentation-1.0.0.dev9/tests/framework/django/test_registration.py +76 -0
  32. wrapture_instrumentation-1.0.0.dev9/tests/framework/django/test_request_options.py +41 -0
  33. wrapture_instrumentation-1.0.0.dev9/tests/framework/django/test_templating.py +54 -0
  34. wrapture_instrumentation-1.0.0.dev9/tests/framework/django/test_tracing.py +232 -0
  35. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/framework/flask/test_templating.py +2 -0
  36. wrapture_instrumentation-1.0.0.dev9/tests/template/jinja2/__init__.py +0 -0
  37. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/template/jinja2/test_rendering.py +8 -0
  38. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/LICENSE +0 -0
  39. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/MANIFEST.in +0 -0
  40. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/TESTING.md +0 -0
  41. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/demo/__init__.py +0 -0
  42. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/demo/database_sqlalchemy.py +0 -0
  43. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/demo/database_sqlite3.py +0 -0
  44. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/demo/external_aiohttp.py +0 -0
  45. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/demo/external_http_client.py +0 -0
  46. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/demo/external_httpx.py +0 -0
  47. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/demo/external_requests.py +0 -0
  48. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/demo/external_urllib3.py +0 -0
  49. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/demo/external_urllib_request.py +0 -0
  50. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/demo/external_xmlrpc_client.py +0 -0
  51. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/demo/framework_fastapi.py +0 -0
  52. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/demo/framework_flask.py +0 -0
  53. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/demo/framework_starlette.py +0 -0
  54. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/demo/rpc_grpc.py +0 -0
  55. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/demo/server_aiohttp.py +0 -0
  56. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/demo/server_uvicorn.py +0 -0
  57. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/demo/server_werkzeug.py +0 -0
  58. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/demo/server_wsgiref.py +0 -0
  59. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/demo/server_xmlrpc.py +0 -0
  60. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/demo/template_jinja2.py +0 -0
  61. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/setup.cfg +0 -0
  62. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/database/__init__.py +0 -0
  63. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/database/sqlalchemy/README.md +0 -0
  64. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/database/sqlalchemy/__init__.py +0 -0
  65. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/database/sqlalchemy/dialects.py +0 -0
  66. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/database/sqlalchemy/engine_base.py +0 -0
  67. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/database/sqlalchemy/engine_default.py +0 -0
  68. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/database/sqlite3/README.md +0 -0
  69. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/database/sqlite3/__init__.py +0 -0
  70. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/database/sqlite3/dbapi2.py +0 -0
  71. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/external/__init__.py +0 -0
  72. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/external/aiohttp_client/README.md +0 -0
  73. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/external/aiohttp_client/__init__.py +0 -0
  74. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/external/aiohttp_client/client.py +0 -0
  75. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/external/http_client/README.md +0 -0
  76. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/external/http_client/__init__.py +0 -0
  77. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/external/http_client/client.py +0 -0
  78. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/external/httpx/README.md +0 -0
  79. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/external/httpx/__init__.py +0 -0
  80. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/external/httpx/_client.py +0 -0
  81. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/external/requests/README.md +0 -0
  82. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/external/requests/__init__.py +0 -0
  83. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/external/requests/sessions.py +0 -0
  84. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/external/urllib3/README.md +0 -0
  85. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/external/urllib3/__init__.py +0 -0
  86. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/external/urllib3/pools.py +0 -0
  87. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/external/urllib_request/README.md +0 -0
  88. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/external/urllib_request/__init__.py +0 -0
  89. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/external/urllib_request/request.py +0 -0
  90. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/external/xmlrpc_client/README.md +0 -0
  91. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/external/xmlrpc_client/__init__.py +0 -0
  92. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/external/xmlrpc_client/client.py +0 -0
  93. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/framework/__init__.py +0 -0
  94. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/framework/fastapi/README.md +0 -0
  95. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/framework/fastapi/__init__.py +0 -0
  96. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/framework/fastapi/applications.py +0 -0
  97. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/framework/fastapi/routing.py +0 -0
  98. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/framework/flask/README.md +0 -0
  99. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/framework/flask/__init__.py +0 -0
  100. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/framework/flask/app.py +0 -0
  101. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/framework/flask/blueprints.py +0 -0
  102. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/framework/flask/common.py +0 -0
  103. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/framework/flask/scaffold.py +0 -0
  104. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/framework/starlette/README.md +0 -0
  105. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/framework/starlette/__init__.py +0 -0
  106. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/framework/starlette/applications.py +0 -0
  107. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/framework/starlette/routing.py +0 -0
  108. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/py.typed +0 -0
  109. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/rpc/__init__.py +0 -0
  110. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/rpc/grpc/README.md +0 -0
  111. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/rpc/grpc/__init__.py +0 -0
  112. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/rpc/grpc/interceptors.py +0 -0
  113. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/server/__init__.py +0 -0
  114. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/server/aiohttp_web/README.md +0 -0
  115. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/server/aiohttp_web/__init__.py +0 -0
  116. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/server/aiohttp_web/web_app.py +0 -0
  117. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/server/aiohttp_web/web_urldispatcher.py +0 -0
  118. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/server/uvicorn/README.md +0 -0
  119. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/server/uvicorn/__init__.py +0 -0
  120. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/server/uvicorn/config.py +0 -0
  121. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/server/werkzeug_serving/README.md +0 -0
  122. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/server/werkzeug_serving/__init__.py +0 -0
  123. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/server/werkzeug_serving/serving.py +0 -0
  124. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/server/wsgiref_simple_server/README.md +0 -0
  125. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/server/wsgiref_simple_server/__init__.py +0 -0
  126. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/server/wsgiref_simple_server/simple_server.py +0 -0
  127. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/server/xmlrpc_server/README.md +0 -0
  128. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/server/xmlrpc_server/__init__.py +0 -0
  129. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/server/xmlrpc_server/server.py +0 -0
  130. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/template/__init__.py +0 -0
  131. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/template/jinja2/README.md +0 -0
  132. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation/template/jinja2/__init__.py +0 -0
  133. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation.egg-info/dependency_links.txt +0 -0
  134. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation.egg-info/not-zip-safe +0 -0
  135. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation.egg-info/requires.txt +0 -0
  136. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/src/wrapture_instrumentation.egg-info/top_level.txt +0 -0
  137. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/__init__.py +0 -0
  138. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/conftest.py +0 -0
  139. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/database/__init__.py +0 -0
  140. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/database/sqlalchemy/__init__.py +0 -0
  141. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/database/sqlalchemy/conftest.py +0 -0
  142. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/database/sqlalchemy/test_apply_remove.py +0 -0
  143. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/database/sqlalchemy/test_class.py +0 -0
  144. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/database/sqlalchemy/test_composition.py +0 -0
  145. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/database/sqlalchemy/test_recording.py +0 -0
  146. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/database/sqlalchemy/test_registration.py +0 -0
  147. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/database/sqlite3/__init__.py +0 -0
  148. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/database/sqlite3/conftest.py +0 -0
  149. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/database/sqlite3/test_apply_remove.py +0 -0
  150. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/database/sqlite3/test_class.py +0 -0
  151. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/database/sqlite3/test_recording.py +0 -0
  152. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/database/sqlite3/test_registration.py +0 -0
  153. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/__init__.py +0 -0
  154. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/aiohttp_client/__init__.py +0 -0
  155. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/aiohttp_client/conftest.py +0 -0
  156. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/aiohttp_client/test_apply_remove.py +0 -0
  157. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/aiohttp_client/test_class.py +0 -0
  158. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/aiohttp_client/test_composition.py +0 -0
  159. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/aiohttp_client/test_propagation.py +0 -0
  160. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/aiohttp_client/test_recording.py +0 -0
  161. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/aiohttp_client/test_registration.py +0 -0
  162. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/http_client/__init__.py +0 -0
  163. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/http_client/conftest.py +0 -0
  164. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/http_client/test_apply_remove.py +0 -0
  165. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/http_client/test_class.py +0 -0
  166. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/http_client/test_layering.py +0 -0
  167. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/http_client/test_recording.py +0 -0
  168. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/http_client/test_registration.py +0 -0
  169. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/httpx/__init__.py +0 -0
  170. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/httpx/conftest.py +0 -0
  171. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/httpx/test_apply_remove.py +0 -0
  172. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/httpx/test_async.py +0 -0
  173. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/httpx/test_class.py +0 -0
  174. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/httpx/test_propagation.py +0 -0
  175. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/httpx/test_recording.py +0 -0
  176. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/httpx/test_registration.py +0 -0
  177. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/requests/__init__.py +0 -0
  178. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/requests/conftest.py +0 -0
  179. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/requests/test_apply_remove.py +0 -0
  180. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/requests/test_class.py +0 -0
  181. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/requests/test_propagation.py +0 -0
  182. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/requests/test_recording.py +0 -0
  183. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/requests/test_registration.py +0 -0
  184. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/urllib3/__init__.py +0 -0
  185. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/urllib3/conftest.py +0 -0
  186. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/urllib3/test_apply_remove.py +0 -0
  187. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/urllib3/test_class.py +0 -0
  188. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/urllib3/test_composition.py +0 -0
  189. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/urllib3/test_propagation.py +0 -0
  190. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/urllib3/test_recording.py +0 -0
  191. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/urllib3/test_registration.py +0 -0
  192. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/urllib_request/__init__.py +0 -0
  193. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/urllib_request/conftest.py +0 -0
  194. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/urllib_request/test_apply_remove.py +0 -0
  195. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/urllib_request/test_class.py +0 -0
  196. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/urllib_request/test_propagation.py +0 -0
  197. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/urllib_request/test_registration.py +0 -0
  198. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/urllib_request/test_requests.py +0 -0
  199. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/xmlrpc_client/__init__.py +0 -0
  200. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/xmlrpc_client/conftest.py +0 -0
  201. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/xmlrpc_client/test_apply_remove.py +0 -0
  202. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/xmlrpc_client/test_class.py +0 -0
  203. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/xmlrpc_client/test_propagation.py +0 -0
  204. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/xmlrpc_client/test_recording.py +0 -0
  205. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/external/xmlrpc_client/test_registration.py +0 -0
  206. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/framework/__init__.py +0 -0
  207. {wrapture_instrumentation-1.0.0.dev8/tests/framework/fastapi → wrapture_instrumentation-1.0.0.dev9/tests/framework/django}/__init__.py +0 -0
  208. {wrapture_instrumentation-1.0.0.dev8/tests/framework/flask → wrapture_instrumentation-1.0.0.dev9/tests/framework/fastapi}/__init__.py +0 -0
  209. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/framework/fastapi/conftest.py +0 -0
  210. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/framework/fastapi/shop.py +0 -0
  211. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/framework/fastapi/test_apply_remove.py +0 -0
  212. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/framework/fastapi/test_class.py +0 -0
  213. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/framework/fastapi/test_composition.py +0 -0
  214. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/framework/fastapi/test_registration.py +0 -0
  215. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/framework/fastapi/test_request_options.py +0 -0
  216. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/framework/fastapi/test_tracing.py +0 -0
  217. {wrapture_instrumentation-1.0.0.dev8/tests/framework/starlette → wrapture_instrumentation-1.0.0.dev9/tests/framework/flask}/__init__.py +0 -0
  218. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/framework/flask/portal.py +0 -0
  219. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/framework/flask/shop.py +0 -0
  220. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/framework/flask/test_apply_remove.py +0 -0
  221. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/framework/flask/test_class.py +0 -0
  222. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/framework/flask/test_lifecycle.py +0 -0
  223. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/framework/flask/test_registration.py +0 -0
  224. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/framework/flask/test_request_options.py +0 -0
  225. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/framework/flask/test_tracing.py +0 -0
  226. {wrapture_instrumentation-1.0.0.dev8/tests/rpc → wrapture_instrumentation-1.0.0.dev9/tests/framework/starlette}/__init__.py +0 -0
  227. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/framework/starlette/conftest.py +0 -0
  228. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/framework/starlette/shop.py +0 -0
  229. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/framework/starlette/test_apply_remove.py +0 -0
  230. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/framework/starlette/test_class.py +0 -0
  231. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/framework/starlette/test_composition.py +0 -0
  232. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/framework/starlette/test_registration.py +0 -0
  233. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/framework/starlette/test_request_options.py +0 -0
  234. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/framework/starlette/test_tracing.py +0 -0
  235. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/httpserver.py +0 -0
  236. {wrapture_instrumentation-1.0.0.dev8/tests/rpc/grpc → wrapture_instrumentation-1.0.0.dev9/tests/rpc}/__init__.py +0 -0
  237. {wrapture_instrumentation-1.0.0.dev8/tests/server → wrapture_instrumentation-1.0.0.dev9/tests/rpc/grpc}/__init__.py +0 -0
  238. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/rpc/grpc/conftest.py +0 -0
  239. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/rpc/grpc/service.py +0 -0
  240. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/rpc/grpc/test_apply_remove.py +0 -0
  241. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/rpc/grpc/test_class.py +0 -0
  242. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/rpc/grpc/test_propagation.py +0 -0
  243. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/rpc/grpc/test_recording.py +0 -0
  244. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/rpc/grpc/test_registration.py +0 -0
  245. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/rpc/grpc/test_server.py +0 -0
  246. {wrapture_instrumentation-1.0.0.dev8/tests/server/aiohttp_web → wrapture_instrumentation-1.0.0.dev9/tests/server}/__init__.py +0 -0
  247. {wrapture_instrumentation-1.0.0.dev8/tests/server/uvicorn → wrapture_instrumentation-1.0.0.dev9/tests/server/aiohttp_web}/__init__.py +0 -0
  248. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/aiohttp_web/conftest.py +0 -0
  249. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/aiohttp_web/shop.py +0 -0
  250. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/aiohttp_web/test_apply_remove.py +0 -0
  251. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/aiohttp_web/test_class.py +0 -0
  252. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/aiohttp_web/test_composition.py +0 -0
  253. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/aiohttp_web/test_join.py +0 -0
  254. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/aiohttp_web/test_recording.py +0 -0
  255. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/aiohttp_web/test_registration.py +0 -0
  256. {wrapture_instrumentation-1.0.0.dev8/tests/server/werkzeug_serving → wrapture_instrumentation-1.0.0.dev9/tests/server/uvicorn}/__init__.py +0 -0
  257. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/uvicorn/conftest.py +0 -0
  258. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/uvicorn/test_apply_remove.py +0 -0
  259. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/uvicorn/test_class.py +0 -0
  260. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/uvicorn/test_composition.py +0 -0
  261. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/uvicorn/test_recording.py +0 -0
  262. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/uvicorn/test_registration.py +0 -0
  263. {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
  264. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/werkzeug_serving/conftest.py +0 -0
  265. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/werkzeug_serving/test_apply_remove.py +0 -0
  266. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/werkzeug_serving/test_class.py +0 -0
  267. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/werkzeug_serving/test_composition.py +0 -0
  268. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/werkzeug_serving/test_recording.py +0 -0
  269. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/werkzeug_serving/test_registration.py +0 -0
  270. {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
  271. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/wsgiref_simple_server/conftest.py +0 -0
  272. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/wsgiref_simple_server/test_apply_remove.py +0 -0
  273. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/wsgiref_simple_server/test_class.py +0 -0
  274. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/wsgiref_simple_server/test_composition.py +0 -0
  275. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/wsgiref_simple_server/test_recording.py +0 -0
  276. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/wsgiref_simple_server/test_registration.py +0 -0
  277. {wrapture_instrumentation-1.0.0.dev8/tests/template → wrapture_instrumentation-1.0.0.dev9/tests/server/xmlrpc_server}/__init__.py +0 -0
  278. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/xmlrpc_server/conftest.py +0 -0
  279. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/xmlrpc_server/test_apply_remove.py +0 -0
  280. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/xmlrpc_server/test_class.py +0 -0
  281. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/xmlrpc_server/test_join.py +0 -0
  282. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/xmlrpc_server/test_recording.py +0 -0
  283. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/server/xmlrpc_server/test_registration.py +0 -0
  284. {wrapture_instrumentation-1.0.0.dev8/tests/template/jinja2 → wrapture_instrumentation-1.0.0.dev9/tests/template}/__init__.py +0 -0
  285. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/template/jinja2/test_apply_remove.py +0 -0
  286. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/template/jinja2/test_class.py +0 -0
  287. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/template/jinja2/test_registration.py +0 -0
  288. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/template/jinja2/test_with_flask.py +0 -0
  289. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/test_asgi.py +0 -0
  290. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/test_package.py +0 -0
  291. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/test_wsgi.py +0 -0
  292. {wrapture_instrumentation-1.0.0.dev8 → wrapture_instrumentation-1.0.0.dev9}/tests/wsgi.py +0 -0
  293. {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 annotated with the
232
- template's own name; the loading pipeline
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, named by the spelling the call
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.dev8
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 (Flask first,
33
- more to follow), each registered under the bare target name, so that
34
- tracing a framework is one config entry and no code.
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/). Flask
39
- > is the first target and covers its basics; see the table below.
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`) and, in a test,
74
- through `wrapture.instrumentation("flask")` scoping the
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-2-Clause, as wrapture.
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 (Flask first,
11
- more to follow), each registered under the bare target name, so that
12
- tracing a framework is one config entry and no code.
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/). Flask
17
- > is the first target and covers its basics; see the table below.
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`) and, in a test,
52
- through `wrapture.instrumentation("flask")` scoping the
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-2-Clause, as wrapture.
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
 
@@ -22,5 +22,5 @@ def _format_version(parts: tuple[str, ...]) -> str:
22
22
  )
23
23
 
24
24
 
25
- __version_info__ = ("1", "0", "0", "dev8")
25
+ __version_info__ = ("1", "0", "0", "dev9")
26
26
  __version__ = _format_version(__version_info__)
@@ -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).