fastapi-mongo-base 1.5.0__tar.gz → 1.5.2__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 (87) hide show
  1. {fastapi_mongo_base-1.5.0/src/fastapi_mongo_base.egg-info → fastapi_mongo_base-1.5.2}/PKG-INFO +1 -1
  2. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/pyproject.toml +1 -1
  3. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/src/fastapi_mongo_base/errors/__init__.py +4 -4
  4. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/src/fastapi_mongo_base/errors/base.py +5 -5
  5. fastapi_mongo_base-1.5.2/src/fastapi_mongo_base/errors/exceptions.py +25 -0
  6. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/src/fastapi_mongo_base/errors/http.py +33 -20
  7. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/src/fastapi_mongo_base/tasks.py +24 -3
  8. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2/src/fastapi_mongo_base.egg-info}/PKG-INFO +1 -1
  9. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/src/fastapi_mongo_base.egg-info/SOURCES.txt +1 -0
  10. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/tests/test_http_errors.py +10 -13
  11. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/LICENSE.txt +0 -0
  12. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/MANIFEST.in +0 -0
  13. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/README.md +0 -0
  14. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/docs/boilerplate.md +0 -0
  15. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/docs/changelog.md +0 -0
  16. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/docs/contributing.md +0 -0
  17. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/docs/endpoints.md +0 -0
  18. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/docs/extra.css +0 -0
  19. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/docs/index.md +0 -0
  20. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/docs/installation.md +0 -0
  21. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/docs/license.md +0 -0
  22. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/docs/quickstart.md +0 -0
  23. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/docs/settings.md +0 -0
  24. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/docs/tutorial.md +0 -0
  25. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/docs/usage.md +0 -0
  26. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/mkdocs.yml +0 -0
  27. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/pytest.ini +0 -0
  28. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/setup.cfg +0 -0
  29. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/src/fastapi_mongo_base/__init__.py +0 -0
  30. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/src/fastapi_mongo_base/core/__init__.py +0 -0
  31. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/src/fastapi_mongo_base/core/app_factory.py +0 -0
  32. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/src/fastapi_mongo_base/core/config.py +0 -0
  33. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/src/fastapi_mongo_base/core/db.py +0 -0
  34. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/src/fastapi_mongo_base/core/exceptions.py +0 -0
  35. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/src/fastapi_mongo_base/db/__init__.py +0 -0
  36. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/src/fastapi_mongo_base/db/mongo.py +0 -0
  37. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/src/fastapi_mongo_base/db/redis.py +0 -0
  38. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/src/fastapi_mongo_base/db/sql.py +0 -0
  39. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/src/fastapi_mongo_base/errors/handlers.py +0 -0
  40. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/src/fastapi_mongo_base/errors/mongodb.py +0 -0
  41. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/src/fastapi_mongo_base/errors/redis.py +0 -0
  42. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/src/fastapi_mongo_base/errors/resource.py +0 -0
  43. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/src/fastapi_mongo_base/errors/responses.py +0 -0
  44. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/src/fastapi_mongo_base/errors/sql.py +0 -0
  45. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/src/fastapi_mongo_base/i18n/__init__.py +0 -0
  46. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/src/fastapi_mongo_base/i18n/languages.py +0 -0
  47. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/src/fastapi_mongo_base/i18n/messages.py +0 -0
  48. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/src/fastapi_mongo_base/logging/__init__.py +0 -0
  49. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/src/fastapi_mongo_base/logging/formatters.py +0 -0
  50. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/src/fastapi_mongo_base/middlewares/__init__.py +0 -0
  51. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/src/fastapi_mongo_base/middlewares/prometheus.py +0 -0
  52. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/src/fastapi_mongo_base/middlewares/timer.py +0 -0
  53. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/src/fastapi_mongo_base/models.py +0 -0
  54. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/src/fastapi_mongo_base/monitoring/__init__.py +0 -0
  55. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/src/fastapi_mongo_base/monitoring/middleware.py +0 -0
  56. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/src/fastapi_mongo_base/monitoring/mongo.py +0 -0
  57. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/src/fastapi_mongo_base/monitoring/sentry.py +0 -0
  58. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/src/fastapi_mongo_base/py.typed +0 -0
  59. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/src/fastapi_mongo_base/routes.py +0 -0
  60. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/src/fastapi_mongo_base/schemas.py +0 -0
  61. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/src/fastapi_mongo_base/sql/__init__.py +0 -0
  62. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/src/fastapi_mongo_base/sql/models.py +0 -0
  63. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/src/fastapi_mongo_base/sql/session.py +0 -0
  64. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/src/fastapi_mongo_base/utils/__init__.py +0 -0
  65. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/src/fastapi_mongo_base/utils/basic.py +0 -0
  66. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/src/fastapi_mongo_base/utils/bsontools.py +0 -0
  67. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/src/fastapi_mongo_base/utils/timezone.py +0 -0
  68. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/src/fastapi_mongo_base/utils/usso_routes.py +0 -0
  69. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/src/fastapi_mongo_base.egg-info/dependency_links.txt +0 -0
  70. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/src/fastapi_mongo_base.egg-info/requires.txt +0 -0
  71. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/src/fastapi_mongo_base.egg-info/top_level.txt +0 -0
  72. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/tests/__init__.py +0 -0
  73. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/tests/app/__init__.py +0 -0
  74. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/tests/app/logs/app.log +0 -0
  75. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/tests/app/main.py +0 -0
  76. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/tests/app/server.py +0 -0
  77. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/tests/conftest.py +0 -0
  78. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/tests/test_apis.py +0 -0
  79. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/tests/test_app.py +0 -0
  80. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/tests/test_db.py +0 -0
  81. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/tests/test_i18n.py +0 -0
  82. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/tests/test_middlewares.py +0 -0
  83. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/tests/test_mongodb_errors.py +0 -0
  84. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/tests/test_monitoring_mongo.py +0 -0
  85. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/tests/test_openapi_errors.py +0 -0
  86. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/tests/test_sentry.py +0 -0
  87. {fastapi_mongo_base-1.5.0 → fastapi_mongo_base-1.5.2}/tests/test_usso_routes_workspace.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fastapi-mongo-base
