bookalimo 0.1.5__tar.gz → 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 (60) hide show
  1. bookalimo-1.0.0/PKG-INFO +307 -0
  2. bookalimo-1.0.0/README.md +249 -0
  3. {bookalimo-0.1.5 → bookalimo-1.0.0}/pyproject.toml +22 -15
  4. bookalimo-1.0.0/src/bookalimo/__init__.py +24 -0
  5. bookalimo-1.0.0/src/bookalimo/_version.py +9 -0
  6. bookalimo-1.0.0/src/bookalimo/client.py +310 -0
  7. bookalimo-1.0.0/src/bookalimo/config.py +16 -0
  8. bookalimo-1.0.0/src/bookalimo/exceptions.py +125 -0
  9. bookalimo-1.0.0/src/bookalimo/integrations/__init__.py +1 -0
  10. bookalimo-1.0.0/src/bookalimo/integrations/google_places/__init__.py +31 -0
  11. bookalimo-1.0.0/src/bookalimo/integrations/google_places/client_async.py +258 -0
  12. bookalimo-1.0.0/src/bookalimo/integrations/google_places/client_sync.py +257 -0
  13. bookalimo-1.0.0/src/bookalimo/integrations/google_places/common.py +245 -0
  14. bookalimo-1.0.0/src/bookalimo/integrations/google_places/proto_adapter.py +224 -0
  15. bookalimo-0.1.5/src/bookalimo/_logging.py → bookalimo-1.0.0/src/bookalimo/logging.py +45 -42
  16. bookalimo-1.0.0/src/bookalimo/schemas/__init__.py +97 -0
  17. bookalimo-1.0.0/src/bookalimo/schemas/base.py +56 -0
  18. bookalimo-0.1.5/src/bookalimo/models.py → bookalimo-1.0.0/src/bookalimo/schemas/booking.py +88 -100
  19. bookalimo-1.0.0/src/bookalimo/schemas/places/__init__.py +37 -0
  20. bookalimo-1.0.0/src/bookalimo/schemas/places/common.py +198 -0
  21. bookalimo-1.0.0/src/bookalimo/schemas/places/google.py +596 -0
  22. bookalimo-1.0.0/src/bookalimo/schemas/places/place.py +337 -0
  23. bookalimo-1.0.0/src/bookalimo/services/__init__.py +11 -0
  24. bookalimo-1.0.0/src/bookalimo/services/pricing.py +191 -0
  25. bookalimo-1.0.0/src/bookalimo/services/reservations.py +227 -0
  26. bookalimo-1.0.0/src/bookalimo/transport/__init__.py +7 -0
  27. bookalimo-1.0.0/src/bookalimo/transport/auth.py +41 -0
  28. bookalimo-1.0.0/src/bookalimo/transport/base.py +44 -0
  29. bookalimo-1.0.0/src/bookalimo/transport/httpx_async.py +230 -0
  30. bookalimo-1.0.0/src/bookalimo/transport/httpx_sync.py +230 -0
  31. bookalimo-1.0.0/src/bookalimo/transport/retry.py +102 -0
  32. bookalimo-1.0.0/src/bookalimo/transport/utils.py +59 -0
  33. bookalimo-1.0.0/src/bookalimo.egg-info/PKG-INFO +307 -0
  34. bookalimo-1.0.0/src/bookalimo.egg-info/SOURCES.txt +47 -0
  35. {bookalimo-0.1.5 → bookalimo-1.0.0}/src/bookalimo.egg-info/requires.txt +8 -8
  36. bookalimo-1.0.0/tests/test_client.py +327 -0
  37. bookalimo-1.0.0/tests/test_config.py +347 -0
  38. bookalimo-1.0.0/tests/test_exceptions.py +392 -0
  39. bookalimo-1.0.0/tests/test_google_places.py +740 -0
  40. bookalimo-1.0.0/tests/test_integration.py +870 -0
  41. bookalimo-1.0.0/tests/test_real_api_integration.py +454 -0
  42. bookalimo-1.0.0/tests/test_schemas.py +585 -0
  43. bookalimo-1.0.0/tests/test_services.py +495 -0
  44. bookalimo-1.0.0/tests/test_transport.py +722 -0
  45. bookalimo-0.1.5/PKG-INFO +0 -392
  46. bookalimo-0.1.5/README.md +0 -334
  47. bookalimo-0.1.5/src/bookalimo/__init__.py +0 -31
  48. bookalimo-0.1.5/src/bookalimo/_client.py +0 -420
  49. bookalimo-0.1.5/src/bookalimo/exceptions.py +0 -15
  50. bookalimo-0.1.5/src/bookalimo/wrapper.py +0 -444
  51. bookalimo-0.1.5/src/bookalimo.egg-info/PKG-INFO +0 -392
  52. bookalimo-0.1.5/src/bookalimo.egg-info/SOURCES.txt +0 -18
  53. bookalimo-0.1.5/tests/test_client.py +0 -70
  54. bookalimo-0.1.5/tests/test_models.py +0 -50
  55. bookalimo-0.1.5/tests/test_wrapper.py +0 -69
  56. {bookalimo-0.1.5 → bookalimo-1.0.0}/LICENSE +0 -0
  57. {bookalimo-0.1.5 → bookalimo-1.0.0}/setup.cfg +0 -0
  58. {bookalimo-0.1.5 → bookalimo-1.0.0}/src/bookalimo/py.typed +0 -0
  59. {bookalimo-0.1.5 → bookalimo-1.0.0}/src/bookalimo.egg-info/dependency_links.txt +0 -0
  60. {bookalimo-0.1.5 → bookalimo-1.0.0}/src/bookalimo.egg-info/top_level.txt +0 -0
