notex-python 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,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 NoteX
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,323 @@
1
+ Metadata-Version: 2.4
2
+ Name: notex-python
3
+ Version: 0.1.0
4
+ Summary: Typed, dependency-free Python SDK for the NoteX API
5
+ Author: NoteX
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://notexapp.com
8
+ Project-URL: Documentation, https://be-docs.notexapp.com
9
+ Keywords: notex,ai,notes,sdk,api-client
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Operating System :: OS Independent
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3 :: Only
15
+ Classifier: Programming Language :: Python :: 3.9
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Typing :: Typed
21
+ Requires-Python: >=3.9
22
+ Description-Content-Type: text/markdown
23
+ License-File: LICENSE
24
+ Provides-Extra: test
25
+ Requires-Dist: pytest>=7; extra == "test"
26
+ Provides-Extra: dev
27
+ Requires-Dist: build>=1.2; extra == "dev"
28
+ Requires-Dist: pytest>=7; extra == "dev"
29
+ Requires-Dist: pyright>=1.1.400; extra == "dev"
30
+ Requires-Dist: ruff>=0.12; extra == "dev"
31
+ Requires-Dist: twine>=6; extra == "dev"
32
+ Dynamic: license-file
33
+
34
+ # NoteX Python SDK
35
+
36
+ Typed, dependency-free Python SDK for API-key-enabled NoteX endpoints.
37
+
38
+ ```bash
39
+ pip install notex-python
40
+ ```
41
+
42
+ ```python
43
+ from notex import NotexClient
44
+
45
+ client = NotexClient(api_key="ntx_live_xxx")
46
+ ```
47
+
48
+ Requires Python 3.9 or newer.
49
+
50
+ ## Naming convention
51
+
52
+ The public SDK has one flat, explicit naming convention:
53
+
54
+ | Operation | Convention | Examples |
55
+ | --- | --- | --- |
56
+ | Read one value | `get_<resource>()` | `get_profile()`, `get_task_result()` |
57
+ | Read a collection | `list_<resources>()` | `list_notes()` |
58
+ | Validate input | `validate_<resource>()` | `validate_source()` |
59
+ | Create content | `create_<resource>()` | `create_note()`, `create_quiz()` |
60
+ | Wait for an async operation | `wait_for_<resource>()` | `wait_for_task()` |
61
+
62
+ Sync and async clients expose the same method names. The async variants are
63
+ awaited.
64
+
65
+ ## Multi-user integration
66
+
67
+ Each client represents one user API key for one request or background job.
68
+ Do not mutate a singleton client's key between users.
69
+
70
+ ```python
71
+ from notex import NotexClient
72
+
73
+
74
+ def notex_for_connection(connection_id: str) -> NotexClient:
75
+ api_key = credential_store.decrypt(connection_id)
76
+ return NotexClient(api_key=api_key)
77
+ ```
78
+
79
+ The SDK does not create, list, delete, persist, or automatically load API
80
+ keys. The integrating backend owns credential storage and rotation.
81
+
82
+ ## Supported methods
83
+
84
+ ### Account and notes
85
+
86
+ ```python
87
+ credits = client.get_credits()
88
+ quota = client.get_quota()
89
+ profile = client.get_profile()
90
+ notes = client.list_notes(limit=20, sort_field="createdAt", sort_order=-1)
91
+ ```
92
+
93
+ Credit fields vary by account/plan. `Credits` exposes optional
94
+ `total_credits`, `reward_credits`, `purchased_credits`, `user_type`, and
95
+ `has_paid`, while `raw` preserves the complete backend payload. `balance` is
96
+ an optional compatibility alias for responses that provide `balance` or
97
+ `total_credits`.
98
+
99
+ ### Validate and create notes
100
+
101
+ Create a note from a web URL:
102
+
103
+ ```python
104
+ submission = client.create_note(
105
+ web_url="https://youtu.be/example",
106
+ language_hints=["en"],
107
+ )
108
+ ```
109
+
110
+ Convenience equivalent:
111
+
112
+ ```python
113
+ submission = client.create_note_from_url(
114
+ "https://youtu.be/example",
115
+ language_hints=["en"],
116
+ )
117
+ ```
118
+
119
+ Create a note from an existing NoteX file URL:
120
+
121
+ ```python
122
+ submission = client.create_note_from_file_url(
123
+ "audio/user-1/lecture.mp3",
124
+ language_hints=["en"],
125
+ )
126
+ ```
127
+
128
+ Create a note from a local file:
129
+
130
+ ```python
131
+ submission = client.create_note_from_file(
132
+ "./lecture.mp3",
133
+ upload_file_name="lecture.mp3",
134
+ language_hints=["en"],
135
+ content_type="audio/mpeg",
136
+ )
137
+ ```
138
+
139
+ The local-file method performs the complete internal flow:
140
+
141
+ 1. Request a presigned upload contract.
142
+ 2. Upload the file directly without the NoteX API key.
143
+ 3. Submit note creation using the returned `file_url`.
144
+
145
+ Presign and direct-upload helpers are intentionally private. Use
146
+ `upload_file_name` when the local filename contains characters rejected by the
147
+ target gateway or object storage.
148
+
149
+ Validate a source before spending credits:
150
+
151
+ ```python
152
+ validation = client.validate_source(web_url="https://youtu.be/example")
153
+ ```
154
+
155
+ Exactly one of `web_url` or `file_url` is accepted by `create_note()` and
156
+ `validate_source()`.
157
+
158
+ ### Create content from a note
159
+
160
+ All create methods return `TaskSubmission` with a `task_id`.
161
+
162
+ ```python
163
+ flashcards = client.create_flashcards(
164
+ "note-id",
165
+ num_cards=10,
166
+ difficulty="medium",
167
+ )
168
+ quiz = client.create_quiz("note-id", num_questions=10)
169
+ mindmap = client.create_mindmap("note-id")
170
+ podcast = client.create_podcast("note-id", duration=180)
171
+ shorts = client.create_shorts("note-id", voice_id="en-US-Standard-A")
172
+ quiz_video = client.create_quiz_video("note-id", voice_id="en-US-Standard-A")
173
+ slides = client.create_slide("note-id", template_id="default", language="en")
174
+ translation = client.create_translation("note-id", language="vi")
175
+ ```
176
+
177
+ ### Poll task results
178
+
179
+ Use `get_task_result()` when the integrating backend manages scheduling:
180
+
181
+ ```python
182
+ result = client.get_task_result(submission.task_id)
183
+ ```
184
+
185
+ Use `wait_for_task()` in a worker when a blocking helper is appropriate:
186
+
187
+ ```python
188
+ result = client.wait_for_task(
189
+ submission.task_id,
190
+ poll_interval=5,
191
+ timeout=120,
192
+ )
193
+ ```
194
+
195
+ Do not run file uploads or blocking task polling directly in a web request.
196
+ Use a durable queue or background worker.
197
+
198
+ Completed results can be parsed into feature-specific typed models:
199
+
200
+ ```python
201
+ from notex import FlashcardSet
202
+
203
+ result = client.wait_for_task(flashcards.task_id)
204
+ flashcard_set = FlashcardSet.from_task_result(result)
205
+ print(flashcard_set.cards[0].front)
206
+ ```
207
+
208
+ Available result models include `GeneratedNote`, `FlashcardSet`, `QuizSet`,
209
+ `Mindmap`, `Podcast`, `Video`, and `SlideDeck`.
210
+
211
+ ## Async client
212
+
213
+ `AsyncNotexClient` exposes the same names and runs blocking standard-library
214
+ I/O in worker threads so the event loop remains responsive.
215
+
216
+ ```python
217
+ from notex import AsyncNotexClient
218
+
219
+ client = AsyncNotexClient(api_key="ntx_live_xxx")
220
+
221
+ submission = await client.create_quiz("note-id", num_questions=10)
222
+ result = await client.wait_for_task(submission.task_id, timeout=120)
223
+ ```
224
+
225
+ ## Errors and retry behavior
226
+
227
+ ```python
228
+ from notex import NotexAuthenticationError, NotexRateLimitError
229
+
230
+ try:
231
+ client.get_credits()
232
+ except NotexAuthenticationError:
233
+ reconnect_notex_account()
234
+ except NotexRateLimitError as error:
235
+ reschedule_job(error.retry_after)
236
+ ```
237
+
238
+ Public errors:
239
+
240
+ - `NotexAPIError`
241
+ - `NotexAuthenticationError`
242
+ - `NotexPermissionError`
243
+ - `NotexRateLimitError`
244
+ - `NotexUploadError`
245
+ - `NotexTaskError`
246
+
247
+ GET and HEAD requests retry transient network failures and HTTP 429/5xx
248
+ responses, honoring `Retry-After`. Content-creating POST requests are not
249
+ retried by default because repeating them can create duplicate work.
250
+
251
+ ## API compatibility
252
+
253
+ Every high-level method accepts `endpoint=` and `base_url=` overrides. This
254
+ allows an integration to adopt a new backend version before the SDK releases
255
+ an update.
256
+
257
+ ```python
258
+ client.get_credits(endpoint="/v3/credits/me")
259
+ client.create_flashcards("note-id", endpoint="/v7/create/flashcards")
260
+ ```
261
+
262
+ For a documented endpoint that is not wrapped yet, use the low-level escape
263
+ hatch:
264
+
265
+ ```python
266
+ response = client.request(
267
+ "POST",
268
+ "/v10/feature",
269
+ form={"note_id": "note-id"},
270
+ headers={"Idempotency-Key": "internal-job-id"},
271
+ )
272
+ ```
273
+
274
+ ## Real API integration tests
275
+
276
+ Copy the safe template and put the real key/base URL in the local file:
277
+
278
+ ```powershell
279
+ Copy-Item .notex-test.env.example .notex-test.env
280
+ ```
281
+
282
+ Edit `.notex-test.env`:
283
+
284
+ ```dotenv
285
+ NOTEX_TEST_API_KEY=ntx_test_your_real_key
286
+ NOTEX_TEST_BASE_URL=https://api.notexapp.com
287
+ ```
288
+
289
+ The file is ignored by Git. Read-only tests cover profile, credits, quota, and
290
+ note listing:
291
+
292
+ ```bash
293
+ python -m pytest tests/test_staging_integration.py -v
294
+ ```
295
+
296
+ Creation tests can upload files and spend credits, so they require explicit
297
+ opt-in:
298
+
299
+ ```dotenv
300
+ NOTEX_RUN_WRITE_TESTS=1
301
+ NOTEX_TEST_WEB_URL=https://youtu.be/example
302
+ NOTEX_TEST_FILE=C:\path\to\lecture.mp3
303
+ NOTEX_TEST_NOTE_ID=existing-note-id
304
+ NOTEX_TEST_FEATURES=flashcards,quiz,mindmap,translation
305
+ ```
306
+
307
+ Optional feature configuration is documented in
308
+ `.notex-test.env.example`. Test output is not persisted by the suite; local
309
+ credentials and `.notex-test-results/` are both excluded from Git.
310
+
311
+ ## Development and release checks
312
+
313
+ ```bash
314
+ python -m pip install -e ".[dev]"
315
+ python -m ruff check .
316
+ python -m pyright
317
+ python -m pytest -q
318
+ python -m build
319
+ python -m twine check dist/*
320
+ ```
321
+
322
+ See [RELEASING.md](RELEASING.md) for the Trusted Publishing release flow.
323
+ Never log, commit, or return API keys to frontend clients.
@@ -0,0 +1,290 @@
1
+ # NoteX Python SDK
2
+
3
+ Typed, dependency-free Python SDK for API-key-enabled NoteX endpoints.
4
+
5
+ ```bash
6
+ pip install notex-python
7
+ ```
8
+
9
+ ```python
10
+ from notex import NotexClient
11
+
12
+ client = NotexClient(api_key="ntx_live_xxx")
13
+ ```
14
+
15
+ Requires Python 3.9 or newer.
16
+
17
+ ## Naming convention
18
+
19
+ The public SDK has one flat, explicit naming convention:
20
+
21
+ | Operation | Convention | Examples |
22
+ | --- | --- | --- |
23
+ | Read one value | `get_<resource>()` | `get_profile()`, `get_task_result()` |
24
+ | Read a collection | `list_<resources>()` | `list_notes()` |
25
+ | Validate input | `validate_<resource>()` | `validate_source()` |
26
+ | Create content | `create_<resource>()` | `create_note()`, `create_quiz()` |
27
+ | Wait for an async operation | `wait_for_<resource>()` | `wait_for_task()` |
28
+
29
+ Sync and async clients expose the same method names. The async variants are
30
+ awaited.
31
+
32
+ ## Multi-user integration
33
+
34
+ Each client represents one user API key for one request or background job.
35
+ Do not mutate a singleton client's key between users.
36
+
37
+ ```python
38
+ from notex import NotexClient
39
+
40
+
41
+ def notex_for_connection(connection_id: str) -> NotexClient:
42
+ api_key = credential_store.decrypt(connection_id)
43
+ return NotexClient(api_key=api_key)
44
+ ```
45
+
46
+ The SDK does not create, list, delete, persist, or automatically load API
47
+ keys. The integrating backend owns credential storage and rotation.
48
+
49
+ ## Supported methods
50
+
51
+ ### Account and notes
52
+
53
+ ```python
54
+ credits = client.get_credits()
55
+ quota = client.get_quota()
56
+ profile = client.get_profile()
57
+ notes = client.list_notes(limit=20, sort_field="createdAt", sort_order=-1)
58
+ ```
59
+
60
+ Credit fields vary by account/plan. `Credits` exposes optional
61
+ `total_credits`, `reward_credits`, `purchased_credits`, `user_type`, and
62
+ `has_paid`, while `raw` preserves the complete backend payload. `balance` is
63
+ an optional compatibility alias for responses that provide `balance` or
64
+ `total_credits`.
65
+
66
+ ### Validate and create notes
67
+
68
+ Create a note from a web URL:
69
+
70
+ ```python
71
+ submission = client.create_note(
72
+ web_url="https://youtu.be/example",
73
+ language_hints=["en"],
74
+ )
75
+ ```
76
+
77
+ Convenience equivalent:
78
+
79
+ ```python
80
+ submission = client.create_note_from_url(
81
+ "https://youtu.be/example",
82
+ language_hints=["en"],
83
+ )
84
+ ```
85
+
86
+ Create a note from an existing NoteX file URL:
87
+
88
+ ```python
89
+ submission = client.create_note_from_file_url(
90
+ "audio/user-1/lecture.mp3",
91
+ language_hints=["en"],
92
+ )
93
+ ```
94
+
95
+ Create a note from a local file:
96
+
97
+ ```python
98
+ submission = client.create_note_from_file(
99
+ "./lecture.mp3",
100
+ upload_file_name="lecture.mp3",
101
+ language_hints=["en"],
102
+ content_type="audio/mpeg",
103
+ )
104
+ ```
105
+
106
+ The local-file method performs the complete internal flow:
107
+
108
+ 1. Request a presigned upload contract.
109
+ 2. Upload the file directly without the NoteX API key.
110
+ 3. Submit note creation using the returned `file_url`.
111
+
112
+ Presign and direct-upload helpers are intentionally private. Use
113
+ `upload_file_name` when the local filename contains characters rejected by the
114
+ target gateway or object storage.
115
+
116
+ Validate a source before spending credits:
117
+
118
+ ```python
119
+ validation = client.validate_source(web_url="https://youtu.be/example")
120
+ ```
121
+
122
+ Exactly one of `web_url` or `file_url` is accepted by `create_note()` and
123
+ `validate_source()`.
124
+
125
+ ### Create content from a note
126
+
127
+ All create methods return `TaskSubmission` with a `task_id`.
128
+
129
+ ```python
130
+ flashcards = client.create_flashcards(
131
+ "note-id",
132
+ num_cards=10,
133
+ difficulty="medium",
134
+ )
135
+ quiz = client.create_quiz("note-id", num_questions=10)
136
+ mindmap = client.create_mindmap("note-id")
137
+ podcast = client.create_podcast("note-id", duration=180)
138
+ shorts = client.create_shorts("note-id", voice_id="en-US-Standard-A")
139
+ quiz_video = client.create_quiz_video("note-id", voice_id="en-US-Standard-A")
140
+ slides = client.create_slide("note-id", template_id="default", language="en")
141
+ translation = client.create_translation("note-id", language="vi")
142
+ ```
143
+
144
+ ### Poll task results
145
+
146
+ Use `get_task_result()` when the integrating backend manages scheduling:
147
+
148
+ ```python
149
+ result = client.get_task_result(submission.task_id)
150
+ ```
151
+
152
+ Use `wait_for_task()` in a worker when a blocking helper is appropriate:
153
+
154
+ ```python
155
+ result = client.wait_for_task(
156
+ submission.task_id,
157
+ poll_interval=5,
158
+ timeout=120,
159
+ )
160
+ ```
161
+
162
+ Do not run file uploads or blocking task polling directly in a web request.
163
+ Use a durable queue or background worker.
164
+
165
+ Completed results can be parsed into feature-specific typed models:
166
+
167
+ ```python
168
+ from notex import FlashcardSet
169
+
170
+ result = client.wait_for_task(flashcards.task_id)
171
+ flashcard_set = FlashcardSet.from_task_result(result)
172
+ print(flashcard_set.cards[0].front)
173
+ ```
174
+
175
+ Available result models include `GeneratedNote`, `FlashcardSet`, `QuizSet`,
176
+ `Mindmap`, `Podcast`, `Video`, and `SlideDeck`.
177
+
178
+ ## Async client
179
+
180
+ `AsyncNotexClient` exposes the same names and runs blocking standard-library
181
+ I/O in worker threads so the event loop remains responsive.
182
+
183
+ ```python
184
+ from notex import AsyncNotexClient
185
+
186
+ client = AsyncNotexClient(api_key="ntx_live_xxx")
187
+
188
+ submission = await client.create_quiz("note-id", num_questions=10)
189
+ result = await client.wait_for_task(submission.task_id, timeout=120)
190
+ ```
191
+
192
+ ## Errors and retry behavior
193
+
194
+ ```python
195
+ from notex import NotexAuthenticationError, NotexRateLimitError
196
+
197
+ try:
198
+ client.get_credits()
199
+ except NotexAuthenticationError:
200
+ reconnect_notex_account()
201
+ except NotexRateLimitError as error:
202
+ reschedule_job(error.retry_after)
203
+ ```
204
+
205
+ Public errors:
206
+
207
+ - `NotexAPIError`
208
+ - `NotexAuthenticationError`
209
+ - `NotexPermissionError`
210
+ - `NotexRateLimitError`
211
+ - `NotexUploadError`
212
+ - `NotexTaskError`
213
+
214
+ GET and HEAD requests retry transient network failures and HTTP 429/5xx
215
+ responses, honoring `Retry-After`. Content-creating POST requests are not
216
+ retried by default because repeating them can create duplicate work.
217
+
218
+ ## API compatibility
219
+
220
+ Every high-level method accepts `endpoint=` and `base_url=` overrides. This
221
+ allows an integration to adopt a new backend version before the SDK releases
222
+ an update.
223
+
224
+ ```python
225
+ client.get_credits(endpoint="/v3/credits/me")
226
+ client.create_flashcards("note-id", endpoint="/v7/create/flashcards")
227
+ ```
228
+
229
+ For a documented endpoint that is not wrapped yet, use the low-level escape
230
+ hatch:
231
+
232
+ ```python
233
+ response = client.request(
234
+ "POST",
235
+ "/v10/feature",
236
+ form={"note_id": "note-id"},
237
+ headers={"Idempotency-Key": "internal-job-id"},
238
+ )
239
+ ```
240
+
241
+ ## Real API integration tests
242
+
243
+ Copy the safe template and put the real key/base URL in the local file:
244
+
245
+ ```powershell
246
+ Copy-Item .notex-test.env.example .notex-test.env
247
+ ```
248
+
249
+ Edit `.notex-test.env`:
250
+
251
+ ```dotenv
252
+ NOTEX_TEST_API_KEY=ntx_test_your_real_key
253
+ NOTEX_TEST_BASE_URL=https://api.notexapp.com
254
+ ```
255
+
256
+ The file is ignored by Git. Read-only tests cover profile, credits, quota, and
257
+ note listing:
258
+
259
+ ```bash
260
+ python -m pytest tests/test_staging_integration.py -v
261
+ ```
262
+
263
+ Creation tests can upload files and spend credits, so they require explicit
264
+ opt-in:
265
+
266
+ ```dotenv
267
+ NOTEX_RUN_WRITE_TESTS=1
268
+ NOTEX_TEST_WEB_URL=https://youtu.be/example
269
+ NOTEX_TEST_FILE=C:\path\to\lecture.mp3
270
+ NOTEX_TEST_NOTE_ID=existing-note-id
271
+ NOTEX_TEST_FEATURES=flashcards,quiz,mindmap,translation
272
+ ```
273
+
274
+ Optional feature configuration is documented in
275
+ `.notex-test.env.example`. Test output is not persisted by the suite; local
276
+ credentials and `.notex-test-results/` are both excluded from Git.
277
+
278
+ ## Development and release checks
279
+
280
+ ```bash
281
+ python -m pip install -e ".[dev]"
282
+ python -m ruff check .
283
+ python -m pyright
284
+ python -m pytest -q
285
+ python -m build
286
+ python -m twine check dist/*
287
+ ```
288
+
289
+ See [RELEASING.md](RELEASING.md) for the Trusted Publishing release flow.
290
+ Never log, commit, or return API keys to frontend clients.
@@ -0,0 +1,65 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "notex-python"
7
+ version = "0.1.0"
8
+ description = "Typed, dependency-free Python SDK for the NoteX API"
9
+ readme = { file = "README.md", content-type = "text/markdown" }
10
+ requires-python = ">=3.9"
11
+ license = "MIT"
12
+ authors = [{ name = "NoteX" }]
13
+ keywords = ["notex", "ai", "notes", "sdk", "api-client"]
14
+ classifiers = [
15
+ "Development Status :: 4 - Beta",
16
+ "Intended Audience :: Developers",
17
+ "Operating System :: OS Independent",
18
+ "Programming Language :: Python :: 3",
19
+ "Programming Language :: Python :: 3 :: Only",
20
+ "Programming Language :: Python :: 3.9",
21
+ "Programming Language :: Python :: 3.10",
22
+ "Programming Language :: Python :: 3.11",
23
+ "Programming Language :: Python :: 3.12",
24
+ "Programming Language :: Python :: 3.13",
25
+ "Typing :: Typed",
26
+ ]
27
+ dependencies = []
28
+
29
+ [project.optional-dependencies]
30
+ test = ["pytest>=7"]
31
+ dev = ["build>=1.2", "pytest>=7", "pyright>=1.1.400", "ruff>=0.12", "twine>=6"]
32
+
33
+ [project.urls]
34
+ Homepage = "https://notexapp.com"
35
+ Documentation = "https://be-docs.notexapp.com"
36
+
37
+ [tool.pyright]
38
+ include = ["src/notex_sdk", "tests"]
39
+ pythonVersion = "3.9"
40
+ typeCheckingMode = "basic"
41
+
42
+ [tool.ruff]
43
+ line-length = 100
44
+ target-version = "py39"
45
+
46
+ [tool.ruff.lint]
47
+ select = ["E", "F", "I"]
48
+ ignore = ["E501"]
49
+
50
+ [tool.pytest.ini_options]
51
+ addopts = "-p no:cacheprovider"
52
+ markers = [
53
+ "integration: tests that call a real NoteX environment",
54
+ ]
55
+
56
+ [tool.setuptools]
57
+ package-dir = { "" = "src" }
58
+
59
+ [tool.setuptools.packages.find]
60
+ where = ["src"]
61
+ include = ["notex*", "notex_sdk*"]
62
+
63
+ [tool.setuptools.package-data]
64
+ notex = ["py.typed"]
65
+ notex_sdk = ["py.typed"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+