fastapi-errors-plus 0.5.0__tar.gz → 0.6.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.
Files changed (19) hide show
  1. {fastapi_errors_plus-0.5.0 → fastapi_errors_plus-0.6.0}/LICENSE +1 -0
  2. {fastapi_errors_plus-0.5.0 → fastapi_errors_plus-0.6.0}/PKG-INFO +72 -5
  3. {fastapi_errors_plus-0.5.0 → fastapi_errors_plus-0.6.0}/README.md +71 -4
  4. {fastapi_errors_plus-0.5.0 → fastapi_errors_plus-0.6.0}/fastapi_errors_plus/__init__.py +1 -1
  5. {fastapi_errors_plus-0.5.0 → fastapi_errors_plus-0.6.0}/fastapi_errors_plus/base.py +1 -0
  6. {fastapi_errors_plus-0.5.0 → fastapi_errors_plus-0.6.0}/fastapi_errors_plus/protocol.py +1 -0
  7. {fastapi_errors_plus-0.5.0 → fastapi_errors_plus-0.6.0}/fastapi_errors_plus.egg-info/PKG-INFO +72 -5
  8. {fastapi_errors_plus-0.5.0 → fastapi_errors_plus-0.6.0}/pyproject.toml +27 -1
  9. {fastapi_errors_plus-0.5.0 → fastapi_errors_plus-0.6.0}/tests/test_base.py +1 -0
  10. {fastapi_errors_plus-0.5.0 → fastapi_errors_plus-0.6.0}/fastapi_errors_plus/errors.py +0 -0
  11. {fastapi_errors_plus-0.5.0 → fastapi_errors_plus-0.6.0}/fastapi_errors_plus/py.typed +0 -0
  12. {fastapi_errors_plus-0.5.0 → fastapi_errors_plus-0.6.0}/fastapi_errors_plus.egg-info/SOURCES.txt +0 -0
  13. {fastapi_errors_plus-0.5.0 → fastapi_errors_plus-0.6.0}/fastapi_errors_plus.egg-info/dependency_links.txt +0 -0
  14. {fastapi_errors_plus-0.5.0 → fastapi_errors_plus-0.6.0}/fastapi_errors_plus.egg-info/requires.txt +0 -0
  15. {fastapi_errors_plus-0.5.0 → fastapi_errors_plus-0.6.0}/fastapi_errors_plus.egg-info/top_level.txt +0 -0
  16. {fastapi_errors_plus-0.5.0 → fastapi_errors_plus-0.6.0}/setup.cfg +0 -0
  17. {fastapi_errors_plus-0.5.0 → fastapi_errors_plus-0.6.0}/tests/test_app.py +0 -0
  18. {fastapi_errors_plus-0.5.0 → fastapi_errors_plus-0.6.0}/tests/test_errors.py +0 -0
  19. {fastapi_errors_plus-0.5.0 → fastapi_errors_plus-0.6.0}/tests/test_integration.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fastapi-errors-plus
3
- Version: 0.5.0
3
+ Version: 0.6.0
4
4
  Summary: Universal library for documenting errors in FastAPI endpoints
5
5
  Author-email: Igor Selivanov <seligoroff@gmail.com>
6
6
  License: MIT
