fastapi-errors-plus 0.6.1__py3-none-any.whl → 0.6.2__py3-none-any.whl

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.
@@ -10,5 +10,5 @@ __all__ = [
10
10
  "BaseErrorDTO", # Base implementation (optional)
11
11
  "StandardErrorDTO", # Extended implementation (optional)
12
12
  ]
13
- __version__ = "0.6.1"
13
+ __version__ = "0.6.2"
14
14
 
@@ -122,3 +122,4 @@ class StandardErrorDTO(BaseErrorDTO):
122
122
 
123
123
 
124
124
 
125
+
@@ -140,7 +140,7 @@ class Errors(Mapping):
140
140
 
141
141
  if add_422:
142
142
  self._add_standard_error(
143
- status.HTTP_422_UNPROCESSABLE_ENTITY,
143
+ status.HTTP_422_UNPROCESSABLE_CONTENT,
144
144
  "Validation Error",
145
145
  {"detail": "Validation error"},
146
146
  )
@@ -239,7 +239,7 @@ class Errors(Mapping):
239
239
  STANDARD_DESCRIPTIONS = {
240
240
  status.HTTP_401_UNAUTHORIZED: "Unauthorized",
241
241
  status.HTTP_403_FORBIDDEN: "Forbidden",
242
- status.HTTP_422_UNPROCESSABLE_ENTITY: "Validation Error",
242
+ status.HTTP_422_UNPROCESSABLE_CONTENT: "Validation Error",
243
243
  status.HTTP_500_INTERNAL_SERVER_ERROR: "Internal Server Error",
244
244
  }
245
245
 
@@ -263,7 +263,7 @@ class Errors(Mapping):
263
263
  standard_keys = {
264
264
  status.HTTP_401_UNAUTHORIZED: "StandardUnauthorized",
265
265
  status.HTTP_403_FORBIDDEN: "StandardForbidden",
266
- status.HTTP_422_UNPROCESSABLE_ENTITY: "StandardValidationError",
266
+ status.HTTP_422_UNPROCESSABLE_CONTENT: "StandardValidationError",
267
267
  status.HTTP_500_INTERNAL_SERVER_ERROR: "StandardInternalServerError",
268
268
  }
269
269
  example_key = standard_keys.get(status_code, f"Standard{status_code}")
@@ -50,3 +50,4 @@ class ErrorDTO(Protocol):
50
50
 
51
51
 
52
52
 
53
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fastapi-errors-plus
3
- Version: 0.6.1
3
+ Version: 0.6.2
4
4
  Summary: Universal library for documenting errors in FastAPI endpoints
5
5
  Author-email: Igor Selivanov <seligoroff@gmail.com>
6
6
  License: MIT
@@ -335,6 +335,102 @@ Any class implementing this protocol (through structural typing) can be used wit
335
335
 
336
336
  Both approaches work together — you can mix them in the same `Errors()` call!
337
337
 
338
+ ## Using Pydantic with ErrorDTO
339
+
340
+ **Note:** Pydantic is **not required** to use this library. This section is for projects that already use Pydantic and want to integrate it with the ErrorDTO protocol.
341
+
342
+ Since the library uses structural typing (Protocol), any class that implements the required attributes (`status_code`, `message`, `to_example()`) will work, including Pydantic models.
343
+
344
+ ### Simple Pydantic Model as ErrorDTO
345
+
346
+ ```python
347
+ from pydantic import BaseModel, Field
348
+ from fastapi_errors_plus import Errors
349
+ from typing import Dict, Any
350
+
351
+ class PydanticErrorDTO(BaseModel):
352
+ """Pydantic model implementing ErrorDTO Protocol."""
353
+ status_code: int = Field(..., ge=400, le=599, description="HTTP status code")
354
+ message: str = Field(..., min_length=1, description="Error message")
355
+
356
+ def to_example(self) -> Dict[str, Any]:
357
+ """Generate example for OpenAPI."""
358
+ return {
359
+ self.message: {
360
+ "value": {"detail": self.message},
361
+ },
362
+ }
363
+
364
+ # Usage
365
+ notification_error = PydanticErrorDTO(
366
+ status_code=404,
367
+ message="Notification not found",
368
+ )
369
+
370
+ @router.delete(
371
+ "/{id}",
372
+ responses=Errors(notification_error),
373
+ )
374
+ def delete_item(id: int):
375
+ pass
376
+ ```
377
+
378
+ **Benefits:**
379
+ - Runtime validation through Pydantic
380
+ - Type safety
381
+ - Automatic field documentation
382
+ - Works with ErrorDTO Protocol through structural typing
383
+
384
+ ### Complex ErrorDTO with Pydantic
385
+
386
+ For errors with additional fields:
387
+
388
+ ```python
389
+ from pydantic import BaseModel, Field
390
+ from fastapi_errors_plus import Errors
391
+ from typing import Dict, Any, Optional
392
+
393
+ class DetailedErrorDTO(BaseModel):
394
+ """Pydantic model for errors with additional fields."""
395
+ status_code: int = Field(..., ge=400, le=599)
396
+ message: str = Field(..., min_length=1)
397
+ error_code: Optional[str] = Field(None, description="Internal error code")
398
+ timestamp: Optional[str] = Field(None, description="Error timestamp")
399
+
400
+ def to_example(self) -> Dict[str, Any]:
401
+ """Generate example for OpenAPI."""
402
+ example = {"detail": self.message}
403
+ if self.error_code:
404
+ example["error_code"] = self.error_code
405
+ if self.timestamp:
406
+ example["timestamp"] = self.timestamp
407
+
408
+ return {
409
+ self.message: {
410
+ "value": example,
411
+ },
412
+ }
413
+
414
+ # Usage
415
+ validation_error = DetailedErrorDTO(
416
+ status_code=422,
417
+ message="Validation failed",
418
+ error_code="VALIDATION_ERROR",
419
+ timestamp="2025-01-15T10:30:00Z",
420
+ )
421
+ ```
422
+
423
+ **When to use Pydantic with ErrorDTO:**
424
+ - Your project already uses Pydantic extensively
425
+ - You need runtime validation for error objects
426
+ - You want automatic field documentation
427
+ - You have complex error structures with multiple fields
428
+
429
+ **When not to use Pydantic:**
430
+ - Your project doesn't use Pydantic (use `BaseErrorDTO` or `StandardErrorDTO` instead)
431
+ - You need simple error objects (dataclasses are sufficient)
432
+ - You want to keep dependencies minimal
433
+
338
434
  ## Best Practice: Connecting Exceptions and ErrorDTO
