fastapiabclib 4.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,15 @@
1
+ Metadata-Version: 2.3
2
+ Name: fastapiabclib
3
+ Version: 4.2.0
4
+ Summary: Exception handling and utilities for FastAPI applications
5
+ License: MIT
6
+ Author: Aleksandr Yurlov
7
+ Author-email: sasha.yur@mail.ru
8
+ Requires-Python: >=3.10,<4.0
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.10
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Programming Language :: Python :: 3.13
15
+ Requires-Dist: fastabc (>=4.3.0,<5.0.0)
@@ -0,0 +1,30 @@
1
+ from fastabc import Api, App
2
+
3
+ from .constants import HTTP_CODE_ERROR_DEFAULT, HTTP_CODE_START
4
+ from .exceptions import (
5
+ BadRequestHTTPError,
6
+ BaseHTTPError,
7
+ ForbiddenHTTPError,
8
+ InternalHTTPError,
9
+ NotAllowHTTPError,
10
+ NotFoundHTTPError,
11
+ UnauthorizedHTTPError,
12
+ )
13
+ from .output import abort, json
14
+
15
+ __version__ = "4.3.0"
16
+ __all__ = [
17
+ "Api",
18
+ "App",
19
+ "abort",
20
+ "json",
21
+ "BadRequestHTTPError",
22
+ "BaseHTTPError",
23
+ "ForbiddenHTTPError",
24
+ "InternalHTTPError",
25
+ "NotAllowHTTPError",
26
+ "NotFoundHTTPError",
27
+ "UnauthorizedHTTPError",
28
+ "HTTP_CODE_START",
29
+ "HTTP_CODE_ERROR_DEFAULT",
30
+ ]
@@ -0,0 +1,2 @@
1
+ HTTP_CODE_START = 100
2
+ HTTP_CODE_ERROR_DEFAULT = 500
@@ -0,0 +1,44 @@
1
+ from fastapi import HTTPException
2
+
3
+ from .constants import HTTP_CODE_ERROR_DEFAULT, HTTP_CODE_START
4
+
5
+ __all__ = ["HTTPException"]
6
+
7
+
8
+ class BaseHTTPError(Exception):
9
+ def __init__(self, message: str, code: int) -> None:
10
+ self.code = code if code > HTTP_CODE_START else HTTP_CODE_ERROR_DEFAULT
11
+ self.message = message
12
+
13
+ def __str__(self):
14
+ return f"{self.message} ({self.code})"
15
+
16
+
17
+ class BadRequestHTTPError(BaseHTTPError):
18
+ def __init__(self, message: str = "Bad Request") -> None:
19
+ super().__init__(message, 400)
20
+
21
+
22
+ class UnauthorizedHTTPError(BaseHTTPError):
23
+ def __init__(self, message: str = "Authorization Required") -> None:
24
+ super().__init__(message, 401)
25
+
26
+
27
+ class ForbiddenHTTPError(BaseHTTPError):
28
+ def __init__(self, message: str = "Forbidden") -> None:
29
+ super().__init__(message, 403)
30
+
31
+
32
+ class NotFoundHTTPError(BaseHTTPError):
33
+ def __init__(self, message: str = "Not Found") -> None:
34
+ super().__init__(message, 404)
35
+
36
+
37
+ class NotAllowHTTPError(BaseHTTPError):
38
+ def __init__(self, message: str = "Method Not Allowed") -> None:
39
+ super().__init__(message, 405)
40
+
41
+
42
+ class InternalHTTPError(BaseHTTPError):
43
+ def __init__(self, message: str = "Internal Server Error") -> None:
44
+ super().__init__(message, 500)
@@ -0,0 +1,42 @@
1
+ from typing import Any
2
+
3
+ from fastapi import HTTPException
4
+ from fastapi.responses import JSONResponse
5
+
6
+ from .exceptions import BadRequestHTTPError, BaseHTTPError, InternalHTTPError
7
+ from .structures import JSONError
8
+
9
+
10
+ def json(content: Any, status_code: int = 200) -> JSONResponse:
11
+ """
12
+ Создаёт JSONResponse (аналог sanic.response.json для совместимости).
13
+
14
+ Args:
15
+ content: Данные для JSON-ответа
16
+ status_code: HTTP статус-код (по умолчанию 200)
17
+
18
+ Returns:
19
+ JSONResponse с указанными данными и статус-кодом
20
+
21
+ Example:
22
+ >>> return json({"message": "Success"}, 201)
23
+ >>> return json([item.to_dict() for item in items])
24
+ """
25
+ return JSONResponse(content=content, status_code=status_code)
26
+
27
+
28
+ def abort(exception: Exception | BaseException, description: str | None = None) -> JSONResponse:
29
+ if isinstance(exception, BaseHTTPError):
30
+ pass
31
+ elif isinstance(exception, (ValueError, KeyError, TypeError)):
32
+ description = description if description is not None else str(exception)
33
+ exception = BadRequestHTTPError()
34
+ elif isinstance(exception, HTTPException):
35
+ exception = BaseHTTPError(str(exception.detail), exception.status_code)
36
+ else:
37
+ exception = InternalHTTPError()
38
+
39
+ return JSONResponse(
40
+ content=JSONError.create(exception, description).to_dict(),
41
+ status_code=exception.code
42
+ )
@@ -0,0 +1,25 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass
4
+
5
+
6
+ @dataclass
7
+ class JSONError:
8
+ message: str
9
+ description: str
10
+ error: Exception
11
+
12
+ @classmethod
13
+ def create(cls, exception: Exception, description: str | None = None) -> JSONError:
14
+ return cls(
15
+ message=getattr(exception, "message", str(exception)),
16
+ description=description if isinstance(description, str) else "",
17
+ error=exception,
18
+ )
19
+
20
+ def to_dict(self):
21
+ return {
22
+ "message": self.message,
23
+ "description": self.description,
24
+ "error": f"{type(self.error)} - {self.error}",
25
+ }
@@ -0,0 +1,20 @@
1
+ [tool.poetry]
2
+ name = "fastapiabclib"
3
+ version = "4.2.0"
4
+ description = "Exception handling and utilities for FastAPI applications"
5
+ authors = ["Aleksandr Yurlov <sasha.yur@mail.ru>"]
6
+ license = "MIT"
7
+ packages = [
8
+ { include = "fastapilib" }
9
+ ]
10
+
11
+ [tool.poetry.dependencies]
12
+ python = "^3.10"
13
+ fastabc = "^4.3.0"
14
+
15
+ [tool.poetry.group.dev.dependencies]
16
+ build = "^1.2.2.post1"
17
+
18
+ [build-system]
19
+ requires = ["poetry-core>=1.0.0"]
20
+ build-backend = "poetry.core.masonry.api"