@@ -246,10 +246,10 @@ def delete_item(id: int):
246
246
  ```
247
247
 
248
248
  **Benefits:**
249
- - No need to write ErrorDTO classes from scratch
250
- - Correct implementation out of the box
251
- - Reusable across all endpoints
252
- - Supports inheritance for custom logic
249
+ - No need to write ErrorDTO classes from scratch
250
+ - Correct implementation out of the box
251
+ - Reusable across all endpoints
252
+ - Supports inheritance for custom logic
253
253
 
254
254
  ### 5. Mixed Usage
255
255
 
@@ -319,6 +319,8 @@ class ErrorDTO(Protocol):
319
319
 
320
320
  Any class implementing this protocol (through structural typing) can be used with `Errors()`.
321
321
 
322
+ **Best Practice:** For maximum clarity, consider making your domain exceptions implement the ErrorDTO protocol directly. See [Best Practice: Connecting Exceptions and ErrorDTO](#best-practice-connecting-exceptions-and-errordto) for details.
323
+
322
324
  ### When to Use Protocol vs BaseErrorDTO
323
325
 
324
326
  **Use Protocol (structural typing)** when:
@@ -333,6 +335,71 @@ Any class implementing this protocol (through structural typing) can be used wit
333
335
 
334
336
  Both approaches work together — you can mix them in the same `Errors()` call!
335
337
 
338
+ ## Best Practice: Connecting Exceptions and ErrorDTO
339
+
340
+ ### Problem
341
+
342
+ It's not always clear which exception corresponds to which ErrorDTO:
343
+
344
+ ```python
345
+ # Not clear which exception this documents
346
+ responses=Errors(notification_not_found_error)
347
+ ```
348
+
349
+ ### Solution: Domain Exception as ErrorDTO
350
+
351
+ **Recommended approach** — make your exceptions implement ErrorDTO protocol:
352
+
353
+ ```python
354
+ # domain/exceptions.py
355
+ from typing import Dict, Any
356
+
357
+ class DomainException(Exception):
358
+ """Base exception implementing ErrorDTO protocol."""
359
+ status_code: int
360
+ message: str
361
+
362
+ def to_example(self) -> Dict[str, Any]:
363
+ return {self.message: {"value": {"detail": self.message}}}
364
+
365
+ @classmethod
366
+ def for_openapi(cls):
367
+ """Returns instance for OpenAPI documentation."""
368
+ return cls()
369
+
370
+ class NotificationNotFoundError(DomainException):
371
+ status_code = 404
372
+ message = "Notification not found"
373
+
374
+ def __init__(self, notification_id: str = ""):
375
+ self.notification_id = notification_id
376
+ super().__init__(self.message)
377
+
378
+ @classmethod
379
+ def for_openapi(cls):
380
+ return cls(notification_id="example_id")
381
+
382
+ # In endpoint
383
+ @router.delete(
384
+ "/{notificationId}",
385
+ responses=Errors(
386
+ NotificationNotFoundError.for_openapi(), # Clear connection!
387
+ ),
388
+ )
389
+ async def delete_notification(notification_id: str):
390
+ if not notification:
391
+ raise NotificationNotFoundError(notification_id) # Same exception!
392
+ ```
393
+
394
+ **Benefits:**
395
+ - Exception and ErrorDTO are one class
396
+ - Clear connection visible in endpoint
397
+ - No duplication
398
+ - Type-safe
399
+ - Works with any project architecture
400
+
401
+ See [examples/domain_exceptions.py](examples/domain_exceptions.py) for complete example.
402
+
336
403
  ## Compatibility with Existing Projects
337
404
 
338
405
  If your project already has error DTOs (like `ApiErrorDTO`), they can work with `fastapi-errors-plus` if they implement the `ErrorDTO` protocol:
@@ -220,10 +220,10 @@ def delete_item(id: int):
220
220
  ```
221
221
 
222
222
  **Benefits:**
223
- - No need to write ErrorDTO classes from scratch
224
- - Correct implementation out of the box
225
- - Reusable across all endpoints
226
- - Supports inheritance for custom logic
223
+ - No need to write ErrorDTO classes from scratch
224
+ - Correct implementation out of the box
225
+ - Reusable across all endpoints
226
+ - Supports inheritance for custom logic
227
227
 
228
228
  ### 5. Mixed Usage
229
229
 
@@ -293,6 +293,8 @@ class ErrorDTO(Protocol):
293
293
 
294
294
  Any class implementing this protocol (through structural typing) can be used with `Errors()`.
295
295
 
