cavisson-pythonagent 0.0.1__py3-none-any.whl

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 (180) hide show
  1. cavisson_pythonagent-0.0.1.dist-info/METADATA +32 -0
  2. cavisson_pythonagent-0.0.1.dist-info/RECORD +180 -0
  3. cavisson_pythonagent-0.0.1.dist-info/WHEEL +5 -0
  4. cavisson_pythonagent-0.0.1.dist-info/licenses/LICENSE +19 -0
  5. cavisson_pythonagent-0.0.1.dist-info/top_level.txt +1 -0
  6. pythonagent/__init__.py +22 -0
  7. pythonagent/agent/__init__.py +219 -0
  8. pythonagent/agent/internal/__init__.py +1 -0
  9. pythonagent/agent/internal/agent.py +1651 -0
  10. pythonagent/agent/internal/framesinfo.py +152 -0
  11. pythonagent/agent/internal/heap_dump.py +39 -0
  12. pythonagent/agent/internal/intercept_module.py +70 -0
  13. pythonagent/agent/internal/logs.py +122 -0
  14. pythonagent/agent/internal/metadata/__init__.py +0 -0
  15. pythonagent/agent/internal/metadata/agent_meta_data.py +276 -0
  16. pythonagent/agent/internal/proc_compat.py +75 -0
  17. pythonagent/agent/internal/profile.py +47 -0
  18. pythonagent/agent/internal/provider.py +83 -0
  19. pythonagent/agent/internal/thread_dump.py +85 -0
  20. pythonagent/agent/internal/udp.py +245 -0
  21. pythonagent/agent/internal/udp_message.py +800 -0
  22. pythonagent/agent/probes/Instrumentation/__init__.py +340 -0
  23. pythonagent/agent/probes/Instrumentation/find.py +243 -0
  24. pythonagent/agent/probes/Instrumentation/module_version_resolver.py +155 -0
  25. pythonagent/agent/probes/Instrumentation/new_parser.py +64 -0
  26. pythonagent/agent/probes/Instrumentation/parser.py +129 -0
  27. pythonagent/agent/probes/__init__.py +219 -0
  28. pythonagent/agent/probes/base.py +303 -0
  29. pythonagent/agent/probes/cache/__init__.py +51 -0
  30. pythonagent/agent/probes/cache/redis.py +119 -0
  31. pythonagent/agent/probes/cache/redis_asyncio.py +83 -0
  32. pythonagent/agent/probes/coroutines/__init__.py +1 -0
  33. pythonagent/agent/probes/coroutines/asyncio.py +63 -0
  34. pythonagent/agent/probes/elasticdb/__init__.py +7 -0
  35. pythonagent/agent/probes/elasticdb/aelastic.py +54 -0
  36. pythonagent/agent/probes/frameworks/__init__.py +27 -0
  37. pythonagent/agent/probes/frameworks/agentprofiler.py +105 -0
  38. pythonagent/agent/probes/frameworks/aiohttp_web.py +155 -0
  39. pythonagent/agent/probes/frameworks/aisess.py +151 -0
  40. pythonagent/agent/probes/frameworks/asgi.py +340 -0
  41. pythonagent/agent/probes/frameworks/bottle.py +27 -0
  42. pythonagent/agent/probes/frameworks/cherry.py +25 -0
  43. pythonagent/agent/probes/frameworks/django.py +128 -0
  44. pythonagent/agent/probes/frameworks/falcon.py +21 -0
  45. pythonagent/agent/probes/frameworks/fastapi.py +35 -0
  46. pythonagent/agent/probes/frameworks/flask.py +30 -0
  47. pythonagent/agent/probes/frameworks/pyramid.py +56 -0
  48. pythonagent/agent/probes/frameworks/test.py +108 -0
  49. pythonagent/agent/probes/frameworks/tornado_async_web.py +117 -0
  50. pythonagent/agent/probes/frameworks/tornado_web.py +133 -0
  51. pythonagent/agent/probes/frameworks/wsgi.py +353 -0
  52. pythonagent/agent/probes/grpc/__init__.py +76 -0
  53. pythonagent/agent/probes/grpc/client_interceptor.py +132 -0
  54. pythonagent/agent/probes/grpc/server_interceptor.py +129 -0
  55. pythonagent/agent/probes/havoc/__init__.py +0 -0
  56. pythonagent/agent/probes/havoc/custom_memory_stress.py +186 -0
  57. pythonagent/agent/probes/havoc/custom_thread_stress.py +187 -0
  58. pythonagent/agent/probes/havoc/havoc_constants.py +218 -0
  59. pythonagent/agent/probes/havoc/havoc_manager.py +981 -0
  60. pythonagent/agent/probes/http/__init__.py +49 -0
  61. pythonagent/agent/probes/http/aiohttp_client.py +59 -0
  62. pythonagent/agent/probes/http/boto.py +12 -0
  63. pythonagent/agent/probes/http/httplib.py +110 -0
  64. pythonagent/agent/probes/http/httpx_client.py +116 -0
  65. pythonagent/agent/probes/http/requests.py +15 -0
  66. pythonagent/agent/probes/http/tornado_httpclient.py +85 -0
  67. pythonagent/agent/probes/http/urllib3.py +16 -0
  68. pythonagent/agent/probes/langchain/__init__.py +21 -0
  69. pythonagent/agent/probes/langchain/base_tool.py +95 -0
  70. pythonagent/agent/probes/langchain/langchain_community.py +136 -0
  71. pythonagent/agent/probes/langchain/langchain_core.py +32 -0
  72. pythonagent/agent/probes/langchain/langchain_openai.py +110 -0
  73. pythonagent/agent/probes/logging/__init__.py +106 -0
  74. pythonagent/agent/probes/message_brokers/__init__.py +4 -0
  75. pythonagent/agent/probes/message_brokers/pika.py +126 -0
  76. pythonagent/agent/probes/mongodb/__init__.py +6 -0
  77. pythonagent/agent/probes/mongodb/pymongo.py +286 -0
  78. pythonagent/agent/probes/openai/__init__.py +3 -0
  79. pythonagent/agent/probes/openai/openai.py +797 -0
  80. pythonagent/agent/probes/span.py +101 -0
  81. pythonagent/agent/probes/sql/__init__.py +13 -0
  82. pythonagent/agent/probes/sql/botocores3.py +51 -0
  83. pythonagent/agent/probes/sql/dbapi.py +285 -0
  84. pythonagent/agent/probes/sql/dynamodb.py +90 -0
  85. pythonagent/agent/probes/sql/mysql_connector.py +24 -0
  86. pythonagent/agent/probes/sql/mysql_connector_cext.py +24 -0
  87. pythonagent/agent/probes/sql/mysqldb.py +43 -0
  88. pythonagent/agent/probes/sql/psycopg2.py +174 -0
  89. pythonagent/agent/probes/sql/pymysql.py +25 -0
  90. pythonagent/bootstrap/__init__.py +0 -0
  91. pythonagent/bootstrap/cav_gunicorn.py +26 -0
  92. pythonagent/bootstrap/cavagent_lambda_wrapper.py +291 -0
  93. pythonagent/bootstrap/run.py +47 -0
  94. pythonagent/bootstrap/sitecustomize.py +287 -0
  95. pythonagent/cavisson/netdiagnostics/CavAgent/instrumentationprofile.json +26 -0
  96. pythonagent/cavisson/netdiagnostics/CavAgent/interceptor_points.txt +29 -0
  97. pythonagent/cavisson/netdiagnostics/python/CavAgent/instrumentationprofile.json +42 -0
  98. pythonagent/cavisson/netdiagnostics/python/CavAgent/interceptor_points.txt +29 -0
  99. pythonagent/cavisson/netdiagnostics/python/config/ndsettings.conf +6 -0
  100. pythonagent/config.py +279 -0
  101. pythonagent/find.py +72 -0
  102. pythonagent/find_mod_cls_name.py +54 -0
  103. pythonagent/lang.py +131 -0
  104. pythonagent/lib.py +91 -0
  105. pythonagent/main/__init__.py +0 -0
  106. pythonagent/main/pytrace/__init__.py +79 -0
  107. pythonagent/main/pytrace/commands/__init__.py +0 -0
  108. pythonagent/main/pytrace/commands/auto_discovery.py +25 -0
  109. pythonagent/main/pytrace/commands/run.py +401 -0
  110. pythonagent/main/pytrace/pytrace.py +133 -0
  111. pythonagent/main/wsgi.py +6 -0
  112. pythonagent/main.py +27 -0
  113. pythonagent/run.py +46 -0
  114. pythonagent/sqins.py +8 -0
  115. pythonagent/test.py +73 -0
  116. pythonagent/utils.py +168 -0
  117. pythonagent/vendor/__init__.py +0 -0
  118. pythonagent/vendor/pympler/__init__.py +1 -0
  119. pythonagent/vendor/pympler/asizeof.py +2810 -0
  120. pythonagent/vendor/pympler/charts.py +62 -0
  121. pythonagent/vendor/pympler/classtracker.py +590 -0
  122. pythonagent/vendor/pympler/classtracker_stats.py +780 -0
  123. pythonagent/vendor/pympler/garbagegraph.py +80 -0
  124. pythonagent/vendor/pympler/mprofile.py +97 -0
  125. pythonagent/vendor/pympler/muppy.py +275 -0
  126. pythonagent/vendor/pympler/panels.py +115 -0
  127. pythonagent/vendor/pympler/process.py +238 -0
  128. pythonagent/vendor/pympler/py.typed +0 -0
  129. pythonagent/vendor/pympler/refbrowser.py +451 -0
  130. pythonagent/vendor/pympler/refgraph.py +350 -0
  131. pythonagent/vendor/pympler/summary.py +321 -0
  132. pythonagent/vendor/pympler/tracker.py +267 -0
  133. pythonagent/vendor/pympler/util/__init__.py +0 -0
  134. pythonagent/vendor/pympler/util/bottle.py +3809 -0
  135. pythonagent/vendor/pympler/util/compat.py +23 -0
  136. pythonagent/vendor/pympler/util/stringutils.py +77 -0
  137. pythonagent/vendor/pympler/web.py +346 -0
  138. pythonagent/vendor/werkzeug/__init__.py +20 -0
  139. pythonagent/vendor/werkzeug/_compat.py +228 -0
  140. pythonagent/vendor/werkzeug/_internal.py +473 -0
  141. pythonagent/vendor/werkzeug/_reloader.py +341 -0
  142. pythonagent/vendor/werkzeug/datastructures.py +3120 -0
  143. pythonagent/vendor/werkzeug/debug/__init__.py +498 -0
  144. pythonagent/vendor/werkzeug/debug/console.py +218 -0
  145. pythonagent/vendor/werkzeug/debug/repr.py +297 -0
  146. pythonagent/vendor/werkzeug/debug/tbtools.py +628 -0
  147. pythonagent/vendor/werkzeug/exceptions.py +829 -0
  148. pythonagent/vendor/werkzeug/filesystem.py +64 -0
  149. pythonagent/vendor/werkzeug/formparser.py +584 -0
  150. pythonagent/vendor/werkzeug/http.py +1307 -0
  151. pythonagent/vendor/werkzeug/local.py +420 -0
  152. pythonagent/vendor/werkzeug/middleware/__init__.py +25 -0
  153. pythonagent/vendor/werkzeug/middleware/dispatcher.py +66 -0
  154. pythonagent/vendor/werkzeug/middleware/http_proxy.py +219 -0
  155. pythonagent/vendor/werkzeug/middleware/lint.py +408 -0
  156. pythonagent/vendor/werkzeug/middleware/profiler.py +132 -0
  157. pythonagent/vendor/werkzeug/middleware/proxy_fix.py +169 -0
  158. pythonagent/vendor/werkzeug/middleware/shared_data.py +293 -0
  159. pythonagent/vendor/werkzeug/posixemulation.py +117 -0
  160. pythonagent/vendor/werkzeug/routing.py +2210 -0
  161. pythonagent/vendor/werkzeug/security.py +249 -0
  162. pythonagent/vendor/werkzeug/serving.py +1117 -0
  163. pythonagent/vendor/werkzeug/test.py +1123 -0
  164. pythonagent/vendor/werkzeug/testapp.py +241 -0
  165. pythonagent/vendor/werkzeug/urls.py +1138 -0
  166. pythonagent/vendor/werkzeug/useragents.py +202 -0
  167. pythonagent/vendor/werkzeug/utils.py +778 -0
  168. pythonagent/vendor/werkzeug/wrappers/__init__.py +36 -0
  169. pythonagent/vendor/werkzeug/wrappers/accept.py +50 -0
  170. pythonagent/vendor/werkzeug/wrappers/auth.py +33 -0
  171. pythonagent/vendor/werkzeug/wrappers/base_request.py +673 -0
  172. pythonagent/vendor/werkzeug/wrappers/base_response.py +700 -0
  173. pythonagent/vendor/werkzeug/wrappers/common_descriptors.py +341 -0
  174. pythonagent/vendor/werkzeug/wrappers/cors.py +100 -0
  175. pythonagent/vendor/werkzeug/wrappers/etag.py +304 -0
  176. pythonagent/vendor/werkzeug/wrappers/json.py +145 -0
  177. pythonagent/vendor/werkzeug/wrappers/request.py +49 -0
  178. pythonagent/vendor/werkzeug/wrappers/response.py +84 -0
  179. pythonagent/vendor/werkzeug/wrappers/user_agent.py +14 -0
  180. pythonagent/vendor/werkzeug/wsgi.py +1000 -0