@@ -0,0 +1,307 @@
1
+ Metadata-Version: 2.4
2
+ Name: bookalimo
3
+ Version: 1.0.0
4
+ Summary: Python wrapper for the Book-A-Limo API
5
+ Author-email: Jonathan Oren <jonathan@bookalimo.com>
6
+ Maintainer-email: Jonathan Oren <jonathan@bookalimo.com>
7
+ License: MIT
8
+ Project-URL: Homepage, https://github.com/asparagusbeef/bookalimo-python
9
+ Project-URL: Documentation, https://asparagusbeef.github.io/bookalimo-python
10
+ Project-URL: Repository, https://github.com/asparagusbeef/bookalimo-python
11
+ Project-URL: Issues, https://github.com/asparagusbeef/bookalimo-python/issues
12
+ Project-URL: Changelog, https://github.com/asparagusbeef/bookalimo-python/blob/main/CHANGELOG.md
13
+ Keywords: bookalimo,api,transportation,booking
14
+ Classifier: Development Status :: 3 - Alpha
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.9
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
24
+ Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
25
+ Requires-Python: >=3.9
26
+ Description-Content-Type: text/markdown
27
+ License-File: LICENSE
28
+ Requires-Dist: httpx>=0.25.0
29
+ Requires-Dist: pydantic>=2.11.0
30
+ Requires-Dist: pycountry>=22.0.0
31
+ Requires-Dist: us>=3.0.0
32
+ Requires-Dist: airportsdata>=20230101
33
+ Provides-Extra: places
34
+ Requires-Dist: google-maps-places>=0.1.0; extra == "places"
35
+ Requires-Dist: google-api-core>=2.0.0; extra == "places"
36
+ Provides-Extra: dev
37
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
38
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
39
+ Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
40
+ Requires-Dist: pytest-mock>=3.10.0; extra == "dev"
41
+ Requires-Dist: httpx[mock]>=0.25.0; extra == "dev"
42
+ Requires-Dist: respx>=0.20.0; extra == "dev"
43
+ Requires-Dist: ruff>=0.1.0; extra == "dev"
44
+ Requires-Dist: mypy>=1.5.0; extra == "dev"
45
+ Requires-Dist: pre-commit>=3.0.0; extra == "dev"
46
+ Requires-Dist: build>=1.0.0; extra == "dev"
47
+ Requires-Dist: twine>=4.0.0; extra == "dev"
48
+ Requires-Dist: python-dotenv>=1.0.0; extra == "dev"
49
+ Requires-Dist: types-protobuf>=6.0.0; extra == "dev"
50
+ Provides-Extra: test
51
+ Requires-Dist: pytest>=7.0.0; extra == "test"
52
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == "test"
53
+ Requires-Dist: pytest-cov>=4.0.0; extra == "test"
54
+ Requires-Dist: pytest-mock>=3.10.0; extra == "test"
55
+ Requires-Dist: httpx[mock]>=0.25.0; extra == "test"
56
+ Requires-Dist: respx>=0.20.0; extra == "test"
57
+ Dynamic: license-file
58
+
59
+ # Bookalimo Python SDK
60
+
61
+ [![codecov](https://codecov.io/gh/asparagusbeef/bookalimo-python/branch/main/graph/badge.svg?token=H588J8Q1M8)](https://codecov.io/gh/asparagusbeef/bookalimo-python)
62
+ [![Documentation Status](https://readthedocs.org/projects/bookalimo-python/badge/?version=latest)](https://bookalimo-python.readthedocs.io/en/latest/?badge=latest)
63
+ [![PyPI version](https://badge.fury.io/py/bookalimo.svg)](https://badge.fury.io/py/bookalimo)
64
+ [![Python Support](https://img.shields.io/pypi/pyversions/bookalimo.svg)](https://pypi.org/project/bookalimo/)
65
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
66
+ [![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)
67
+
68
+ Python client library for the Book-A-Limo transportation booking API with async/sync support, type safety, and Google Places integration.
69
+
70
+ ## Features
71
+
72
+ - **Async & Sync Support** - Choose the right client for your use case
73
+ - **Type Safety** - Full Pydantic models with validation
74
+ - **Google Places Integration** - Location search and geocoding
75
+ - **Automatic Retry** - Built-in exponential backoff for reliability
76
+ - **Comprehensive Error Handling** - Detailed exceptions with context
77
+
78
+ ## Installation
79
+
80
+ ```bash
81
+ pip install bookalimo
82
+
83
+ # With Google Places integration
84
+ pip install bookalimo[places]
85
+ ```
86
+
87
+ ## Core API
88
+
89
+ ### Clients
90
+ - `AsyncBookalimo` - Async client for high-concurrency applications
91
+ - `Bookalimo` - Sync client for simple scripts and legacy code
92
+
93
+ ### Services
94
+ - `client.pricing` - Get quotes and update booking details
95
+ - `client.reservations` - Book, list, modify, and cancel reservations
96
+ - `client.places` - Google Places search and geocoding (optional)
97
+
98
+ ### Authentication
99
+ SHA256-based credential system with automatic password hashing:
100
+ ```python
101
+ from bookalimo.transport.auth import Credentials
102
+
103
+ # Agency account
104
+ credentials = Credentials.create("AGENCY123", "password", is_customer=False)
105
+
106
+ # Customer account
107
+ credentials = Credentials.create("user@email.com", "password", is_customer=True)
108
+ ```
109
+
110
+ ### Booking Flow
111
+ 1. **Get Pricing** - `client.pricing.quote()` returns session token + vehicle options
112
+ 2. **Update Details** - `client.pricing.update_details()` modifies booking (optional)
113
+ 3. **Book Reservation** - `client.reservations.book()` confirms with payment
114
+
115
+ ## Quick Example
116
+
117
+ ```python
118
+ import asyncio
119
+ from bookalimo import AsyncBookalimo
120
+ from bookalimo.transport.auth import Credentials
121
+ from bookalimo.schemas.booking import RateType, Location, LocationType, Address, City
122
+
123
+ async def book_ride():
124
+ credentials = Credentials.create("your_id", "your_password")
125
+
126
+ # Define locations
127
+ pickup = Location(
128
+ type=LocationType.ADDRESS,
129
+ address=Address(
130
+ place_name="Empire State Building",
131
+ city=City(city_name="New York", country_code="US", state_code="NY")
132
+ )
133
+ )
134
+
135
+ dropoff = Location(
136
+ type=LocationType.ADDRESS,
137
+ address=Address(
138
+ place_name="JFK Airport",
139
+ city=City(city_name="New York", country_code="US", state_code="NY")
140
+ )
141
+ )
142
+
143
+ async with AsyncBookalimo(credentials=credentials) as client:
144
+ # 1. Get pricing
145
+ quote = await client.pricing.quote(
146
+ rate_type=RateType.P2P,
147
+ date_time="12/25/2024 03:00 PM",
148
+ pickup=pickup,
149
+ dropoff=dropoff,
150
+ passengers=2,
151
+ luggage=2
152
+ )
153
+
154
+ # 2. Book reservation
155
+ booking = await client.reservations.book(
156
+ token=quote.token,
157
+ method="charge" # or credit_card=CreditCard(...)
158
+ )
159
+
160
+ return booking.reservation_id
161
+
162
+ confirmation = asyncio.run(book_ride())
163
+ ```
164
+
165
+ ## Rate Types & Options
166
+
167
+ ```python
168
+ from bookalimo.schemas.booking import RateType
169
+
170
+ # Point-to-point transfer
171
+ quote = await client.pricing.quote(
172
+ rate_type=RateType.P2P,
173
+ pickup=pickup_location,
174
+ dropoff=dropoff_location,
175
+ # ...
176
+ )
177
+
178
+ # Hourly service (minimum 2 hours)
179
+ quote = await client.pricing.quote(
180
+ rate_type=RateType.HOURLY,
181
+ hours=4,
182
+ pickup=pickup_location,
183
+ dropoff=pickup_location, # Same for hourly
184
+ # ...
185
+ )
186
+
187
+ # Daily service
188
+ quote = await client.pricing.quote(
189
+ rate_type=RateType.DAILY,
190
+ pickup=hotel_location,
191
+ dropoff=hotel_location,
192
+ # ...
193
+ )
194
+ ```
195
+
196
+ ## Location Types
197
+
198
+ ```python
199
+ from bookalimo.schemas.booking import Location, LocationType, Address, Airport, City
200
+
201
+ # Street address
202
+ address_location = Location(
203
+ type=LocationType.ADDRESS,
204
+ address=Address(
205
+ place_name="Empire State Building",
206
+ street_name="350 5th Ave",
207
+ city=City(city_name="New York", country_code="US", state_code="NY")
208
+ )
209
+ )
210
+
211
+ # Airport with flight details
212
+ airport_location = Location(
213
+ type=LocationType.AIRPORT,
214
+ airport=Airport(
215
+ iata_code="JFK",
216
+ flight_number="UA123",
217
+ terminal="4"
218
+ )
219
+ )
220
+ ```
221
+
222
+ ## Google Places Integration
223
+
224
+ ```python
225
+ async with AsyncBookalimo(
226
+ credentials=credentials,
227
+ google_places_api_key="your-google-places-key"
228
+ ) as client:
229
+ # Search locations
230
+ results = await client.places.search("JFK Airport Terminal 4")
231
+
232
+ # Convert to booking location
233
+ location = Location(
234
+ type=LocationType.ADDRESS,
235
+ address=Address(
236
+ google_geocode=results[0].google_place.model_dump(),
237
+ place_name=results[0].formatted_address
238
+ )
239
+ )
240
+ ```
241
+
242
+ ## Reservation Management
243
+
244
+ ```python
245
+ # List reservations
246
+ reservations = await client.reservations.list(is_archive=False)
247
+
248
+ # Get details
249
+ details = await client.reservations.get("ABC123")
250
+
251
+ # Modify reservation
252
+ edit_result = await client.reservations.edit(
253
+ confirmation="ABC123",
254
+ passengers=3,
255
+ pickup_date="12/26/2024"
256
+ )
257
+
258
+ # Cancel reservation
259
+ cancel_result = await client.reservations.edit(
260
+ confirmation="ABC123",
261
+ is_cancel=True
262
+ )
263
+ ```
264
+
265
+ ## Error Handling
266
+
267
+ ```python
268
+ from bookalimo.exceptions import BookalimoHTTPError, BookalimoValidationError
269
+
270
+ try:
271
+ booking = await client.reservations.book(...)
272
+ except BookalimoValidationError as e:
273
+ print(f"Invalid input: {e.message}")
274
+ for error in e.errors():
275
+ print(f" {error['loc']}: {error['msg']}")
276
+ except BookalimoHTTPError as e:
277
+ if e.status_code == 401:
278
+ print("Authentication failed")
279
+ elif e.status_code == 400:
280
+ print(f"Bad request: {e.payload}")
281
+ ```
282
+
283
+ ## Documentation
284
+
285
+ **📖 [Complete Documentation](https://asparagusbeef.github.io/bookalimo-python)**
286
+
287
+ - [Quick Start Guide](https://asparagusbeef.github.io/bookalimo-python/guide/quickstart/)
288
+ - [API Reference](https://asparagusbeef.github.io/bookalimo-python/api/)
289
+ - [Examples](https://asparagusbeef.github.io/bookalimo-python/examples/basic/)
290
+
291
+ ## Environment Options
292
+
293
+ ```bash
294
+ export GOOGLE_PLACES_API_KEY="your_google_places_key"
295
+ export BOOKALIMO_LOG_LEVEL="DEBUG"
296
+ ```
297
+
298
+ ## Requirements
299
+
300
+ - Python 3.9+
301
+ - Book-A-Limo API credentials
302
+ - Dependencies: httpx, pydantic, pycountry, us, airportsdata
303
+ - Optional: google-maps-places (for Places integration)
304
+
305
+ ## License
306
+
307
+ MIT License - see [LICENSE](LICENSE) for details.
@@ -0,0 +1,249 @@
1
+ # Bookalimo Python SDK
2
+
3
+ [![codecov](https://codecov.io/gh/asparagusbeef/bookalimo-python/branch/main/graph/badge.svg?token=H588J8Q1M8)](https://codecov.io/gh/asparagusbeef/bookalimo-python)
4
+ [![Documentation Status](https://readthedocs.org/projects/bookalimo-python/badge/?version=latest)](https://bookalimo-python.readthedocs.io/en/latest/?badge=latest)
5
+ [![PyPI version](https://badge.fury.io/py/bookalimo.svg)](https://badge.fury.io/py/bookalimo)
6
+ [![Python Support](https://img.shields.io/pypi/pyversions/bookalimo.svg)](https://pypi.org/project/bookalimo/)
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
8
+ [![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)
9
+
10
+ Python client library for the Book-A-Limo transportation booking API with async/sync support, type safety, and Google Places integration.
11
+
12
+ ## Features
13
+
14
+ - **Async & Sync Support** - Choose the right client for your use case
15
+ - **Type Safety** - Full Pydantic models with validation
16
+ - **Google Places Integration** - Location search and geocoding
17
+ - **Automatic Retry** - Built-in exponential backoff for reliability
18
+ - **Comprehensive Error Handling** - Detailed exceptions with context
19
+
20
+ ## Installation
21
+
22
+ ```bash
23
+ pip install bookalimo
24
+
25
+ # With Google Places integration
26
+ pip install bookalimo[places]
27
+ ```
28
+
29
+ ## Core API
30
+
31
+ ### Clients
32
+ - `AsyncBookalimo` - Async client for high-concurrency applications
33
+ - `Bookalimo` - Sync client for simple scripts and legacy code
34
+
35
+ ### Services
36
+ - `client.pricing` - Get quotes and update booking details
37
+ - `client.reservations` - Book, list, modify, and cancel reservations
38
+ - `client.places` - Google Places search and geocoding (optional)
39
+
40
+ ### Authentication
41
+ SHA256-based credential system with automatic password hashing:
42
+ ```python
43
+ from bookalimo.transport.auth import Credentials
44
+
45
+ # Agency account
46
+ credentials = Credentials.create("AGENCY123", "password", is_customer=False)
47
+
48
+ # Customer account
49
+ credentials = Credentials.create("user@email.com", "password", is_customer=True)
50
+ ```
51
+
52
+ ### Booking Flow
53
+ 1. **Get Pricing** - `client.pricing.quote()` returns session token + vehicle options
54
+ 2. **Update Details** - `client.pricing.update_details()` modifies booking (optional)
55
+ 3. **Book Reservation** - `client.reservations.book()` confirms with payment
56
+
57
+ ## Quick Example
58
+
59
+ ```python
60
+ import asyncio
61
+ from bookalimo import AsyncBookalimo
62
+ from bookalimo.transport.auth import Credentials
63
+ from bookalimo.schemas.booking import RateType, Location, LocationType, Address, City
64
+
65
+ async def book_ride():
66
+ credentials = Credentials.create("your_id", "your_password")
67
+
68
+ # Define locations
69
+ pickup = Location(
70
+ type=LocationType.ADDRESS,
71
+ address=Address(
72
+ place_name="Empire State Building",
73
+ city=City(city_name="New York", country_code="US", state_code="NY")
74
+ )
75
+ )
76
+
77
+ dropoff = Location(
78
+ type=LocationType.ADDRESS,
79
+ address=Address(
80
+ place_name="JFK Airport",
81
+ city=City(city_name="New York", country_code="US", state_code="NY")
82
+ )
83
+ )
84
+
85
+ async with AsyncBookalimo(credentials=credentials) as client:
86
+ # 1. Get pricing
87
+ quote = await client.pricing.quote(
88
+ rate_type=RateType.P2P,
89
+ date_time="12/25/2024 03:00 PM",
90
+ pickup=pickup,
91
+ dropoff=dropoff,
92
+ passengers=2,
93
+ luggage=2
94
+ )
95
+
96
+ # 2. Book reservation
97
+ booking = await client.reservations.book(
98
+ token=quote.token,
99
+ method="charge" # or credit_card=CreditCard(...)
100
+ )
101
+
102
+ return booking.reservation_id
103
+
104
+ confirmation = asyncio.run(book_ride())
105
+ ```
106
+
107
+ ## Rate Types & Options
108
+
109
+ ```python
110
+ from bookalimo.schemas.booking import RateType
111
+
112
+ # Point-to-point transfer
113
+ quote = await client.pricing.quote(
114
+ rate_type=RateType.P2P,
115
+ pickup=pickup_location,
116
+ dropoff=dropoff_location,
117
+ # ...
118
+ )
119
+
120
+ # Hourly service (minimum 2 hours)
121
+ quote = await client.pricing.quote(
122
+ rate_type=RateType.HOURLY,
123
+ hours=4,
124
+ pickup=pickup_location,
125
+ dropoff=pickup_location, # Same for hourly
126
+ # ...
127
+ )
128
+
129
+ # Daily service
130
+ quote = await client.pricing.quote(
131
+ rate_type=RateType.DAILY,
132
+ pickup=hotel_location,
133
+ dropoff=hotel_location,
134
+ # ...
135
+ )
136
+ ```
137
+
138
+ ## Location Types
139
+
140
+ ```python
141
+ from bookalimo.schemas.booking import Location, LocationType, Address, Airport, City
142
+
143
+ # Street address
144
+ address_location = Location(
145
+ type=LocationType.ADDRESS,
146
+ address=Address(
147
+ place_name="Empire State Building",
148
+ street_name="350 5th Ave",
149
+ city=City(city_name="New York", country_code="US", state_code="NY")
150
+ )
151
+ )
152
+
153
+ # Airport with flight details
154
+ airport_location = Location(
155
+ type=LocationType.AIRPORT,
156
+ airport=Airport(
157
+ iata_code="JFK",
158
+ flight_number="UA123",
159
+ terminal="4"
160
+ )
161
+ )
162
+ ```
163
+
164
+ ## Google Places Integration
165
+
166
+ ```python
167
+ async with AsyncBookalimo(
168
+ credentials=credentials,
169
+ google_places_api_key="your-google-places-key"
170
+ ) as client:
171
+ # Search locations
172
+ results = await client.places.search("JFK Airport Terminal 4")
173
+
174
+ # Convert to booking location
175
+ location = Location(
176
+ type=LocationType.ADDRESS,
177
+ address=Address(
178
+ google_geocode=results[0].google_place.model_dump(),
179
+ place_name=results[0].formatted_address
180
+ )
181
+ )
182
+ ```
183
+
184
+ ## Reservation Management
185
+
186
+ ```python
187
+ # List reservations
188
+ reservations = await client.reservations.list(is_archive=False)
189
+
190
+ # Get details
191
+ details = await client.reservations.get("ABC123")
192
+
193
+ # Modify reservation
194
+ edit_result = await client.reservations.edit(
195
+ confirmation="ABC123",
196
+ passengers=3,
197
+ pickup_date="12/26/2024"
198
+ )
199
+
200
+ # Cancel reservation
201
+ cancel_result = await client.reservations.edit(
202
+ confirmation="ABC123",
203
+ is_cancel=True
204
+ )
205
+ ```
206
+
207
+ ## Error Handling
208
+
209
+ ```python
210
+ from bookalimo.exceptions import BookalimoHTTPError, BookalimoValidationError
211
+
212
+ try:
213
+ booking = await client.reservations.book(...)
214
+ except BookalimoValidationError as e:
215
+ print(f"Invalid input: {e.message}")
216
+ for error in e.errors():
217
+ print(f" {error['loc']}: {error['msg']}")
218
+ except BookalimoHTTPError as e:
219
+ if e.status_code == 401:
220
+ print("Authentication failed")
221
+ elif e.status_code == 400:
222
+ print(f"Bad request: {e.payload}")
223
+ ```
224
+
225
+ ## Documentation
226
+
227
+ **📖 [Complete Documentation](https://asparagusbeef.github.io/bookalimo-python)**
228
+
229
+ - [Quick Start Guide](https://asparagusbeef.github.io/bookalimo-python/guide/quickstart/)
230
+ - [API Reference](https://asparagusbeef.github.io/bookalimo-python/api/)
231
+ - [Examples](https://asparagusbeef.github.io/bookalimo-python/examples/basic/)
232
+
233
+ ## Environment Options
234
+
235
+ ```bash
236
+ export GOOGLE_PLACES_API_KEY="your_google_places_key"
237
+ export BOOKALIMO_LOG_LEVEL="DEBUG"
238
+ ```
239
+
240
+ ## Requirements
241
+
242
+ - Python 3.9+
243
+ - Book-A-Limo API credentials
244
+ - Dependencies: httpx, pydantic, pycountry, us, airportsdata
245
+ - Optional: google-maps-places (for Places integration)
246
+
247
+ ## License
248
+
249
+ MIT License - see [LICENSE](LICENSE) for details.
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "bookalimo"
7
- version = "0.1.5"
7
+ version = "1.0.0"
8
8
  description = "Python wrapper for the Book-A-Limo API"
9
9
  readme = "README.md"
10
10
  license = {text = "MIT"}
@@ -30,7 +30,7 @@ classifiers = [
30
30
  keywords = ["bookalimo", "api", "transportation", "booking"]
31
31
  dependencies = [
32
32
  "httpx>=0.25.0",
33
- "pydantic>=2.0.0",
33
+ "pydantic>=2.11.0",
34
34
  "pycountry>=22.0.0",
35
35
  "us>=3.0.0",
36
36
  "airportsdata>=20230101",
@@ -38,6 +38,10 @@ dependencies = [
38
38
  requires-python = ">=3.9"
39
39
 
40
40
  [project.optional-dependencies]
41
+ places = [
42
+ "google-maps-places>=0.1.0",
43
+ "google-api-core>=2.0.0",
44
+ ]
41
45
  dev = [
42
46
  "pytest>=7.0.0",
43
47
  "pytest-asyncio>=0.21.0",
@@ -48,14 +52,10 @@ dev = [
48
52
  "ruff>=0.1.0",
49
53
  "mypy>=1.5.0",
50
54
  "pre-commit>=3.0.0",
51
- "mkdocs>=1.5.0",
52
- "mkdocs-material>=9.0.0",
53
- "mkdocstrings[python]>=0.23.0",
54
- ]
55
- docs = [
56
- "mkdocs>=1.5.0",
57
- "mkdocs-material>=9.0.0",
58
- "mkdocstrings[python]>=0.23.0",
55
+ "build>=1.0.0",
56
+ "twine>=4.0.0",
57
+ "python-dotenv>=1.0.0",
58
+ "types-protobuf>=6.0.0",
59
59
  ]
60
60
  test = [
61
61
  "pytest>=7.0.0",
@@ -67,11 +67,11 @@ test = [
67
67
  ]
68
68
 
69
69
  [project.urls]
70
- Homepage = "https://github.com/yourusername/bookalimo-python"
71
- Documentation = "https://yourusername.github.io/bookalimo-python"
72
- Repository = "https://github.com/yourusername/bookalimo-python"
73
- Issues = "https://github.com/yourusername/bookalimo-python/issues"
74
- Changelog = "https://github.com/yourusername/bookalimo-python/blob/main/CHANGELOG.md"
70
+ Homepage = "https://github.com/asparagusbeef/bookalimo-python"
71
+ Documentation = "https://asparagusbeef.github.io/bookalimo-python"
72
+ Repository = "https://github.com/asparagusbeef/bookalimo-python"
73
+ Issues = "https://github.com/asparagusbeef/bookalimo-python/issues"
74
+ Changelog = "https://github.com/asparagusbeef/bookalimo-python/blob/main/CHANGELOG.md"
75
75
 
76
76
  [tool.setuptools.packages.find]
77
77
  where = ["src"]
@@ -96,6 +96,9 @@ lint.ignore = [
96
96
  "E501", # line too long, handled by black
97
97
  "B008", # do not perform function calls in argument defaults
98
98
  "C901", # too complex
99
+ "UP045", # until I have time to Optional[] -> X | None everywhere.
100
+ "UP035", # until I have time to Dict[] -> dict[]
101
+ "UP006",
99
102
  ]
100
103
 
101
104
  [tool.ruff.lint.per-file-ignores]
@@ -122,6 +125,7 @@ warn_unreachable = true
122
125
  warn_unused_configs = true
123
126
  warn_unused_ignores = true
124
127
  mypy_path = "stubs"
128
+ disable_error_code = ["prop-decorator"]
125
129
 
126
130
  [[tool.mypy.overrides]]
127
131
  module = "tests.*"
@@ -135,9 +139,12 @@ minversion = "7.0"
135
139
  addopts = "-ra -q --strict-markers --strict-config"
136
140
  testpaths = ["tests"]
137
141
  asyncio_mode = "auto"
142
+ filterwarnings = ["ignore:Using google_geocode instead of city is recommended:UserWarning"]
138
143
  markers = [
139
144
  "slow: marks tests as slow (deselect with '-m \"not slow\"')",
140
145
  "integration: marks tests as integration tests",
146
+ "network: marks tests as network tests",
147
+ "performance: marks tests as performance tests",
141
148
  ]
142
149
 
143
150
  # Coverage configuration
@@ -0,0 +1,24 @@
1
+ """
2
+ Bookalimo SDK - Python client for the Book-A-Limo API.
3
+
4
+ Provides clean, typed interfaces for booking transportation services.
5
+ """
6
+
7
+ from ._version import __version__
8
+ from .client import AsyncBookalimo, Bookalimo
9
+ from .exceptions import (
10
+ BookalimoError,
11
+ BookalimoHTTPError,
12
+ BookalimoTimeout,
13
+ BookalimoValidationError,
14
+ )
15
+
16
+ __all__ = [
17
+ "Bookalimo",
18
+ "AsyncBookalimo",
19
+ "BookalimoError",
20
+ "BookalimoHTTPError",
21
+ "BookalimoTimeout",
22
+ "BookalimoValidationError",
23
+ "__version__",
24
+ ]
@@ -0,0 +1,9 @@
1
+ """Version information for the bookalimo package."""
2
+
3
+ from importlib.metadata import PackageNotFoundError, version
4
+
5
+ try:
6
+ __version__ = version("bookalimo")
7
+ except PackageNotFoundError:
8
+ # Development/editable install fallback
9
+ __version__ = "0.0.0"