Skip to content

Commit

Permalink
minor updates and fix for websockets in asgi (#97)
Browse files Browse the repository at this point in the history
  • Loading branch information
claws authored Dec 27, 2023
1 parent 4786678 commit 2fabe65
Show file tree
Hide file tree
Showing 13 changed files with 45 additions and 37 deletions.
11 changes: 6 additions & 5 deletions examples/decorators/decorator_count_exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
.. code-block:: console
$ curl :8000/metrics
$ curl localhost:8000/metrics
# HELP request_handler_exceptions Number of exceptions in requests
# TYPE request_handler_exceptions counter
request_handler_exceptions{route="/"} 3
Expand Down Expand Up @@ -43,8 +43,6 @@ async def handle_request(duration):


async def handle_requests():
# Start up the server to expose the metrics.
await svr.start(port=8000)
# Generate some requests.
while True:
try:
Expand All @@ -56,13 +54,16 @@ async def handle_requests():
if __name__ == "__main__":
loop = asyncio.get_event_loop()

svr = Service()
svc = Service()

# Start up the server to expose the metrics.
loop.run_until_complete(svc.start(port=8000))

try:
loop.run_until_complete(handle_requests())
except KeyboardInterrupt:
pass
finally:
loop.run_until_complete(svr.stop())
loop.run_until_complete(svc.stop())
loop.stop()
loop.close()
18 changes: 12 additions & 6 deletions examples/decorators/decorator_inprogress.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
.. code-block:: console
$ curl :8000/metrics
$ curl localhost:8000/metrics
# HELP request_in_progress Number of requests in progress
# TYPE request_in_progress gauge
request_in_progress{route="/"} 1
Expand All @@ -37,23 +37,29 @@ async def handle_request(duration):


async def handle_requests():
# Start up the server to expose the metrics.
await svr.start(port=8000)
# Generate some requests.
while True:
await handle_request(random.random())
# Perform two requests to increase likelihood of observing two
# requests in progress when fetching metrics.
await asyncio.gather(
handle_request(random.random()),
handle_request(random.random()),
)


if __name__ == "__main__":
loop = asyncio.get_event_loop()

svr = Service()
svc = Service()

# Start up the server to expose the metrics.
loop.run_until_complete(svc.start(port=8000))

try:
loop.run_until_complete(handle_requests())
except KeyboardInterrupt:
pass
finally:
loop.run_until_complete(svr.stop())
loop.run_until_complete(svc.stop())
loop.stop()
loop.close()
11 changes: 6 additions & 5 deletions examples/decorators/decorator_timer.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
.. code-block:: console
$ curl :8000/metrics
$ curl localhost:8000/metrics
# HELP request_processing_seconds Time spent processing request
# TYPE request_processing_seconds summary
request_processing_seconds_count 77
Expand Down Expand Up @@ -40,8 +40,6 @@ async def handle_request(duration):


async def handle_requests():
# Start up the server to expose the metrics.
await svr.start(port=8000)
# Generate some requests.
while True:
await handle_request(random.random())
Expand All @@ -50,13 +48,16 @@ async def handle_requests():
if __name__ == "__main__":
loop = asyncio.get_event_loop()

svr = Service()
svc = Service()

# Start up the server to expose the metrics.
loop.run_until_complete(svc.start(port=8000))

try:
loop.run_until_complete(handle_requests())
except KeyboardInterrupt:
pass
finally:
loop.run_until_complete(svr.stop())
loop.run_until_complete(svc.stop())
loop.stop()
loop.close()
2 changes: 2 additions & 0 deletions examples/service/app-service-example.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
from aioprometheus import Counter, Gauge, Histogram, Summary
from aioprometheus.service import Service

logger = logging.getLogger(__name__)


class ExampleApp:
"""
Expand Down
2 changes: 1 addition & 1 deletion requirements.dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ fastapi
uvicorn
quart; python_version > '3.7'

# psutil is used in example code
# psutil is used by examples
psutil
2 changes: 1 addition & 1 deletion src/aioprometheus/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@
# The 'pusher' and 'service' modules must be explicitly imported by package
# users as they depend on optional extras.

__version__ = "23.3.0"
__version__ = "23.12.0"
8 changes: 4 additions & 4 deletions src/aioprometheus/asgi/middleware.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from typing import Any, Awaitable, Callable, Dict, Optional, Sequence

from aioprometheus import REGISTRY, Counter, Registry
from aioprometheus.mypy_types import LabelsType
from ..collectors import REGISTRY, Counter, Registry
from ..mypy_types import LabelsType

Scope = Dict[str, Any]
Message = Dict[str, Any]
Expand Down Expand Up @@ -148,7 +148,7 @@ async def __call__(self, scope: Scope, receive: Receive, send: Send):
await self.asgi_callable(scope, receive, send)
return

if scope["type"] == "http":
if scope["type"] in ("http", "websocket"):

def wrapped_send(response):
"""
Expand All @@ -171,7 +171,7 @@ def wrapped_send(response):

# Store HTTP path and method so they can be used later in the send
# method to complete metrics updates.
method = scope["method"]
method = scope.get("method")
path = self.get_full_or_template_path(scope)
labels = {"method": method, "path": path}

Expand Down
3 changes: 1 addition & 2 deletions src/aioprometheus/collectors.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@
import orjson
import quantile

from aioprometheus.mypy_types import LabelsType, NumericValueType

from . import histogram
from .metricdict import MetricDict
from .mypy_types import LabelsType, NumericValueType

METRIC_NAME_RE = re.compile(r"^[a-zA-Z_:][a-zA-Z0-9_:]*$")
RESTRICTED_LABELS_NAMES = ("job",)
Expand Down
2 changes: 1 addition & 1 deletion src/aioprometheus/mypy_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import quantile

from aioprometheus import histogram
from . import histogram

LabelsType = Dict[str, str]
NumericValueType = Union[int, float, histogram.Histogram, quantile.Estimator]
Expand Down
3 changes: 1 addition & 2 deletions src/aioprometheus/renderer.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from typing import Sequence, Tuple

from aioprometheus import Registry

from .collectors import Registry
from .formats.base import IFormatter
from .negotiator import negotiate

Expand Down
12 changes: 6 additions & 6 deletions src/aioprometheus/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@

DEFAULT_METRICS_PATH = "/metrics"

METRICS_URL_KEY: aiohttp.web.AppKey = aiohttp.web.AppKey("metrics_url")


class Service:
"""
Expand Down Expand Up @@ -135,18 +137,16 @@ async def start(

self._app = aiohttp.web.Application()
self._metrics_url = metrics_url
self._app["metrics_url"] = metrics_url
self._app[METRICS_URL_KEY] = metrics_url
self._app.router.add_route(GET, metrics_url, self.handle_metrics)
self._app.router.add_route(GET, self._root_url, self.handle_root)
self._app.router.add_route(GET, "/robots.txt", self.handle_robots)
self._runner = aiohttp.web.AppRunner(self._app)
self._runner = aiohttp.web.AppRunner(self._app, shutdown_timeout=2.0)
await self._runner.setup()

self._https = ssl is not None
try:
self._site = aiohttp.web.TCPSite(
self._runner, addr, port, ssl_context=ssl, shutdown_timeout=2.0
)
self._site = aiohttp.web.TCPSite(self._runner, addr, port, ssl_context=ssl)
await self._site.start()
except Exception:
logger.exception("error creating metrics server")
Expand Down Expand Up @@ -193,7 +193,7 @@ async def handle_root(
Serves a trivial page with a link to the metrics. Use this if ever
you need to point a health check at your the service.
"""
metrics_url = request.app["metrics_url"]
metrics_url = request.app[METRICS_URL_KEY]
return aiohttp.web.Response(
content_type="text/html",
text=f"<html><body><a href='{metrics_url}'>metrics</a></body></html>",
Expand Down
4 changes: 2 additions & 2 deletions tests/test_aiohttp.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@ async def handle_metrics(request):
[aiohttp.web.get("/", index), aiohttp.web.get("/metrics", handle_metrics)]
)

runner = aiohttp.web.AppRunner(app)
runner = aiohttp.web.AppRunner(app, shutdown_timeout=1.0)
await runner.setup()

site = aiohttp.web.TCPSite(runner, "127.0.0.1", 0, shutdown_timeout=1.0)
site = aiohttp.web.TCPSite(runner, "127.0.0.1", 0)
await site.start()

# Fetch ephemeral port that was bound.
Expand Down
4 changes: 2 additions & 2 deletions tests/test_dist.bash
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ echo "Removing any old artefacts"
rm -rf test_venv

echo "Creating test virtual environment"
python -m venv test_venv
python3.11 -m venv test_venv

echo "Entering test virtual environment"
source test_venv/bin/activate
Expand All @@ -22,7 +22,7 @@ echo "Upgrading pip"
pip install pip --upgrade

echo "Install test dependencies and extras to check integrations"
pip install asynctest requests aiohttp fastapi quart httpx
pip install asynctest requests aiohttp fastapi quart httpx aiohttp_basicauth

echo "Installing $RELEASE_ARCHIVE"
pip install $RELEASE_ARCHIVE[aiohttp,starlette,quart]
Expand Down

0 comments on commit 2fabe65

Please sign in to comment.