mtx-api-py 0.4.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 (33) hide show
  1. mtx_api_py-0.4.0/.gitignore +28 -0
  2. mtx_api_py-0.4.0/LICENSE.txt +21 -0
  3. mtx_api_py-0.4.0/PKG-INFO +323 -0
  4. mtx_api_py-0.4.0/README.md +298 -0
  5. mtx_api_py-0.4.0/pyproject.toml +158 -0
  6. mtx_api_py-0.4.0/src/mtx_api/__init__.py +25 -0
  7. mtx_api_py-0.4.0/src/mtx_api/client/__init__.py +3 -0
  8. mtx_api_py-0.4.0/src/mtx_api/client/_auth_client.py +230 -0
  9. mtx_api_py-0.4.0/src/mtx_api/client/_base_client.py +50 -0
  10. mtx_api_py-0.4.0/src/mtx_api/client/_jurisdiction_client.py +74 -0
  11. mtx_api_py-0.4.0/src/mtx_api/client/_jurisdiction_elements_client.py +41 -0
  12. mtx_api_py-0.4.0/src/mtx_api/client/_location_client.py +61 -0
  13. mtx_api_py-0.4.0/src/mtx_api/client/_mtx_http_client.py +201 -0
  14. mtx_api_py-0.4.0/src/mtx_api/client/_request_client.py +374 -0
  15. mtx_api_py-0.4.0/src/mtx_api/client/_service_client.py +94 -0
  16. mtx_api_py-0.4.0/src/mtx_api/client/_typology_client.py +64 -0
  17. mtx_api_py-0.4.0/src/mtx_api/client/_user_client.py +135 -0
  18. mtx_api_py-0.4.0/src/mtx_api/client/mtx_client.py +51 -0
  19. mtx_api_py-0.4.0/src/mtx_api/models/__init__.py +0 -0
  20. mtx_api_py-0.4.0/src/mtx_api/models/additional_data.py +334 -0
  21. mtx_api_py-0.4.0/src/mtx_api/models/auth.py +84 -0
  22. mtx_api_py-0.4.0/src/mtx_api/models/base.py +26 -0
  23. mtx_api_py-0.4.0/src/mtx_api/models/common.py +103 -0
  24. mtx_api_py-0.4.0/src/mtx_api/models/errors.py +117 -0
  25. mtx_api_py-0.4.0/src/mtx_api/models/jurisdiction.py +101 -0
  26. mtx_api_py-0.4.0/src/mtx_api/models/medias.py +97 -0
  27. mtx_api_py-0.4.0/src/mtx_api/models/request.py +253 -0
  28. mtx_api_py-0.4.0/src/mtx_api/models/request_comment.py +53 -0
  29. mtx_api_py-0.4.0/src/mtx_api/models/request_media.py +32 -0
  30. mtx_api_py-0.4.0/src/mtx_api/models/service.py +207 -0
  31. mtx_api_py-0.4.0/src/mtx_api/models/typology.py +69 -0
  32. mtx_api_py-0.4.0/src/mtx_api/py.typed +0 -0
  33. mtx_api_py-0.4.0/src/mtx_api/settings.py +11 -0
