Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ok/error logic to the decorator #79

Merged
merged 19 commits into from
Aug 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@ jobs:
python-version: ${{ matrix.python-version }}
cache: poetry
- name: Install dependencies
run: poetry install --no-interaction --no-root --with dev
run: poetry install --no-interaction --no-root --with dev,examples
- name: Check code formatting
run: poetry run black .
- name: Lint code
run: poetry run pyright
- name: Lint lib code
run: poetry run mypy src --enable-incomplete-feature=Unpack
- name: Lint lib examples
run: poetry run mypy examples --enable-incomplete-feature=Unpack
- name: Run tests
run: poetry run pytest -n auto
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

### Added

-
- Added support for `record_error_if` and `record_success_if`

### Changed

Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ poetry install --with examples
Code in this repository is:

- formatted using [black](https://black.readthedocs.io/en/stable/).
- contains type definitions (which are linted by [pyright](https://microsoft.github.io/pyright/))
- contains type definitions (which are linted by [mypy](https://www.mypy-lang.org/))
- tested using [pytest](https://docs.pytest.org/)

In order to run these tools locally you have to install them, you can install them using poetry:
Expand All @@ -176,8 +176,8 @@ After that you can run the tools individually
```sh
# Formatting using black
poetry run black .
# Lint using pyright
poetry run pyright
# Lint using mypy
poetry run mypy .
# Run the tests using pytest
poetry run pytest
# Run a single test, and clear the cache
Expand Down
6 changes: 6 additions & 0 deletions examples/django_example/mypy.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[mypy]
plugins =
mypy_django_plugin.main

[mypy.plugins.django-stubs]
django_settings_module = "django_example.settings"
42 changes: 42 additions & 0 deletions examples/fastapi-example.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from autometrics import autometrics
from fastapi import FastAPI, Response
from fastapi.responses import JSONResponse
from prometheus_client import generate_latest

app = FastAPI()
Expand Down Expand Up @@ -44,5 +45,46 @@ async def do_something_async():
return "async world"


def response_is_error(response: Response):
if response.status_code >= 400:
return True


@app.get("/not-implemented")
@autometrics(record_error_if=response_is_error)
def not_implemented():
return JSONResponse(
status_code=501, content={"message": "This endpoint is not implemented"}
)


@app.get("/flowers/{flower_name}")
def flower(flower_name: str):
try:
return JSONResponse(content={"message": get_pretty_flower(flower_name)})
except NotFoundError as error:
return JSONResponse(status_code=404, content={"message": str(error)})


class NotFoundError(Exception):
pass


def is_not_found_error(error: Exception):
return isinstance(error, NotFoundError)


@autometrics(record_success_if=is_not_found_error)
def get_pretty_flower(flower_name: str):
"""Returns whether the flower is pretty"""
print(f"Getting pretty flower for {flower_name}")
flowers = ["rose", "tulip", "daisy"]
if flower_name not in flowers:
raise NotFoundError(
f"Flower {flower_name} not found. Perhaps you meant one of these: {', '.join(flowers)}?"
)
return f"A {flower_name} is pretty"


if __name__ == "__main__":
uvicorn.run(app, host="localhost", port=8080)
468 changes: 329 additions & 139 deletions poetry.lock

Large diffs are not rendered by default.

27 changes: 25 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ classifiers = [
"Topic :: Software Development :: Build Tools",
"Topic :: Software Development :: Libraries :: Python Modules",
"Topic :: System :: Monitoring",
"Typing :: Typed"
]
packages = [{ include = "autometrics", from = "src" }]

[tool.poetry.dependencies]
opentelemetry-api = "^1.17.0"
opentelemetry-exporter-prometheus = "^1.12.0rc1"
opentelemetry-sdk = "^1.17.0"
prometheus-client = "^0.16.0 || ^0.17.0"
Expand All @@ -35,12 +35,28 @@ typing-extensions = "^4.5.0"
[tool.poetry.group.dev]
optional = true

[tool.mypy]
namespace_packages = true
mypy_path = "src"
enable_incomplete_feature = "Unpack"

# This override is needed because with certain flavors of python and
# mypy you can get the following error:
# opentelemetry/attributes/__init__.py:14: error: invalid syntax
# Which at the time of writing is a line that states ignore types:
# `# type: ignore`
[[tool.mypy.overrides]]
module = [
"opentelemetry.attributes",
]
follow_imports = "skip"

[tool.poetry.group.dev.dependencies]
pyright = "^1.1.307"
pytest = "^7.3.0"
pytest-asyncio = "^0.21.0"
black = "^23.3.0"
pytest-xdist = "^3.3.1"
mypy = "^1.5.1"
twine = "4.0.2"

[tool.poetry.group.examples]
Expand Down Expand Up @@ -83,6 +99,13 @@ uvicorn = "0.21.1"
webencodings = "0.5.1"
zipp = "3.15.0"
locust = "^2.15.1"
django-stubs = "4.2.3"



[tool.poetry.group.development.dependencies]
types-requests = "^2.31.0.2"
django-stubs = "^4.2.3"

[build-system]
requires = ["poetry-core"]
Expand Down
Loading