From 567d746c24a6b2b5ea6f63516f10c1e75e338756 Mon Sep 17 00:00:00 2001 From: Simon Gurcke Date: Tue, 19 Mar 2024 10:26:53 +1000 Subject: [PATCH 1/2] Get more package versions --- apitally/common.py | 31 +++++++++++++++++++++++++++++++ apitally/django.py | 24 ++---------------------- apitally/flask.py | 16 ++-------------- apitally/litestar.py | 16 ++-------------- apitally/starlette.py | 20 ++------------------ 5 files changed, 39 insertions(+), 68 deletions(-) create mode 100644 apitally/common.py diff --git a/apitally/common.py b/apitally/common.py new file mode 100644 index 0000000..22baea3 --- /dev/null +++ b/apitally/common.py @@ -0,0 +1,31 @@ +import sys +from importlib.metadata import PackageNotFoundError, version +from typing import Dict, Optional + + +def get_versions(*packages, app_version: Optional[str]) -> Dict[str, str]: + versions = _get_common_package_versions() + for package in packages: + versions[package] = _get_package_version(package) + if app_version: + versions["app"] = app_version + return {n: v for n, v in versions.items() if v is not None} + + +def _get_common_package_versions() -> Dict[str, Optional[str]]: + return { + "python": f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}", + "apitally": _get_package_version("apitally"), + "uvicorn": _get_package_version("uvicorn"), + "hypercorn": _get_package_version("hypercorn"), + "daphne": _get_package_version("daphne"), + "gunicorn": _get_package_version("gunicorn"), + "uwsgi": _get_package_version("uwsgi"), + } + + +def _get_package_version(name: str) -> Optional[str]: + try: + return version(name) + except PackageNotFoundError: + return None diff --git a/apitally/django.py b/apitally/django.py index 32fbf7e..dd76de2 100644 --- a/apitally/django.py +++ b/apitally/django.py @@ -1,10 +1,8 @@ from __future__ import annotations import json -import sys import time from dataclasses import dataclass -from importlib.metadata import PackageNotFoundError, version from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional from django.conf import settings @@ -14,6 +12,7 @@ from django.utils.module_loading import import_string from apitally.client.threading import ApitallyClient +from apitally.common import get_versions if TYPE_CHECKING: @@ -172,7 +171,7 @@ def _get_app_info( if openapi := _get_openapi(views, openapi_url): app_info["openapi"] = openapi app_info["paths"] = _get_paths(views) - app_info["versions"] = _get_versions(app_version) + app_info["versions"] = get_versions("django", "djangorestframework", "django-ninja", app_version=app_version) app_info["client"] = "python:django" return app_info @@ -251,22 +250,3 @@ def _extract_views_from_url_patterns( ) ) return views - - -def _get_versions(app_version: Optional[str]) -> Dict[str, str]: - versions = { - "python": f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}", - "apitally": version("apitally"), - "django": version("django"), - } - try: - versions["djangorestframework"] = version("djangorestframework") - except PackageNotFoundError: # pragma: no cover - pass - try: - versions["django-ninja"] = version("django-ninja") - except PackageNotFoundError: # pragma: no cover - pass - if app_version: - versions["app"] = app_version - return versions diff --git a/apitally/flask.py b/apitally/flask.py index f1764a4..7c353a7 100644 --- a/apitally/flask.py +++ b/apitally/flask.py @@ -1,8 +1,6 @@ from __future__ import annotations -import sys import time -from importlib.metadata import version from threading import Timer from typing import TYPE_CHECKING, Any, Dict, Iterable, List, Optional, Tuple @@ -12,6 +10,7 @@ from werkzeug.test import Client from apitally.client.threading import ApitallyClient +from apitally.common import get_versions if TYPE_CHECKING: @@ -103,7 +102,7 @@ def _get_app_info(app: Flask, app_version: Optional[str] = None, openapi_url: Op app_info["openapi"] = openapi if paths := _get_paths(app.url_map): app_info["paths"] = paths - app_info["versions"] = _get_versions(app_version) + app_info["versions"] = get_versions("flask", app_version=app_version) app_info["client"] = "python:flask" return app_info @@ -124,14 +123,3 @@ def _get_openapi(app: WSGIApplication, openapi_url: str) -> Optional[str]: if response.status_code != 200: return None return response.get_data(as_text=True) - - -def _get_versions(app_version: Optional[str]) -> Dict[str, str]: - versions = { - "python": f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}", - "apitally": version("apitally"), - "flask": version("flask"), - } - if app_version: - versions["app"] = app_version - return versions diff --git a/apitally/litestar.py b/apitally/litestar.py index 82270a1..08d4744 100644 --- a/apitally/litestar.py +++ b/apitally/litestar.py @@ -1,8 +1,6 @@ import contextlib import json -import sys import time -from importlib.metadata import version from typing import Callable, Dict, List, Optional from litestar.app import DEFAULT_OPENAPI_CONFIG, Litestar @@ -15,6 +13,7 @@ from litestar.types import ASGIApp, Message, Receive, Scope, Send from apitally.client.asyncio import ApitallyClient +from apitally.common import get_versions __all__ = ["ApitallyPlugin"] @@ -48,7 +47,7 @@ def on_startup(self, app: Litestar) -> None: app_info = { "openapi": _get_openapi(app), "paths": [route for route in _get_routes(app) if not self.filter_path(route["path"])], - "versions": _get_versions(self.app_version), + "versions": get_versions("litestar", app_version=self.app_version), "client": "python:litestar", } self.client.set_app_info(app_info) @@ -174,14 +173,3 @@ def _get_routes(app: Litestar) -> List[Dict[str, str]]: for method in route.methods if route.scope_type == ScopeType.HTTP and method != "OPTIONS" ] - - -def _get_versions(app_version: Optional[str]) -> Dict[str, str]: - versions = { - "python": f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}", - "apitally": version("apitally"), - "litestar": version("litestar"), - } - if app_version: - versions["app"] = app_version - return versions diff --git a/apitally/starlette.py b/apitally/starlette.py index 1f76fee..24e1013 100644 --- a/apitally/starlette.py +++ b/apitally/starlette.py @@ -2,9 +2,7 @@ import asyncio import json -import sys import time -from importlib.metadata import PackageNotFoundError, version from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional, Tuple, Union from httpx import HTTPStatusError @@ -17,6 +15,7 @@ from starlette.types import ASGIApp from apitally.client.asyncio import ApitallyClient +from apitally.common import get_versions if TYPE_CHECKING: @@ -145,7 +144,7 @@ def _get_app_info(app: ASGIApp, app_version: Optional[str] = None, openapi_url: app_info["openapi"] = openapi if endpoints := _get_endpoint_info(app): app_info["paths"] = [{"path": endpoint.path, "method": endpoint.http_method} for endpoint in endpoints] - app_info["versions"] = _get_versions(app_version) + app_info["versions"] = get_versions("fastapi", "starlette", app_version=app_version) app_info["client"] = "python:starlette" return app_info @@ -179,18 +178,3 @@ def _register_shutdown_handler(app: Union[ASGIApp, Router], shutdown_handler: Ca app.add_event_handler("shutdown", shutdown_handler) elif hasattr(app, "app"): _register_shutdown_handler(app.app, shutdown_handler) - - -def _get_versions(app_version: Optional[str]) -> Dict[str, str]: - versions = { - "python": f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}", - "apitally": version("apitally"), - "starlette": version("starlette"), - } - try: - versions["fastapi"] = version("fastapi") - except PackageNotFoundError: # pragma: no cover - pass - if app_version: - versions["app"] = app_version - return versions From 80fbced0b75db03da2601a4a38809bd818f955be Mon Sep 17 00:00:00 2001 From: Simon Gurcke Date: Tue, 19 Mar 2024 10:42:35 +1000 Subject: [PATCH 2/2] Fix --- apitally/common.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apitally/common.py b/apitally/common.py index 22baea3..ab66f3e 100644 --- a/apitally/common.py +++ b/apitally/common.py @@ -3,7 +3,7 @@ from typing import Dict, Optional -def get_versions(*packages, app_version: Optional[str]) -> Dict[str, str]: +def get_versions(*packages, app_version: Optional[str] = None) -> Dict[str, str]: versions = _get_common_package_versions() for package in packages: versions[package] = _get_package_version(package)