Skip to content

Commit

Permalink
Rename to apitally-python
Browse files Browse the repository at this point in the history
  • Loading branch information
itssimon committed Aug 15, 2023
1 parent 0639a5c commit d956dea
Show file tree
Hide file tree
Showing 15 changed files with 58 additions and 60 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,6 @@ jobs:
- name: Install test dependencies
run: poetry install --no-interaction --no-root --only test
- name: Install app dependencies
run: poetry run pip install ${{ matrix.deps }} ./dist/starlette_apitally-*.whl
run: poetry run pip install ${{ matrix.deps }} ./dist/apitally-*.whl
- name: Run tests
run: poetry run make test
10 changes: 5 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
.PHONY: format check test test-coverage

format:
ruff check starlette_apitally tests --fix --select I
black starlette_apitally tests
ruff check apitally tests --fix --select I
black apitally tests

check:
ruff check starlette_apitally tests
mypy --install-types --non-interactive starlette_apitally tests
black --check --diff starlette_apitally tests
ruff check apitally tests
mypy --install-types --non-interactive apitally tests
black --check --diff apitally tests
poetry check

test:
Expand Down
18 changes: 8 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,22 @@
# Starlette Apitally
# Apitally client for Python

[![Tests](https://github.com/apitally/starlette-apitally/actions/workflows/tests.yaml/badge.svg?event=push)](https://github.com/apitally/starlette-apitally/actions)
[![Codecov](https://codecov.io/gh/apitally/starlette-apitally/branch/main/graph/badge.svg?token=UNLYBY4Y3V)](https://codecov.io/gh/apitally/starlette-apitally)
[![PyPI](https://img.shields.io/pypi/v/starlette-apitally?logo=pypi&logoColor=white&color=%23006dad)](https://pypi.org/project/starlette-apitally/)
[![Tests](https://github.com/apitally/apitally-python/actions/workflows/tests.yaml/badge.svg?event=push)](https://github.com/apitally/apitally-python/actions)
[![Codecov](https://codecov.io/gh/apitally/apitally-python/branch/main/graph/badge.svg?token=UNLYBY4Y3V)](https://codecov.io/gh/apitally/apitally-python)
[![PyPI](https://img.shields.io/pypi/v/apitally?logo=pypi&logoColor=white&color=%23006dad)](https://pypi.org/project/apitally/)

Apitally integration for Starlette / FastAPI.

The integration is implemented as a middleware which sends metrics about requests and responses to [Apitally](https://apitally.io) every 10 seconds. This is done asynchronously and does not impact the performance of your application.
Apitally client library for Python.

## Installation

```bash
pip install starlette-apitally
pip install apitally
```

## Usage with FastAPI

```python
from fastapi import FastAPI
from starlette_apitally import ApitallyMiddleware
from apitally.fastapi import ApitallyMiddleware

app = FastAPI()
app.add_middleware(ApitallyMiddleware, client_id="<your-client-id>")
Expand All @@ -28,7 +26,7 @@ app.add_middleware(ApitallyMiddleware, client_id="<your-client-id>")

```python
from starlette.applications import Starlette
from starlette_apitally import ApitallyMiddleware
from apitally.starlette import ApitallyMiddleware

app = Starlette()
app.add_middleware(ApitallyMiddleware, client_id="<your-client-id>")
Expand Down
File renamed without changes.
4 changes: 2 additions & 2 deletions starlette_apitally/client.py → apitally/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
import backoff
import httpx

from starlette_apitally.keys import KeyRegistry
from starlette_apitally.requests import RequestLogger
from apitally.keys import KeyRegistry
from apitally.requests import RequestLogger


logger = logging.getLogger(__name__)
Expand Down
6 changes: 3 additions & 3 deletions starlette_apitally/fastapi.py → apitally/fastapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
from fastapi.security.utils import get_authorization_scheme_param
from starlette.status import HTTP_401_UNAUTHORIZED, HTTP_403_FORBIDDEN

from starlette_apitally.client import ApitallyClient
from starlette_apitally.keys import KeyInfo
from starlette_apitally.starlette import ApitallyMiddleware
from apitally.client import ApitallyClient
from apitally.keys import KeyInfo
from apitally.starlette import ApitallyMiddleware


__all__ = ["ApitallyMiddleware", "KeyInfo", "api_key_auth"]
Expand Down
File renamed without changes.
File renamed without changes.
10 changes: 5 additions & 5 deletions starlette_apitally/starlette.py → apitally/starlette.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@
from starlette.testclient import TestClient
from starlette.types import ASGIApp

import starlette_apitally
from starlette_apitally.client import ApitallyClient
from starlette_apitally.keys import KeyInfo
import apitally
from apitally.client import ApitallyClient
from apitally.keys import KeyInfo


if TYPE_CHECKING:
Expand Down Expand Up @@ -142,7 +142,7 @@ def _get_app_info(app: ASGIApp, app_version: Optional[str], openapi_url: Optiona
elif 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["client"] = "starlette-apitally"
app_info["client"] = "apitally-python"
return app_info


Expand Down Expand Up @@ -175,7 +175,7 @@ def _get_routes(app: ASGIApp) -> List[BaseRoute]:
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}",
"starlette-apitally": starlette_apitally.__version__,
"apitally": apitally.__version__,
"starlette": starlette.__version__,
}
try:
Expand Down
8 changes: 4 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ requires = ["poetry-core", "poetry-dynamic-versioning"]
build-backend = "poetry_dynamic_versioning.backend"

[tool.poetry]
name = "starlette-apitally"
name = "apitally"
version = "0.0.0"
description = "Apitally integration for Starlette"
description = "Apitally client library for Python"
authors = ["Simon Gurcke <[email protected]>"]
license = "MIT License"
repository = "https://github.com/apitally/starlette-apitally"
repository = "https://github.com/apitally/apitally-python"
readme = "README.md"

[tool.poetry.dependencies]
Expand Down Expand Up @@ -58,7 +58,7 @@ asyncio_mode = "auto"
testpaths = ["tests"]

[tool.coverage.run]
source = ["starlette_apitally"]
source = ["apitally"]

[tool.coverage.report]
exclude_lines = ["pragma: no cover", "if TYPE_CHECKING"]
14 changes: 7 additions & 7 deletions tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@


if TYPE_CHECKING:
from starlette_apitally.client import ApitallyClient
from apitally.client import ApitallyClient


CLIENT_ID = "76b5cb91-a0a4-4ea0-a894-57d2b9fcb2c9"
Expand All @@ -19,10 +19,10 @@

@pytest.fixture()
async def client(mocker: MockerFixture) -> AsyncIterator[ApitallyClient]:
from starlette_apitally.client import ApitallyClient
from apitally.client import ApitallyClient

mocker.patch("starlette_apitally.client.ApitallyClient.start_sync_loop")
mocker.patch("starlette_apitally.client.ApitallyClient._run_sync_loop")
mocker.patch("apitally.client.ApitallyClient.start_sync_loop")
mocker.patch("apitally.client.ApitallyClient._run_sync_loop")

client = ApitallyClient(client_id=CLIENT_ID, env=ENV, enable_keys=True)
client.request_logger.log_request(
Expand All @@ -41,7 +41,7 @@ async def client(mocker: MockerFixture) -> AsyncIterator[ApitallyClient]:


async def test_send_requests_data(client: ApitallyClient, httpx_mock: HTTPXMock):
from starlette_apitally.client import HUB_BASE_URL, HUB_VERSION
from apitally.client import HUB_BASE_URL, HUB_VERSION

httpx_mock.add_response()
async with client.get_http_client() as http_client:
Expand All @@ -55,7 +55,7 @@ async def test_send_requests_data(client: ApitallyClient, httpx_mock: HTTPXMock)


async def test_send_app_info(client: ApitallyClient, httpx_mock: HTTPXMock):
from starlette_apitally.client import HUB_BASE_URL, HUB_VERSION
from apitally.client import HUB_BASE_URL, HUB_VERSION

httpx_mock.add_response()
app_info = {"paths": [], "client_version": "1.0.0", "starlette_version": "0.28.0", "python_version": "3.11.4"}
Expand All @@ -70,7 +70,7 @@ async def test_send_app_info(client: ApitallyClient, httpx_mock: HTTPXMock):


async def test_get_keys(client: ApitallyClient, httpx_mock: HTTPXMock):
from starlette_apitally.client import HUB_BASE_URL, HUB_VERSION
from apitally.client import HUB_BASE_URL, HUB_VERSION

httpx_mock.add_response(json={"salt": "x", "keys": {"x": {"key_id": 1, "expires_in_seconds": None}}})
await client.get_keys()
Expand Down
8 changes: 4 additions & 4 deletions tests/test_fastapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@
if TYPE_CHECKING:
from fastapi import FastAPI

from starlette_apitally.keys import KeyInfo # import here to avoid pydantic error
from apitally.keys import KeyInfo # import here to avoid pydantic error


@pytest.fixture()
def app_with_auth() -> FastAPI:
from fastapi import Depends, FastAPI, Security

from starlette_apitally.fastapi import api_key_auth
from apitally.fastapi import api_key_auth

app = FastAPI()

Expand All @@ -42,7 +42,7 @@ def baz():
def test_api_key_auth(app_with_auth: FastAPI, mocker: MockerFixture):
from starlette.testclient import TestClient

from starlette_apitally.keys import KeyInfo, KeyRegistry
from apitally.keys import KeyInfo, KeyRegistry

client = TestClient(app_with_auth)
key_registry = KeyRegistry()
Expand All @@ -55,7 +55,7 @@ def test_api_key_auth(app_with_auth: FastAPI, mocker: MockerFixture):
)
}
headers = {"Authorization": "ApiKey 7ll40FB.DuHxzQQuGQU4xgvYvTpmnii7K365j9VI"}
mock = mocker.patch("starlette_apitally.fastapi.ApitallyClient.get_instance")
mock = mocker.patch("apitally.fastapi.ApitallyClient.get_instance")
mock.return_value.key_registry = key_registry

# Unauthenticated
Expand Down
2 changes: 1 addition & 1 deletion tests/test_keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@


def test_keys():
from starlette_apitally.keys import KeyRegistry
from apitally.keys import KeyRegistry

keys = KeyRegistry()

Expand Down
4 changes: 2 additions & 2 deletions tests/test_requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@


if TYPE_CHECKING:
from starlette_apitally.requests import RequestLogger
from apitally.requests import RequestLogger


@pytest.fixture()
def requests() -> RequestLogger:
from starlette_apitally.requests import RequestLogger
from apitally.requests import RequestLogger

requests = RequestLogger()
requests.log_request(
Expand Down
32 changes: 16 additions & 16 deletions tests/test_starlette.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ def event_loop() -> Iterator[AbstractEventLoop]:
params=["starlette", "fastapi"] if find_spec("fastapi") is not None else ["starlette"],
)
async def app(request: FixtureRequest, module_mocker: MockerFixture) -> Starlette:
module_mocker.patch("starlette_apitally.client.ApitallyClient.start_sync_loop")
module_mocker.patch("starlette_apitally.client.ApitallyClient.send_app_info")
module_mocker.patch("apitally.client.ApitallyClient.start_sync_loop")
module_mocker.patch("apitally.client.ApitallyClient.send_app_info")
if request.param == "starlette":
return get_starlette_app()
elif request.param == "fastapi":
Expand All @@ -55,7 +55,7 @@ def app_with_auth() -> Starlette:
from starlette.responses import JSONResponse, PlainTextResponse
from starlette.routing import Route

from starlette_apitally.starlette import ApitallyKeysBackend
from apitally.starlette import ApitallyKeysBackend

@requires(["authenticated", "foo"])
def foo(request: Request):
Expand Down Expand Up @@ -93,7 +93,7 @@ def get_starlette_app() -> Starlette:
from starlette.responses import PlainTextResponse
from starlette.routing import Route

from starlette_apitally.starlette import ApitallyMiddleware
from apitally.starlette import ApitallyMiddleware

background_task_mock = MagicMock()

Expand Down Expand Up @@ -124,7 +124,7 @@ def baz(request: Request):
def get_fastapi_app() -> Starlette:
from fastapi import FastAPI

from starlette_apitally.fastapi import ApitallyMiddleware
from apitally.fastapi import ApitallyMiddleware

background_task_mock = MagicMock()

Expand Down Expand Up @@ -154,8 +154,8 @@ def baz():


def test_middleware_param_validation(app: Starlette):
from starlette_apitally.client import ApitallyClient
from starlette_apitally.starlette import ApitallyMiddleware
from apitally.client import ApitallyClient
from apitally.starlette import ApitallyMiddleware

ApitallyClient._instance = None

Expand All @@ -172,7 +172,7 @@ def test_middleware_param_validation(app: Starlette):
def test_middleware_requests_ok(app: Starlette, mocker: MockerFixture):
from starlette.testclient import TestClient

mock = mocker.patch("starlette_apitally.requests.RequestLogger.log_request")
mock = mocker.patch("apitally.requests.RequestLogger.log_request")
client = TestClient(app)
background_task_mock: MagicMock = app.state.background_task_mock # type: ignore[attr-defined]

Expand Down Expand Up @@ -203,8 +203,8 @@ def test_middleware_requests_ok(app: Starlette, mocker: MockerFixture):
def test_middleware_requests_error(app: Starlette, mocker: MockerFixture):
from starlette.testclient import TestClient

mocker.patch("starlette_apitally.client.ApitallyClient.send_app_info")
mock = mocker.patch("starlette_apitally.requests.RequestLogger.log_request")
mocker.patch("apitally.client.ApitallyClient.send_app_info")
mock = mocker.patch("apitally.requests.RequestLogger.log_request")
client = TestClient(app, raise_server_exceptions=False)

response = client.post("/baz/")
Expand All @@ -220,8 +220,8 @@ def test_middleware_requests_error(app: Starlette, mocker: MockerFixture):
def test_middleware_requests_unhandled(app: Starlette, mocker: MockerFixture):
from starlette.testclient import TestClient

mocker.patch("starlette_apitally.client.ApitallyClient.send_app_info")
mock = mocker.patch("starlette_apitally.requests.RequestLogger.log_request")
mocker.patch("apitally.client.ApitallyClient.send_app_info")
mock = mocker.patch("apitally.requests.RequestLogger.log_request")
client = TestClient(app)

response = client.post("/xxx/")
Expand All @@ -232,7 +232,7 @@ def test_middleware_requests_unhandled(app: Starlette, mocker: MockerFixture):
def test_keys_auth_backend(app_with_auth: Starlette, mocker: MockerFixture):
from starlette.testclient import TestClient

from starlette_apitally.keys import KeyInfo, KeyRegistry
from apitally.keys import KeyInfo, KeyRegistry

client = TestClient(app_with_auth)
key_registry = KeyRegistry()
Expand All @@ -245,7 +245,7 @@ def test_keys_auth_backend(app_with_auth: Starlette, mocker: MockerFixture):
)
}
headers = {"Authorization": "ApiKey 7ll40FB.DuHxzQQuGQU4xgvYvTpmnii7K365j9VI"}
mock = mocker.patch("starlette_apitally.starlette.ApitallyClient.get_instance")
mock = mocker.patch("apitally.starlette.ApitallyClient.get_instance")
mock.return_value.key_registry = key_registry

# Unauthenticated
Expand Down Expand Up @@ -277,9 +277,9 @@ def test_keys_auth_backend(app_with_auth: Starlette, mocker: MockerFixture):


def test_get_app_info(app: Starlette, mocker: MockerFixture):
from starlette_apitally.starlette import _get_app_info
from apitally.starlette import _get_app_info

mocker.patch("starlette_apitally.starlette.ApitallyClient")
mocker.patch("apitally.starlette.ApitallyClient")
if app.middleware_stack is None:
app.middleware_stack = app.build_middleware_stack()

Expand Down

0 comments on commit d956dea

Please sign in to comment.