Skip to content

Commit

Permalink
Add request counter (#129)
Browse files Browse the repository at this point in the history
  • Loading branch information
ahopkins authored Sep 22, 2022
1 parent cbc4dbb commit 293d884
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 1 deletion.
2 changes: 2 additions & 0 deletions sanic_ext/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@
from sanic_ext.extensions.http.cors import cors
from sanic_ext.extensions.openapi import openapi
from sanic_ext.extensions.templating.render import render
from sanic_ext.extras.request import CountedRequest
from sanic_ext.extras.serializer.decorator import serializer
from sanic_ext.extras.validation.decorator import validate

__version__ = version("sanic-ext")

__all__ = [
"Config",
"CountedRequest",
"Extend",
"Extension",
"cors",
Expand Down
46 changes: 46 additions & 0 deletions sanic_ext/extras/request.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
from itertools import count

from sanic import Request, Sanic
from sanic.compat import Header
from sanic.models.protocol_types import TransportProtocol


class CountedRequest(Request):
__slots__ = ()

_counter = count()
count = next(_counter)

def __init__(
self,
url_bytes: bytes,
headers: Header,
version: str,
method: str,
transport: TransportProtocol,
app: Sanic,
head: bytes = b"",
stream_id: int = 0,
):
super().__init__(
url_bytes,
headers,
version,
method,
transport,
app,
head,
stream_id,
)
self.__class__._increment()
if hasattr(self.app, "multiplexer"):
self.app.multiplexer.state["request_count"] = self.__class__.count

@classmethod
def _increment(cls):
cls.count = next(cls._counter)

@classmethod
def reset_count(cls):
cls._counter = count()
cls.count = next(cls._counter)
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ sanic_ext =

[options.extras_require]
test =
sanic_testing==22.9.0b1
sanic_testing>=22.9.0b1
coverage
pytest
pytest-cov
Expand Down
1 change: 1 addition & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ def reset_globals():
OperationStore.reset()
Extend.reset()
Extension.reset()
Sanic._app_registry.clear()


@pytest.fixture(autouse=True)
Expand Down
42 changes: 42 additions & 0 deletions tests/extra/test_request_counted.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
from unittest.mock import Mock

import pytest
from sanic import Sanic
from sanic.compat import Header
from sanic.response import json
from sanic_testing.reusable import ReusableClient

from sanic_ext import CountedRequest


@pytest.fixture(autouse=True)
def reset_counter():
yield
CountedRequest.reset_count()


def test_counter_increments(app: Sanic):
app.request_class = CountedRequest

@app.get("/")
async def handler(request: CountedRequest):
return json({"count": request.count})

@app.get("/info")
async def info(request: CountedRequest):
return json({"state": request.app.m.state})

with ReusableClient(app) as client:
for i in range(1, 10):
_, response = client.get("/")
assert response.json["count"] == i


def test_counter_increment_on_state(app: Sanic):
mock = Mock()
mock.state = {}
app.multiplexer = mock

for i in range(1, 10):
CountedRequest(b"/", Header({}), "", "", Mock(), app)
assert CountedRequest.count == i

0 comments on commit 293d884

Please sign in to comment.