@@ -0,0 +1,420 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ werkzeug.local
4
+ ~~~~~~~~~~~~~~
5
+
6
+ This module implements context-local objects.
7
+
8
+ :copyright: 2007 Pallets
9
+ :license: BSD-3-Clause
10
+ """
11
+ import copy
12
+ from functools import update_wrapper
13
+
14
+ from ._compat import implements_bool
15
+ from ._compat import PY2
16
+ from .wsgi import ClosingIterator
17
+
18
+ # since each thread has its own greenlet we can just use those as identifiers
19
+ # for the context. If greenlets are not available we fall back to the
20
+ # current thread ident depending on where it is.
21
+ try:
22
+ from greenlet import getcurrent as get_ident
23
+ except ImportError:
24
+ try:
25
+ from thread import get_ident
26
+ except ImportError:
27
+ from _thread import get_ident
28
+
29
+
30
+ def release_local(local):
31
+ """Releases the contents of the local for the current context.
32
+ This makes it possible to use locals without a manager.
33
+
34
+ Example::
35
+
36
+ >>> loc = Local()
37
+ >>> loc.foo = 42
38
+ >>> release_local(loc)
39
+ >>> hasattr(loc, 'foo')
40
+ False
41
+
42
+ With this function one can release :class:`Local` objects as well
43
+ as :class:`LocalStack` objects. However it is not possible to
44
+ release data held by proxies that way, one always has to retain
45
+ a reference to the underlying local object in order to be able
46
+ to release it.
47
+
48
+ .. versionadded:: 0.6.1
49
+ """
50
+ local.__release_local__()
51
+
52
+
53
+ class Local(object):
54
+ __slots__ = ("__storage__", "__ident_func__")
55
+
56
+ def __init__(self):
57
+ object.__setattr__(self, "__storage__", {})
58
+ object.__setattr__(self, "__ident_func__", get_ident)
59
+
60
+ def __iter__(self):
61
+ return iter(self.__storage__.items())
62
+
63
+ def __call__(self, proxy):
64
+ """Create a proxy for a name."""
65
+ return LocalProxy(self, proxy)
66
+
67
+ def __release_local__(self):
68
+ self.__storage__.pop(self.__ident_func__(), None)
69
+
70
+ def __getattr__(self, name):
71
+ try:
72
+ return self.__storage__[self.__ident_func__()][name]
73
+ except KeyError:
74
+ raise AttributeError(name)
75
+
76
+ def __setattr__(self, name, value):
77
+ ident = self.__ident_func__()
78
+ storage = self.__storage__
79
+ try:
80
+ storage[ident][name] = value
81
+ except KeyError:
82
+ storage[ident] = {name: value}
83
+
84
+ def __delattr__(self, name):
85
+ try:
86
+ del self.__storage__[self.__ident_func__()][name]
87
+ except KeyError:
88
+ raise AttributeError(name)
89
+
90
+
91
+ class LocalStack(object):
92
+ """This class works similar to a :class:`Local` but keeps a stack
93
+ of objects instead. This is best explained with an example::
94
+
95
+ >>> ls = LocalStack()
96
+ >>> ls.push(42)
97
+ >>> ls.top
98
+ 42
99
+ >>> ls.push(23)
100
+ >>> ls.top
101
+ 23
102
+ >>> ls.pop()
103
+ 23
104
+ >>> ls.top
105
+ 42
106
+
107
+ They can be force released by using a :class:`LocalManager` or with
108
+ the :func:`release_local` function but the correct way is to pop the
109
+ item from the stack after using. When the stack is empty it will
110
+ no longer be bound to the current context (and as such released).
111
+
112
+ By calling the stack without arguments it returns a proxy that resolves to
113
+ the topmost item on the stack.
114
+
115
+ .. versionadded:: 0.6.1
116
+ """
117
+
118
+ def __init__(self):
119
+ self._local = Local()
120
+
121
+ def __release_local__(self):
122
+ self._local.__release_local__()
123
+
124
+ @property
125
+ def __ident_func__(self):
126
+ return self._local.__ident_func__
127
+
128
+ @__ident_func__.setter
129
+ def __ident_func__(self, value):
130
+ object.__setattr__(self._local, "__ident_func__", value)
131
+
132
+ def __call__(self):
133
+ def _lookup():
134
+ rv = self.top
135
+ if rv is None:
136
+ raise RuntimeError("object unbound")
137
+ return rv
138
+
139
+ return LocalProxy(_lookup)
140
+
141
+ def push(self, obj):
142
+ """Pushes a new item to the stack"""
143
+ rv = getattr(self._local, "stack", None)
144
+ if rv is None:
145
+ self._local.stack = rv = []
146
+ rv.append(obj)
147
+ return rv
148
+
149
+ def pop(self):
150
+ """Removes the topmost item from the stack, will return the
151
+ old value or `None` if the stack was already empty.
152
+ """
153
+ stack = getattr(self._local, "stack", None)
154
+ if stack is None:
155
+ return None
156
+ elif len(stack) == 1:
157
+ release_local(self._local)
158
+ return stack[-1]
159
+ else:
160
+ return stack.pop()
161
+
162
+ @property
163
+ def top(self):
164
+ """The topmost item on the stack. If the stack is empty,
165
+ `None` is returned.
166
+ """
167
+ try:
168
+ return self._local.stack[-1]
169
+ except (AttributeError, IndexError):
170
+ return None
171
+
172
+
173
+ class LocalManager(object):
174
+ """Local objects cannot manage themselves. For that you need a local
175
+ manager. You can pass a local manager multiple locals or add them later
176
+ by appending them to `manager.locals`. Every time the manager cleans up,
177
+ it will clean up all the data left in the locals for this context.
178
+
179
+ The `ident_func` parameter can be added to override the default ident
180
+ function for the wrapped locals.
181
+
182
+ .. versionchanged:: 0.6.1
183
+ Instead of a manager the :func:`release_local` function can be used
184
+ as well.
185
+
186
+ .. versionchanged:: 0.7
187
+ `ident_func` was added.
188
+ """
189
+
190
+ def __init__(self, locals=None, ident_func=None):
191
+ if locals is None:
192
+ self.locals = []
193
+ elif isinstance(locals, Local):
194
+ self.locals = [locals]
195
+ else:
196
+ self.locals = list(locals)
197
+ if ident_func is not None:
198
+ self.ident_func = ident_func
199
+ for local in self.locals:
200
+ object.__setattr__(local, "__ident_func__", ident_func)
201
+ else:
202
+ self.ident_func = get_ident
203
+
204
+ def get_ident(self):
205
+ """Return the context identifier the local objects use internally for
206
+ this context. You cannot override this method to change the behavior
207
+ but use it to link other context local objects (such as SQLAlchemy's
208
+ scoped sessions) to the Werkzeug locals.
209
+
210
+ .. versionchanged:: 0.7
211
+ You can pass a different ident function to the local manager that
212
+ will then be propagated to all the locals passed to the
213
+ constructor.
214
+ """
215
+ return self.ident_func()
216
+
217
+ def cleanup(self):
218
+ """Manually clean up the data in the locals for this context. Call
219
+ this at the end of the request or use `make_middleware()`.
220
+ """
221
+ for local in self.locals:
222
+ release_local(local)
223
+
224
+ def make_middleware(self, app):
225
+ """Wrap a WSGI application so that cleaning up happens after
226
+ request end.
227
+ """
228
+
229
+ def application(environ, start_response):
230
+ return ClosingIterator(app(environ, start_response), self.cleanup)
231
+
232
+ return application
233
+
234
+ def middleware(self, func):
235
+ """Like `make_middleware` but for decorating functions.
236
+
237
+ Example usage::
238
+
239
+ @manager.middleware
240
+ def application(environ, start_response):
241
+ ...
242
+
243
+ The difference to `make_middleware` is that the function passed
244
+ will have all the arguments copied from the inner application
245
+ (name, docstring, module).
246
+ """
247
+ return update_wrapper(self.make_middleware(func), func)
248
+
249
+ def __repr__(self):
250
+ return "<%s storages: %d>" % (self.__class__.__name__, len(self.locals))
251
+
252
+
253
+ @implements_bool
254
+ class LocalProxy(object):
255
+ """Acts as a proxy for a werkzeug local. Forwards all operations to
256
+ a proxied object. The only operations not supported for forwarding
257
+ are right handed operands and any kind of assignment.
258
+
259
+ Example usage::
260
+
261
+ from pythonagent.vendor.werkzeug.local import Local
262
+ l = Local()
263
+
264
+ # these are proxies
265
+ request = l('request')
266
+ user = l('user')
267
+
268
+
269
+ from pythonagent.vendor.werkzeug.local import LocalStack
270
+ _response_local = LocalStack()
271
+
272
+ # this is a proxy
273
+ response = _response_local()
274
+
275
+ Whenever something is bound to l.user / l.request the proxy objects
276
+ will forward all operations. If no object is bound a :exc:`RuntimeError`
277
+ will be raised.
278
+
279
+ To create proxies to :class:`Local` or :class:`LocalStack` objects,
280
+ call the object as shown above. If you want to have a proxy to an
281
+ object looked up by a function, you can (as of Werkzeug 0.6.1) pass
282
+ a function to the :class:`LocalProxy` constructor::
283
+
284
+ session = LocalProxy(lambda: get_current_request().session)
285
+
286
+ .. versionchanged:: 0.6.1
287
+ The class can be instantiated with a callable as well now.
288
+ """
289
+
290
+ __slots__ = ("__local", "__dict__", "__name__", "__wrapped__")
291
+
292
+ def __init__(self, local, name=None):
293
+ object.__setattr__(self, "_LocalProxy__local", local)
294
+ object.__setattr__(self, "__name__", name)
295
+ if callable(local) and not hasattr(local, "__release_local__"):
296
+ # "local" is a callable that is not an instance of Local or
297
+ # LocalManager: mark it as a wrapped function.
298
+ object.__setattr__(self, "__wrapped__", local)
299
+
300
+ def _get_current_object(self):
301
+ """Return the current object. This is useful if you want the real
302
+ object behind the proxy at a time for performance reasons or because
303
+ you want to pass the object into a different context.
304
+ """
305
+ if not hasattr(self.__local, "__release_local__"):
306
+ return self.__local()
307
+ try:
308
+ return getattr(self.__local, self.__name__)
309
+ except AttributeError:
310
+ raise RuntimeError("no object bound to %s" % self.__name__)
311
+
312
+ @property
313
+ def __dict__(self):
314
+ try:
315
+ return self._get_current_object().__dict__
316
+ except RuntimeError:
317
+ raise AttributeError("__dict__")
318
+
319
+ def __repr__(self):
320
+ try:
321
+ obj = self._get_current_object()
322
+ except RuntimeError:
323
+ return "<%s unbound>" % self.__class__.__name__
324
+ return repr(obj)
325
+
326
+ def __bool__(self):
327
+ try:
328
+ return bool(self._get_current_object())
329
+ except RuntimeError:
330
+ return False
331
+
332
+ def __unicode__(self):
333
+ try:
334
+ return unicode(self._get_current_object()) # noqa
335
+ except RuntimeError:
336
+ return repr(self)
337
+
338
+ def __dir__(self):
339
+ try:
340
+ return dir(self._get_current_object())
341
+ except RuntimeError:
342
+ return []
343
+
344
+ def __getattr__(self, name):
345
+ if name == "__members__":
346
+ return dir(self._get_current_object())
347
+ return getattr(self._get_current_object(), name)
348
+
349
+ def __setitem__(self, key, value):
350
+ self._get_current_object()[key] = value
351
+
352
+ def __delitem__(self, key):
353
+ del self._get_current_object()[key]
354
+
355
+ if PY2:
356
+ __getslice__ = lambda x, i, j: x._get_current_object()[i:j]
357
+
358
+ def __setslice__(self, i, j, seq):
359
+ self._get_current_object()[i:j] = seq
360
+
361
+ def __delslice__(self, i, j):
362
+ del self._get_current_object()[i:j]
363
+
364
+ __setattr__ = lambda x, n, v: setattr(x._get_current_object(), n, v)
365
+ __delattr__ = lambda x, n: delattr(x._get_current_object(), n)
366
+ __str__ = lambda x: str(x._get_current_object())
367
+ __lt__ = lambda x, o: x._get_current_object() < o
368
+ __le__ = lambda x, o: x._get_current_object() <= o
369
+ __eq__ = lambda x, o: x._get_current_object() == o
370
+ __ne__ = lambda x, o: x._get_current_object() != o
371
+ __gt__ = lambda x, o: x._get_current_object() > o
372
+ __ge__ = lambda x, o: x._get_current_object() >= o
373
+ __cmp__ = lambda x, o: cmp(x._get_current_object(), o) # noqa
374
+ __hash__ = lambda x: hash(x._get_current_object())
375
+ __call__ = lambda x, *a, **kw: x._get_current_object()(*a, **kw)
376
+ __len__ = lambda x: len(x._get_current_object())
377
+ __getitem__ = lambda x, i: x._get_current_object()[i]
378
+ __iter__ = lambda x: iter(x._get_current_object())
379
+ __contains__ = lambda x, i: i in x._get_current_object()
380
+ __add__ = lambda x, o: x._get_current_object() + o
381
+ __sub__ = lambda x, o: x._get_current_object() - o
382
+ __mul__ = lambda x, o: x._get_current_object() * o
383
+ __floordiv__ = lambda x, o: x._get_current_object() // o
384
+ __mod__ = lambda x, o: x._get_current_object() % o
385
+ __divmod__ = lambda x, o: x._get_current_object().__divmod__(o)
386
+ __pow__ = lambda x, o: x._get_current_object() ** o
387
+ __lshift__ = lambda x, o: x._get_current_object() << o
388
+ __rshift__ = lambda x, o: x._get_current_object() >> o
389
+ __and__ = lambda x, o: x._get_current_object() & o
390
+ __xor__ = lambda x, o: x._get_current_object() ^ o
391
+ __or__ = lambda x, o: x._get_current_object() | o
392
+ __div__ = lambda x, o: x._get_current_object().__div__(o)
393
+ __truediv__ = lambda x, o: x._get_current_object().__truediv__(o)
394
+ __neg__ = lambda x: -(x._get_current_object())
395
+ __pos__ = lambda x: +(x._get_current_object())
396
+ __abs__ = lambda x: abs(x._get_current_object())
397
+ __invert__ = lambda x: ~(x._get_current_object())
398
+ __complex__ = lambda x: complex(x._get_current_object())
399
+ __int__ = lambda x: int(x._get_current_object())
400
+ __long__ = lambda x: long(x._get_current_object()) # noqa
401
+ __float__ = lambda x: float(x._get_current_object())
402
+ __oct__ = lambda x: oct(x._get_current_object())
403
+ __hex__ = lambda x: hex(x._get_current_object())
404
+ __index__ = lambda x: x._get_current_object().__index__()
405
+ __coerce__ = lambda x, o: x._get_current_object().__coerce__(x, o)
406
+ __enter__ = lambda x: x._get_current_object().__enter__()
407
+ __exit__ = lambda x, *a, **kw: x._get_current_object().__exit__(*a, **kw)
408
+ __radd__ = lambda x, o: o + x._get_current_object()
409
+ __rsub__ = lambda x, o: o - x._get_current_object()
410
+ __rmul__ = lambda x, o: o * x._get_current_object()
411
+ __rdiv__ = lambda x, o: o / x._get_current_object()
412
+ if PY2:
413
+ __rtruediv__ = lambda x, o: x._get_current_object().__rtruediv__(o)
414
+ else:
415
+ __rtruediv__ = __rdiv__
416
+ __rfloordiv__ = lambda x, o: o // x._get_current_object()
417
+ __rmod__ = lambda x, o: o % x._get_current_object()
418
+ __rdivmod__ = lambda x, o: x._get_current_object().__rdivmod__(o)
419
+ __copy__ = lambda x: copy.copy(x._get_current_object())
420
+ __deepcopy__ = lambda x, memo: copy.deepcopy(x._get_current_object(), memo)
@@ -0,0 +1,25 @@
1
+ """
2
+ Middleware
3
+ ==========
4
+
5
+ A WSGI middleware is a WSGI application that wraps another application
6
+ in order to observe or change its behavior. Werkzeug provides some
7
+ middleware for common use cases.
8
+
9
+ .. toctree::
10
+ :maxdepth: 1
11
+
12
+ proxy_fix
13
+ shared_data
14
+ dispatcher
15
+ http_proxy
16
+ lint
17
+ profiler
18
+
19
+ The :doc:`interactive debugger </debug>` is also a middleware that can
20
+ be applied manually, although it is typically used automatically with
21
+ the :doc:`development server </serving>`.
22
+
23
+ :copyright: 2007 Pallets
24
+ :license: BSD-3-Clause
25
+ """
@@ -0,0 +1,66 @@
1
+ """
2
+ Application Dispatcher
3
+ ======================
4
+
5
+ This middleware creates a single WSGI application that dispatches to
6
+ multiple other WSGI applications mounted at different URL paths.
7
+
8
+ A common example is writing a Single Page Application, where you have a
9
+ backend API and a frontend written in JavaScript that does the routing
10
+ in the browser rather than requesting different pages from the server.
11
+ The frontend is a single HTML and JS file that should be served for any
12
+ path besides "/api".
13
+
14
+ This example dispatches to an API app under "/api", an admin app
15
+ under "/admin", and an app that serves frontend files for all other
16
+ requests::
17
+
18
+ app = DispatcherMiddleware(serve_frontend, {
19
+ '/api': api_app,
20
+ '/admin': admin_app,
21
+ })
22
+
23
+ In production, you might instead handle this at the HTTP server level,
24
+ serving files or proxying to application servers based on location. The
25
+ API and admin apps would each be deployed with a separate WSGI server,
26
+ and the static files would be served directly by the HTTP server.
27
+
28
+ .. autoclass:: DispatcherMiddleware
29
+
30
+ :copyright: 2007 Pallets
31
+ :license: BSD-3-Clause
32
+ """
33
+
34
+
35
+ class DispatcherMiddleware(object):
36
+ """Combine multiple applications as a single WSGI application.
37
+ Requests are dispatched to an application based on the path it is
38
+ mounted under.
39
+
40
+ :param app: The WSGI application to dispatch to if the request
41
+ doesn't match a mounted path.
42
+ :param mounts: Maps path prefixes to applications for dispatching.
43
+ """
44
+
45
+ def __init__(self, app, mounts=None):
46
+ self.app = app
47
+ self.mounts = mounts or {}
48
+
49
+ def __call__(self, environ, start_response):
50
+ script = environ.get("PATH_INFO", "")
51
+ path_info = ""
52
+
53
+ while "/" in script:
54
+ if script in self.mounts:
55
+ app = self.mounts[script]
56
+ break
57
+
58
+ script, last_item = script.rsplit("/", 1)
59
+ path_info = "/%s%s" % (last_item, path_info)
60
+ else:
61
+ app = self.mounts.get(script, self.app)
62
+
63
+ original_script_name = environ.get("SCRIPT_NAME", "")
64
+ environ["SCRIPT_NAME"] = original_script_name + script
65
+ environ["PATH_INFO"] = path_info
66
+ return app(environ, start_response)