flatmark 1.0.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.
Files changed (34) hide show
  1. flatmark-1.0.0/PKG-INFO +50 -0
  2. flatmark-1.0.0/README.md +41 -0
  3. flatmark-1.0.0/flatmark/__init__.py +8 -0
  4. flatmark-1.0.0/flatmark/api/__init__.py +1 -0
  5. flatmark-1.0.0/flatmark/api/account/__init__.py +1 -0
  6. flatmark-1.0.0/flatmark/api/account/get_me.py +176 -0
  7. flatmark-1.0.0/flatmark/api/convert/__init__.py +1 -0
  8. flatmark-1.0.0/flatmark/api/convert/convert_document.py +253 -0
  9. flatmark-1.0.0/flatmark/api/convert/get_conversion_result.py +237 -0
  10. flatmark-1.0.0/flatmark/api/convert/submit_conversion_job.py +284 -0
  11. flatmark-1.0.0/flatmark/api/jobs/__init__.py +1 -0
  12. flatmark-1.0.0/flatmark/api/jobs/get_job.py +189 -0
  13. flatmark-1.0.0/flatmark/api/jobs/list_jobs.py +211 -0
  14. flatmark-1.0.0/flatmark/client.py +268 -0
  15. flatmark-1.0.0/flatmark/errors.py +16 -0
  16. flatmark-1.0.0/flatmark/models/__init__.py +33 -0
  17. flatmark-1.0.0/flatmark/models/body_convert_document.py +75 -0
  18. flatmark-1.0.0/flatmark/models/body_submit_conversion_job.py +102 -0
  19. flatmark-1.0.0/flatmark/models/credits_info.py +95 -0
  20. flatmark-1.0.0/flatmark/models/get_conversion_result_format.py +9 -0
  21. flatmark-1.0.0/flatmark/models/job_response.py +230 -0
  22. flatmark-1.0.0/flatmark/models/job_response_page.py +97 -0
  23. flatmark-1.0.0/flatmark/models/job_response_result_type_0.py +45 -0
  24. flatmark-1.0.0/flatmark/models/job_submit_response.py +109 -0
  25. flatmark-1.0.0/flatmark/models/me_response.py +135 -0
  26. flatmark-1.0.0/flatmark/models/problem.py +190 -0
  27. flatmark-1.0.0/flatmark/models/problem_errors_type_0_item.py +45 -0
  28. flatmark-1.0.0/flatmark/models/rate_limit_info.py +118 -0
  29. flatmark-1.0.0/flatmark/models/sync_convert_response.py +87 -0
  30. flatmark-1.0.0/flatmark/models/sync_convert_response_meta.py +47 -0
  31. flatmark-1.0.0/flatmark/py.typed +1 -0
  32. flatmark-1.0.0/flatmark/types.py +54 -0
  33. flatmark-1.0.0/pyproject.toml +29 -0
  34. flatmark-1.0.0/pyproject.toml.orig +25 -0