339
435
 
340
436
  ### Problem
@@ -0,0 +1,10 @@
1
+ fastapi_errors_plus/__init__.py,sha256=EGgxWvcYC_R3mwD8wDu5_Cx7U2E58pnYnC3YHrDtzJY,454
2
+ fastapi_errors_plus/base.py,sha256=tGCroiEZM9aNYH9ikmYbp-FHZF7yDMfZyMMF-5rc9qQ,3581
3
+ fastapi_errors_plus/errors.py,sha256=zS1AO_auXfDlrnfNMHkvNpUwREXs76atL_fRDlm_cUo,20871
4
+ fastapi_errors_plus/protocol.py,sha256=HaoMr73cL64y3Q9KcO0cKh_DcJbcR3VHxMZLsmpjsWI,1219
5
+ fastapi_errors_plus/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ fastapi_errors_plus-0.6.2.dist-info/licenses/LICENSE,sha256=PpYbS0f6IOOqH1JNR3K1UKZdEio6iO2ur9r8TwIZ7zs,1094
7
+ fastapi_errors_plus-0.6.2.dist-info/METADATA,sha256=a9v0T3zfWh8uSBmK6UpzRvun7yS7DxgyO80odgtUECY,24420
8
+ fastapi_errors_plus-0.6.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
9
+ fastapi_errors_plus-0.6.2.dist-info/top_level.txt,sha256=vmHLF1-DQYB2quqrvdBA0g6rDtgOWQBrA1m-X_WyNk8,20
10
+ fastapi_errors_plus-0.6.2.dist-info/RECORD,,
@@ -1,10 +0,0 @@
1
- fastapi_errors_plus/__init__.py,sha256=aYuyu5HwVWzgT0QhkKhHuJez0ARHoHG0ynQCHQPzbrc,454
2
- fastapi_errors_plus/base.py,sha256=iTQ6WFxc5fLoY0Omi8aPNua7wBqQj20Z5ZPOOJhTIow,3580
3
- fastapi_errors_plus/errors.py,sha256=7ikmrSphWOH_nnxLC0HPQ0RPiuR1u8olw3bxGxdLv50,20868
4
- fastapi_errors_plus/protocol.py,sha256=466lfnVKWa1jjD0iWy3r_FIXFIqTuATJOT9sqXxbKZE,1218
5
- fastapi_errors_plus/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
- fastapi_errors_plus-0.6.1.dist-info/licenses/LICENSE,sha256=W_dONuuw-DA1UPcP9NPnQbhCbtMkLjhUr3Ne96398VU,1093
7
- fastapi_errors_plus-0.6.1.dist-info/METADATA,sha256=PA7WauqlQWEKuOIz_Mcv5ECBaLgTCng1cSKN34fJof4,21455
8
- fastapi_errors_plus-0.6.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
9
- fastapi_errors_plus-0.6.1.dist-info/top_level.txt,sha256=vmHLF1-DQYB2quqrvdBA0g6rDtgOWQBrA1m-X_WyNk8,20
10
- fastapi_errors_plus-0.6.1.dist-info/RECORD,,