bookalimo 0.1.1__tar.gz → 0.1.3__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bookalimo
3
- Version: 0.1.1
3
+ Version: 0.1.3
4
4
  Summary: Python wrapper for the Book-A-Limo API
5
5
  Author-email: Jonathan Oren <jonathan@bookalimo.com>
6
6
  Maintainer-email: Jonathan Oren <jonathan@bookalimo.com>
@@ -63,13 +63,13 @@ Dynamic: license-file
63
63
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
64
64
  [![Code style: ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
65
65
 
66
- A modern, async Python wrapper for the Book-A-Limo API with full type support.
66
+ A modern, async Python wrapper for the Book-A-Limo API with full type support. Built on top of `httpx` and `pydantic`.
67
67
 
68
68
  ## Features
69
69
 
70
- * **Async/await** (built on `httpx`)
71
- * **Typed Pydantic models** for requests & responses
72
- * **Input validation**
70
+ * **Asynchronous**
71
+ * **Fully Typed** for requests & responses
72
+ * **Input validation** including airports and addresses.
73
73
  * **Clean, minimal interface** for each API operation
74
74
  * **Custom exceptions & error handling**
75
75
  * **Tests and examples**
@@ -104,37 +104,26 @@ async def main():
104
104
  # For Travel Agents (customers: pass is_customer=True)
105
105
  credentials = create_credentials("TA10007", "your_password")
106
106
 
107
- async with AsyncClient() as http_client:
108
- async with BookALimo(credentials, http_client=http_client) as client:
109
- # Build locations
110
- pickup = create_airport_location("JFK", "New York")
111
- dropoff = create_address_location("53 East 34th Street, Manhattan")
112
-
113
- prices = await client.get_prices(
114
- rate_type=RateType.P2P,
115
- date_time="09/05/2025 12:44 AM",
116
- pickup=pickup,
117
- dropoff=dropoff,
118
- passengers=2,
119
- luggage=3,
120
- )
121
-
122
- print(f"Available cars: {len(prices.prices)}")
123
- for price in prices.prices:
124
- print(f"- {price.car_description}: ${price.price}")
107
+ async with BookALimo(credentials) as client:
108
+ # Build locations
109
+ pickup = create_airport_location("JFK", "New York")
110
+ dropoff = create_address_location("53 East 34th Street, Manhattan")
125
111
 
126
- if __name__ == "__main__":
127
- asyncio.run(main())
128
- ```
112
+ prices = await client.get_prices(
113
+ rate_type=RateType.P2P,
114
+ date_time="09/05/2025 12:44 AM",
115
+ pickup=pickup,
116
+ dropoff=dropoff,
117
+ passengers=2,
118
+ luggage=3,
119
+ )
129
120
 
130
- ### Using the Sandbox
121
+ print(f"Available cars: {len(prices.prices)}")
122
+ for price in prices.prices:
123
+ print(f"- {price.car_description}: ${price.price}")
131
124
 
132
- ```python
133
- async with AsyncClient() as http_client:
134
- async with BookALimo(
135
- credentials, http_client=http_client, sandbox=True
136
- ) as client:
137
- ...
125
+ if __name__ == "__main__":
126
+ asyncio.run(main())
138
127
  ```
139
128
 
140
129
  ## Authentication
@@ -251,7 +240,7 @@ stops = [
251
240
  ### Using Account Info (Travel Agents)
252
241
 
253
242
  ```python
254
- from bookalimo.models import Account # models (not re-exported at top-level)
243
+ from bookalimo.models import Account
255
244
 
256
245
  account = Account(
257
246
  id="TA10007",
@@ -289,7 +278,7 @@ cancel_result = await client.edit_reservation(
289
278
  ## Error Handling
290
279
 
291
280
  ```python
292
- from bookalimo._client import BookALimoError # currently defined here
281
+ from bookalimo.exceptions import BookALimoError
293
282
 
294
283
  try:
295
284
  reservations = await client.list_reservations()
@@ -320,7 +309,6 @@ mkdocs serve
320
309
 
321
310
  * Never log raw passwords or credit card numbers.
322
311
  * Store credentials securely (e.g., environment variables, secrets managers).
323
- * Use sandbox for testing.
324
312
 
325
313
  ## License
326
314
 
@@ -5,13 +5,13 @@
5
5
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
6
  [![Code style: ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
7
7
 
8
- A modern, async Python wrapper for the Book-A-Limo API with full type support.
8
+ A modern, async Python wrapper for the Book-A-Limo API with full type support. Built on top of `httpx` and `pydantic`.
9
9
 
10
10
  ## Features
11
11
 
12
- * **Async/await** (built on `httpx`)
13
- * **Typed Pydantic models** for requests & responses
14
- * **Input validation**
12
+ * **Asynchronous**
13
+ * **Fully Typed** for requests & responses
14
+ * **Input validation** including airports and addresses.
15
15
  * **Clean, minimal interface** for each API operation
16
16
  * **Custom exceptions & error handling**
17
17
  * **Tests and examples**
@@ -46,37 +46,26 @@ async def main():
46
46
  # For Travel Agents (customers: pass is_customer=True)
47
47
  credentials = create_credentials("TA10007", "your_password")
48
48
 
49
- async with AsyncClient() as http_client:
50
- async with BookALimo(credentials, http_client=http_client) as client:
51
- # Build locations
52
- pickup = create_airport_location("JFK", "New York")
53
- dropoff = create_address_location("53 East 34th Street, Manhattan")
54
-
55
- prices = await client.get_prices(
56
- rate_type=RateType.P2P,
57
- date_time="09/05/2025 12:44 AM",
58
- pickup=pickup,
59
- dropoff=dropoff,
60
- passengers=2,
61
- luggage=3,
62
- )
63
-
64
- print(f"Available cars: {len(prices.prices)}")
65
- for price in prices.prices:
66
- print(f"- {price.car_description}: ${price.price}")
49
+ async with BookALimo(credentials) as client:
50
+ # Build locations
51
+ pickup = create_airport_location("JFK", "New York")
52
+ dropoff = create_address_location("53 East 34th Street, Manhattan")
67
53
 
68
- if __name__ == "__main__":
69
- asyncio.run(main())
70
- ```
54
+ prices = await client.get_prices(
55
+ rate_type=RateType.P2P,
56
+ date_time="09/05/2025 12:44 AM",
57
+ pickup=pickup,
58
+ dropoff=dropoff,
59
+ passengers=2,
60
+ luggage=3,
61
+ )
71
62
 
72
- ### Using the Sandbox
63
+ print(f"Available cars: {len(prices.prices)}")
64
+ for price in prices.prices:
65
+ print(f"- {price.car_description}: ${price.price}")
73
66
 
74
- ```python
75
- async with AsyncClient() as http_client:
76
- async with BookALimo(
77
- credentials, http_client=http_client, sandbox=True
78
- ) as client:
79
- ...
67
+ if __name__ == "__main__":
68
+ asyncio.run(main())
80
69
  ```
81
70
 
82
71
  ## Authentication
@@ -193,7 +182,7 @@ stops = [
193
182
  ### Using Account Info (Travel Agents)
194
183
 
195
184
  ```python
196
- from bookalimo.models import Account # models (not re-exported at top-level)
185
+ from bookalimo.models import Account
197
186
 
198
187
  account = Account(
199
188
  id="TA10007",
@@ -231,7 +220,7 @@ cancel_result = await client.edit_reservation(
231
220
  ## Error Handling
232
221
 
233
222
  ```python
234
- from bookalimo._client import BookALimoError # currently defined here
223
+ from bookalimo.exceptions import BookALimoError
235
224
 
236
225
  try:
237
226
  reservations = await client.list_reservations()
@@ -262,7 +251,6 @@ mkdocs serve
262
251
 
263
252
  * Never log raw passwords or credit card numbers.
264
253
  * Store credentials securely (e.g., environment variables, secrets managers).
265
- * Use sandbox for testing.
266
254
 
267
255
  ## License
268
256
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "bookalimo"
7
- version = "0.1.1"
7
+ version = "0.1.3"
8
8
  description = "Python wrapper for the Book-A-Limo API"
9
9
  readme = "README.md"
10
10
  license = {text = "MIT"}
@@ -10,6 +10,7 @@ from typing import Any, Optional, cast
10
10
  import httpx
11
11
  from pydantic import BaseModel
12
12
 
13
+ from .exceptions import BookALimoError
13
14
  from .models import (
14
15
  BookRequest,
15
16
  BookResponse,
@@ -37,20 +38,6 @@ def get_version() -> str:
37
38
  return __version__
38
39
 
39
40
 
40
- class BookALimoError(Exception):
41
- """Base exception for Book-A-Limo API errors."""
42
-
43
- def __init__(
44
- self,
45
- message: str,
46
- status_code: Optional[int] = None,
47
- response_data: Optional[dict[str, Any]] = None,
48
- ):
49
- super().__init__(message)
50
- self.status_code = status_code
51
- self.response_data = response_data or {}
52
-
53
-
54
41
  class BookALimoClient:
55
42
  """
56
43
  Base HTTP client for Book-A-Limo API.
@@ -63,9 +50,7 @@ class BookALimoClient:
63
50
  credentials: Credentials,
64
51
  user_agent: str = "bookalimo-python",
65
52
  version: Optional[str] = None,
66
- sandbox: bool = False,
67
53
  base_url: str = "https://api.bookalimo.com",
68
- base_url_sandbox: str = "https://sandbox.bookalimo.com",
69
54
  http_timeout: float = 5.0,
70
55
  ):
71
56
  """Initialize the client with an HTTP client."""
@@ -76,9 +61,7 @@ class BookALimoClient:
76
61
  "content-type": "application/json",
77
62
  "user-agent": f"{user_agent}/{version}",
78
63
  }
79
- self.sandbox = sandbox
80
64
  self.base_url = base_url
81
- self.base_url_sandbox = base_url_sandbox
82
65
  self.http_timeout = http_timeout
83
66
 
84
67
  def _convert_model_to_api_dict(self, data: dict[str, Any]) -> dict[str, Any]:
@@ -175,10 +158,6 @@ class BookALimoClient:
175
158
  result.append(char.lower())
176
159
  return "".join(result)
177
160
 
178
- def get_base_url(self) -> str:
179
- """Get the base URL for the API."""
180
- return self.base_url_sandbox if self.sandbox else self.base_url
181
-
182
161
  async def _make_request(
183
162
  self,
184
163
  endpoint: str,
@@ -201,7 +180,7 @@ class BookALimoClient:
201
180
  Raises:
202
181
  BookALimoError: On API errors or HTTP errors
203
182
  """
204
- url = f"{self.get_base_url()}{endpoint}"
183
+ url = f"{self.base_url}{endpoint}"
205
184
 
206
185
  # Convert model data to API format
207
186
  api_data = self._convert_model_to_api_dict(data.model_dump())
@@ -0,0 +1,15 @@
1
+ from typing import Any, Optional
2
+
3
+
4
+ class BookALimoError(Exception):
5
+ """Base exception for Book-A-Limo API errors."""
6
+
7
+ def __init__(
8
+ self,
9
+ message: str,
10
+ status_code: Optional[int] = None,
11
+ response_data: Optional[dict[str, Any]] = None,
12
+ ):
13
+ super().__init__(message)
14
+ self.status_code = status_code
15
+ self.response_data = response_data or {}
@@ -8,7 +8,8 @@ from typing import Any, Optional
8
8
 
9
9
  from httpx import AsyncClient
10
10
 
11
- from ._client import BookALimoClient, BookALimoError
11
+ from ._client import BookALimoClient
12
+ from .exceptions import BookALimoError
12
13
  from .models import (
13
14
  Address,
14
15
  Airport,
@@ -44,7 +45,8 @@ class BookALimo:
44
45
  self,
45
46
  credentials: Credentials,
46
47
  http_client: Optional[AsyncClient] = None,
47
- sandbox: bool = False,
48
+ base_url: str = "https://api.bookalimo.com",
49
+ http_timeout: float = 5.0,
48
50
  **kwargs: Any,
49
51
  ):
50
52
  """
@@ -52,7 +54,6 @@ class BookALimo:
52
54
 
53
55
  Args:
54
56
  credentials: User ID and password hash for authentication.
55
- sandbox: Set to True to use the sandbox environment.
56
57
  http_client: Optional custom httpx.AsyncClient instance.
57
58
  **kwargs: Additional options passed to the BookALimoClient.
58
59
  """
@@ -60,8 +61,9 @@ class BookALimo:
60
61
  self.http_client = http_client or AsyncClient()
61
62
  self.client = BookALimoClient(
62
63
  credentials=credentials,
63
- sandbox=sandbox,
64
64
  client=self.http_client,
65
+ base_url=base_url,
66
+ http_timeout=http_timeout,
65
67
  **kwargs,
66
68
  )
67
69
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bookalimo
3
- Version: 0.1.1
3
+ Version: 0.1.3
4
4
  Summary: Python wrapper for the Book-A-Limo API
5
5
  Author-email: Jonathan Oren <jonathan@bookalimo.com>
6
6
  Maintainer-email: Jonathan Oren <jonathan@bookalimo.com>
@@ -63,13 +63,13 @@ Dynamic: license-file
63
63
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
64
64
  [![Code style: ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
65
65
 
66
- A modern, async Python wrapper for the Book-A-Limo API with full type support.
66
+ A modern, async Python wrapper for the Book-A-Limo API with full type support. Built on top of `httpx` and `pydantic`.
67
67
 
68
68
  ## Features
69
69
 
70
- * **Async/await** (built on `httpx`)
71
- * **Typed Pydantic models** for requests & responses
72
- * **Input validation**
70
+ * **Asynchronous**
71
+ * **Fully Typed** for requests & responses
72
+ * **Input validation** including airports and addresses.
73
73
  * **Clean, minimal interface** for each API operation
74
74
  * **Custom exceptions & error handling**
75
75
  * **Tests and examples**
@@ -104,37 +104,26 @@ async def main():
104
104
  # For Travel Agents (customers: pass is_customer=True)
105
105
  credentials = create_credentials("TA10007", "your_password")
106
106
 
107
- async with AsyncClient() as http_client:
108
- async with BookALimo(credentials, http_client=http_client) as client:
109
- # Build locations
110
- pickup = create_airport_location("JFK", "New York")
111
- dropoff = create_address_location("53 East 34th Street, Manhattan")
112
-
113
- prices = await client.get_prices(
114
- rate_type=RateType.P2P,
115
- date_time="09/05/2025 12:44 AM",
116
- pickup=pickup,
117
- dropoff=dropoff,
118
- passengers=2,
119
- luggage=3,
120
- )
121
-
122
- print(f"Available cars: {len(prices.prices)}")
123
- for price in prices.prices:
124
- print(f"- {price.car_description}: ${price.price}")
107
+ async with BookALimo(credentials) as client:
108
+ # Build locations
109
+ pickup = create_airport_location("JFK", "New York")
110
+ dropoff = create_address_location("53 East 34th Street, Manhattan")
125
111
 
126
- if __name__ == "__main__":
127
- asyncio.run(main())
128
- ```
112
+ prices = await client.get_prices(
113
+ rate_type=RateType.P2P,
114
+ date_time="09/05/2025 12:44 AM",
115
+ pickup=pickup,
116
+ dropoff=dropoff,
117
+ passengers=2,
118
+ luggage=3,
119
+ )
129
120
 
130
- ### Using the Sandbox
121
+ print(f"Available cars: {len(prices.prices)}")
122
+ for price in prices.prices:
123
+ print(f"- {price.car_description}: ${price.price}")
131
124
 
132
- ```python
133
- async with AsyncClient() as http_client:
134
- async with BookALimo(
135
- credentials, http_client=http_client, sandbox=True
136
- ) as client:
137
- ...
125
+ if __name__ == "__main__":
126
+ asyncio.run(main())
138
127
  ```
139
128
 
140
129
  ## Authentication
@@ -251,7 +240,7 @@ stops = [
251
240
  ### Using Account Info (Travel Agents)
252
241
 
253
242
  ```python
254
- from bookalimo.models import Account # models (not re-exported at top-level)
243
+ from bookalimo.models import Account
255
244
 
256
245
  account = Account(
257
246
  id="TA10007",
@@ -289,7 +278,7 @@ cancel_result = await client.edit_reservation(
289
278
  ## Error Handling
290
279
 
291
280
  ```python
292
- from bookalimo._client import BookALimoError # currently defined here
281
+ from bookalimo.exceptions import BookALimoError
293
282
 
294
283
  try:
295
284
  reservations = await client.list_reservations()
@@ -320,7 +309,6 @@ mkdocs serve
320
309
 
321
310
  * Never log raw passwords or credit card numbers.
322
311
  * Store credentials securely (e.g., environment variables, secrets managers).
323
- * Use sandbox for testing.
324
312
 
325
313
  ## License
326
314
 
@@ -3,6 +3,7 @@ README.md
3
3
  pyproject.toml
4
4
  src/bookalimo/__init__.py
5
5
  src/bookalimo/_client.py
6
+ src/bookalimo/exceptions.py
6
7
  src/bookalimo/models.py
7
8
  src/bookalimo/py.typed
8
9
  src/bookalimo/wrapper.py
@@ -4,7 +4,8 @@ import httpx
4
4
  import pytest
5
5
  import respx
6
6
 
7
- from bookalimo._client import BookALimoClient, BookALimoError
7
+ from bookalimo._client import BookALimoClient
8
+ from bookalimo.exceptions import BookALimoError
8
9
  from bookalimo.models import ListReservationsResponse
9
10
 
10
11
 
File without changes
File without changes