@@ -0,0 +1,50 @@
1
+ Metadata-Version: 2.3
2
+ Name: flatmark
3
+ Version: 1.0.0
4
+ Summary: A client library for accessing flatmark
5
+ Requires-Dist: httpx>=0.23.1,<0.29.0
6
+ Requires-Dist: attrs>=22.2.0
7
+ Requires-Python: >=3.11
8
+ Description-Content-Type: text/markdown
9
+
10
+ # flatmark — Python SDK
11
+
12
+ Document to Markdown API and MCP server for PDF, Word, PowerPoint, Excel and HTML. OCR queue for large files. Hosted in Germany.
13
+
14
+ ```sh
15
+ pip install flatmark
16
+ ```
17
+
18
+ [Get an API key](https://flatmark.dev/go/pypi-sdk?to=/app/api-keys) and pass it to the client:
19
+
20
+ ```python
21
+ import os
22
+
23
+ from flatmark import AuthenticatedClient
24
+ from flatmark.api.account import get_me
25
+
26
+ client = AuthenticatedClient(
27
+ base_url="https://api.flatmark.dev",
28
+ token=os.environ["FLATMARK_API_KEY"],
29
+ auth_header_name="X-API-Key",
30
+ prefix="",
31
+ )
32
+ print(get_me.sync(client=client))
33
+ ```
34
+
35
+ Every operation is a module with `sync`, `sync_detailed`, `asyncio` and `asyncio_detailed`; file fields take a `flatmark.types.File(payload=..., file_name=..., mime_type=...)`.
36
+
37
+ `submit_conversion_job` queues a job: poll `get_job` until its `status` is `succeeded` or `failed`, then fetch `get_conversion_result`.
38
+
39
+ ## Operations
40
+
41
+ | Operation | Module | What it does |
42
+ |---|---|---|
43
+ | `GET /v1/me` | `flatmark.api.account.get_me` | Your plan, remaining requests, and remaining credits |
44
+ | `GET /v1/jobs/{job_id}` | `flatmark.api.jobs.get_job` | Get one queued job by ID |
45
+ | `GET /v1/jobs` | `flatmark.api.jobs.list_jobs` | List your queued jobs, newest first |
46
+ | `POST /v1/convert` | `flatmark.api.convert.convert_document` | Convert a document to Markdown in one call |
47
+ | `POST /v1/convert/jobs` | `flatmark.api.convert.submit_conversion_job` | Queue a document for conversion with OCR and tables |
48
+ | `GET /v1/convert/jobs/{job_id}/result` | `flatmark.api.convert.get_conversion_result` | Download a queued job's Markdown or JSON |
49
+
50
+ Generated with openapi-python-client from [`openapi.sdk.json`](../openapi.sdk.json). API reference: https://flatmark.dev/docs · Support: https://flatmark.dev/support
@@ -0,0 +1,41 @@
1
+ # flatmark — Python SDK
2
+
3
+ Document to Markdown API and MCP server for PDF, Word, PowerPoint, Excel and HTML. OCR queue for large files. Hosted in Germany.
4
+
5
+ ```sh
6
+ pip install flatmark
7
+ ```
8
+
9
+ [Get an API key](https://flatmark.dev/go/pypi-sdk?to=/app/api-keys) and pass it to the client:
10
+
11
+ ```python
12
+ import os
13
+
14
+ from flatmark import AuthenticatedClient
15
+ from flatmark.api.account import get_me
16
+
17
+ client = AuthenticatedClient(
18
+ base_url="https://api.flatmark.dev",
19
+ token=os.environ["FLATMARK_API_KEY"],
20
+ auth_header_name="X-API-Key",
21
+ prefix="",
22
+ )
23
+ print(get_me.sync(client=client))
24
+ ```
25
+
26
+ Every operation is a module with `sync`, `sync_detailed`, `asyncio` and `asyncio_detailed`; file fields take a `flatmark.types.File(payload=..., file_name=..., mime_type=...)`.
27
+
28
+ `submit_conversion_job` queues a job: poll `get_job` until its `status` is `succeeded` or `failed`, then fetch `get_conversion_result`.
29
+
30
+ ## Operations
31
+
32
+ | Operation | Module | What it does |
33
+ |---|---|---|
34
+ | `GET /v1/me` | `flatmark.api.account.get_me` | Your plan, remaining requests, and remaining credits |
35
+ | `GET /v1/jobs/{job_id}` | `flatmark.api.jobs.get_job` | Get one queued job by ID |
36
+ | `GET /v1/jobs` | `flatmark.api.jobs.list_jobs` | List your queued jobs, newest first |
37
+ | `POST /v1/convert` | `flatmark.api.convert.convert_document` | Convert a document to Markdown in one call |
38
+ | `POST /v1/convert/jobs` | `flatmark.api.convert.submit_conversion_job` | Queue a document for conversion with OCR and tables |
39
+ | `GET /v1/convert/jobs/{job_id}/result` | `flatmark.api.convert.get_conversion_result` | Download a queued job's Markdown or JSON |
40
+
41
+ Generated with openapi-python-client from [`openapi.sdk.json`](../openapi.sdk.json). API reference: https://flatmark.dev/docs · Support: https://flatmark.dev/support
@@ -0,0 +1,8 @@
1
+ """A client library for accessing flatmark"""
2
+
3
+ from .client import AuthenticatedClient, Client
4
+
5
+ __all__ = (
6
+ "AuthenticatedClient",
7
+ "Client",
8
+ )
@@ -0,0 +1 @@
1
+ """Contains methods for accessing the API"""
@@ -0,0 +1 @@
1
+ """Contains endpoint functions for accessing the API"""
@@ -0,0 +1,176 @@
1
+ from http import HTTPStatus
2
+ from typing import Any
3
+
4
+ import httpx
5
+
6
+ from ... import errors
7
+ from ...client import AuthenticatedClient, Client
8
+ from ...models.me_response import MeResponse
9
+ from ...types import Response
10
+
11
+
12
+ def _get_kwargs() -> dict[str, Any]:
13
+
14
+ _kwargs: dict[str, Any] = {
15
+ "method": "get",
16
+ "url": "/v1/me",
17
+ }
18
+
19
+ return _kwargs
20
+
21
+
22
+ def _parse_response(*, client: AuthenticatedClient | Client, response: httpx.Response) -> MeResponse | None:
23
+ if response.status_code == 200:
24
+ response_200 = MeResponse.from_dict(response.json())
25
+
26
+ return response_200
27
+
28
+ if client.raise_on_unexpected_status:
29
+ raise errors.UnexpectedStatus(response.status_code, response.content)
30
+ else:
31
+ return None
32
+
33
+
34
+ def _build_response(*, client: AuthenticatedClient | Client, response: httpx.Response) -> Response[MeResponse]:
35
+ return Response(
36
+ status_code=HTTPStatus(response.status_code),
37
+ content=response.content,
38
+ headers=response.headers,
39
+ parsed=_parse_response(client=client, response=response),
40
+ )
41
+
42
+
43
+ def sync_detailed(
44
+ *,
45
+ client: AuthenticatedClient,
46
+ ) -> Response[MeResponse]:
47
+ """Your plan, remaining requests, and remaining credits
48
+
49
+ Check where you stand before a call fails.
50
+
51
+ Returns the plan this request runs on and whether your key was recognized.
52
+ Without an `X-API-Key`, the call runs anonymously at the rate limit for
53
+ calls without a key. It also returns the requests left in the current window
54
+ and the features your plan includes. On plans priced in credits, it returns
55
+ the credits left in the current billing period.
56
+
57
+ This call does not count against your rate limit, so the numbers it reports
58
+ are the numbers you have.
59
+
60
+ **Credits:** free. This endpoint is not metered.
61
+
62
+ Raises:
63
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
64
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
65
+
66
+ Returns:
67
+ Response[MeResponse]
68
+ """
69
+
70
+ kwargs = _get_kwargs()
71
+
72
+ response = client.get_httpx_client().request(
73
+ **kwargs,
74
+ )
75
+
76
+ return _build_response(client=client, response=response)
77
+
78
+
79
+ def sync(
80
+ *,
81
+ client: AuthenticatedClient,
82
+ ) -> MeResponse | None:
83
+ """Your plan, remaining requests, and remaining credits
84
+
85
+ Check where you stand before a call fails.
86
+
87
+ Returns the plan this request runs on and whether your key was recognized.
88
+ Without an `X-API-Key`, the call runs anonymously at the rate limit for
89
+ calls without a key. It also returns the requests left in the current window
90
+ and the features your plan includes. On plans priced in credits, it returns
91
+ the credits left in the current billing period.
92
+
93
+ This call does not count against your rate limit, so the numbers it reports
94
+ are the numbers you have.
95
+
96
+ **Credits:** free. This endpoint is not metered.
97
+
98
+ Raises:
99
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
100
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
101
+
102
+ Returns:
103
+ MeResponse
104
+ """
105
+
106
+ return sync_detailed(
107
+ client=client,
108
+ ).parsed
109
+
110
+
111
+ async def asyncio_detailed(
112
+ *,
113
+ client: AuthenticatedClient,
114
+ ) -> Response[MeResponse]:
115
+ """Your plan, remaining requests, and remaining credits
116
+
117
+ Check where you stand before a call fails.
118
+
119
+ Returns the plan this request runs on and whether your key was recognized.
120
+ Without an `X-API-Key`, the call runs anonymously at the rate limit for
121
+ calls without a key. It also returns the requests left in the current window
122
+ and the features your plan includes. On plans priced in credits, it returns
123
+ the credits left in the current billing period.
124
+
125
+ This call does not count against your rate limit, so the numbers it reports
126
+ are the numbers you have.
127
+
128
+ **Credits:** free. This endpoint is not metered.
129
+
130
+ Raises:
131
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
132
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
133
+
134
+ Returns:
135
+ Response[MeResponse]
136
+ """
137
+
138
+ kwargs = _get_kwargs()
139
+
140
+ response = await client.get_async_httpx_client().request(**kwargs)
141
+
142
+ return _build_response(client=client, response=response)
143
+
144
+
145
+ async def asyncio(
146
+ *,
147
+ client: AuthenticatedClient,
148
+ ) -> MeResponse | None:
149
+ """Your plan, remaining requests, and remaining credits
150
+
151
+ Check where you stand before a call fails.
152
+
153
+ Returns the plan this request runs on and whether your key was recognized.
154
+ Without an `X-API-Key`, the call runs anonymously at the rate limit for
155
+ calls without a key. It also returns the requests left in the current window
156
+ and the features your plan includes. On plans priced in credits, it returns
157
+ the credits left in the current billing period.
158
+
159
+ This call does not count against your rate limit, so the numbers it reports
160
+ are the numbers you have.
161
+
162
+ **Credits:** free. This endpoint is not metered.
163
+
164
+ Raises:
165
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
166
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
167
+
168
+ Returns:
169
+ MeResponse
170
+ """
171
+
172
+ return (
173
+ await asyncio_detailed(
174
+ client=client,
175
+ )
176
+ ).parsed
@@ -0,0 +1 @@
1
+ """Contains endpoint functions for accessing the API"""
@@ -0,0 +1,253 @@
1
+ from http import HTTPStatus
2
+ from typing import Any
3
+
4
+ import httpx
5
+
6
+ from ... import errors
7
+ from ...client import AuthenticatedClient, Client
8
+ from ...models.body_convert_document import BodyConvertDocument
9
+ from ...models.problem import Problem
10
+ from ...models.sync_convert_response import SyncConvertResponse
11
+ from ...types import Response
12
+
13
+
14
+ def _get_kwargs(
15
+ *,
16
+ body: BodyConvertDocument,
17
+ ) -> dict[str, Any]:
18
+ headers: dict[str, Any] = {}
19
+
20
+ _kwargs: dict[str, Any] = {
21
+ "method": "post",
22
+ "url": "/v1/convert",
23
+ }
24
+
25
+ _kwargs["files"] = body.to_multipart()
26
+
27
+ headers["Content-Type"] = "multipart/form-data; boundary=+++"
28
+
29
+ _kwargs["headers"] = headers
30
+ return _kwargs
31
+
32
+
33
+ def _parse_response(
34
+ *, client: AuthenticatedClient | Client, response: httpx.Response
35
+ ) -> Problem | SyncConvertResponse | None:
36
+ if response.status_code == 200:
37
+ response_200 = SyncConvertResponse.from_dict(response.json())
38
+
39
+ return response_200
40
+
41
+ if response.status_code == 402:
42
+ response_402 = Problem.from_dict(response.json())
43
+
44
+ return response_402
45
+
46
+ if response.status_code == 413:
47
+ response_413 = Problem.from_dict(response.json())
48
+
49
+ return response_413
50
+
51
+ if response.status_code == 415:
52
+ response_415 = Problem.from_dict(response.json())
53
+
54
+ return response_415
55
+
56
+ if response.status_code == 422:
57
+ response_422 = Problem.from_dict(response.json())
58
+
59
+ return response_422
60
+
61
+ if response.status_code == 429:
62
+ response_429 = Problem.from_dict(response.json())
63
+
64
+ return response_429
65
+
66
+ if response.status_code == 500:
67
+ response_500 = Problem.from_dict(response.json())
68
+
69
+ return response_500
70
+
71
+ if response.status_code == 503:
72
+ response_503 = Problem.from_dict(response.json())
73
+
74
+ return response_503
75
+
76
+ if response.status_code == 504:
77
+ response_504 = Problem.from_dict(response.json())
78
+
79
+ return response_504
80
+
81
+ if client.raise_on_unexpected_status:
82
+ raise errors.UnexpectedStatus(response.status_code, response.content)
83
+ else:
84
+ return None
85
+
86
+
87
+ def _build_response(
88
+ *, client: AuthenticatedClient | Client, response: httpx.Response
89
+ ) -> Response[Problem | SyncConvertResponse]:
90
+ return Response(
91
+ status_code=HTTPStatus(response.status_code),
92
+ content=response.content,
93
+ headers=response.headers,
94
+ parsed=_parse_response(client=client, response=response),
95
+ )
96
+
97
+
98
+ def sync_detailed(
99
+ *,
100
+ client: AuthenticatedClient,
101
+ body: BodyConvertDocument,
102
+ ) -> Response[Problem | SyncConvertResponse]:
103
+ """Convert a document to Markdown in one call
104
+
105
+ Converts one document up to 8 MB and returns the Markdown in the response.
106
+
107
+ Accepted types: PDF (`application/pdf`), Word `.docx`, PowerPoint `.pptx`,
108
+ Excel `.xlsx`, HTML (`text/html`) and plain text (`text/plain`). The
109
+ Content-Type of the file part decides how it is read. Conversion uses
110
+ MarkItDown. PDFs come back as plain text without headings and without OCR.
111
+ For scans, tables and page numbers, use the queue (`POST /v1/convert/jobs`).
112
+
113
+ Works without an API key at the anonymous rate limit. With a key, a
114
+ rejected or failed call costs no credits.
115
+
116
+ **Credits:** 1 per call.
117
+
118
+ Args:
119
+ body (BodyConvertDocument):
120
+
121
+ Raises:
122
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
123
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
124
+
125
+ Returns:
126
+ Response[Problem | SyncConvertResponse]
127
+ """
128
+
129
+ kwargs = _get_kwargs(
130
+ body=body,
131
+ )
132
+
133
+ response = client.get_httpx_client().request(
134
+ **kwargs,
135
+ )
136
+
137
+ return _build_response(client=client, response=response)
138
+
139
+
140
+ def sync(
141
+ *,
142
+ client: AuthenticatedClient,
143
+ body: BodyConvertDocument,
144
+ ) -> Problem | SyncConvertResponse | None:
145
+ """Convert a document to Markdown in one call
146
+
147
+ Converts one document up to 8 MB and returns the Markdown in the response.
148
+
149
+ Accepted types: PDF (`application/pdf`), Word `.docx`, PowerPoint `.pptx`,
150
+ Excel `.xlsx`, HTML (`text/html`) and plain text (`text/plain`). The
151
+ Content-Type of the file part decides how it is read. Conversion uses
152
+ MarkItDown. PDFs come back as plain text without headings and without OCR.
153
+ For scans, tables and page numbers, use the queue (`POST /v1/convert/jobs`).
154
+
155
+ Works without an API key at the anonymous rate limit. With a key, a
156
+ rejected or failed call costs no credits.
157
+
158
+ **Credits:** 1 per call.
159
+
160
+ Args:
161
+ body (BodyConvertDocument):
162
+
163
+ Raises:
164
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
165
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
166
+
167
+ Returns:
168
+ Problem | SyncConvertResponse
169
+ """
170
+
171
+ return sync_detailed(
172
+ client=client,
173
+ body=body,
174
+ ).parsed
175
+
176
+
177
+ async def asyncio_detailed(
178
+ *,
179
+ client: AuthenticatedClient,
180
+ body: BodyConvertDocument,
181
+ ) -> Response[Problem | SyncConvertResponse]:
182
+ """Convert a document to Markdown in one call
183
+
184
+ Converts one document up to 8 MB and returns the Markdown in the response.
185
+
186
+ Accepted types: PDF (`application/pdf`), Word `.docx`, PowerPoint `.pptx`,
187
+ Excel `.xlsx`, HTML (`text/html`) and plain text (`text/plain`). The
188
+ Content-Type of the file part decides how it is read. Conversion uses
189
+ MarkItDown. PDFs come back as plain text without headings and without OCR.
190
+ For scans, tables and page numbers, use the queue (`POST /v1/convert/jobs`).
191
+
192
+ Works without an API key at the anonymous rate limit. With a key, a
193
+ rejected or failed call costs no credits.
194
+
195
+ **Credits:** 1 per call.
196
+
197
+ Args:
198
+ body (BodyConvertDocument):
199
+
200
+ Raises:
201
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
202
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
203
+
204
+ Returns:
205
+ Response[Problem | SyncConvertResponse]
206
+ """
207
+
208
+ kwargs = _get_kwargs(
209
+ body=body,
210
+ )
211
+
212
+ response = await client.get_async_httpx_client().request(**kwargs)
213
+
214
+ return _build_response(client=client, response=response)
215
+
216
+
217
+ async def asyncio(
218
+ *,
219
+ client: AuthenticatedClient,
220
+ body: BodyConvertDocument,
221
+ ) -> Problem | SyncConvertResponse | None:
222
+ """Convert a document to Markdown in one call
223
+
224
+ Converts one document up to 8 MB and returns the Markdown in the response.
225
+
226
+ Accepted types: PDF (`application/pdf`), Word `.docx`, PowerPoint `.pptx`,
227
+ Excel `.xlsx`, HTML (`text/html`) and plain text (`text/plain`). The
228
+ Content-Type of the file part decides how it is read. Conversion uses
229
+ MarkItDown. PDFs come back as plain text without headings and without OCR.
230
+ For scans, tables and page numbers, use the queue (`POST /v1/convert/jobs`).
231
+
232
+ Works without an API key at the anonymous rate limit. With a key, a
233
+ rejected or failed call costs no credits.
234
+
235
+ **Credits:** 1 per call.
236
+
237
+ Args:
238
+ body (BodyConvertDocument):
239
+
240
+ Raises:
241
+ errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
242
+ httpx.TimeoutException: If the request takes longer than Client.timeout.
243
+
244
+ Returns:
245
+ Problem | SyncConvertResponse
246
+ """
247
+
248
+ return (
249
+ await asyncio_detailed(
250
+ client=client,
251
+ body=body,
252
+ )
253
+ ).parsed