Skip to content

Commit 13df124

Browse files
authored
Relax registry type annotations for exposition (#1149)
* Turn Collector into a Protocol We require Python >= 3.9 now, so there's no reason to avoid this any more. Signed-off-by: Colin Watson <[email protected]> * Relax registry type annotations for exposition Anything with a suitable `collect` method will do: for instance, it's sometimes useful to be able to define a class whose `collect` method yields all metrics from a registry whose names have a given prefix, and such a class doesn't need to inherit from `CollectorRegistry`. Signed-off-by: Colin Watson <[email protected]> --------- Signed-off-by: Colin Watson <[email protected]>
1 parent a264ec0 commit 13df124

File tree

5 files changed

+25
-28
lines changed

5 files changed

+25
-28
lines changed

prometheus_client/aiohttp/exposition.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44
from aiohttp.typedefs import Handler
55

66
from ..exposition import _bake_output
7-
from ..registry import CollectorRegistry, REGISTRY
7+
from ..registry import Collector, REGISTRY
88

99

1010
def make_aiohttp_handler(
11-
registry: CollectorRegistry = REGISTRY,
11+
registry: Collector = REGISTRY,
1212
disable_compression: bool = False,
1313
) -> Handler:
1414
"""Create a aiohttp handler which serves the metrics from a registry."""

prometheus_client/asgi.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
from urllib.parse import parse_qs
33

44
from .exposition import _bake_output
5-
from .registry import CollectorRegistry, REGISTRY
5+
from .registry import Collector, REGISTRY
66

77

8-
def make_asgi_app(registry: CollectorRegistry = REGISTRY, disable_compression: bool = False) -> Callable:
8+
def make_asgi_app(registry: Collector = REGISTRY, disable_compression: bool = False) -> Callable:
99
"""Create a ASGI app which serves the metrics from a registry."""
1010

1111
async def prometheus_app(scope, receive, send):

prometheus_client/bridge/graphite.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from timeit import default_timer
99
from typing import Callable, Tuple
1010

11-
from ..registry import CollectorRegistry, REGISTRY
11+
from ..registry import Collector, REGISTRY
1212

1313
# Roughly, have to keep to what works as a file name.
1414
# We also remove periods, so labels can be distinguished.
@@ -48,7 +48,7 @@ def run(self):
4848
class GraphiteBridge:
4949
def __init__(self,
5050
address: Tuple[str, int],
51-
registry: CollectorRegistry = REGISTRY,
51+
registry: Collector = REGISTRY,
5252
timeout_seconds: float = 30,
5353
_timer: Callable[[], float] = time.time,
5454
tags: bool = False,

prometheus_client/exposition.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
from wsgiref.simple_server import make_server, WSGIRequestHandler, WSGIServer
2020

2121
from .openmetrics import exposition as openmetrics
22-
from .registry import CollectorRegistry, REGISTRY
22+
from .registry import Collector, REGISTRY
2323
from .utils import floatToGoString, parse_version
2424

2525
__all__ = (
@@ -118,7 +118,7 @@ def _bake_output(registry, accept_header, accept_encoding_header, params, disabl
118118
return '200 OK', headers, output
119119

120120

121-
def make_wsgi_app(registry: CollectorRegistry = REGISTRY, disable_compression: bool = False) -> Callable:
121+
def make_wsgi_app(registry: Collector = REGISTRY, disable_compression: bool = False) -> Callable:
122122
"""Create a WSGI app which serves the metrics from a registry."""
123123

124124
def prometheus_app(environ, start_response):
@@ -223,7 +223,7 @@ def _get_ssl_ctx(
223223
def start_wsgi_server(
224224
port: int,
225225
addr: str = '0.0.0.0',
226-
registry: CollectorRegistry = REGISTRY,
226+
registry: Collector = REGISTRY,
227227
certfile: Optional[str] = None,
228228
keyfile: Optional[str] = None,
229229
client_cafile: Optional[str] = None,
@@ -252,12 +252,12 @@ class TmpServer(ThreadingWSGIServer):
252252
start_http_server = start_wsgi_server
253253

254254

255-
def generate_latest(registry: CollectorRegistry = REGISTRY, escaping: str = openmetrics.UNDERSCORES) -> bytes:
255+
def generate_latest(registry: Collector = REGISTRY, escaping: str = openmetrics.UNDERSCORES) -> bytes:
256256
"""
257257
Generates the exposition format using the basic Prometheus text format.
258258
259259
Params:
260-
registry: CollectorRegistry to export data from.
260+
registry: Collector to export data from.
261261
escaping: Escaping scheme used for metric and label names.
262262
263263
Returns: UTF-8 encoded string containing the metrics in text format.
@@ -330,7 +330,7 @@ def sample_line(samples):
330330
return ''.join(output).encode('utf-8')
331331

332332

333-
def choose_encoder(accept_header: str) -> Tuple[Callable[[CollectorRegistry], bytes], str]:
333+
def choose_encoder(accept_header: str) -> Tuple[Callable[[Collector], bytes], str]:
334334
# Python client library accepts a narrower range of content-types than
335335
# Prometheus does.
336336
accept_header = accept_header or ''
@@ -408,7 +408,7 @@ def gzip_accepted(accept_encoding_header: str) -> bool:
408408

409409
class MetricsHandler(BaseHTTPRequestHandler):
410410
"""HTTP handler that gives metrics from ``REGISTRY``."""
411-
registry: CollectorRegistry = REGISTRY
411+
registry: Collector = REGISTRY
412412

413413
def do_GET(self) -> None:
414414
# Prepare parameters
@@ -429,7 +429,7 @@ def log_message(self, format: str, *args: Any) -> None:
429429
"""Log nothing."""
430430

431431
@classmethod
432-
def factory(cls, registry: CollectorRegistry) -> type:
432+
def factory(cls, registry: Collector) -> type:
433433
"""Returns a dynamic MetricsHandler class tied
434434
to the passed registry.
435435
"""
@@ -444,7 +444,7 @@ def factory(cls, registry: CollectorRegistry) -> type:
444444
return MyMetricsHandler
445445

446446

447-
def write_to_textfile(path: str, registry: CollectorRegistry, escaping: str = openmetrics.ALLOWUTF8, tmpdir: Optional[str] = None) -> None:
447+
def write_to_textfile(path: str, registry: Collector, escaping: str = openmetrics.ALLOWUTF8, tmpdir: Optional[str] = None) -> None:
448448
"""Write metrics to the given path.
449449
450450
This is intended for use with the Node exporter textfile collector.
@@ -592,7 +592,7 @@ def tls_auth_handler(
592592
def push_to_gateway(
593593
gateway: str,
594594
job: str,
595-
registry: CollectorRegistry,
595+
registry: Collector,
596596
grouping_key: Optional[Dict[str, Any]] = None,
597597
timeout: Optional[float] = 30,
598598
handler: Callable = default_handler,
@@ -603,7 +603,7 @@ def push_to_gateway(
603603
'http://pushgateway.local', or 'pushgateway.local'.
604604
Scheme defaults to 'http' if none is provided
605605
`job` is the job label to be attached to all pushed metrics
606-
`registry` is an instance of CollectorRegistry
606+
`registry` is a Collector, normally an instance of CollectorRegistry
607607
`grouping_key` please see the pushgateway documentation for details.
608608
Defaults to None
609609
`timeout` is how long push will attempt to connect before giving up.
@@ -641,7 +641,7 @@ def push_to_gateway(
641641
def pushadd_to_gateway(
642642
gateway: str,
643643
job: str,
644-
registry: Optional[CollectorRegistry],
644+
registry: Optional[Collector],
645645
grouping_key: Optional[Dict[str, Any]] = None,
646646
timeout: Optional[float] = 30,
647647
handler: Callable = default_handler,
@@ -652,7 +652,7 @@ def pushadd_to_gateway(
652652
'http://pushgateway.local', or 'pushgateway.local'.
653653
Scheme defaults to 'http' if none is provided
654654
`job` is the job label to be attached to all pushed metrics
655-
`registry` is an instance of CollectorRegistry
655+
`registry` is a Collector, normally an instance of CollectorRegistry
656656
`grouping_key` please see the pushgateway documentation for details.
657657
Defaults to None
658658
`timeout` is how long push will attempt to connect before giving up.
@@ -702,7 +702,7 @@ def _use_gateway(
702702
method: str,
703703
gateway: str,
704704
job: str,
705-
registry: Optional[CollectorRegistry],
705+
registry: Optional[Collector],
706706
grouping_key: Optional[Dict[str, Any]],
707707
timeout: Optional[float],
708708
handler: Callable,

prometheus_client/registry.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,21 @@
1-
from abc import ABC, abstractmethod
21
import copy
32
from threading import Lock
4-
from typing import Dict, Iterable, List, Optional
3+
from typing import Dict, Iterable, List, Optional, Protocol
54

65
from .metrics_core import Metric
76

87

9-
# Ideally this would be a Protocol, but Protocols are only available in Python >= 3.8.
10-
class Collector(ABC):
11-
@abstractmethod
8+
class Collector(Protocol):
129
def collect(self) -> Iterable[Metric]:
13-
pass
10+
"""Collect metrics."""
1411

1512

16-
class _EmptyCollector(Collector):
13+
class _EmptyCollector:
1714
def collect(self) -> Iterable[Metric]:
1815
return []
1916

2017

21-
class CollectorRegistry(Collector):
18+
class CollectorRegistry:
2219
"""Metric collector registry.
2320
2421
Collectors must have a no-argument method 'collect' that returns a list of

0 commit comments

Comments
 (0)