137
137
---
138
138
"""
139
139
140
+ from __future__ import annotations
141
+
140
142
import logging
141
- import typing
142
- from typing import Collection
143
+ from typing import Any , Callable , Collection , TypeVar
143
144
144
145
import psycopg # pylint: disable=import-self
145
- from psycopg import (
146
- AsyncCursor as pg_async_cursor , # pylint: disable=import-self,no-name-in-module
147
- )
148
- from psycopg import (
149
- Cursor as pg_cursor , # pylint: disable=no-name-in-module,import-self
150
- )
151
146
from psycopg .sql import Composed # pylint: disable=no-name-in-module
152
147
153
148
from opentelemetry .instrumentation import dbapi
154
149
from opentelemetry .instrumentation .instrumentor import BaseInstrumentor
155
150
from opentelemetry .instrumentation .psycopg .package import _instruments
156
151
from opentelemetry .instrumentation .psycopg .version import __version__
152
+ from opentelemetry .trace import TracerProvider
157
153
158
154
_logger = logging .getLogger (__name__ )
159
155
_OTEL_CURSOR_FACTORY_KEY = "_otel_orig_cursor_factory"
160
156
157
+ ConnectionT = TypeVar (
158
+ "ConnectionT" , psycopg .Connection , psycopg .AsyncConnection
159
+ )
160
+ CursorT = TypeVar ("CursorT" , psycopg .Cursor , psycopg .AsyncCursor )
161
+
161
162
162
163
class PsycopgInstrumentor (BaseInstrumentor ):
163
164
_CONNECTION_ATTRIBUTES = {
@@ -172,7 +173,7 @@ class PsycopgInstrumentor(BaseInstrumentor):
172
173
def instrumentation_dependencies (self ) -> Collection [str ]:
173
174
return _instruments
174
175
175
- def _instrument (self , ** kwargs ):
176
+ def _instrument (self , ** kwargs : Any ):
176
177
"""Integrate with PostgreSQL Psycopg library.
177
178
Psycopg: http://initd.org/psycopg/
178
179
"""
@@ -223,7 +224,7 @@ def _instrument(self, **kwargs):
223
224
enable_attribute_commenter = enable_attribute_commenter ,
224
225
)
225
226
226
- def _uninstrument (self , ** kwargs ):
227
+ def _uninstrument (self , ** kwargs : Any ):
227
228
""" "Disable Psycopg instrumentation"""
228
229
dbapi .unwrap_connect (psycopg , "connect" ) # pylint: disable=no-member
229
230
dbapi .unwrap_connect (
@@ -237,7 +238,9 @@ def _uninstrument(self, **kwargs):
237
238
238
239
# TODO(owais): check if core dbapi can do this for all dbapi implementations e.g, pymysql and mysql
239
240
@staticmethod
240
- def instrument_connection (connection , tracer_provider = None ):
241
+ def instrument_connection (
242
+ connection : ConnectionT , tracer_provider : TracerProvider | None = None
243
+ ) -> ConnectionT :
241
244
"""Enable instrumentation in a psycopg connection.
242
245
243
246
Args:
@@ -269,7 +272,7 @@ def instrument_connection(connection, tracer_provider=None):
269
272
270
273
# TODO(owais): check if core dbapi can do this for all dbapi implementations e.g, pymysql and mysql
271
274
@staticmethod
272
- def uninstrument_connection (connection ) :
275
+ def uninstrument_connection (connection : ConnectionT ) -> ConnectionT :
273
276
connection .cursor_factory = getattr (
274
277
connection , _OTEL_CURSOR_FACTORY_KEY , None
275
278
)
@@ -281,9 +284,9 @@ def uninstrument_connection(connection):
281
284
class DatabaseApiIntegration (dbapi .DatabaseApiIntegration ):
282
285
def wrapped_connection (
283
286
self ,
284
- connect_method : typing . Callable [..., typing . Any ],
285
- args : typing . Tuple [ typing . Any , typing . Any ],
286
- kwargs : typing . Dict [ typing . Any , typing . Any ],
287
+ connect_method : Callable [..., Any ],
288
+ args : tuple [ Any , Any ],
289
+ kwargs : dict [ Any , Any ],
287
290
):
288
291
"""Add object proxy to connection object."""
289
292
base_cursor_factory = kwargs .pop ("cursor_factory" , None )
@@ -299,9 +302,9 @@ def wrapped_connection(
299
302
class DatabaseApiAsyncIntegration (dbapi .DatabaseApiIntegration ):
300
303
async def wrapped_connection (
301
304
self ,
302
- connect_method : typing . Callable [..., typing . Any ],
303
- args : typing . Tuple [ typing . Any , typing . Any ],
304
- kwargs : typing . Dict [ typing . Any , typing . Any ],
305
+ connect_method : Callable [..., Any ],
306
+ args : tuple [ Any , Any ],
307
+ kwargs : dict [ Any , Any ],
305
308
):
306
309
"""Add object proxy to connection object."""
307
310
base_cursor_factory = kwargs .pop ("cursor_factory" , None )
@@ -317,7 +320,7 @@ async def wrapped_connection(
317
320
318
321
319
322
class CursorTracer (dbapi .CursorTracer ):
320
- def get_operation_name (self , cursor , args ) :
323
+ def get_operation_name (self , cursor : CursorT , args : list [ Any ]) -> str :
321
324
if not args :
322
325
return ""
323
326
@@ -332,7 +335,7 @@ def get_operation_name(self, cursor, args):
332
335
333
336
return ""
334
337
335
- def get_statement (self , cursor , args ) :
338
+ def get_statement (self , cursor : CursorT , args : list [ Any ]) -> str :
336
339
if not args :
337
340
return ""
338
341
@@ -342,7 +345,11 @@ def get_statement(self, cursor, args):
342
345
return statement
343
346
344
347
345
- def _new_cursor_factory (db_api = None , base_factory = None , tracer_provider = None ):
348
+ def _new_cursor_factory (
349
+ db_api : DatabaseApiIntegration | None = None ,
350
+ base_factory : type [psycopg .Cursor ] | None = None ,
351
+ tracer_provider : TracerProvider | None = None ,
352
+ ):
346
353
if not db_api :
347
354
db_api = DatabaseApiIntegration (
348
355
__name__ ,
@@ -352,21 +359,21 @@ def _new_cursor_factory(db_api=None, base_factory=None, tracer_provider=None):
352
359
tracer_provider = tracer_provider ,
353
360
)
354
361
355
- base_factory = base_factory or pg_cursor
362
+ base_factory = base_factory or psycopg . Cursor
356
363
_cursor_tracer = CursorTracer (db_api )
357
364
358
365
class TracedCursorFactory (base_factory ):
359
- def execute (self , * args , ** kwargs ):
366
+ def execute (self , * args : Any , ** kwargs : Any ):
360
367
return _cursor_tracer .traced_execution (
361
368
self , super ().execute , * args , ** kwargs
362
369
)
363
370
364
- def executemany (self , * args , ** kwargs ):
371
+ def executemany (self , * args : Any , ** kwargs : Any ):
365
372
return _cursor_tracer .traced_execution (
366
373
self , super ().executemany , * args , ** kwargs
367
374
)
368
375
369
- def callproc (self , * args , ** kwargs ):
376
+ def callproc (self , * args : Any , ** kwargs : Any ):
370
377
return _cursor_tracer .traced_execution (
371
378
self , super ().callproc , * args , ** kwargs
372
379
)
@@ -375,7 +382,9 @@ def callproc(self, *args, **kwargs):
375
382
376
383
377
384
def _new_cursor_async_factory (
378
- db_api = None , base_factory = None , tracer_provider = None
385
+ db_api : DatabaseApiAsyncIntegration | None = None ,
386
+ base_factory : type [psycopg .AsyncCursor ] | None = None ,
387
+ tracer_provider : TracerProvider | None = None ,
379
388
):
380
389
if not db_api :
381
390
db_api = DatabaseApiAsyncIntegration (
@@ -385,21 +394,21 @@ def _new_cursor_async_factory(
385
394
version = __version__ ,
386
395
tracer_provider = tracer_provider ,
387
396
)
388
- base_factory = base_factory or pg_async_cursor
397
+ base_factory = base_factory or psycopg . AsyncCursor
389
398
_cursor_tracer = CursorTracer (db_api )
390
399
391
400
class TracedCursorAsyncFactory (base_factory ):
392
- async def execute (self , * args , ** kwargs ):
401
+ async def execute (self , * args : Any , ** kwargs : Any ):
393
402
return await _cursor_tracer .traced_execution (
394
403
self , super ().execute , * args , ** kwargs
395
404
)
396
405
397
- async def executemany (self , * args , ** kwargs ):
406
+ async def executemany (self , * args : Any , ** kwargs : Any ):
398
407
return await _cursor_tracer .traced_execution (
399
408
self , super ().executemany , * args , ** kwargs
400
409
)
401
410
402
- async def callproc (self , * args , ** kwargs ):
411
+ async def callproc (self , * args : Any , ** kwargs : Any ):
403
412
return await _cursor_tracer .traced_execution (
404
413
self , super ().callproc , * args , ** kwargs
405
414
)
0 commit comments