296
+ **Best Practice:** For maximum clarity, consider making your domain exceptions implement the ErrorDTO protocol directly. See [Best Practice: Connecting Exceptions and ErrorDTO](#best-practice-connecting-exceptions-and-errordto) for details.
297
+
296
298
  ### When to Use Protocol vs BaseErrorDTO
297
299
 
298
300
  **Use Protocol (structural typing)** when:
@@ -307,6 +309,71 @@ Any class implementing this protocol (through structural typing) can be used wit
307
309
 
308
310
  Both approaches work together — you can mix them in the same `Errors()` call!
309
311
 
312
+ ## Best Practice: Connecting Exceptions and ErrorDTO
313
+
314
+ ### Problem
315
+
316
+ It's not always clear which exception corresponds to which ErrorDTO:
317
+
318
+ ```python
319
+ # Not clear which exception this documents
320
+ responses=Errors(notification_not_found_error)
321
+ ```
322
+
323
+ ### Solution: Domain Exception as ErrorDTO
324
+
325
+ **Recommended approach** — make your exceptions implement ErrorDTO protocol:
326
+
327
+ ```python
328
+ # domain/exceptions.py
329
+ from typing import Dict, Any
330
+
331
+ class DomainException(Exception):
332
+ """Base exception implementing ErrorDTO protocol."""
333
+ status_code: int
334
+ message: str
335
+
336
+ def to_example(self) -> Dict[str, Any]:
337
+ return {self.message: {"value": {"detail": self.message}}}
338
+
339
+ @classmethod
340
+ def for_openapi(cls):
341
+ """Returns instance for OpenAPI documentation."""
342
+ return cls()
343
+
344
+ class NotificationNotFoundError(DomainException):
345
+ status_code = 404
346
+ message = "Notification not found"
347
+
348
+ def __init__(self, notification_id: str = ""):
349
+ self.notification_id = notification_id
350
+ super().__init__(self.message)
351
+
352
+ @classmethod
353
+ def for_openapi(cls):
354
+ return cls(notification_id="example_id")
355
+
356
+ # In endpoint
357
+ @router.delete(
358
+ "/{notificationId}",
359
+ responses=Errors(
360
+ NotificationNotFoundError.for_openapi(), # Clear connection!
361
+ ),
362
+ )
363
+ async def delete_notification(notification_id: str):
364
+ if not notification:
365
+ raise NotificationNotFoundError(notification_id) # Same exception!
366
+ ```
367
+
368
+ **Benefits:**
369
+ - Exception and ErrorDTO are one class
370
+ - Clear connection visible in endpoint
371
+ - No duplication
372
+ - Type-safe
373
+ - Works with any project architecture
374
+
375
+ See [examples/domain_exceptions.py](examples/domain_exceptions.py) for complete example.
376
+
310
377
  ## Compatibility with Existing Projects
311
378
 
312
379
  If your project already has error DTOs (like `ApiErrorDTO`), they can work with `fastapi-errors-plus` if they implement the `ErrorDTO` protocol:
@@ -10,5 +10,5 @@ __all__ = [
10
10
  "BaseErrorDTO", # Base implementation (optional)
11
11
  "StandardErrorDTO", # Extended implementation (optional)
12
12
  ]
13
- __version__ = "0.5.0"
13
+ __version__ = "0.6.0"
14
14
 
@@ -121,3 +121,4 @@ class StandardErrorDTO(BaseErrorDTO):
121
121
  }
122
122
 
123
123
 
124
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fastapi-errors-plus
3
- Version: 0.5.0
3
+ Version: 0.6.0
4
4
  Summary: Universal library for documenting errors in FastAPI endpoints
5
5
  Author-email: Igor Selivanov <seligoroff@gmail.com>
6
6
  License: MIT