@@ -0,0 +1,28 @@
1
+ # Python
2
+ __pycache__/
3
+ *.pyc
4
+ *.pyo
5
+ *.pyd
6
+ *.coverage
7
+ .coverage*
8
+ htmlcov/
9
+ *.egg-info/
10
+ .dist/
11
+ build/
12
+
13
+ # Virtual environments
14
+ .venv/
15
+ .env/
16
+
17
+ # uv
18
+ .uv/
19
+ uv.lock
20
+
21
+ # IDEs/Editors
22
+ .idea/
23
+ .vscode/
24
+
25
+ .env
26
+
27
+ .cov/
28
+ dist/
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Radmas Technologies S.L.
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: mtx-api-py
3
+ Version: 0.4.0
4
+ Summary: SDK (wrapper) en Python para la API externa de MTX
5
+ Project-URL: Repository, https://bitbucket.org/radmas/mtx_api_py
6
+ Author-email: Álvaro Martín Rodríguez <alvaro.martin@radmas.com>
7
+ License: MIT
8
+ License-File: LICENSE.txt
9
+ Keywords: api,mtx,sdk
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Programming Language :: Python
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3 :: Only
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Topic :: Software Development :: Libraries
18
+ Classifier: Typing :: Typed
19
+ Requires-Python: >=3.12.0
20
+ Requires-Dist: httpx~=0.28.1
21
+ Requires-Dist: pydantic-settings~=2.12.0
22
+ Requires-Dist: pydantic~=2.12.4
23
+ Requires-Dist: pyjwt~=2.10.1
24
+ Description-Content-Type: text/markdown
25
+
26
+ # MTX API PY
27
+
28
+ Python SDK (wrapper) to consume the MTX API.
29
+
30
+ ## Installation
31
+
32
+ ```bash
33
+ pip install mtx-api-py
34
+ ```
35
+
36
+ ## Quick start
37
+
38
+ ```python
39
+ import asyncio
40
+ from mtx_api import MTXClient
41
+
42
+
43
+ async def main():
44
+ async with MTXClient(
45
+ base_url="https://api.mtx.example.com",
46
+ client_id="YOUR_CLIENT_ID",
47
+ jwt_secret="BASE64_SECRET", # optional; only if you will use auth.login_jwt
48
+ ) as client:
49
+ ok = await client.base.status(access_token="<ACCESS_TOKEN>")
50
+ print(ok)
51
+
52
+
53
+ asyncio.run(main())
54
+ ```
55
+
56
+ ## Configure via environment variables (.env)
57
+
58
+ You can configure the client using environment variables or a `.env` file at the project root:
59
+
60
+ ```bash
61
+ # .env
62
+ MTX_BASE_URL=https://api.mtx.example.com
63
+ MTX_CLIENT_ID=YOUR_CLIENT_ID
64
+ MTX_JWT_SECRET=BASE64_SECRET # Optional: only needed if you will use login_jwt
65
+ ```
66
+
67
+ ```python
68
+ import asyncio
69
+ from mtx_api import MTXClient
70
+ from dotenv import load_dotenv
71
+
72
+ load_dotenv() # Load environment variables from .env
73
+
74
+
75
+ async def main():
76
+ async with MTXClient() as client:
77
+ ok = await client.base.status(access_token="<ACCESS_TOKEN>")
78
+ print(ok)
79
+
80
+
81
+ asyncio.run(main())
82
+ ```
83
+
84
+ ## Available functions
85
+
86
+ All available functions accept their parameters as keyword arguments.
87
+ You can omit arguments that are not needed and accept None.
88
+
89
+ ### client.base:
90
+
91
+ ```
92
+ status(
93
+ access_token: str | None
94
+ ) -> bool
95
+ ```
96
+ ```
97
+ openapi() -> str
98
+ ```
99
+
100
+ ### client.auth:
101
+
102
+ ```
103
+ login_anonymous(
104
+ device_id: str
105
+ ) -> Authentication
106
+ ```
107
+ ```
108
+ login_jwt(
109
+ email: str,
110
+ first_name: str | None,
111
+ last_name: str | None,
112
+ register: bool | None,
113
+ legal_terms_accepted: bool | None
114
+ ) -> Authentication
115
+ ```
116
+ ```
117
+ login_refresh(
118
+ refresh_token: str
119
+ ) -> Authentication
120
+ ```
121
+ ```
122
+ register(
123
+ username: str,
124
+ password: str,
125
+ first_name: str,
126
+ last_name: str,
127
+ legal_terms_accepted: bool,
128
+ jurisdiction_code: str | None
129
+ ) -> Authentication
130
+ ```
131
+ ```
132
+ login(
133
+ username: str,
134
+ password: str
135
+ ) -> Authentication
136
+ ```
137
+
138
+ ### client.user:
139
+
140
+ ```
141
+ profile(
142
+ access_token: str | None
143
+ ) -> Profile
144
+ ```
145
+ ```
146
+ update_profile(
147
+ access_token: str | None,
148
+ email: str | None,
149
+ username: str | None,
150
+ first_name: str | None,
151
+ last_name: str | None,
152
+ twitter_nickname: str | None,
153
+ phone: str | None,
154
+ gender: str | None,
155
+ birthday: str | None
156
+ ) -> Profile
157
+ ```
158
+
159
+ ```
160
+ accept_terms(
161
+ access_token: str
162
+ ) -> bool
163
+ ```
164
+ ```
165
+ legal_terms() -> LegalTerms
166
+ ```
167
+
168
+ ### client.services:
169
+
170
+ ```
171
+ list(
172
+ access_token: str | None,
173
+ jurisdiction_codes: list[str],
174
+ lat: float | None,
175
+ lng: float | None,
176
+ typology_ids: list[str] | None
177
+ ) -> ServiceList
178
+ ```
179
+ ```
180
+ detail(
181
+ access_token: str | None,
182
+ service_id: str,
183
+ jurisdiction_code: str
184
+ ) -> Service
185
+ ```
186
+
187
+ ### client.typologies:
188
+
189
+ ```
190
+ list(
191
+ access_token: str | None,
192
+ jurisdiction_codes: list[str],
193
+ jurisdiction_element_id: str | None,
194
+ typology_ids: list[str] | None,
195
+ lat: float | None,
196
+ lng: float | None,
197
+ page: int | None,
198
+ limit: int | None
199
+ ) -> TypologyList
200
+ ```
201
+ ### client.jurisdictions:
202
+ ```
203
+ list(
204
+ access_token: str | None,
205
+ lat: float | None,
206
+ lng: float | None
207
+ ) -> JurisdictionList
208
+ ```
209
+ ```
210
+ detail(
211
+ access_token: str | None,
212
+ jurisdiction_code: str
213
+ ) -> Jurisdiction
214
+ ```
215
+ ### client.jurisdiction_elements:
216
+ ```
217
+ list(
218
+ access_token: str | None,
219
+ jurisdiction_code: str
220
+ ) -> JurisdictionElementList
221
+ ```
222
+
223
+ ### client.location:
224
+ ```
225
+ resolve(
226
+ jurisdiction_element_id: str,
227
+ formatted_address: str | None,
228
+ lat: float | None,
229
+ lng: float | None
230
+ ) -> LocationAdditionalDataList
231
+ ```
232
+
233
+ ### client.requests:
234
+
235
+ ```
236
+ list(
237
+ access_token: str | None,
238
+ jurisdiction_codes: list[str] | None,
239
+ service_request_ids: list[str] | None,
240
+ service_ids: list[str] | None,
241
+ start_date: str | None,
242
+ end_date: str | None,
243
+ own: bool | None,
244
+ lat: float | None,
245
+ lng: float | None,
246
+ page: int | None,
247
+ limit: int | None,
248
+ address_and_service_request_id: str | None,
249
+ status: list[str] | None,
250
+ typology_ids: list[str] | None,
251
+ distance: int | None,
252
+ following: bool | None,
253
+ order: str | None,
254
+ complaints: bool | None,
255
+ reiterations: bool | None,
256
+ user_reiterated: bool | None,
257
+ user_complaint: bool | None,
258
+ jurisdiction_element_ids: list[str] | None,
259
+ level: int | None,
260
+ polygon: list[float] | None,
261
+ final_ok: bool | None,
262
+ final_not_ok: bool | None,
263
+ final_status: bool | None,
264
+ interested: bool | None,
265
+ timezone: str | None
266
+ ) -> RequestList
267
+ ```
268
+ ```
269
+ detail(
270
+ access_token: str | None,
271
+ request_id: str
272
+ ) -> Request
273
+ ```
274
+ ```
275
+ create(
276
+ access_token: str | None,
277
+ service_id: str,
278
+ jurisdiction_code: str,
279
+ jurisdiction_element_id: str | None,
280
+ origin_device_id: str | None,
281
+ description: str | None,
282
+ public: bool | None,
283
+ lat: float | None,
284
+ lng: float | None,
285
+ address_string: str | None,
286
+ email: str | None,
287
+ first_name: str | None,
288
+ last_name: str | None,
289
+ phone: str | None,
290
+ twitter_nickname: str | None,
291
+ additional_data: Sequence[AdditionalDataValue] | None
292
+ ) -> CreatedRequest
293
+ ```
294
+ ```
295
+ attach_media(
296
+ access_token: str | None,
297
+ request_id: str,
298
+ jurisdiction_code: str,
299
+ file: tuple[str, bytes]
300
+ ) -> RequestMedia
301
+ ```
302
+ ```
303
+ attach_comment(
304
+ access_token: str | None,
305
+ request_id: str,
306
+ comment: str | None,
307
+ files: Sequence[tuple[str, bytes]]
308
+ ) -> RequestComment
309
+ ```
310
+
311
+ ## Errors
312
+
313
+ - HTTP errors raise `ApiError` with fields `status_code`, `code`, and `description`.
314
+ - Response model decoding/validation errors raise `ApiDecodingError`.
315
+ - SDK parameter validation errors raise specific exceptions (all extend `ValueError`):
316
+ - `MissingBaseUrlError`: missing `base_url` configuration (via `MTX_BASE_URL` or `base_url` parameter).
317
+ - `MissingClientIdError`: missing `client_id` configuration (via `MTX_CLIENT_ID` or `client_id` parameter).
318
+ - `MissingJwtSecretError`: missing JWT secret configuration (via `MTX_JWT_SECRET` or `jwt_secret` parameter) when using `auth.login_jwt`.
319
+ - `MissingJurisdictionCodesError`: missing `jurisdiction_codes`/`jurisdiction_code` in calls that require it.
320
+ - `MissingServiceIdError`: missing `service_id` in calls that require it.
321
+ - `MissingRequestIdError`: missing `request_id` in calls that require it.
322
+ - `MissingArgumentError`: a required argument is missing.
323
+ - `InvalidEmailError`: the email is not valid.
@@ -0,0 +1,298 @@
1
+ # MTX API PY
2
+
3
+ Python SDK (wrapper) to consume the MTX API.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install mtx-api-py
9
+ ```
10
+
11
+ ## Quick start
12
+
13
+ ```python
14
+ import asyncio
15
+ from mtx_api import MTXClient
16
+
17
+
18
+ async def main():
19
+ async with MTXClient(
20
+ base_url="https://api.mtx.example.com",
21
+ client_id="YOUR_CLIENT_ID",
22
+ jwt_secret="BASE64_SECRET", # optional; only if you will use auth.login_jwt
23
+ ) as client:
24
+ ok = await client.base.status(access_token="<ACCESS_TOKEN>")
25
+ print(ok)
26
+
27
+
28
+ asyncio.run(main())
29
+ ```
30
+
31
+ ## Configure via environment variables (.env)
32
+
33
+ You can configure the client using environment variables or a `.env` file at the project root:
34
+
35
+ ```bash
36
+ # .env
37
+ MTX_BASE_URL=https://api.mtx.example.com
38
+ MTX_CLIENT_ID=YOUR_CLIENT_ID
39
+ MTX_JWT_SECRET=BASE64_SECRET # Optional: only needed if you will use login_jwt
40
+ ```
41
+
42
+ ```python
43
+ import asyncio
44
+ from mtx_api import MTXClient
45
+ from dotenv import load_dotenv
46
+
47
+ load_dotenv() # Load environment variables from .env
48
+
49
+
50
+ async def main():
51
+ async with MTXClient() as client:
52
+ ok = await client.base.status(access_token="<ACCESS_TOKEN>")
53
+ print(ok)
54
+
55
+
56
+ asyncio.run(main())
57
+ ```
58
+
59
+ ## Available functions
60
+
61
+ All available functions accept their parameters as keyword arguments.
62
+ You can omit arguments that are not needed and accept None.
63
+
64
+ ### client.base:
65
+
66
+ ```
67
+ status(
68
+ access_token: str | None
69
+ ) -> bool
70
+ ```
71
+ ```
72
+ openapi() -> str
73
+ ```
74
+
75
+ ### client.auth:
76
+
77
+ ```
78
+ login_anonymous(
79
+ device_id: str
80
+ ) -> Authentication
81
+ ```
82
+ ```
83
+ login_jwt(
84
+ email: str,
85
+ first_name: str | None,
86
+ last_name: str | None,
87
+ register: bool | None,
88
+ legal_terms_accepted: bool | None
89
+ ) -> Authentication
90
+ ```
91
+ ```
92
+ login_refresh(
93
+ refresh_token: str
94
+ ) -> Authentication
95
+ ```
96
+ ```
97
+ register(
98
+ username: str,
99
+ password: str,
100
+ first_name: str,
101
+ last_name: str,
102
+ legal_terms_accepted: bool,
103
+ jurisdiction_code: str | None
104
+ ) -> Authentication
105
+ ```
106
+ ```
107
+ login(
108
+ username: str,
109
+ password: str
110
+ ) -> Authentication
111
+ ```
112
+
113
+ ### client.user:
114
+
115
+ ```
116
+ profile(
117
+ access_token: str | None
118
+ ) -> Profile
119
+ ```
120
+ ```
121
+ update_profile(
122
+ access_token: str | None,
123
+ email: str | None,
124
+ username: str | None,
125
+ first_name: str | None,
126
+ last_name: str | None,
127
+ twitter_nickname: str | None,
128
+ phone: str | None,
129
+ gender: str | None,
130
+ birthday: str | None
131
+ ) -> Profile
132
+ ```
133
+
134
+ ```
135
+ accept_terms(
136
+ access_token: str
137
+ ) -> bool
138
+ ```
139
+ ```
140
+ legal_terms() -> LegalTerms
141
+ ```
142
+
143
+ ### client.services:
144
+
145
+ ```
146
+ list(
147
+ access_token: str | None,
148
+ jurisdiction_codes: list[str],
149
+ lat: float | None,
150
+ lng: float | None,
151
+ typology_ids: list[str] | None
152
+ ) -> ServiceList
153
+ ```
154
+ ```
155
+ detail(
156
+ access_token: str | None,
157
+ service_id: str,
158
+ jurisdiction_code: str
159
+ ) -> Service
160
+ ```
161
+
162
+ ### client.typologies:
163
+
164
+ ```
165
+ list(
166
+ access_token: str | None,
167
+ jurisdiction_codes: list[str],
168
+ jurisdiction_element_id: str | None,
169
+ typology_ids: list[str] | None,
170
+ lat: float | None,
171
+ lng: float | None,
172
+ page: int | None,
173
+ limit: int | None
174
+ ) -> TypologyList
175
+ ```
176
+ ### client.jurisdictions:
177
+ ```
178
+ list(
179
+ access_token: str | None,
180
+ lat: float | None,
181
+ lng: float | None
182
+ ) -> JurisdictionList
183
+ ```
184
+ ```
185
+ detail(
186
+ access_token: str | None,
187
+ jurisdiction_code: str
188
+ ) -> Jurisdiction
189
+ ```
190
+ ### client.jurisdiction_elements:
191
+ ```
192
+ list(
193
+ access_token: str | None,
194
+ jurisdiction_code: str
195
+ ) -> JurisdictionElementList
196
+ ```
197
+
198
+ ### client.location:
199
+ ```
200
+ resolve(
201
+ jurisdiction_element_id: str,
202
+ formatted_address: str | None,
203
+ lat: float | None,
204
+ lng: float | None
205
+ ) -> LocationAdditionalDataList
206
+ ```
207
+
208
+ ### client.requests:
209
+
210
+ ```
211
+ list(
212
+ access_token: str | None,
213
+ jurisdiction_codes: list[str] | None,
214
+ service_request_ids: list[str] | None,
215
+ service_ids: list[str] | None,
216
+ start_date: str | None,
217
+ end_date: str | None,
218
+ own: bool | None,
219
+ lat: float | None,
220
+ lng: float | None,
221
+ page: int | None,
222
+ limit: int | None,
223
+ address_and_service_request_id: str | None,
224
+ status: list[str] | None,
225
+ typology_ids: list[str] | None,
226
+ distance: int | None,
227
+ following: bool | None,
228
+ order: str | None,
229
+ complaints: bool | None,
230
+ reiterations: bool | None,
231
+ user_reiterated: bool | None,
232
+ user_complaint: bool | None,
233
+ jurisdiction_element_ids: list[str] | None,
234
+ level: int | None,
235
+ polygon: list[float] | None,
236
+ final_ok: bool | None,
237
+ final_not_ok: bool | None,
238
+ final_status: bool | None,
239
+ interested: bool | None,
240
+ timezone: str | None
241
+ ) -> RequestList
242
+ ```
243
+ ```
244
+ detail(
245
+ access_token: str | None,
246
+ request_id: str
247
+ ) -> Request
248
+ ```
249
+ ```
250
+ create(
251
+ access_token: str | None,
252
+ service_id: str,
253
+ jurisdiction_code: str,
254
+ jurisdiction_element_id: str | None,
255
+ origin_device_id: str | None,
256
+ description: str | None,
257
+ public: bool | None,
258
+ lat: float | None,
259
+ lng: float | None,
260
+ address_string: str | None,
261
+ email: str | None,
262
+ first_name: str | None,
263
+ last_name: str | None,
264
+ phone: str | None,
265
+ twitter_nickname: str | None,
266
+ additional_data: Sequence[AdditionalDataValue] | None
267
+ ) -> CreatedRequest
268
+ ```
269
+ ```
270
+ attach_media(
271
+ access_token: str | None,
272
+ request_id: str,
273
+ jurisdiction_code: str,
274
+ file: tuple[str, bytes]
275
+ ) -> RequestMedia
276
+ ```
277
+ ```
278
+ attach_comment(
279
+ access_token: str | None,
280
+ request_id: str,
281
+ comment: str | None,
282
+ files: Sequence[tuple[str, bytes]]
283
+ ) -> RequestComment
284
+ ```
285
+
286
+ ## Errors
287
+
288
+ - HTTP errors raise `ApiError` with fields `status_code`, `code`, and `description`.
289
+ - Response model decoding/validation errors raise `ApiDecodingError`.
290
+ - SDK parameter validation errors raise specific exceptions (all extend `ValueError`):
291
+ - `MissingBaseUrlError`: missing `base_url` configuration (via `MTX_BASE_URL` or `base_url` parameter).
292
+ - `MissingClientIdError`: missing `client_id` configuration (via `MTX_CLIENT_ID` or `client_id` parameter).
293
+ - `MissingJwtSecretError`: missing JWT secret configuration (via `MTX_JWT_SECRET` or `jwt_secret` parameter) when using `auth.login_jwt`.
294
+ - `MissingJurisdictionCodesError`: missing `jurisdiction_codes`/`jurisdiction_code` in calls that require it.
295
+ - `MissingServiceIdError`: missing `service_id` in calls that require it.
296
+ - `MissingRequestIdError`: missing `request_id` in calls that require it.
297
+ - `MissingArgumentError`: a required argument is missing.
298
+ - `InvalidEmailError`: the email is not valid.