notletters-client 0.1.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.
@@ -0,0 +1,46 @@
1
+ # Dependencies
2
+ node_modules/
3
+ .pnp.*
4
+ .yarn/
5
+ .pnpm-store/
6
+
7
+ # Build
8
+ dist/
9
+ build/
10
+ *.tsbuildinfo
11
+ *.egg-info/
12
+ .eggs/
13
+ wheels/
14
+
15
+ # Tests and coverage
16
+ coverage/
17
+ .nyc_output/
18
+ .pytest_cache/
19
+ .mypy_cache/
20
+ .ruff_cache/
21
+ htmlcov/
22
+ .coverage
23
+ .coverage.*
24
+
25
+ # Python
26
+ __pycache__/
27
+ *.py[cod]
28
+ *$py.class
29
+ .venv/
30
+ venv/
31
+ env/
32
+
33
+ # Secrets
34
+ .env
35
+ .env.*
36
+ !.env.example
37
+ AGENTS.md
38
+
39
+ # GitBook / HonKit
40
+ _book/
41
+
42
+ # OS and editors
43
+ .DS_Store
44
+ Thumbs.db
45
+ .idea/
46
+ *.swp
@@ -0,0 +1,15 @@
1
+ ISC License
2
+
3
+ Copyright (c) 2026 api-kit contributors
4
+
5
+ Permission to use, copy, modify, and/or distribute this software for any
6
+ purpose with or without fee is hereby granted, provided that the above
7
+ copyright notice and this permission notice appear in all copies.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
@@ -0,0 +1,186 @@
1
+ Metadata-Version: 2.5
2
+ Name: notletters-client
3
+ Version: 0.1.0
4
+ Summary: Python client for the NotLetters email receiving and mailbox API
5
+ Project-URL: Repository, https://github.com/TysikGG/api-kit
6
+ Project-URL: Documentation, https://notletters.com/user/documentation
7
+ License-Expression: ISC
8
+ License-File: LICENSE
9
+ Requires-Python: >=3.10
10
+ Requires-Dist: httpx>=0.27
11
+ Description-Content-Type: text/markdown
12
+
13
+ # notletters-client
14
+
15
+ [![PyPI version](https://img.shields.io/pypi/v/notletters-client.svg)](https://pypi.org/project/notletters-client/)
16
+ [![Python versions](https://img.shields.io/pypi/pyversions/notletters-client.svg)](https://pypi.org/project/notletters-client/)
17
+ [![License: ISC](https://img.shields.io/badge/License-ISC-blue.svg)](https://opensource.org/licenses/ISC)
18
+
19
+ Modern, typed Python client for the [NotLetters API](https://notletters.com). Manage disposable email mailboxes, retrieve incoming messages, search message contents, change mailbox passwords, and purchase mail accounts in bulk. Built on [HTTPX](https://www.python-httpx.org).
20
+
21
+ Official API documentation: <https://notletters.com/user/documentation>
22
+
23
+ ---
24
+
25
+ ## Features
26
+
27
+ - ✉️ **Message Retrieval & Search** — Fetch incoming emails with full HTML and plain text bodies, search queries, and star filters.
28
+ - 📬 **Bulk Mailbox Purchase** — Order mailboxes programmatically across limit, unlimited, RU zone, and personal categories.
29
+ - 🔑 **Password Management** — Change passwords for managed mailboxes.
30
+ - 💰 **Account Information** — Check your account balance and rate limits.
31
+ - 🐍 **Modern Python** — Type-annotated, Google-style docstrings, context manager support (`with NotLetters(...) as client:`).
32
+ - 🚨 **Structured Errors** — Clear `NotLettersError` exceptions with subclasses for common HTTP status codes.
33
+
34
+ ---
35
+
36
+ ## Installation
37
+
38
+ ```bash
39
+ pip install notletters-client
40
+ ```
41
+
42
+ Requires Python 3.10 or higher.
43
+
44
+ ---
45
+
46
+ ## Quick Start (Safe Check)
47
+
48
+ The quick check only inspects your account balance and user profile. It does not purchase mailboxes or spend money.
49
+
50
+ ```python
51
+ import os
52
+ from notletters import NotLetters
53
+
54
+ api_token = os.environ["NOTLETTERS_API_TOKEN"]
55
+
56
+ with NotLetters(api_token) as client:
57
+ profile = client.get_me()
58
+ print(f"Authenticated as: {profile['username']}")
59
+ print(f"Balance: {profile['balance']} RUB")
60
+ print(f"Rate limit: {profile['rate_limit']} req/min")
61
+ ```
62
+
63
+ ---
64
+
65
+ ## Usage Guide
66
+
67
+ ### 1. Retrieving Emails from a Mailbox
68
+
69
+ Retrieve incoming messages for a mailbox with optional text search and star filtering:
70
+
71
+ ```python
72
+ import os
73
+ from notletters import NotLetters
74
+
75
+ with NotLetters(os.environ["NOTLETTERS_API_TOKEN"]) as client:
76
+ letters = client.get_letters(
77
+ email="test@notletters.com",
78
+ password="mailbox-password",
79
+ search="Confirmation Code",
80
+ star=False,
81
+ )
82
+
83
+ for letter in letters:
84
+ print(f"ID: {letter['id']}")
85
+ print(f"From: {letter['sender_name']} <{letter['sender']}>")
86
+ print(f"Subject: {letter['subject']}")
87
+ print(f"Text body: {letter['letter']['text']}")
88
+ ```
89
+
90
+ ### 2. Changing Mailbox Password
91
+
92
+ Update the password of an existing mailbox:
93
+
94
+ ```python
95
+ import os
96
+ from notletters import NotLetters
97
+
98
+ with NotLetters(os.environ["NOTLETTERS_API_TOKEN"]) as client:
99
+ res = client.change_password(
100
+ email="test@notletters.com",
101
+ old_password="old-password",
102
+ new_password="new-password",
103
+ )
104
+ print(res["data"]) # "password successful changed"
105
+ ```
106
+
107
+ ### 3. Purchasing Mailboxes
108
+
109
+ > [!WARNING]
110
+ > Purchasing mailboxes charges your NotLetters account balance.
111
+
112
+ ```python
113
+ import os
114
+ from notletters import EmailType, NotLetters
115
+
116
+ # EmailType:
117
+ # - EmailType.LIMIT (0) - Limited emails
118
+ # - EmailType.UNLIMITED (1) - Unlimited emails
119
+ # - EmailType.RU_ZONE (2) - Russian zone emails
120
+ # - EmailType.PERSONAL (3) - Personal emails
121
+
122
+ with NotLetters(os.environ["NOTLETTERS_API_TOKEN"]) as client:
123
+ accounts = client.buy_emails(count=2, type_email=EmailType.LIMIT)
124
+
125
+ for account in accounts:
126
+ print(f"Email: {account.email}")
127
+ print(f"Password: {account.password}")
128
+ print(f"Raw: {account.raw}")
129
+ ```
130
+
131
+ ### 4. Parsing Credentials
132
+
133
+ Parse any raw `"email:password"` string into a structured object:
134
+
135
+ ```python
136
+ from notletters import parse_mail
137
+
138
+ account = parse_mail("user@notletters.com:pass123")
139
+ print(account.email) # "user@notletters.com"
140
+ print(account.password) # "pass123"
141
+ print(str(account)) # "user@notletters.com:pass123"
142
+ ```
143
+
144
+ ---
145
+
146
+ ## Error Handling
147
+
148
+ When the API returns an error, the client raises a `NotLettersError` with status code and payload details:
149
+
150
+ ```python
151
+ import os
152
+ from notletters import (
153
+ NotLetters,
154
+ NotLettersBadRequestError,
155
+ NotLettersError,
156
+ NotLettersPaymentRequiredError,
157
+ NotLettersUnauthorizedError,
158
+ )
159
+
160
+ with NotLetters("invalid-token") as client:
161
+ try:
162
+ client.get_me()
163
+ except NotLettersUnauthorizedError:
164
+ print("Invalid or expired API token")
165
+ except NotLettersPaymentRequiredError:
166
+ print("Insufficient balance for operation")
167
+ except NotLettersError as err:
168
+ print(f"NotLetters API error [{err.status_code}]: {err.message}")
169
+ ```
170
+
171
+ ---
172
+
173
+ ## Configuration Options
174
+
175
+ | Option | Type | Default | Description |
176
+ | :--- | :--- | :--- | :--- |
177
+ | `api_token` | `str \| None` | `os.environ.get("NOTLETTERS_API_TOKEN")` | Bearer token for API authentication |
178
+ | `base_url` | `str \| None` | `https://api.notletters.com/v1` | Custom base URL for the API |
179
+ | `timeout` | `float` | `30.0` | Request timeout in seconds |
180
+ | `user_agent` | `str \| None` | `notletters-client/0.1.0` | Custom User-Agent header |
181
+
182
+ ---
183
+
184
+ ## License
185
+
186
+ [ISC](LICENSE)
@@ -0,0 +1,174 @@
1
+ # notletters-client
2
+
3
+ [![PyPI version](https://img.shields.io/pypi/v/notletters-client.svg)](https://pypi.org/project/notletters-client/)
4
+ [![Python versions](https://img.shields.io/pypi/pyversions/notletters-client.svg)](https://pypi.org/project/notletters-client/)
5
+ [![License: ISC](https://img.shields.io/badge/License-ISC-blue.svg)](https://opensource.org/licenses/ISC)
6
+
7
+ Modern, typed Python client for the [NotLetters API](https://notletters.com). Manage disposable email mailboxes, retrieve incoming messages, search message contents, change mailbox passwords, and purchase mail accounts in bulk. Built on [HTTPX](https://www.python-httpx.org).
8
+
9
+ Official API documentation: <https://notletters.com/user/documentation>
10
+
11
+ ---
12
+
13
+ ## Features
14
+
15
+ - ✉️ **Message Retrieval & Search** — Fetch incoming emails with full HTML and plain text bodies, search queries, and star filters.
16
+ - 📬 **Bulk Mailbox Purchase** — Order mailboxes programmatically across limit, unlimited, RU zone, and personal categories.
17
+ - 🔑 **Password Management** — Change passwords for managed mailboxes.
18
+ - 💰 **Account Information** — Check your account balance and rate limits.
19
+ - 🐍 **Modern Python** — Type-annotated, Google-style docstrings, context manager support (`with NotLetters(...) as client:`).
20
+ - 🚨 **Structured Errors** — Clear `NotLettersError` exceptions with subclasses for common HTTP status codes.
21
+
22
+ ---
23
+
24
+ ## Installation
25
+
26
+ ```bash
27
+ pip install notletters-client
28
+ ```
29
+
30
+ Requires Python 3.10 or higher.
31
+
32
+ ---
33
+
34
+ ## Quick Start (Safe Check)
35
+
36
+ The quick check only inspects your account balance and user profile. It does not purchase mailboxes or spend money.
37
+
38
+ ```python
39
+ import os
40
+ from notletters import NotLetters
41
+
42
+ api_token = os.environ["NOTLETTERS_API_TOKEN"]
43
+
44
+ with NotLetters(api_token) as client:
45
+ profile = client.get_me()
46
+ print(f"Authenticated as: {profile['username']}")
47
+ print(f"Balance: {profile['balance']} RUB")
48
+ print(f"Rate limit: {profile['rate_limit']} req/min")
49
+ ```
50
+
51
+ ---
52
+
53
+ ## Usage Guide
54
+
55
+ ### 1. Retrieving Emails from a Mailbox
56
+
57
+ Retrieve incoming messages for a mailbox with optional text search and star filtering:
58
+
59
+ ```python
60
+ import os
61
+ from notletters import NotLetters
62
+
63
+ with NotLetters(os.environ["NOTLETTERS_API_TOKEN"]) as client:
64
+ letters = client.get_letters(
65
+ email="test@notletters.com",
66
+ password="mailbox-password",
67
+ search="Confirmation Code",
68
+ star=False,
69
+ )
70
+
71
+ for letter in letters:
72
+ print(f"ID: {letter['id']}")
73
+ print(f"From: {letter['sender_name']} <{letter['sender']}>")
74
+ print(f"Subject: {letter['subject']}")
75
+ print(f"Text body: {letter['letter']['text']}")
76
+ ```
77
+
78
+ ### 2. Changing Mailbox Password
79
+
80
+ Update the password of an existing mailbox:
81
+
82
+ ```python
83
+ import os
84
+ from notletters import NotLetters
85
+
86
+ with NotLetters(os.environ["NOTLETTERS_API_TOKEN"]) as client:
87
+ res = client.change_password(
88
+ email="test@notletters.com",
89
+ old_password="old-password",
90
+ new_password="new-password",
91
+ )
92
+ print(res["data"]) # "password successful changed"
93
+ ```
94
+
95
+ ### 3. Purchasing Mailboxes
96
+
97
+ > [!WARNING]
98
+ > Purchasing mailboxes charges your NotLetters account balance.
99
+
100
+ ```python
101
+ import os
102
+ from notletters import EmailType, NotLetters
103
+
104
+ # EmailType:
105
+ # - EmailType.LIMIT (0) - Limited emails
106
+ # - EmailType.UNLIMITED (1) - Unlimited emails
107
+ # - EmailType.RU_ZONE (2) - Russian zone emails
108
+ # - EmailType.PERSONAL (3) - Personal emails
109
+
110
+ with NotLetters(os.environ["NOTLETTERS_API_TOKEN"]) as client:
111
+ accounts = client.buy_emails(count=2, type_email=EmailType.LIMIT)
112
+
113
+ for account in accounts:
114
+ print(f"Email: {account.email}")
115
+ print(f"Password: {account.password}")
116
+ print(f"Raw: {account.raw}")
117
+ ```
118
+
119
+ ### 4. Parsing Credentials
120
+
121
+ Parse any raw `"email:password"` string into a structured object:
122
+
123
+ ```python
124
+ from notletters import parse_mail
125
+
126
+ account = parse_mail("user@notletters.com:pass123")
127
+ print(account.email) # "user@notletters.com"
128
+ print(account.password) # "pass123"
129
+ print(str(account)) # "user@notletters.com:pass123"
130
+ ```
131
+
132
+ ---
133
+
134
+ ## Error Handling
135
+
136
+ When the API returns an error, the client raises a `NotLettersError` with status code and payload details:
137
+
138
+ ```python
139
+ import os
140
+ from notletters import (
141
+ NotLetters,
142
+ NotLettersBadRequestError,
143
+ NotLettersError,
144
+ NotLettersPaymentRequiredError,
145
+ NotLettersUnauthorizedError,
146
+ )
147
+
148
+ with NotLetters("invalid-token") as client:
149
+ try:
150
+ client.get_me()
151
+ except NotLettersUnauthorizedError:
152
+ print("Invalid or expired API token")
153
+ except NotLettersPaymentRequiredError:
154
+ print("Insufficient balance for operation")
155
+ except NotLettersError as err:
156
+ print(f"NotLetters API error [{err.status_code}]: {err.message}")
157
+ ```
158
+
159
+ ---
160
+
161
+ ## Configuration Options
162
+
163
+ | Option | Type | Default | Description |
164
+ | :--- | :--- | :--- | :--- |
165
+ | `api_token` | `str \| None` | `os.environ.get("NOTLETTERS_API_TOKEN")` | Bearer token for API authentication |
166
+ | `base_url` | `str \| None` | `https://api.notletters.com/v1` | Custom base URL for the API |
167
+ | `timeout` | `float` | `30.0` | Request timeout in seconds |
168
+ | `user_agent` | `str \| None` | `notletters-client/0.1.0` | Custom User-Agent header |
169
+
170
+ ---
171
+
172
+ ## License
173
+
174
+ [ISC](LICENSE)
@@ -0,0 +1,21 @@
1
+ import os
2
+ import sys
3
+
4
+ from notletters import NotLetters
5
+
6
+
7
+ def main() -> None:
8
+ api_token = os.environ.get("NOTLETTERS_API_TOKEN")
9
+ if not api_token:
10
+ print("Please set NOTLETTERS_API_TOKEN environment variable", file=sys.stderr)
11
+ sys.exit(1)
12
+
13
+ with NotLetters(api_token) as client:
14
+ profile = client.get_me()
15
+ print(f"Authenticated as: {profile['username']} (ID: {profile['id']})")
16
+ print(f"Current balance: {profile['balance']} RUB")
17
+ print(f"Rate limit: {profile['rate_limit']} req/min")
18
+
19
+
20
+ if __name__ == "__main__":
21
+ main()
@@ -0,0 +1,44 @@
1
+ # Publish trigger
2
+ # NotLetters API client
3
+ [build-system]
4
+ requires = ["hatchling"]
5
+ build-backend = "hatchling.build"
6
+
7
+ [project]
8
+ name = "notletters-client"
9
+ version = "0.1.0"
10
+ description = "Python client for the NotLetters email receiving and mailbox API"
11
+ readme = "README.md"
12
+ requires-python = ">=3.10"
13
+ license = "ISC"
14
+ dependencies = [
15
+ "httpx>=0.27",
16
+ ]
17
+
18
+ [project.urls]
19
+ Repository = "https://github.com/TysikGG/api-kit"
20
+ Documentation = "https://notletters.com/user/documentation"
21
+
22
+ [dependency-groups]
23
+ dev = [
24
+ "pytest>=8",
25
+ "pytest-httpx>=0.30",
26
+ "ruff>=0.8",
27
+ ]
28
+
29
+ [tool.hatch.build.targets.wheel]
30
+ packages = ["src/notletters"]
31
+
32
+ [tool.pytest.ini_options]
33
+ markers = [
34
+ "live: calls the real NotLetters API and needs NOTLETTERS_API_TOKEN",
35
+ ]
36
+ testpaths = ["tests"]
37
+
38
+ [tool.ruff]
39
+ target-version = "py310"
40
+ line-length = 100
41
+ src = ["src", "tests", "examples"]
42
+
43
+ [tool.ruff.lint]
44
+ select = ["E", "F", "I", "UP"]
@@ -0,0 +1,41 @@
1
+ from .client import NotLetters
2
+ from .errors import (
3
+ NotLettersBadRequestError,
4
+ NotLettersError,
5
+ NotLettersForbiddenError,
6
+ NotLettersInternalServerError,
7
+ NotLettersNotFoundError,
8
+ NotLettersPaymentRequiredError,
9
+ NotLettersUnauthorizedError,
10
+ create_notletters_error,
11
+ )
12
+ from .types import (
13
+ ChangePasswordResult,
14
+ EmailType,
15
+ Letter,
16
+ LetterBody,
17
+ LetterFilters,
18
+ Mail,
19
+ UserData,
20
+ parse_mail,
21
+ )
22
+
23
+ __all__ = [
24
+ "ChangePasswordResult",
25
+ "EmailType",
26
+ "Letter",
27
+ "LetterBody",
28
+ "LetterFilters",
29
+ "Mail",
30
+ "NotLetters",
31
+ "NotLettersBadRequestError",
32
+ "NotLettersError",
33
+ "NotLettersForbiddenError",
34
+ "NotLettersInternalServerError",
35
+ "NotLettersNotFoundError",
36
+ "NotLettersPaymentRequiredError",
37
+ "NotLettersUnauthorizedError",
38
+ "UserData",
39
+ "create_notletters_error",
40
+ "parse_mail",
41
+ ]