Skip to content

Commit 57a5452

Browse files
Ihor BilousIhor Bilous
authored andcommitted
Fix issue #29: Start using pydantic.dataclasses instead of simple dataclasses
1 parent 92c788a commit 57a5452

File tree

11 files changed

+51
-59
lines changed

11 files changed

+51
-59
lines changed

examples/testing/projects.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1-
from mailtrap import MailtrapApiClient
1+
from mailtrap import MailtrapClient
22
from mailtrap.models.projects import Project
33

44
API_TOKEN = "YOU_API_TOKEN"
55
ACCOUNT_ID = "YOU_ACCOUNT_ID"
66

7-
client = MailtrapApiClient(token=API_TOKEN)
8-
testing_api = client.testing_api(ACCOUNT_ID)
9-
projects_api = testing_api.projects
7+
client = MailtrapClient(token=API_TOKEN, account_id=ACCOUNT_ID)
8+
projects_api = client.testing_api.projects
109

1110

1211
def list_projects() -> list[Project]:

mailtrap/__init__.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
from .client import MailtrapApiClient
21
from .client import MailtrapClient
32
from .exceptions import APIError
43
from .exceptions import AuthorizationError

mailtrap/client.py

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
from typing import NoReturn
22
from typing import Optional
33
from typing import Union
4+
from typing import cast
45

56
import requests
67

78
from mailtrap.api.testing import TestingApi
8-
from mailtrap.config import GENERAL_ENDPOINT
9+
from mailtrap.config import GENERAL_HOST
910
from mailtrap.exceptions import APIError
1011
from mailtrap.exceptions import AuthorizationError
1112
from mailtrap.exceptions import ClientConfigurationError
@@ -26,17 +27,28 @@ def __init__(
2627
api_port: int = DEFAULT_PORT,
2728
bulk: bool = False,
2829
sandbox: bool = False,
30+
account_id: Optional[str] = None,
2931
inbox_id: Optional[str] = None,
3032
) -> None:
3133
self.token = token
3234
self.api_host = api_host
3335
self.api_port = api_port
3436
self.bulk = bulk
3537
self.sandbox = sandbox
38+
self.account_id = account_id
3639
self.inbox_id = inbox_id
3740

3841
self._validate_itself()
3942

43+
@property
44+
def testing_api(self) -> TestingApi:
45+
self._validate_account_id()
46+
return TestingApi(
47+
account_id=cast(str, self.account_id),
48+
inbox_id=self.inbox_id,
49+
client=HttpClient(host=GENERAL_HOST, headers=self.headers),
50+
)
51+
4052
def send(self, mail: BaseMail) -> dict[str, Union[bool, list[str]]]:
4153
response = requests.post(
4254
self.api_send_url, headers=self.headers, json=mail.api_data
@@ -102,21 +114,6 @@ def _validate_itself(self) -> None:
102114
if self.bulk and self.sandbox:
103115
raise ClientConfigurationError("bulk mode is not allowed in sandbox mode")
104116

105-
106-
class MailtrapApiClient:
107-
def __init__(self, token: str) -> None:
108-
self.token = token
109-
110-
def testing_api(self, account_id: str, inbox_id: Optional[str] = None) -> TestingApi:
111-
http_client = HttpClient(host=GENERAL_ENDPOINT, headers=self.headers)
112-
return TestingApi(account_id=account_id, inbox_id=inbox_id, client=http_client)
113-
114-
@property
115-
def headers(self) -> dict[str, str]:
116-
return {
117-
"Authorization": f"Bearer {self.token}",
118-
"Content-Type": "application/json",
119-
"User-Agent": (
120-
"mailtrap-python (https://github.com/railsware/mailtrap-python)"
121-
),
122-
}
117+
def _validate_account_id(self) -> None:
118+
if not self.account_id:
119+
raise ClientConfigurationError("`account_id` is required for Testing API")

mailtrap/config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
GENERAL_ENDPOINT = "mailtrap.io"
1+
GENERAL_HOST = "mailtrap.io"
22

33
DEFAULT_REQUEST_TIMEOUT = 30 # in seconds

mailtrap/models/common.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
from pydantic import BaseModel
1+
from pydantic.dataclasses import dataclass
22

33

4-
class DeletedObject(BaseModel):
4+
@dataclass
5+
class DeletedObject:
56
id: int

mailtrap/models/inboxes.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
from typing import Optional
22

3-
from pydantic import BaseModel
3+
from pydantic.dataclasses import dataclass
44

55
from mailtrap.models.permissions import Permissions
66

77

8-
class Inbox(BaseModel):
8+
@dataclass
9+
class Inbox:
910
id: int
1011
name: str
1112
username: str

mailtrap/models/permissions.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
from pydantic import BaseModel
1+
from pydantic.dataclasses import dataclass
22

33

4-
class Permissions(BaseModel):
4+
@dataclass
5+
class Permissions:
56
can_read: bool
67
can_update: bool
78
can_destroy: bool

mailtrap/models/projects.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,21 @@
1-
from pydantic import BaseModel
1+
from typing import Optional
2+
3+
from pydantic.dataclasses import dataclass
24

35
from mailtrap.models.inboxes import Inbox
46
from mailtrap.models.permissions import Permissions
57

68

7-
class ShareLinks(BaseModel):
9+
@dataclass
10+
class ShareLinks:
811
admin: str
912
viewer: str
1013

1114

12-
class Project(BaseModel):
15+
@dataclass
16+
class Project:
1317
id: int
1418
name: str
15-
share_links: ShareLinks
1619
inboxes: list[Inbox]
1720
permissions: Permissions
21+
share_links: Optional[ShareLinks] = None

pyproject.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,7 @@ classifiers = [
1717
"Programming Language :: Python :: 3.13",
1818
]
1919
requires-python = ">=3.9"
20-
dependencies = [
21-
"requests>=2.26.0",
22-
"pydantic>=2.11.7",
23-
]
20+
dynamic = ["dependencies"]
2421

2522
[project.urls]
2623
Homepage = "https://mailtrap.io/"
@@ -32,6 +29,9 @@ Repository = "https://github.com/railsware/mailtrap-python.git"
3229
requires = ["setuptools"]
3330
build-backend = "setuptools.build_meta"
3431

32+
[tool.setuptools.dynamic]
33+
dependencies = {file = ["requirements.txt"]}
34+
3535
[tool.isort]
3636
profile = "black"
3737
line_length = 90

tests/unit/api/test_projects.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import responses
55

66
from mailtrap.api.resources.projects import ProjectsApi
7-
from mailtrap.config import GENERAL_ENDPOINT
7+
from mailtrap.config import GENERAL_HOST
88
from mailtrap.exceptions import APIError
99
from mailtrap.http import HttpClient
1010
from mailtrap.models.common import DeletedObject
@@ -13,12 +13,12 @@
1313

1414
ACCOUNT_ID = "321"
1515
PROJECT_ID = 123
16-
BASE_PROJECTS_URL = f"https://{GENERAL_ENDPOINT}/api/accounts/{ACCOUNT_ID}/projects"
16+
BASE_PROJECTS_URL = f"https://{GENERAL_HOST}/api/accounts/{ACCOUNT_ID}/projects"
1717

1818

1919
@pytest.fixture
2020
def client() -> ProjectsApi:
21-
return ProjectsApi(account_id=ACCOUNT_ID, client=HttpClient(GENERAL_ENDPOINT))
21+
return ProjectsApi(account_id=ACCOUNT_ID, client=HttpClient(GENERAL_HOST))
2222

2323

2424
@pytest.fixture

0 commit comments

Comments
 (0)