khaleejiapi 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.
@@ -0,0 +1,54 @@
1
+ # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2
+
3
+ # dependencies
4
+ /node_modules
5
+ **/node_modules
6
+ /.pnp
7
+ .pnp.*
8
+ .yarn/*
9
+ !.yarn/patches
10
+ !.yarn/plugins
11
+ !.yarn/releases
12
+ !.yarn/versions
13
+
14
+ # SDK build artifacts
15
+ sdk/typescript/dist/
16
+ sdk/python/dist/
17
+ sdk/python/__pycache__/
18
+ sdk/python/*.egg-info/
19
+
20
+ # testing
21
+ /coverage
22
+
23
+ # next.js
24
+ /.next/
25
+ /out/
26
+
27
+ # production
28
+ /build
29
+
30
+ # misc
31
+ .DS_Store
32
+ *.pem
33
+
34
+ # debug
35
+ npm-debug.log*
36
+ yarn-debug.log*
37
+ yarn-error.log*
38
+ .pnpm-debug.log*
39
+
40
+ # env files (can opt-in for committing if needed)
41
+ .env*
42
+
43
+ # vercel
44
+ .vercel
45
+
46
+ # typescript
47
+ *.tsbuildinfo
48
+ next-env.d.ts
49
+
50
+ # terraform
51
+ terraform/*.tfplan
52
+ terraform/*.bin
53
+ terraform/.terraform/
54
+ terraform/terraform.tfvars
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 KhaleejiAPI
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,297 @@
1
+ Metadata-Version: 2.4
2
+ Name: khaleejiapi
3
+ Version: 1.0.0
4
+ Summary: Official Python SDK for KhaleejiAPI - Middle East API Platform
5
+ Project-URL: Homepage, https://khaleejiapi.dev
6
+ Project-URL: Documentation, https://khaleejiapi.dev/docs/sdks
7
+ Project-URL: Repository, https://github.com/xidioda/khaleejiapi/tree/master/sdk/python
8
+ Project-URL: Issues, https://github.com/xidioda/khaleejiapi/issues
9
+ Author-email: KhaleejiAPI <hello@khaleejiapi.dev>
10
+ License: MIT
11
+ Keywords: api,dubai,khaleejiapi,middle-east,sdk,uae
12
+ Classifier: Development Status :: 5 - Production/Stable
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Typing :: Typed
22
+ Requires-Python: >=3.9
23
+ Requires-Dist: httpx<1.0.0,>=0.25.0
24
+ Provides-Extra: dev
25
+ Requires-Dist: mypy>=1.8; extra == 'dev'
26
+ Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
27
+ Requires-Dist: pytest-httpx>=0.30; extra == 'dev'
28
+ Requires-Dist: pytest>=8.0; extra == 'dev'
29
+ Requires-Dist: ruff>=0.3; extra == 'dev'
30
+ Description-Content-Type: text/markdown
31
+
32
+ # KhaleejiAPI Python SDK
33
+
34
+ [![PyPI version](https://img.shields.io/pypi/v/khaleejiapi.svg)](https://pypi.org/project/khaleejiapi/)
35
+ [![Python](https://img.shields.io/pypi/pyversions/khaleejiapi.svg)](https://pypi.org/project/khaleejiapi/)
36
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
37
+
38
+ The official Python SDK for [KhaleejiAPI](https://khaleejiapi.dev) — the Middle East API platform providing 20+ production-ready APIs for validation, geolocation, finance, translation, and more.
39
+
40
+ ## Installation
41
+
42
+ ```bash
43
+ pip install khaleejiapi
44
+ ```
45
+
46
+ ## Quick Start
47
+
48
+ ```python
49
+ from khaleejiapi import KhaleejiAPI
50
+
51
+ client = KhaleejiAPI("kapi_live_your_api_key")
52
+
53
+ # Validate an email
54
+ result = client.validation.validate_email("user@example.com")
55
+ print(result["valid"]) # True
56
+
57
+ # Look up an IP address
58
+ ip_data = client.geo.lookup_ip("8.8.8.8")
59
+ print(ip_data["country"]["name"]) # United States
60
+
61
+ client.close()
62
+ ```
63
+
64
+ ### Using a context manager
65
+
66
+ ```python
67
+ with KhaleejiAPI("kapi_live_your_api_key") as client:
68
+ rates = client.finance.get_exchange_rates("USD")
69
+ print(rates["rates"]["AED"])
70
+ ```
71
+
72
+ ### Async usage
73
+
74
+ ```python
75
+ import asyncio
76
+ from khaleejiapi import AsyncKhaleejiAPI
77
+
78
+ async def main():
79
+ async with AsyncKhaleejiAPI("kapi_live_your_api_key") as client:
80
+ result = await client.validation.validate_email("user@example.com")
81
+ print(result["valid"])
82
+
83
+ asyncio.run(main())
84
+ ```
85
+
86
+ ## Configuration
87
+
88
+ ```python
89
+ client = KhaleejiAPI(
90
+ "kapi_live_your_api_key",
91
+ base_url="https://khaleejiapi.dev/api", # default
92
+ timeout=30.0, # seconds (default)
93
+ max_retries=2, # automatic retries on 429/5xx (default)
94
+ )
95
+ ```
96
+
97
+ ## API Reference
98
+
99
+ ### Validation
100
+
101
+ ```python
102
+ # Email validation (syntax, MX, disposable, role-account checks)
103
+ result = client.validation.validate_email("user@example.com")
104
+ # Returns: { valid, email, reason, checks: { syntax, disposable, mx, role }, domain, localPart, suggestion? }
105
+
106
+ # Phone validation (GCC countries with carrier detection)
107
+ result = client.validation.validate_phone("+971501234567")
108
+ # Returns: { valid, phone, e164, country: { code, name, nameAr, prefix }, type, nationalNumber, reason }
109
+
110
+ # VAT / TRN validation (UAE Tax Registration Number)
111
+ result = client.validation.validate_vat("100000000000003")
112
+ # Returns: { valid, trn, country, countryName, reason }
113
+
114
+ # IBAN validation (MENA region with bank identification)
115
+ result = client.validation.validate_iban("AE070331234567890123456")
116
+ # Returns: { valid, iban, countryCode, country, bank: { name, bic }, reason }
117
+
118
+ # Emirates ID validation
119
+ result = client.validation.validate_emirates_id("784-1990-1234567-1")
120
+ # Returns: { valid, emiratesId, formatted, components: { year, random, checkDigit } }
121
+ ```
122
+
123
+ ### Geolocation
124
+
125
+ ```python
126
+ # IP geolocation (supports IPv4 and IPv6)
127
+ result = client.geo.lookup_ip("8.8.8.8")
128
+ # Returns: { ip, type, continent, country, region, city, postal, location, connection }
129
+
130
+ # Omit IP to look up the caller's IP
131
+ result = client.geo.lookup_ip()
132
+
133
+ # Timezone lookup by location name or coordinates
134
+ result = client.geo.get_timezone("Dubai")
135
+ result = client.geo.get_timezone(lat=25.2048, lon=55.2708)
136
+ # Returns: { timezone, utcOffset, dstOffset, localTime, isDST }
137
+
138
+ # Geocoding (forward and reverse)
139
+ result = client.geo.geocode(address="Burj Khalifa, Dubai")
140
+ result = client.geo.geocode(lat=25.1972, lon=55.2744)
141
+ # Returns: { formattedAddress, latitude, longitude, components }
142
+
143
+ # Weather
144
+ result = client.geo.get_weather(city="Dubai")
145
+ # Returns: { city, country, current: { temperature, humidity, description, ... } }
146
+ ```
147
+
148
+ ### Finance
149
+
150
+ ```python
151
+ # Exchange rates (170+ currencies, base defaults to AED)
152
+ result = client.finance.get_exchange_rates("USD")
153
+ # Returns: { base, timestamp, rates: { AED: 3.6725, EUR: 0.92, ... } }
154
+
155
+ # Currency conversion
156
+ result = client.finance.get_exchange_rates("USD", target="AED", amount=100)
157
+ # Returns: { from, to, amount, rate, converted, timestamp }
158
+
159
+ # VAT calculator
160
+ result = client.finance.calculate_vat(1000, "AE")
161
+ # Returns: { amount, vatRate, vatAmount, total, country, inclusive }
162
+
163
+ # Public holidays (UAE and GCC)
164
+ result = client.finance.get_holidays("AE", year=2025)
165
+ # Returns: { country, year, holidays: [{ name, nameAr, date, type }] }
166
+ ```
167
+
168
+ ### Documents
169
+
170
+ ```python
171
+ # Image processing (resize, crop, compress, convert)
172
+ with open("photo.jpg", "rb") as f:
173
+ processed = client.documents.process_image(
174
+ f.read(),
175
+ operations={"width": 800, "format": "webp", "quality": 80},
176
+ )
177
+ with open("output.webp", "wb") as f:
178
+ f.write(processed)
179
+
180
+ # PDF generation from HTML
181
+ pdf_bytes = client.documents.generate_pdf(html="<h1>Invoice</h1><p>Amount: 500 AED</p>")
182
+ with open("invoice.pdf", "wb") as f:
183
+ f.write(pdf_bytes)
184
+
185
+ # PDF generation from URL
186
+ pdf_bytes = client.documents.generate_pdf(url="https://example.com", options={"format": "A4"})
187
+ ```
188
+
189
+ ### Communication
190
+
191
+ ```python
192
+ # Translation (Arabic ↔ English with auto-detection)
193
+ result = client.communication.translate("Hello, welcome to Dubai")
194
+ # Returns: { text, translated, detectedLanguage, wordsMatched, totalWords }
195
+
196
+ result = client.communication.translate("مرحبا", target="en")
197
+
198
+ # URL shortener
199
+ result = client.communication.shorten_url("https://example.com/very/long/url")
200
+ # Returns: { code, shortUrl, originalUrl, expiresInDays, createdAt }
201
+
202
+ result = client.communication.shorten_url("https://example.com", custom_alias="my-link")
203
+ ```
204
+
205
+ ### Utility
206
+
207
+ ```python
208
+ # QR code generation
209
+ qr_bytes = client.utility.generate_qr("https://khaleejiapi.dev", size=400, format="png")
210
+ with open("qr.png", "wb") as f:
211
+ f.write(qr_bytes)
212
+
213
+ # Fraud detection
214
+ result = client.utility.check_fraud(
215
+ email="suspicious@tempmail.com",
216
+ ip="185.220.101.42",
217
+ phone="+1234567",
218
+ )
219
+ # Returns: { riskScore, riskLevel, signals: [{ field, risk, score, reason }], recommendation }
220
+ ```
221
+
222
+ ## Error Handling
223
+
224
+ The SDK raises typed exceptions for every error class:
225
+
226
+ ```python
227
+ from khaleejiapi import (
228
+ KhaleejiAPI,
229
+ KhaleejiAPIError, # Base class for all errors
230
+ AuthenticationError, # 401 — invalid or missing API key
231
+ ForbiddenError, # 403 — missing scope
232
+ ValidationError, # 400 — bad request parameters
233
+ NotFoundError, # 404 — resource not found
234
+ RateLimitError, # 429 — rate limit exceeded
235
+ ConflictError, # 409 — resource conflict
236
+ ServerError, # 5xx — server error
237
+ )
238
+
239
+ try:
240
+ result = client.validation.validate_email("bad")
241
+ except RateLimitError as e:
242
+ print(f"Rate limited! Retry after {e.retry_after}s")
243
+ except AuthenticationError:
244
+ print("Check your API key")
245
+ except KhaleejiAPIError as e:
246
+ print(f"API error {e.code}: {e.message} (HTTP {e.status_code})")
247
+ ```
248
+
249
+ ## Rate Limiting
250
+
251
+ Rate-limit headers are automatically parsed and available after every request:
252
+
253
+ ```python
254
+ result = client.validation.validate_email("user@example.com")
255
+ rl = client.last_rate_limit
256
+ print(f"Remaining: {rl.get('remaining')} / {rl.get('limit')}")
257
+ ```
258
+
259
+ The SDK automatically retries on HTTP 429 (and 5xx) with exponential backoff.
260
+ Configure with `max_retries` (default `2`).
261
+
262
+ ## Type Safety
263
+
264
+ This SDK is fully typed and ships with a `py.typed` marker (PEP 561).
265
+ All response types are `TypedDict` subclasses for excellent IDE autocompletion:
266
+
267
+ ```python
268
+ from khaleejiapi import EmailValidationResult
269
+
270
+ def process(result: EmailValidationResult) -> None:
271
+ if result["valid"]:
272
+ print(f"Domain: {result['domain']}")
273
+ ```
274
+
275
+ ## Development
276
+
277
+ ```bash
278
+ # Clone the repository
279
+ git clone https://github.com/khaleejiapi/sdk-python.git
280
+ cd sdk-python
281
+
282
+ # Install dev dependencies
283
+ pip install -e ".[dev]"
284
+
285
+ # Run tests
286
+ pytest
287
+
288
+ # Type checking
289
+ mypy src/
290
+
291
+ # Linting
292
+ ruff check src/ tests/
293
+ ```
294
+
295
+ ## License
296
+
297
+ MIT — see [LICENSE](./LICENSE) for details.
@@ -0,0 +1,266 @@
1
+ # KhaleejiAPI Python SDK
2
+
3
+ [![PyPI version](https://img.shields.io/pypi/v/khaleejiapi.svg)](https://pypi.org/project/khaleejiapi/)
4
+ [![Python](https://img.shields.io/pypi/pyversions/khaleejiapi.svg)](https://pypi.org/project/khaleejiapi/)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
+
7
+ The official Python SDK for [KhaleejiAPI](https://khaleejiapi.dev) — the Middle East API platform providing 20+ production-ready APIs for validation, geolocation, finance, translation, and more.
8
+
9
+ ## Installation
10
+
11
+ ```bash
12
+ pip install khaleejiapi
13
+ ```
14
+
15
+ ## Quick Start
16
+
17
+ ```python
18
+ from khaleejiapi import KhaleejiAPI
19
+
20
+ client = KhaleejiAPI("kapi_live_your_api_key")
21
+
22
+ # Validate an email
23
+ result = client.validation.validate_email("user@example.com")
24
+ print(result["valid"]) # True
25
+
26
+ # Look up an IP address
27
+ ip_data = client.geo.lookup_ip("8.8.8.8")
28
+ print(ip_data["country"]["name"]) # United States
29
+
30
+ client.close()
31
+ ```
32
+
33
+ ### Using a context manager
34
+
35
+ ```python
36
+ with KhaleejiAPI("kapi_live_your_api_key") as client:
37
+ rates = client.finance.get_exchange_rates("USD")
38
+ print(rates["rates"]["AED"])
39
+ ```
40
+
41
+ ### Async usage
42
+
43
+ ```python
44
+ import asyncio
45
+ from khaleejiapi import AsyncKhaleejiAPI
46
+
47
+ async def main():
48
+ async with AsyncKhaleejiAPI("kapi_live_your_api_key") as client:
49
+ result = await client.validation.validate_email("user@example.com")
50
+ print(result["valid"])
51
+
52
+ asyncio.run(main())
53
+ ```
54
+
55
+ ## Configuration
56
+
57
+ ```python
58
+ client = KhaleejiAPI(
59
+ "kapi_live_your_api_key",
60
+ base_url="https://khaleejiapi.dev/api", # default
61
+ timeout=30.0, # seconds (default)
62
+ max_retries=2, # automatic retries on 429/5xx (default)
63
+ )
64
+ ```
65
+
66
+ ## API Reference
67
+
68
+ ### Validation
69
+
70
+ ```python
71
+ # Email validation (syntax, MX, disposable, role-account checks)
72
+ result = client.validation.validate_email("user@example.com")
73
+ # Returns: { valid, email, reason, checks: { syntax, disposable, mx, role }, domain, localPart, suggestion? }
74
+
75
+ # Phone validation (GCC countries with carrier detection)
76
+ result = client.validation.validate_phone("+971501234567")
77
+ # Returns: { valid, phone, e164, country: { code, name, nameAr, prefix }, type, nationalNumber, reason }
78
+
79
+ # VAT / TRN validation (UAE Tax Registration Number)
80
+ result = client.validation.validate_vat("100000000000003")
81
+ # Returns: { valid, trn, country, countryName, reason }
82
+
83
+ # IBAN validation (MENA region with bank identification)
84
+ result = client.validation.validate_iban("AE070331234567890123456")
85
+ # Returns: { valid, iban, countryCode, country, bank: { name, bic }, reason }
86
+
87
+ # Emirates ID validation
88
+ result = client.validation.validate_emirates_id("784-1990-1234567-1")
89
+ # Returns: { valid, emiratesId, formatted, components: { year, random, checkDigit } }
90
+ ```
91
+
92
+ ### Geolocation
93
+
94
+ ```python
95
+ # IP geolocation (supports IPv4 and IPv6)
96
+ result = client.geo.lookup_ip("8.8.8.8")
97
+ # Returns: { ip, type, continent, country, region, city, postal, location, connection }
98
+
99
+ # Omit IP to look up the caller's IP
100
+ result = client.geo.lookup_ip()
101
+
102
+ # Timezone lookup by location name or coordinates
103
+ result = client.geo.get_timezone("Dubai")
104
+ result = client.geo.get_timezone(lat=25.2048, lon=55.2708)
105
+ # Returns: { timezone, utcOffset, dstOffset, localTime, isDST }
106
+
107
+ # Geocoding (forward and reverse)
108
+ result = client.geo.geocode(address="Burj Khalifa, Dubai")
109
+ result = client.geo.geocode(lat=25.1972, lon=55.2744)
110
+ # Returns: { formattedAddress, latitude, longitude, components }
111
+
112
+ # Weather
113
+ result = client.geo.get_weather(city="Dubai")
114
+ # Returns: { city, country, current: { temperature, humidity, description, ... } }
115
+ ```
116
+
117
+ ### Finance
118
+
119
+ ```python
120
+ # Exchange rates (170+ currencies, base defaults to AED)
121
+ result = client.finance.get_exchange_rates("USD")
122
+ # Returns: { base, timestamp, rates: { AED: 3.6725, EUR: 0.92, ... } }
123
+
124
+ # Currency conversion
125
+ result = client.finance.get_exchange_rates("USD", target="AED", amount=100)
126
+ # Returns: { from, to, amount, rate, converted, timestamp }
127
+
128
+ # VAT calculator
129
+ result = client.finance.calculate_vat(1000, "AE")
130
+ # Returns: { amount, vatRate, vatAmount, total, country, inclusive }
131
+
132
+ # Public holidays (UAE and GCC)
133
+ result = client.finance.get_holidays("AE", year=2025)
134
+ # Returns: { country, year, holidays: [{ name, nameAr, date, type }] }
135
+ ```
136
+
137
+ ### Documents
138
+
139
+ ```python
140
+ # Image processing (resize, crop, compress, convert)
141
+ with open("photo.jpg", "rb") as f:
142
+ processed = client.documents.process_image(
143
+ f.read(),
144
+ operations={"width": 800, "format": "webp", "quality": 80},
145
+ )
146
+ with open("output.webp", "wb") as f:
147
+ f.write(processed)
148
+
149
+ # PDF generation from HTML
150
+ pdf_bytes = client.documents.generate_pdf(html="<h1>Invoice</h1><p>Amount: 500 AED</p>")
151
+ with open("invoice.pdf", "wb") as f:
152
+ f.write(pdf_bytes)
153
+
154
+ # PDF generation from URL
155
+ pdf_bytes = client.documents.generate_pdf(url="https://example.com", options={"format": "A4"})
156
+ ```
157
+
158
+ ### Communication
159
+
160
+ ```python
161
+ # Translation (Arabic ↔ English with auto-detection)
162
+ result = client.communication.translate("Hello, welcome to Dubai")
163
+ # Returns: { text, translated, detectedLanguage, wordsMatched, totalWords }
164
+
165
+ result = client.communication.translate("مرحبا", target="en")
166
+
167
+ # URL shortener
168
+ result = client.communication.shorten_url("https://example.com/very/long/url")
169
+ # Returns: { code, shortUrl, originalUrl, expiresInDays, createdAt }
170
+
171
+ result = client.communication.shorten_url("https://example.com", custom_alias="my-link")
172
+ ```
173
+
174
+ ### Utility
175
+
176
+ ```python
177
+ # QR code generation
178
+ qr_bytes = client.utility.generate_qr("https://khaleejiapi.dev", size=400, format="png")
179
+ with open("qr.png", "wb") as f:
180
+ f.write(qr_bytes)
181
+
182
+ # Fraud detection
183
+ result = client.utility.check_fraud(
184
+ email="suspicious@tempmail.com",
185
+ ip="185.220.101.42",
186
+ phone="+1234567",
187
+ )
188
+ # Returns: { riskScore, riskLevel, signals: [{ field, risk, score, reason }], recommendation }
189
+ ```
190
+
191
+ ## Error Handling
192
+
193
+ The SDK raises typed exceptions for every error class:
194
+
195
+ ```python
196
+ from khaleejiapi import (
197
+ KhaleejiAPI,
198
+ KhaleejiAPIError, # Base class for all errors
199
+ AuthenticationError, # 401 — invalid or missing API key
200
+ ForbiddenError, # 403 — missing scope
201
+ ValidationError, # 400 — bad request parameters
202
+ NotFoundError, # 404 — resource not found
203
+ RateLimitError, # 429 — rate limit exceeded
204
+ ConflictError, # 409 — resource conflict
205
+ ServerError, # 5xx — server error
206
+ )
207
+
208
+ try:
209
+ result = client.validation.validate_email("bad")
210
+ except RateLimitError as e:
211
+ print(f"Rate limited! Retry after {e.retry_after}s")
212
+ except AuthenticationError:
213
+ print("Check your API key")
214
+ except KhaleejiAPIError as e:
215
+ print(f"API error {e.code}: {e.message} (HTTP {e.status_code})")
216
+ ```
217
+
218
+ ## Rate Limiting
219
+
220
+ Rate-limit headers are automatically parsed and available after every request:
221
+
222
+ ```python
223
+ result = client.validation.validate_email("user@example.com")
224
+ rl = client.last_rate_limit
225
+ print(f"Remaining: {rl.get('remaining')} / {rl.get('limit')}")
226
+ ```
227
+
228
+ The SDK automatically retries on HTTP 429 (and 5xx) with exponential backoff.
229
+ Configure with `max_retries` (default `2`).
230
+
231
+ ## Type Safety
232
+
233
+ This SDK is fully typed and ships with a `py.typed` marker (PEP 561).
234
+ All response types are `TypedDict` subclasses for excellent IDE autocompletion:
235
+
236
+ ```python
237
+ from khaleejiapi import EmailValidationResult
238
+
239
+ def process(result: EmailValidationResult) -> None:
240
+ if result["valid"]:
241
+ print(f"Domain: {result['domain']}")
242
+ ```
243
+
244
+ ## Development
245
+
246
+ ```bash
247
+ # Clone the repository
248
+ git clone https://github.com/khaleejiapi/sdk-python.git
249
+ cd sdk-python
250
+
251
+ # Install dev dependencies
252
+ pip install -e ".[dev]"
253
+
254
+ # Run tests
255
+ pytest
256
+
257
+ # Type checking
258
+ mypy src/
259
+
260
+ # Linting
261
+ ruff check src/ tests/
262
+ ```
263
+
264
+ ## License
265
+
266
+ MIT — see [LICENSE](./LICENSE) for details.
@@ -0,0 +1,51 @@
1
+ [build-system]
2
+ requires = ["hatchling>=1.27"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "khaleejiapi"
7
+ version = "1.0.0"
8
+ description = "Official Python SDK for KhaleejiAPI - Middle East API Platform"
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ license = {text = "MIT"}
12
+ license-files = []
13
+ authors = [{ name = "KhaleejiAPI", email = "hello@khaleejiapi.dev" }]
14
+ keywords = ["khaleejiapi", "api", "sdk", "middle-east", "uae", "dubai"]
15
+ classifiers = [
16
+ "Development Status :: 5 - Production/Stable",
17
+ "Intended Audience :: Developers",
18
+ "License :: OSI Approved :: MIT License",
19
+ "Programming Language :: Python :: 3",
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 = ["httpx>=0.25.0,<1.0.0"]
28
+
29
+ [project.optional-dependencies]
30
+ dev = ["pytest>=8.0", "pytest-asyncio>=0.23", "pytest-httpx>=0.30", "mypy>=1.8", "ruff>=0.3"]
31
+
32
+ [project.urls]
33
+ Homepage = "https://khaleejiapi.dev"
34
+ Documentation = "https://khaleejiapi.dev/docs/sdks"
35
+ Repository = "https://github.com/xidioda/khaleejiapi/tree/master/sdk/python"
36
+ Issues = "https://github.com/xidioda/khaleejiapi/issues"
37
+
38
+ [tool.hatch.build.targets.wheel]
39
+ packages = ["src/khaleejiapi"]
40
+
41
+ [tool.ruff]
42
+ target-version = "py39"
43
+ line-length = 100
44
+
45
+ [tool.mypy]
46
+ python_version = "3.9"
47
+ strict = true
48
+
49
+ [tool.pytest.ini_options]
50
+ asyncio_mode = "auto"
51
+ testpaths = ["tests"]