3
- Version: 1.5.0
3
+ Version: 1.5.2
4
4
  Summary: A simple boilerplate application, including models and schemas and abstract router, for FastAPI with MongoDB
5
5
  Author-email: Mahdi Kiani <mahdikiany@gmail.com>
6
6
  Maintainer-email: Mahdi Kiani <mahdikiany@gmail.com>
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "fastapi-mongo-base"
7
- version = "1.5.0"
7
+ version = "1.5.2"
8
8
  description = "A simple boilerplate application, including models and schemas and abstract router, for FastAPI with MongoDB"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -11,15 +11,15 @@ from .handlers import (
11
11
  )
12
12
  from .http import (
13
13
  AlreadyExistsError,
14
- APIError,
14
+ BadRequestError,
15
15
  ConflictError,
16
16
  ForbiddenError,
17
17
  GoneError,
18
- HTTPClientError,
19
18
  LockedError,
20
19
  NotFoundError,
21
20
  PaymentRequiredError,
22
21
  ServerError,
22
+ UnauthorizedError,
23
23
  )
24
24
  from .mongodb import (
25
25
  DocumentAlreadyExistsError,
@@ -55,9 +55,9 @@ from .responses import (
55
55
  __all__ = [
56
56
  "COMMON_ERROR_RESPONSES",
57
57
  "EXCEPTION_HANDLERS",
58
- "APIError",
59
58
  "APIErrorResponseModel",
60
59
  "AlreadyExistsError",
60
+ "BadRequestError",
61
61
  "BaseHTTPException",
62
62
  "ConflictError",
63
63
  "DocumentAlreadyExistsError",
@@ -65,7 +65,6 @@ __all__ = [
65
65
  "DocumentNotFoundError",
66
66
  "ForbiddenError",
67
67
  "GoneError",
68
- "HTTPClientError",
69
68
  "InternalErrorResponseModel",
70
69
  "LockedError",
71
70
  "MongoDBConnectionError",
@@ -84,6 +83,7 @@ __all__ = [
84
83
  "ResourceNotFoundError",
85
84
  "ResourcePaymentRequiredError",
86
85
  "ServerError",
86
+ "UnauthorizedError",
87
87
  "ValidationErrorResponseModel",
88
88
  "ValidationReason",
89
89
  "base_http_exception_handler",
@@ -25,8 +25,8 @@ class BaseHTTPException(HTTPException):
25
25
 
26
26
  def __init__(
27
27
  self,
28
- status_code: int,
29
- error_code: str,
28
+ status_code: int | None = None,
29
+ error_code: str | None = None,
30
30
  detail: str | None = None,
31
31
  message: dict | None = None,
32
32
  **kwargs: object,
@@ -42,8 +42,8 @@ class BaseHTTPException(HTTPException):
42
42
  **kwargs: Additional error data.
43
43
 
44
44
  """
45
- self.status_code = status_code
46
- self.error_code = error_code
45
+ self.status_code = status_code or self.status_code
46
+ self.error_code = error_code or self.error_code
47
47
  if message is None:
48
48
  if self.message_en and self.message_fa:
49
49
  self.message = localized(self.message_en, self.message_fa)
@@ -55,4 +55,4 @@ class BaseHTTPException(HTTPException):
55
55
  self.message = message
56
56
  self.detail = detail or str(self.message.get("en"))
57
57
  self.data = kwargs
58
- super().__init__(status_code, detail=detail)
58
+ super().__init__(self.status_code, detail=self.detail)
@@ -0,0 +1,25 @@
1
+ """Exceptions for the fastapi-mongo-base package."""
2
+
3
+ from .base import BaseHTTPException
4
+ from .http import (
5
+ AlreadyExistsError,
6
+ BadRequestError,
7
+ ConflictError,
8
+ ForbiddenError,
9
+ NotFoundError,
10
+ PaymentRequiredError,
11
+ ServerError,
12
+ UnauthorizedError,
13
+ )
14
+
15
+ __all__ = [
16
+ "AlreadyExistsError",
17
+ "BadRequestError",
18
+ "BaseHTTPException",
19
+ "ConflictError",
20
+ "ForbiddenError",
21
+ "NotFoundError",
22
+ "PaymentRequiredError",
23
+ "ServerError",
24
+ "UnauthorizedError",
25
+ ]
@@ -28,7 +28,34 @@ class ServerError(BaseHTTPException):
28
28
  )
29
29
 
30
30
 
31
- class NotFoundError(ServerError):
31
+ class BadRequestError(BaseHTTPException):
32
+ """Raised when a request is invalid."""
33
+
34
+ status_code = 400
35
+ error_code = "bad_request"
36
+ message_en = "Bad request"
37
+ message_fa = "درخواست نامعتبر"
38
+
39
+
40
+ class UnauthorizedError(BaseHTTPException):
41
+ """Raised when a request is unauthorized."""
42
+
43
+ status_code = 401
44
+ error_code = "unauthorized"
45
+ message_en = "Unauthorized"
46
+ message_fa = "دسترسی غیر مجاز"
47
+
48
+
49
+ class ForbiddenError(BaseHTTPException):
50
+ """Raised when a request is forbidden."""
51
+
52
+ status_code = 403
53
+ error_code = "permission_denied"
54
+ message_en = "Permission denied"
55
+ message_fa = "دسترسی غیر مجاز"
56
+
57
+
58
+ class NotFoundError(BaseHTTPException):
32
59
  """Raised when a requested entity is not found."""
33
60
 
34
61
  status_code = 404
@@ -37,7 +64,7 @@ class NotFoundError(ServerError):
37
64
  message_fa = "یافت نشد"
38
65
 
39
66
 
40
- class AlreadyExistsError(ServerError):
67
+ class AlreadyExistsError(BaseHTTPException):
41
68
  """Raised when an entity already exists."""
42
69
 
43
70
  status_code = 409
@@ -46,7 +73,7 @@ class AlreadyExistsError(ServerError):
46
73
  message_fa = "نمونه‌ی مشابه وجود دارد"
47
74
 
48
75
 
49
- class ConflictError(ServerError):
76
+ class ConflictError(BaseHTTPException):
50
77
  """Raised when a request conflicts with current state."""
51
78
 
52
79
  status_code = 409
@@ -55,7 +82,7 @@ class ConflictError(ServerError):
55
82
  message_fa = "اطلاعات ارسال شده تداخل دارد"
56
83
 
57
84
 
58
- class PaymentRequiredError(ServerError):
85
+ class PaymentRequiredError(BaseHTTPException):
59
86
  """Raised when payment is required before access."""
60
87
 
61
88
  status_code = 402
@@ -64,16 +91,7 @@ class PaymentRequiredError(ServerError):
64
91
  message_fa = "برای دسترسی، پرداخت لازم است"
65
92
 
66
93
 
67
- class ForbiddenError(ServerError):
68
- """Raised when the caller lacks permission."""
69
-
70
- status_code = 403
71
- error_code = "permission_denied"
72
- message_en = "Permission denied"
73
- message_fa = "دسترسی غیر مجاز"
74
-
75
-
76
- class GoneError(ServerError):
94
+ class GoneError(BaseHTTPException):
77
95
  """Raised when an entity is no longer available."""
78
96
 
79
97
  status_code = 410
@@ -82,15 +100,10 @@ class GoneError(ServerError):
82
100
  message_fa = "در دسترس نیست"
83
101
 
84
102
 
85
- class LockedError(ServerError):
103
+ class LockedError(BaseHTTPException):
86
104
  """Raised when an entity is locked."""
87
105
 
88
106
  status_code = 423
89
107
  error_code = "resource_locked"
90
108
  message_en = "Resource locked"
91
109
  message_fa = "قفل شده است"
92
-
93
-
94
- # Backward-compatible aliases from earlier refactors.
95
- HTTPClientError = ServerError
96
- APIError = ServerError
@@ -158,7 +158,30 @@ class TaskReferenceList(BaseModel):
158
158
  ])
159
159
 
160
160
 
161
- class TaskMixin(BaseModel):
161
+ class TaskCreateFieldsMixin(BaseModel):
162
+ """Common optional fields accepted when creating async tasks."""
163
+
164
+ user_id: str | None = Field(
165
+ None,
166
+ description="Target user id (omitted = authenticated user)",
167
+ )
168
+ webhook_url: str | None = Field(
169
+ None,
170
+ description="URL to notify when the task completes",
171
+ )
172
+ webhook_custom_headers: dict | None = Field(
173
+ None,
174
+ description="Custom headers to send in webhook requests",
175
+ )
176
+ meta_data: dict | None = Field(
177
+ None,
178
+ description=(
179
+ "Client metadata stored on the task and echoed in webhooks"
180
+ ),
181
+ )
182
+
183
+
184
+ class TaskMixin(TaskCreateFieldsMixin):
162
185
  """Mixin class for entities with task processing capabilities."""
163
186
 
164
187
  task_status: TaskStatusEnum = TaskStatusEnum.draft
@@ -169,8 +192,6 @@ class TaskMixin(BaseModel):
169
192
  task_start_at: datetime | None = None
170
193
  task_end_at: datetime | None = None
171
194
  task_order_score: int = 0
172
- webhook_custom_headers: dict | None = None
173
- webhook_url: str | None = None
174
195
 
175
196
  @property
176
197
  def webhook_exclude_fields(self) -> set[str] | None:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fastapi-mongo-base
3
- Version: 1.5.0
3
+ Version: 1.5.2
4
4
  Summary: A simple boilerplate application, including models and schemas and abstract router, for FastAPI with MongoDB
5
5
  Author-email: Mahdi Kiani <mahdikiany@gmail.com>
6
6
  Maintainer-email: Mahdi Kiani <mahdikiany@gmail.com>
@@ -38,6 +38,7 @@ src/fastapi_mongo_base/db/redis.py
38
38
  src/fastapi_mongo_base/db/sql.py
39
39
  src/fastapi_mongo_base/errors/__init__.py
40
40
  src/fastapi_mongo_base/errors/base.py
41
+ src/fastapi_mongo_base/errors/exceptions.py
41
42
  src/fastapi_mongo_base/errors/handlers.py
42
43
  src/fastapi_mongo_base/errors/http.py
43
44
  src/fastapi_mongo_base/errors/mongodb.py
@@ -4,7 +4,7 @@ import pytest
4
4
  from fastapi import HTTPException
5
5
 
6
6
  from src.fastapi_mongo_base.errors.base import BaseHTTPException
7
- from src.fastapi_mongo_base.errors.http import HTTPClientError, ServerError
7
+ from src.fastapi_mongo_base.errors.http import ServerError
8
8
  from src.fastapi_mongo_base.errors.resource import (
9
9
  AlreadyExistsError,
10
10
  ConflictError,
@@ -108,7 +108,7 @@ LEGACY_ALIASES = [
108
108
  HTTP_ERROR_CASES,
109
109
  )
110
110
  def test_api_error_class_messages(
111
- exc_cls: type[ServerError],
111
+ exc_cls: type[BaseHTTPException],
112
112
  status_code: int,
113
113
  error_code: str,
114
114
  message_en: str,
@@ -126,7 +126,7 @@ def test_api_error_class_messages(
126
126
  HTTP_ERROR_CASES,
127
127
  )
128
128
  def test_api_error_detail_and_bilingual_message(
129
- exc_cls: type[ServerError],
129
+ exc_cls: type[BaseHTTPException],
130
130
  status_code: int,
131
131
  error_code: str,
132
132
  message_en: str,
@@ -146,9 +146,11 @@ def test_api_error_detail_and_bilingual_message(
146
146
  @pytest.mark.parametrize(
147
147
  "exc_cls", ALL_HTTP_ERROR_CLASSES[1:], ids=lambda c: c.__name__
148
148
  )
149
- def test_api_errors_inherit_from_api_error(exc_cls: type[ServerError]) -> None:
149
+ def test_api_errors_inherit_from_api_error(
150
+ exc_cls: type[BaseHTTPException],
151
+ ) -> None:
150
152
  """Every specialized API error extends APIError."""
151
- assert issubclass(exc_cls, ServerError)
153
+ assert issubclass(exc_cls, BaseHTTPException)
152
154
 
153
155
 
154
156
  def test_api_error_inheritance() -> None:
@@ -167,7 +169,7 @@ def test_api_error_inheritance() -> None:
167
169
  ids=[case.id for case in HTTP_ERROR_CASES],
168
170
  )
169
171
  def test_api_error_custom_detail_preserves_bilingual_message(
170
- exc_cls: type[ServerError],
172
+ exc_cls: type[BaseHTTPException],
171
173
  message_en: str,
172
174
  message_fa: str,
173
175
  ) -> None:
@@ -189,13 +191,8 @@ def test_api_error_extra_data() -> None:
189
191
 
190
192
  @pytest.mark.parametrize(("legacy", "canonical"), LEGACY_ALIASES)
191
193
  def test_legacy_resource_error_aliases(
192
- legacy: type[ServerError],
193
- canonical: type[ServerError],
194
+ legacy: type[BaseHTTPException],
195
+ canonical: type[BaseHTTPException],
194
196
  ) -> None:
195
197
  """Resource* names remain aliases of the canonical API errors."""
196
198
  assert legacy is canonical
197
-
198
-
199
- def test_http_client_error_alias() -> None:
200
- """HTTPClientError remains an alias of APIError."""
201
- assert HTTPClientError is ServerError