lojack-api 0.5.0__py3-none-any.whl

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,317 @@
1
+ Metadata-Version: 2.4
2
+ Name: lojack_api
3
+ Version: 0.5.0
4
+ Summary: An async Python client library for the LoJack API, designed for Home Assistant integrations.
5
+ Author: LoJack Clients Contributors
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/devinslick/lojack_api
8
+ Project-URL: Bug Tracker, https://github.com/devinslick/lojack_api/issues
9
+ Keywords: lojack,home-assistant,async,api-client,vehicle-tracking
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Framework :: AsyncIO
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Topic :: Home Automation
20
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
21
+ Classifier: Typing :: Typed
22
+ Requires-Python: >=3.10
23
+ Description-Content-Type: text/markdown
24
+ License-File: LICENSE
25
+ Requires-Dist: aiohttp<4.0,>=3.8
26
+ Provides-Extra: dev
27
+ Requires-Dist: pytest>=7.0; extra == "dev"
28
+ Requires-Dist: pytest-asyncio>=0.21; extra == "dev"
29
+ Requires-Dist: pytest-cov>=4.0; extra == "dev"
30
+ Requires-Dist: mypy>=1.0; extra == "dev"
31
+ Requires-Dist: ruff>=0.1; extra == "dev"
32
+ Requires-Dist: flake8>=4.0; extra == "dev"
33
+ Requires-Dist: aioresponses>=0.7; extra == "dev"
34
+ Dynamic: license-file
35
+
36
+ # lojack_api
37
+
38
+ An async Python client library for the Spireon LoJack API, designed for Home Assistant integrations.
39
+
40
+ ## Features
41
+
42
+ - **Async-first design** - Built with `asyncio` and `aiohttp` for non-blocking I/O
43
+ - **No httpx dependency** - Uses `aiohttp` to avoid version conflicts with Home Assistant
44
+ - **Spireon LoJack API** - Full support for the Spireon identity and services APIs
45
+ - **Session management** - Automatic token refresh and session resumption support
46
+ - **Type hints** - Full typing support with `py.typed` marker
47
+ - **Clean device abstractions** - Device and Vehicle wrappers with convenient methods
48
+
49
+ ## Installation
50
+
51
+ ```bash
52
+ # From the repository
53
+ pip install .
54
+
55
+ # With development dependencies
56
+ pip install .[dev]
57
+ ```
58
+
59
+ ## Quick Start
60
+
61
+ ### Basic Usage
62
+
63
+ ```python
64
+ import asyncio
65
+ from lojack_api import LoJackClient
66
+
67
+ async def main():
68
+ # Create and authenticate (uses default Spireon URLs)
69
+ async with await LoJackClient.create(
70
+ "your_username",
71
+ "your_password"
72
+ ) as client:
73
+ # List all devices/vehicles
74
+ devices = await client.list_devices()
75
+
76
+ for device in devices:
77
+ print(f"Device: {device.name} ({device.id})")
78
+
79
+ # Get current location
80
+ location = await device.get_location()
81
+ if location:
82
+ print(f" Location: {location.latitude}, {location.longitude}")
83
+
84
+ asyncio.run(main())
85
+ ```
86
+
87
+ ### Session Resumption (for Home Assistant)
88
+
89
+ For Home Assistant integrations, you can persist authentication across restarts:
90
+
91
+ ```python
92
+ from lojack_api import LoJackClient, AuthArtifacts
93
+
94
+ # First time - login and save auth
95
+ async def initial_login(username, password):
96
+ client = await LoJackClient.create(username, password)
97
+ auth_data = client.export_auth().to_dict()
98
+ # Save auth_data to Home Assistant storage
99
+ await client.close()
100
+ return auth_data
101
+
102
+ # Later - resume without re-entering password
103
+ async def resume_session(auth_data, username=None, password=None):
104
+ auth = AuthArtifacts.from_dict(auth_data)
105
+ # Pass credentials for auto-refresh if token expires
106
+ client = await LoJackClient.from_auth(auth, username=username, password=password)
107
+ return client
108
+ ```
109
+
110
+ ### Using External aiohttp Session
111
+
112
+ For Home Assistant integrations, pass the shared session:
113
+
114
+ ```python
115
+ from aiohttp import ClientSession
116
+ from lojack_api import LoJackClient
117
+
118
+ async def setup(hass_session: ClientSession, username, password):
119
+ client = await LoJackClient.create(
120
+ username,
121
+ password,
122
+ session=hass_session # Won't be closed when client closes
123
+ )
124
+ return client
125
+ ```
126
+
127
+ ### Working with Vehicles
128
+
129
+ Vehicles have additional properties and commands:
130
+
131
+ ```python
132
+ from lojack_api import Vehicle
133
+
134
+ async def vehicle_example(client):
135
+ devices = await client.list_devices()
136
+
137
+ for device in devices:
138
+ if isinstance(device, Vehicle):
139
+ print(f"Vehicle: {device.name}")
140
+ print(f" VIN: {device.vin}")
141
+ print(f" Make: {device.make} {device.model} ({device.year})")
142
+
143
+ # Vehicle-specific commands
144
+ await device.start_engine()
145
+ await device.honk_horn()
146
+ await device.flash_lights()
147
+ ```
148
+
149
+ ### Device Commands
150
+
151
+ ```python
152
+ # All devices support these commands
153
+ await device.lock(message="Please return this device")
154
+ await device.unlock()
155
+ await device.ring(duration=30)
156
+ await device.request_location_update()
157
+
158
+ # Get location history
159
+ async for location in device.get_history(limit=100):
160
+ print(f"{location.timestamp}: {location.latitude}, {location.longitude}")
161
+ ```
162
+
163
+ ## API Reference
164
+
165
+ ### LoJackClient
166
+
167
+ The main entry point for the API.
168
+
169
+ ```python
170
+ # Factory methods (using default Spireon URLs)
171
+ client = await LoJackClient.create(username, password)
172
+ client = await LoJackClient.from_auth(auth_artifacts)
173
+
174
+ # With custom URLs
175
+ client = await LoJackClient.create(
176
+ username,
177
+ password,
178
+ identity_url="https://identity.spireon.com",
179
+ services_url="https://services.spireon.com/v0/rest"
180
+ )
181
+
182
+ # Properties
183
+ client.is_authenticated # bool
184
+ client.user_id # Optional[str]
185
+
186
+ # Methods
187
+ devices = await client.list_devices() # List[Device | Vehicle]
188
+ device = await client.get_device(device_id) # Device | Vehicle
189
+ locations = await client.get_locations(device_id, limit=10)
190
+ success = await client.send_command(device_id, "locate")
191
+ auth = client.export_auth() # AuthArtifacts
192
+ await client.close()
193
+ ```
194
+
195
+ ### Device
196
+
197
+ Wrapper for tracked devices.
198
+
199
+ ```python
200
+ # Properties
201
+ device.id # str
202
+ device.name # Optional[str]
203
+ device.info # DeviceInfo
204
+ device.last_seen # Optional[datetime]
205
+ device.cached_location # Optional[Location]
206
+
207
+ # Methods
208
+ await device.refresh(force=True)
209
+ location = await device.get_location(force=False)
210
+ async for loc in device.get_history(limit=100):
211
+ ...
212
+ await device.lock(message="...", passcode="...")
213
+ await device.unlock()
214
+ await device.ring(duration=30)
215
+ await device.request_location_update()
216
+ await device.send_command("custom_command")
217
+ ```
218
+
219
+ ### Vehicle (extends Device)
220
+
221
+ Additional properties and methods for vehicles.
222
+
223
+ ```python
224
+ # Properties
225
+ vehicle.vin # Optional[str]
226
+ vehicle.make # Optional[str]
227
+ vehicle.model # Optional[str]
228
+ vehicle.year # Optional[int]
229
+ vehicle.license_plate # Optional[str]
230
+ vehicle.odometer # Optional[float]
231
+
232
+ # Methods
233
+ await vehicle.start_engine()
234
+ await vehicle.stop_engine()
235
+ await vehicle.honk_horn()
236
+ await vehicle.flash_lights()
237
+ ```
238
+
239
+ ### Data Models
240
+
241
+ ```python
242
+ from lojack_api import Location, DeviceInfo, VehicleInfo
243
+
244
+ # Location
245
+ location.latitude # Optional[float]
246
+ location.longitude # Optional[float]
247
+ location.timestamp # Optional[datetime]
248
+ location.accuracy # Optional[float]
249
+ location.speed # Optional[float]
250
+ location.heading # Optional[float]
251
+ location.address # Optional[str]
252
+ location.raw # Dict[str, Any] # Original API response
253
+ ```
254
+
255
+ ### Exceptions
256
+
257
+ ```python
258
+ from lojack_api import (
259
+ LoJackError, # Base exception
260
+ AuthenticationError, # 401 errors, invalid credentials
261
+ AuthorizationError, # 403 errors, permission denied
262
+ ApiError, # Other API errors (has status_code)
263
+ ConnectionError, # Network connectivity issues
264
+ TimeoutError, # Request timeouts
265
+ DeviceNotFoundError, # Device not found (has device_id)
266
+ CommandError, # Command failed (has command, device_id)
267
+ InvalidParameterError, # Invalid parameter (has parameter, value)
268
+ )
269
+ ```
270
+
271
+ ### Spireon API Details
272
+
273
+ The library uses the Spireon LoJack API:
274
+
275
+ - **Identity Service**: `https://identity.spireon.com` - For authentication
276
+ - **Services API**: `https://services.spireon.com/v0/rest` - For device/asset management
277
+
278
+ Authentication uses HTTP Basic Auth with the following headers:
279
+ - `X-Nspire-Apptoken` - Application token
280
+ - `X-Nspire-Correlationid` - Unique request ID
281
+ - `X-Nspire-Usertoken` - User token (after authentication)
282
+
283
+ ## Development
284
+
285
+ ```bash
286
+ # Install dev dependencies
287
+ pip install .[dev]
288
+
289
+ # Run tests
290
+ pytest
291
+
292
+ # Run tests with coverage
293
+ pytest --cov=lojack_api
294
+
295
+ # Type checking
296
+ mypy lojack_api
297
+
298
+ # Linting
299
+ # Preferred: ruff for quick fixes
300
+ ruff check .
301
+
302
+ # Use flake8 for strict style checks (reports shown in CI)
303
+ # Match ruff's line length setting
304
+ flake8 lojack_api/ tests/ --count --show-source --statistics --max-line-length=100
305
+ ```
306
+
307
+ ## License
308
+
309
+ MIT License - see [LICENSE](LICENSE) for details.
310
+
311
+ ## Contributing
312
+
313
+ Contributions are welcome! This library is designed to be vendored into Home Assistant integrations to avoid dependency conflicts.
314
+
315
+ ## Credits
316
+
317
+ This library was inspired by the original [lojack-clients](https://github.com/scorgn/lojack-clients) package and uses the Spireon LoJack API endpoints.
@@ -0,0 +1,13 @@
1
+ lojack_api/__init__.py,sha256=5VPVfFDY-hO3GcdP5k89PJSyXXxf2DfHREnb4SRjTD4,1784
2
+ lojack_api/api.py,sha256=BhDusVVtm-ppB3bE1e_l95g6a1mO_q1TcSHmQitLuRQ,15356
3
+ lojack_api/auth.py,sha256=dbUl2m3G72BPZO5qJn9dafv9VPZNzg7Splu2Agrr9yk,9327
4
+ lojack_api/device.py,sha256=zGo6fJvQBBSgdhVbDmFlYANbh7Q2l7i0ZNdO3W5_XBw,9913
5
+ lojack_api/exceptions.py,sha256=fVI69JADd0v1fjQvdAjG9XouKU__zslwzDb_O3zxFwA,2430
6
+ lojack_api/models.py,sha256=TLSrtoym8veUdBsLxtH4yLjLRZX7pDp6gKwN4a-xetM,8777
7
+ lojack_api/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
+ lojack_api/transport.py,sha256=Mhyv4LiehClevP0MvqrYW2S-xGRhqfPdy3Jnh6jAiBA,6080
9
+ lojack_api-0.5.0.dist-info/licenses/LICENSE,sha256=2raVXId8lZ1YAILtPjUzEy0IhxFXvqMoXqu35vLWszQ,669
10
+ lojack_api-0.5.0.dist-info/METADATA,sha256=hVppwSKbisXIOs8serhN_7eqmQsAUsvQUwc17921mlY,9200
11
+ lojack_api-0.5.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
12
+ lojack_api-0.5.0.dist-info/top_level.txt,sha256=J80LTW9G3zGoloSJ5MF21nZ48JD_VCjGFdhTja3Oguw,11
13
+ lojack_api-0.5.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.10.2)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,14 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026
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 SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
@@ -0,0 +1 @@
1
+ lojack_api