mailflat 0.2.0__tar.gz → 0.3.1__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.
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mailflat
3
- Version: 0.2.0
3
+ Version: 0.3.1
4
4
  Summary: Official Python SDK for MailFlat — disposable, automation-friendly email inboxes with one-line OTP retrieval.
5
5
  Project-URL: Homepage, https://mailflat.net
6
- Project-URL: Documentation, https://mailflat.net/docs
6
+ Project-URL: Documentation, https://mailflat.net
7
7
  Project-URL: Source, https://github.com/onderyentar/mailflat
8
8
  Author-email: MailFlat <support@mailflat.net>
9
9
  License: MIT
@@ -18,7 +18,7 @@ Classifier: Topic :: Communications :: Email
18
18
  Classifier: Topic :: Software Development :: Testing
19
19
  Classifier: Typing :: Typed
20
20
  Requires-Python: >=3.8
21
- Requires-Dist: httpx>=0.24
21
+ Requires-Dist: httpx<1,>=0.24
22
22
  Provides-Extra: dev
23
23
  Requires-Dist: langchain-core>=0.2; extra == 'dev'
24
24
  Requires-Dist: pytest>=7; extra == 'dev'
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "mailflat"
7
- version = "0.2.0"
7
+ version = "0.3.1"
8
8
  description = "Official Python SDK for MailFlat — disposable, automation-friendly email inboxes with one-line OTP retrieval."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.8"
@@ -21,11 +21,16 @@ classifiers = [
21
21
  "Topic :: Software Development :: Testing",
22
22
  "Typing :: Typed",
23
23
  ]
24
- dependencies = ["httpx>=0.24"]
24
+ # ÜST SINIR: httpx henüz 1.0 ÖNCESİ ve 1.0 ilan edilmiş bir kırılma eşiği. Sınırsız bırakmak
25
+ # B-047'nin (mcp>=1.2 → mcp 2.0.0 modülü kaldırdı → uvx mailflat-mcp çöktü) aynısına davetiye.
26
+ # Bugün 0.28.1 ile sorunsuz; sınır 1.0 çıkınca bilinçli olarak yükseltilecek.
27
+ dependencies = ["httpx>=0.24,<1"]
25
28
 
26
29
  [project.urls]
27
30
  Homepage = "https://mailflat.net"
28
- Documentation = "https://mailflat.net/docs"
31
+ # /docs prod'da kapalı (FastAPI Swagger yüzeyi, bkz. app/main.py::_openapi_urls).
32
+ # Public doküman sayfası açılınca burası oraya güncellenecek.
33
+ Documentation = "https://mailflat.net"
29
34
  Source = "https://github.com/onderyentar/mailflat"
30
35
 
31
36
  [project.optional-dependencies]
@@ -27,7 +27,7 @@ from .errors import (
27
27
  )
28
28
  from .inbox import Inbox, Message
29
29
 
30
- __version__ = "0.2.0"
30
+ __version__ = "0.3.0"
31
31
 
32
32
  __all__ = [
33
33
  "MailFlat",
@@ -42,6 +42,17 @@ class Message:
42
42
  send_error: str | None = None
43
43
  received_at: str | None = None
44
44
  raw: dict[str, Any] = field(default_factory=dict, repr=False)
45
+ # Bu mesajı döndüren Inbox (msg.delete() şekeri için). Inbox.messages()/latest()/wait_* doldurur.
46
+ _inbox: "Inbox | None" = field(default=None, repr=False, compare=False)
47
+
48
+ def delete(self) -> dict[str, Any]:
49
+ """Bu maili sil (inbox kalır). Mesaj bir Inbox'tan geldiyse çalışır."""
50
+ if self._inbox is None or self.id is None:
51
+ raise ValueError(
52
+ "This message isn't attached to an inbox (or has no id). "
53
+ "Use inbox.delete_message(message_id) instead."
54
+ )
55
+ return self._inbox.delete_message(self.id)
45
56
 
46
57
  @classmethod
47
58
  def from_dict(cls, data: dict[str, Any]) -> "Message":
@@ -87,16 +98,22 @@ class Inbox:
87
98
  return f"<Inbox {self.address!r}>"
88
99
 
89
100
  # ----------------------------------------------------------------- okuma
101
+ def _wrap(self, data: dict[str, Any]) -> Message:
102
+ """API mail dict'ini Message'a çevirir + bu inbox ref'ini iliştirir (msg.delete() için)."""
103
+ m = Message.from_dict(data)
104
+ m._inbox = self
105
+ return m
106
+
90
107
  def messages(self) -> list[Message]:
91
108
  """Inbox'taki tüm mesajları (yeniden eskiye) döndürür."""
92
109
  res = self._client._get(f"/api/v1/inboxes/{self.address}/messages")
93
- return [Message.from_dict(e) for e in (res.get("emails") or [])]
110
+ return [self._wrap(e) for e in (res.get("emails") or [])]
94
111
 
95
112
  def latest(self) -> Message | None:
96
113
  """En son mesajı döndürür (yoksa None)."""
97
114
  res = self._client._get(f"/api/v1/inboxes/{self.address}/latest")
98
115
  email = res.get("email")
99
- return Message.from_dict(email) if email else None
116
+ return self._wrap(email) if email else None
100
117
 
101
118
  def wait_for_message(
102
119
  self, *, timeout: float = 30, poll_interval: float = 1.0
@@ -115,7 +132,7 @@ class Inbox:
115
132
  )
116
133
  email = res.get("email")
117
134
  if email:
118
- return Message.from_dict(email)
135
+ return self._wrap(email)
119
136
  if time.monotonic() >= deadline:
120
137
  raise OTPTimeoutError(
121
138
  f"No message arrived for {self.address} within {timeout}s"
@@ -158,3 +175,7 @@ class Inbox:
158
175
  def delete(self) -> dict[str, Any]:
159
176
  """Inbox'u ve tüm mesajlarını siler. Geri alınamaz."""
160
177
  return self._client._delete(f"/api/v1/inboxes/{self.address}")
178
+
179
+ def delete_message(self, message_id: int) -> dict[str, Any]:
180
+ """Inbox'taki TEK bir maili siler (inbox kalır). `Message.delete()` bunu çağırır."""
181
+ return self._client._delete(f"/api/v1/inboxes/{self.address}/messages/{message_id}")
File without changes
File without changes
File without changes
File without changes