@@ -246,10 +246,10 @@ def delete_item(id: int):
246
246
  ```
247
247
 
248
248
  **Benefits:**
249
- - No need to write ErrorDTO classes from scratch
250
- - Correct implementation out of the box
251
- - Reusable across all endpoints
252
- - Supports inheritance for custom logic
249
+ - No need to write ErrorDTO classes from scratch
250
+ - Correct implementation out of the box
251
+ - Reusable across all endpoints
252
+ - Supports inheritance for custom logic
253
253
 
254
254
  ### 5. Mixed Usage
255
255
 
@@ -319,6 +319,8 @@ class ErrorDTO(Protocol):
319
319
 
320
320
  Any class implementing this protocol (through structural typing) can be used with `Errors()`.
321
321
 
322
+ **Best Practice:** For maximum clarity, consider making your domain exceptions implement the ErrorDTO protocol directly. See [Best Practice: Connecting Exceptions and ErrorDTO](#best-practice-connecting-exceptions-and-errordto) for details.
323
+
322
324
  ### When to Use Protocol vs BaseErrorDTO
323
325
 
324
326
  **Use Protocol (structural typing)** when:
@@ -333,6 +335,71 @@ Any class implementing this protocol (through structural typing) can be used wit
333
335
 
334
336
  Both approaches work together — you can mix them in the same `Errors()` call!
335
337
 
338
+ ## Best Practice: Connecting Exceptions and ErrorDTO
339
+
340
+ ### Problem
341
+
342
+ It's not always clear which exception corresponds to which ErrorDTO:
343
+
344
+ ```python
345
+ # Not clear which exception this documents
346
+ responses=Errors(notification_not_found_error)
347
+ ```
348
+
349
+ ### Solution: Domain Exception as ErrorDTO
350
+
351
+ **Recommended approach** — make your exceptions implement ErrorDTO protocol:
352
+
353
+ ```python
354
+ # domain/exceptions.py
355
+ from typing import Dict, Any
356
+
357
+ class DomainException(Exception):
358
+ """Base exception implementing ErrorDTO protocol."""
359
+ status_code: int
360
+ message: str
361
+
362
+ def to_example(self) -> Dict[str, Any]:
363
+ return {self.message: {"value": {"detail": self.message}}}
364
+
365
+ @classmethod
366
+ def for_openapi(cls):
367
+ """Returns instance for OpenAPI documentation."""
368
+ return cls()
369
+
370
+ class NotificationNotFoundError(DomainException):
371
+ status_code = 404
372
+ message = "Notification not found"
373
+
374
+ def __init__(self, notification_id: str = ""):
375
+ self.notification_id = notification_id
376
+ super().__init__(self.message)
377
+
378
+ @classmethod
379
+ def for_openapi(cls):
380
+ return cls(notification_id="example_id")
381
+
382
+ # In endpoint
383
+ @router.delete(
384
+ "/{notificationId}",
385
+ responses=Errors(
386
+ NotificationNotFoundError.for_openapi(), # Clear connection!
387
+ ),
388
+ )
389
+ async def delete_notification(notification_id: str):
390
+ if not notification:
391
+ raise NotificationNotFoundError(notification_id) # Same exception!
392
+ ```
393
+
394
+ **Benefits:**
395
+ - Exception and ErrorDTO are one class
396
+ - Clear connection visible in endpoint
397
+ - No duplication
398
+ - Type-safe
399
+ - Works with any project architecture
400
+
401
+ See [examples/domain_exceptions.py](examples/domain_exceptions.py) for complete example.
402
+
336
403
  ## Compatibility with Existing Projects
337
404
 
338
405
  If your project already has error DTOs (like `ApiErrorDTO`), they can work with `fastapi-errors-plus` if they implement the `ErrorDTO` protocol:
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "fastapi-errors-plus"
7
- version = "0.5.0"
7
+ version = "0.6.0"
8
8
  description = "Universal library for documenting errors in FastAPI endpoints"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.8"
@@ -46,3 +46,29 @@ python_files = "test_*.py"
46
46
  python_classes = "Test*"
47
47
  python_functions = "test_*"
48
48
 
49
+ [tool.coverage.run]
50
+ source = ["fastapi_errors_plus"]
51
+ omit = [
52
+ "*/tests/*",
53
+ "*/__pycache__/*",
54
+ "*/venv/*",
55
+ "*/.venv/*",
56
+ ]
57
+
58
+ [tool.coverage.report]
59
+ exclude_lines = [
60
+ "pragma: no cover",
61
+ "def __repr__",
62
+ "raise AssertionError",
63
+ "raise NotImplementedError",
64
+ "if __name__ == .__main__.:",
65
+ "if TYPE_CHECKING:",
66
+ "@abstractmethod",
67
+ ]
68
+ precision = 2
69
+ show_missing = true
70
+ skip_covered = false
71
+
72
+ [tool.coverage.html]
73
+ directory = "tests/htmlcov"
74
+
@@ -303,3 +303,4 @@ class TestBaseErrorDTOCompatibility:
303
303
  assert status.HTTP_500_INTERNAL_SERVER_ERROR in responses
304
304
 
305
305
 
306
+