Skip to content

Commit

Permalink
Various
Browse files Browse the repository at this point in the history
  • Loading branch information
bendikrb committed Nov 6, 2023
1 parent 063129d commit f2a9d09
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 24 deletions.
15 changes: 10 additions & 5 deletions kassalappy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import asyncio
import logging
from typing import TYPE_CHECKING, Any, Literal
from typing import TYPE_CHECKING, Literal

import aiohttp
import async_timeout
Expand Down Expand Up @@ -47,11 +47,11 @@ async def execute(
self,
endpoint: str,
method: str = aiohttp.hdrs.METH_GET,
params: dict[str, Any] | None = None,
data: dict[Any, Any] | None = None,
params: dict[str, any] | None = None,
data: dict[any, any] | None = None,
timeout: int | None = None,
map_to_model: bool = False,
) -> dict[Any, Any] | KassalappResource | list[KassalappResource] | None:
) -> dict[any, any] | KassalappResource | list[KassalappResource] | None:
""""Execute a API request and return the data."""
timeout = timeout or self.timeout

Expand All @@ -76,9 +76,14 @@ async def execute(
_LOGGER.exception("Error connecting to kassalapp")
raise

async def healthy(self):
"""Check if the Kassalapp API is working."""
result = await self.execute("health")
return result.get("message") == "Healthy"

async def get_shopping_lists(self):
"""Get shopping lists."""
return await self.execute(f"shopping-lists")
return await self.execute("shopping-lists")

async def get_shopping_list(self, list_id: int, include_items: bool = False):
"""Get a shopping list."""
Expand Down
4 changes: 4 additions & 0 deletions kassalappy/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,8 @@
HTTPStatus.TOO_MANY_REQUESTS,
HTTPStatus.PRECONDITION_REQUIRED,
]
HTTP_CODES_NO_ACCESS: Final = [
HTTPStatus.UNAUTHORIZED,
HTTPStatus.FORBIDDEN,
]
HTTP_CODES_FATAL: Final = [HTTPStatus.BAD_REQUEST]
7 changes: 5 additions & 2 deletions kassalappy/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ def __init__(
self,
status: int,
message: str = "HTTP error",
extension_code: str = API_ERR_CODE_UNKNOWN,
errors: dict[str, str] | None = None,
):
self.status = status
self.message = message
self.extension_code = extension_code
self.errors = errors
super().__init__(self.message)


Expand All @@ -22,3 +22,6 @@ class FatalHttpException(HttpException):

class RetryableHttpException(HttpException):
"""Exception raised for HTTP codes that are possible to retry."""

class AuthorizationError(FatalHttpException):
"""Invalid login exception."""
2 changes: 1 addition & 1 deletion kassalappy/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from datetime import datetime
from typing import TYPE_CHECKING

from enum import Enum
from pydantic import BaseModel


Expand Down
41 changes: 26 additions & 15 deletions kassalappy/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,21 @@

import logging
import re

import aiohttp

from http import HTTPStatus

from .const import (
API_ERR_CODE_UNKNOWN,
HTTP_CODES_NO_ACCESS,
HTTP_CODES_FATAL,
HTTP_CODES_RETRYABLE,
)
from .exceptions import FatalHttpException, RetryableHttpException
from .exceptions import (
AuthorizationError,
FatalHttpException,
RetryableHttpException,
)
from .models import (
KassalappResource,
ShoppingList,
Expand Down Expand Up @@ -53,30 +59,35 @@ async def extract_response_data(

result = await response.json()
if response.ok:
data = result.get("data")
data = result.get("data") or result
if map_to_model:
model = path_to_model(response.url.path)
if isinstance(data, list):
return [model(**d) for d in data]
return model(**data)
return data

if response.status in HTTP_CODES_RETRYABLE:
error_message = result.get("message")
error_message = result.get("message")
errors = result.get("errors", {})

raise RetryableHttpException(
response.status, message=error_message
)
if response.status == HTTPStatus.NOT_FOUND:
raise FatalHttpException(response.status, error_message)

if response.status in HTTP_CODES_FATAL:
error_message = result.get("message", "")
# if error_code == API_ERR_CODE_UNAUTH:
# raise InvalidLogin(response.status, error_message)
if response.status == HTTPStatus.UNPROCESSABLE_ENTITY:
raise FatalHttpException(response.status, error_message, errors)

raise FatalHttpException(response.status, error_message)
if response.status in HTTP_CODES_NO_ACCESS:
raise AuthorizationError(response.status, error_message, errors)

if response.status in HTTP_CODES_RETRYABLE:
raise RetryableHttpException(response.status, error_message)

if response.status in HTTP_CODES_FATAL:
raise FatalHttpException(response.status, error_message, errors)

error_message = result.get("mesasge", "")
# if reached here the HTTP response code is not currently handled
raise FatalHttpException(
response.status, f"Unhandled error: {error_message}"
response.status,
f"Unhandled error: {error_message}",
errors,
)
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "kassalappy"
version = "0.6.0"
version = "0.7.0"
description = ""
authors = ["Bendik R. Brenne <[email protected]>"]
license = "MIT"
Expand Down

0 comments on commit f2a9d09

Please sign in to comment.