fleetpull 0.1.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.
Files changed (252) hide show
  1. fleetpull/__init__.py +36 -0
  2. fleetpull/api/__init__.py +32 -0
  3. fleetpull/api/auth_ingress.py +216 -0
  4. fleetpull/api/catalog.py +139 -0
  5. fleetpull/api/fetch.py +229 -0
  6. fleetpull/api/identity.py +90 -0
  7. fleetpull/api/sync.py +735 -0
  8. fleetpull/cli.py +146 -0
  9. fleetpull/config/__init__.py +47 -0
  10. fleetpull/config/base.py +18 -0
  11. fleetpull/config/example.py +90 -0
  12. fleetpull/config/geotab.py +78 -0
  13. fleetpull/config/http.py +32 -0
  14. fleetpull/config/loading.py +195 -0
  15. fleetpull/config/logger.py +139 -0
  16. fleetpull/config/providers.py +520 -0
  17. fleetpull/config/rate_limit.py +50 -0
  18. fleetpull/config/resolution.py +156 -0
  19. fleetpull/config/retry.py +69 -0
  20. fleetpull/config/root.py +157 -0
  21. fleetpull/config/sections.py +146 -0
  22. fleetpull/endpoints/__init__.py +24 -0
  23. fleetpull/endpoints/geotab/__init__.py +12 -0
  24. fleetpull/endpoints/geotab/_requests.py +427 -0
  25. fleetpull/endpoints/geotab/annotation_logs.py +73 -0
  26. fleetpull/endpoints/geotab/audits.py +70 -0
  27. fleetpull/endpoints/geotab/devices.py +79 -0
  28. fleetpull/endpoints/geotab/driver_changes.py +73 -0
  29. fleetpull/endpoints/geotab/duty_status_logs.py +75 -0
  30. fleetpull/endpoints/geotab/dvir_logs.py +76 -0
  31. fleetpull/endpoints/geotab/exception_events.py +119 -0
  32. fleetpull/endpoints/geotab/fault_data.py +72 -0
  33. fleetpull/endpoints/geotab/fill_ups.py +79 -0
  34. fleetpull/endpoints/geotab/fuel_and_energy_used.py +74 -0
  35. fleetpull/endpoints/geotab/fuel_tax_details.py +75 -0
  36. fleetpull/endpoints/geotab/log_records.py +74 -0
  37. fleetpull/endpoints/geotab/media_files.py +74 -0
  38. fleetpull/endpoints/geotab/shipment_logs.py +71 -0
  39. fleetpull/endpoints/geotab/status_data.py +71 -0
  40. fleetpull/endpoints/geotab/text_messages.py +77 -0
  41. fleetpull/endpoints/geotab/trips.py +102 -0
  42. fleetpull/endpoints/geotab/users.py +81 -0
  43. fleetpull/endpoints/motive/__init__.py +12 -0
  44. fleetpull/endpoints/motive/_spec_builders.py +94 -0
  45. fleetpull/endpoints/motive/driver_idle_rollups.py +113 -0
  46. fleetpull/endpoints/motive/driving_periods.py +85 -0
  47. fleetpull/endpoints/motive/groups.py +61 -0
  48. fleetpull/endpoints/motive/idle_events.py +94 -0
  49. fleetpull/endpoints/motive/users.py +64 -0
  50. fleetpull/endpoints/motive/vehicle_locations.py +170 -0
  51. fleetpull/endpoints/motive/vehicle_utilizations.py +122 -0
  52. fleetpull/endpoints/motive/vehicles.py +106 -0
  53. fleetpull/endpoints/registry.py +280 -0
  54. fleetpull/endpoints/samsara/__init__.py +12 -0
  55. fleetpull/endpoints/samsara/_spec_builders.py +202 -0
  56. fleetpull/endpoints/samsara/addresses.py +77 -0
  57. fleetpull/endpoints/samsara/asset_locations.py +217 -0
  58. fleetpull/endpoints/samsara/driver_fuel_energy_reports.py +124 -0
  59. fleetpull/endpoints/samsara/driver_vehicle_assignments.py +211 -0
  60. fleetpull/endpoints/samsara/drivers.py +169 -0
  61. fleetpull/endpoints/samsara/engine_states.py +114 -0
  62. fleetpull/endpoints/samsara/gps_readings.py +113 -0
  63. fleetpull/endpoints/samsara/idling_events.py +195 -0
  64. fleetpull/endpoints/samsara/odometer_readings.py +116 -0
  65. fleetpull/endpoints/samsara/trips.py +217 -0
  66. fleetpull/endpoints/samsara/vehicle_fuel_energy_reports.py +139 -0
  67. fleetpull/endpoints/samsara/vehicles.py +121 -0
  68. fleetpull/endpoints/shared/__init__.py +57 -0
  69. fleetpull/endpoints/shared/base.py +529 -0
  70. fleetpull/endpoints/shared/request_shape.py +227 -0
  71. fleetpull/endpoints/shared/resume.py +74 -0
  72. fleetpull/endpoints/shared/spec_builders.py +59 -0
  73. fleetpull/endpoints/shared/sync_mode.py +159 -0
  74. fleetpull/endpoints/shared/url_paths.py +149 -0
  75. fleetpull/exceptions.py +320 -0
  76. fleetpull/incremental/__init__.py +27 -0
  77. fleetpull/incremental/cursor.py +66 -0
  78. fleetpull/incremental/resolution.py +152 -0
  79. fleetpull/incremental/seed.py +53 -0
  80. fleetpull/incremental/window.py +94 -0
  81. fleetpull/logger/__init__.py +5 -0
  82. fleetpull/logger/setup.py +145 -0
  83. fleetpull/model_contract/__init__.py +6 -0
  84. fleetpull/model_contract/coercions.py +33 -0
  85. fleetpull/model_contract/response.py +45 -0
  86. fleetpull/models/__init__.py +7 -0
  87. fleetpull/models/geotab/__init__.py +166 -0
  88. fleetpull/models/geotab/annotation_log.py +109 -0
  89. fleetpull/models/geotab/audit.py +56 -0
  90. fleetpull/models/geotab/device.py +217 -0
  91. fleetpull/models/geotab/driver_change.py +102 -0
  92. fleetpull/models/geotab/duty_status_log.py +200 -0
  93. fleetpull/models/geotab/dvir_log.py +184 -0
  94. fleetpull/models/geotab/exception_event.py +135 -0
  95. fleetpull/models/geotab/fault_data.py +168 -0
  96. fleetpull/models/geotab/fill_up.py +189 -0
  97. fleetpull/models/geotab/fuel_and_energy_used.py +81 -0
  98. fleetpull/models/geotab/fuel_tax_detail.py +150 -0
  99. fleetpull/models/geotab/log_record.py +68 -0
  100. fleetpull/models/geotab/media_file.py +133 -0
  101. fleetpull/models/geotab/shared.py +221 -0
  102. fleetpull/models/geotab/shipment_log.py +105 -0
  103. fleetpull/models/geotab/status_data.py +108 -0
  104. fleetpull/models/geotab/text_message.py +125 -0
  105. fleetpull/models/geotab/trip.py +162 -0
  106. fleetpull/models/geotab/user.py +187 -0
  107. fleetpull/models/motive/__init__.py +43 -0
  108. fleetpull/models/motive/driver_idle_rollup.py +109 -0
  109. fleetpull/models/motive/driving_period.py +82 -0
  110. fleetpull/models/motive/group.py +49 -0
  111. fleetpull/models/motive/idle_event.py +77 -0
  112. fleetpull/models/motive/shared.py +192 -0
  113. fleetpull/models/motive/user.py +217 -0
  114. fleetpull/models/motive/vehicle.py +162 -0
  115. fleetpull/models/motive/vehicle_location.py +127 -0
  116. fleetpull/models/motive/vehicle_utilization.py +128 -0
  117. fleetpull/models/samsara/__init__.py +108 -0
  118. fleetpull/models/samsara/address.py +149 -0
  119. fleetpull/models/samsara/asset_location.py +131 -0
  120. fleetpull/models/samsara/driver.py +232 -0
  121. fleetpull/models/samsara/driver_fuel_energy_report.py +153 -0
  122. fleetpull/models/samsara/driver_vehicle_assignment.py +168 -0
  123. fleetpull/models/samsara/engine_state.py +92 -0
  124. fleetpull/models/samsara/gps_reading.py +146 -0
  125. fleetpull/models/samsara/idling_event.py +174 -0
  126. fleetpull/models/samsara/odometer_reading.py +90 -0
  127. fleetpull/models/samsara/trip.py +199 -0
  128. fleetpull/models/samsara/vehicle.py +167 -0
  129. fleetpull/models/samsara/vehicle_fuel_energy_report.py +191 -0
  130. fleetpull/network/__init__.py +9 -0
  131. fleetpull/network/auth/__init__.py +15 -0
  132. fleetpull/network/auth/authenticate.py +271 -0
  133. fleetpull/network/auth/manager.py +223 -0
  134. fleetpull/network/auth/models.py +57 -0
  135. fleetpull/network/auth/strategies.py +169 -0
  136. fleetpull/network/classifiers/__init__.py +11 -0
  137. fleetpull/network/classifiers/geotab.py +145 -0
  138. fleetpull/network/classifiers/motive.py +79 -0
  139. fleetpull/network/classifiers/samsara.py +80 -0
  140. fleetpull/network/client/__init__.py +25 -0
  141. fleetpull/network/client/page.py +32 -0
  142. fleetpull/network/client/profile.py +27 -0
  143. fleetpull/network/client/registry.py +103 -0
  144. fleetpull/network/client/registry_base.py +150 -0
  145. fleetpull/network/client/runtime.py +44 -0
  146. fleetpull/network/client/transport.py +381 -0
  147. fleetpull/network/contract/__init__.py +50 -0
  148. fleetpull/network/contract/auth.py +48 -0
  149. fleetpull/network/contract/classifier.py +189 -0
  150. fleetpull/network/contract/envelope_fetcher.py +33 -0
  151. fleetpull/network/contract/envelopes.py +189 -0
  152. fleetpull/network/contract/outcome.py +43 -0
  153. fleetpull/network/contract/page_decoder.py +101 -0
  154. fleetpull/network/contract/request.py +97 -0
  155. fleetpull/network/decoders/__init__.py +40 -0
  156. fleetpull/network/decoders/_window_stamp.py +78 -0
  157. fleetpull/network/decoders/geotab.py +309 -0
  158. fleetpull/network/decoders/motive.py +204 -0
  159. fleetpull/network/decoders/motive_reports.py +114 -0
  160. fleetpull/network/decoders/samsara.py +343 -0
  161. fleetpull/network/decoders/samsara_reports.py +119 -0
  162. fleetpull/network/decoders/single_page.py +55 -0
  163. fleetpull/network/limits/__init__.py +13 -0
  164. fleetpull/network/limits/bucket_math.py +58 -0
  165. fleetpull/network/limits/limiter.py +153 -0
  166. fleetpull/network/limits/registry.py +96 -0
  167. fleetpull/network/posture/__init__.py +6 -0
  168. fleetpull/network/posture/client_options.py +96 -0
  169. fleetpull/network/retry/__init__.py +13 -0
  170. fleetpull/network/retry/decision.py +155 -0
  171. fleetpull/network/tls/__init__.py +5 -0
  172. fleetpull/network/tls/truststore_context.py +35 -0
  173. fleetpull/orchestrator/__init__.py +30 -0
  174. fleetpull/orchestrator/backfill.py +127 -0
  175. fleetpull/orchestrator/batch.py +155 -0
  176. fleetpull/orchestrator/bisection.py +271 -0
  177. fleetpull/orchestrator/drivers.py +350 -0
  178. fleetpull/orchestrator/entry.py +347 -0
  179. fleetpull/orchestrator/executors.py +128 -0
  180. fleetpull/orchestrator/fanout.py +163 -0
  181. fleetpull/orchestrator/feed_drive.py +266 -0
  182. fleetpull/orchestrator/metadata_projection.py +195 -0
  183. fleetpull/orchestrator/outcome.py +53 -0
  184. fleetpull/orchestrator/recording.py +85 -0
  185. fleetpull/orchestrator/resume.py +143 -0
  186. fleetpull/orchestrator/roster_harvest.py +108 -0
  187. fleetpull/orchestrator/roster_refresh.py +363 -0
  188. fleetpull/orchestrator/runner.py +262 -0
  189. fleetpull/orchestrator/shape_resolution.py +221 -0
  190. fleetpull/orchestrator/spine.py +166 -0
  191. fleetpull/orchestrator/streaming.py +153 -0
  192. fleetpull/orchestrator/unit_loop.py +273 -0
  193. fleetpull/orchestrator/watermark_drive.py +455 -0
  194. fleetpull/paths/__init__.py +13 -0
  195. fleetpull/paths/datasets.py +38 -0
  196. fleetpull/paths/partitions.py +41 -0
  197. fleetpull/paths/resolution.py +98 -0
  198. fleetpull/polars_typing/__init__.py +20 -0
  199. fleetpull/py.typed +0 -0
  200. fleetpull/records/__init__.py +19 -0
  201. fleetpull/records/convert.py +53 -0
  202. fleetpull/records/dataframe.py +63 -0
  203. fleetpull/records/event_time.py +70 -0
  204. fleetpull/records/fields.py +190 -0
  205. fleetpull/records/flatten.py +54 -0
  206. fleetpull/records/roster_members.py +74 -0
  207. fleetpull/records/schema.py +73 -0
  208. fleetpull/records/validation.py +62 -0
  209. fleetpull/resources/__init__.py +10 -0
  210. fleetpull/resources/config.example.yaml +222 -0
  211. fleetpull/roster/__init__.py +16 -0
  212. fleetpull/roster/definition.py +46 -0
  213. fleetpull/roster/key.py +40 -0
  214. fleetpull/roster/registry.py +93 -0
  215. fleetpull/state/__init__.py +36 -0
  216. fleetpull/state/cursors.py +417 -0
  217. fleetpull/state/database.py +463 -0
  218. fleetpull/state/migrations.py +430 -0
  219. fleetpull/state/reconcile.py +127 -0
  220. fleetpull/state/rosters.py +159 -0
  221. fleetpull/state/run_ledger.py +572 -0
  222. fleetpull/state/work_units.py +648 -0
  223. fleetpull/storage/__init__.py +30 -0
  224. fleetpull/storage/append.py +187 -0
  225. fleetpull/storage/atomic.py +161 -0
  226. fleetpull/storage/files.py +176 -0
  227. fleetpull/storage/frames.py +98 -0
  228. fleetpull/storage/metadata.py +161 -0
  229. fleetpull/storage/partitioned.py +205 -0
  230. fleetpull/storage/pruning.py +169 -0
  231. fleetpull/storage/read.py +35 -0
  232. fleetpull/storage/result.py +34 -0
  233. fleetpull/storage/single_file.py +130 -0
  234. fleetpull/storage/splitting.py +88 -0
  235. fleetpull/storage/staging.py +178 -0
  236. fleetpull/storage/writers.py +145 -0
  237. fleetpull/timing/__init__.py +21 -0
  238. fleetpull/timing/canon.py +92 -0
  239. fleetpull/timing/clock.py +192 -0
  240. fleetpull/timing/codec.py +122 -0
  241. fleetpull/timing/sleeper.py +65 -0
  242. fleetpull/vocabulary/__init__.py +16 -0
  243. fleetpull/vocabulary/json_types.py +20 -0
  244. fleetpull/vocabulary/provider.py +29 -0
  245. fleetpull/vocabulary/quota_scope.py +47 -0
  246. fleetpull/vocabulary/response_category.py +32 -0
  247. fleetpull-0.1.0.dist-info/METADATA +248 -0
  248. fleetpull-0.1.0.dist-info/RECORD +252 -0
  249. fleetpull-0.1.0.dist-info/WHEEL +5 -0
  250. fleetpull-0.1.0.dist-info/entry_points.txt +2 -0
  251. fleetpull-0.1.0.dist-info/licenses/LICENSE +202 -0
  252. fleetpull-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,248 @@
1
+ Metadata-Version: 2.4
2
+ Name: fleetpull
3
+ Version: 0.1.0
4
+ Summary: Pull fleet telematics data from provider APIs (Motive, Samsara, GeoTab) into typed polars DataFrames and parquet: retrieval, dtype coercion, and light structural normalization — no assumed end use.
5
+ Author-email: Andrew Jordan <andrewjordan3@gmail.com>
6
+ Maintainer-email: Andrew Jordan <andrewjordan3@gmail.com>
7
+ License-Expression: Apache-2.0
8
+ Project-URL: Homepage, https://github.com/andrewjordan3/fleetpull
9
+ Project-URL: Repository, https://github.com/andrewjordan3/fleetpull
10
+ Project-URL: Issues, https://github.com/andrewjordan3/fleetpull/issues
11
+ Keywords: telematics,fleet,motive,samsara,geotab,polars,api-client
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
19
+ Classifier: Topic :: Scientific/Engineering :: Information Analysis
20
+ Classifier: Typing :: Typed
21
+ Requires-Python: >=3.12
22
+ Description-Content-Type: text/markdown
23
+ License-File: LICENSE
24
+ Requires-Dist: httpx>=0.27.0
25
+ Requires-Dist: polars>=1.0.0
26
+ Requires-Dist: pydantic>=2.7.0
27
+ Requires-Dist: pyyaml>=6.0.0
28
+ Requires-Dist: truststore>=0.9.0
29
+ Requires-Dist: tzdata>=2025.2
30
+ Provides-Extra: dev
31
+ Requires-Dist: ruff>=0.5.0; extra == "dev"
32
+ Requires-Dist: mypy>=1.10.0; extra == "dev"
33
+ Requires-Dist: pytest>=8.0.0; extra == "dev"
34
+ Requires-Dist: pytest-cov>=4.1.0; extra == "dev"
35
+ Requires-Dist: import-linter>=2.0; extra == "dev"
36
+ Requires-Dist: types-pyyaml; extra == "dev"
37
+ Dynamic: license-file
38
+
39
+ # fleetpull
40
+
41
+ fleetpull pulls fleet telematics data from provider APIs — **Motive**,
42
+ **Samsara**, and **GeoTab** — and delivers it as typed, dtype-coerced,
43
+ lightly normalized tabular output: Polars DataFrames in memory, parquet on
44
+ disk, staying as close to the raw API responses as is reasonable.
45
+
46
+ It is deliberately narrow. fleetpull does no cross-endpoint merging, builds
47
+ no unified cross-provider schema, performs no semantic deduplication, loads
48
+ no warehouse, and assumes no end use — downstream processing is the
49
+ consumer's concern. What it does instead is be rigorous about retrieval:
50
+ probed (never merely documented) provider behavior, crash-safe incremental
51
+ state, token-bucket rate limiting at the transport boundary, and one
52
+ explicit schema per (provider, endpoint).
53
+
54
+ **Status:** alpha. The two public verbs below are settled, and coverage is
55
+ broad — the Motive and Samsara endpoint inventories and the GeoTab `Get` and
56
+ feed surfaces are all shipped (see [ENDPOINTS.md](ENDPOINTS.md)). Pre-1.0,
57
+ the internals are still free to improve.
58
+
59
+ ## Install
60
+
61
+ ```bash
62
+ pip install fleetpull
63
+ # or
64
+ uv add fleetpull
65
+ ```
66
+
67
+ The latest development version, straight from source:
68
+
69
+ ```bash
70
+ pip install git+https://github.com/andrewjordan3/fleetpull
71
+ ```
72
+
73
+ Python ≥ 3.12. Core dependencies: `httpx`, `polars`, `pydantic` 2.x,
74
+ `pyyaml`, `truststore`, `tzdata`.
75
+
76
+ To scaffold a starter config for the `sync` verb below, run
77
+ `fleetpull init-config` — it writes an annotated `fleetpull_config.yaml`
78
+ you edit and point `sync` at.
79
+
80
+ ## The two verbs
81
+
82
+ ### `fetch` — one snapshot, in memory
83
+
84
+ The programmatic convenience verb: one endpoint's full current listing as an
85
+ eager, typed Polars DataFrame. No disk, no state, no configuration file.
86
+
87
+ ```python
88
+ from fleetpull import Endpoints, fetch
89
+
90
+ vehicles = fetch(Endpoints.Motive.vehicles, auth='your-api-key')
91
+ devices = fetch(
92
+ Endpoints.Geotab.devices,
93
+ auth={'username': '...', 'password': '...', 'database': '...'},
94
+ )
95
+ ```
96
+
97
+ - `auth` is a bare API-key string for Motive/Samsara and named fields (a
98
+ mapping or `GeotabAuthConfig`) for GeoTab. Credentials are wrapped in
99
+ `SecretStr` at the boundary and never appear in errors or logs.
100
+ - Behind a TLS-intercepting corporate proxy (Zscaler-class), pass
101
+ `use_truststore=True` to build TLS contexts from the OS trust store.
102
+ - `fetch` exposes **snapshot endpoints only** — a snapshot is bounded by
103
+ entity count, so the in-memory contract stays honest. Windowed history is
104
+ `sync` territory, and the type checker (plus a runtime guard) enforces the
105
+ split.
106
+ - An empty result is a zero-row frame carrying the full typed schema, never
107
+ `None`.
108
+
109
+ ### `Sync` — config-driven incremental pipeline
110
+
111
+ The pipeline verb: a YAML config selects providers and endpoints; each run
112
+ fetches incrementally, writes parquet, and commits its resume state.
113
+ `fleetpull init-config` writes a documented starter config to edit.
114
+
115
+ ```python
116
+ from fleetpull import Sync
117
+
118
+ Sync('fleetpull_config.yaml').run()
119
+ ```
120
+
121
+ ```yaml
122
+ sync:
123
+ default_start_date: 2025-01-01 # cold-start backfill anchor
124
+
125
+ storage:
126
+ dataset_root: /data/fleet # parquet lands here
127
+
128
+ logging:
129
+ console_level: INFO
130
+
131
+ providers:
132
+ motive:
133
+ endpoints: [vehicles, vehicle_locations, driving_periods]
134
+ # api_key: falls back to the MOTIVE_API_KEY environment variable
135
+ samsara:
136
+ endpoints: [vehicles]
137
+ # api_key: falls back to SAMSARA_API_KEY
138
+ geotab:
139
+ auth:
140
+ username: user@example.com
141
+ database: my_database
142
+ # password: falls back to GEOTAB_PASSWORD
143
+ endpoints: [devices, users, trips]
144
+ lookback_days: 7 # late-arrival refetch margin
145
+ ```
146
+
147
+ The same run is available from the shell: `fleetpull sync fleetpull_config.yaml`.
148
+
149
+ Endpoints run and commit independently — one endpoint's failure never halts
150
+ its siblings; a run with failures ends by raising `SyncFailuresError`
151
+ carrying every failure (queue order within each provider — feeders then
152
+ consumers, config order within each — providers in config order).
153
+
154
+ Output is one folder per endpoint under `dataset_root`:
155
+
156
+ ```
157
+ data/
158
+ motive/
159
+ vehicles/ # snapshot: one file, replaced each run
160
+ data.parquet
161
+ metadata.json # human-readable run summary — never read by the program
162
+ driving_periods/ # windowed: hive date partitions
163
+ date=2026-07-15/part.parquet
164
+ date=2026-07-16/part.parquet
165
+ metadata.json
166
+ ```
167
+
168
+ Hive `date=YYYY-MM-DD` layout is read natively by `pl.scan_parquet` and
169
+ BigQuery external tables. Operational state (watermarks, run ledger, backfill
170
+ work units) lives in SQLite at `<dataset_root>/.fleetpull/state.sqlite3`;
171
+ crash-safety ordering (parquet first, cursor second) plus delete-by-window
172
+ merge makes interrupted runs refetch idempotently — at-least-once fetching,
173
+ exactly-once data.
174
+
175
+ ## Output contract
176
+
177
+ - **One schema per (provider, endpoint).** Column dtypes derive from each
178
+ endpoint's Pydantic response model; nested objects flatten to
179
+ double-underscore-joined columns (`driver__id`). No cross-endpoint or
180
+ cross-provider unification, ever.
181
+ - **Event timestamps are timezone-aware UTC** end to end.
182
+ - **Exact-duplicate rows** (artifacts of pagination and crash refetch) are
183
+ dropped at write time; same-id-different-payload reconciliation belongs to
184
+ consumers.
185
+ - Values arrive as the provider sent them — no unit conversion, no semantic
186
+ cleanup. Provider quirks worth knowing (GeoTab's seconds-despite-the-name
187
+ `engineHours`, sentinel dates, per-endpoint window anchoring) are recorded
188
+ in [ENDPOINTS.md](ENDPOINTS.md) and DESIGN §8.
189
+
190
+ ## Errors
191
+
192
+ Consumers catch `FleetpullError` or its five public subclasses:
193
+
194
+ | Exception | When | Reasonable reaction |
195
+ |---|---|---|
196
+ | `ConfigurationError` | Bad config or wiring | Fix config, rerun |
197
+ | `AuthenticationError` | Rejected credentials | Fix credentials |
198
+ | `ProviderResponseError` | Non-retryable or contract-violating response | Investigate before rerunning |
199
+ | `RetriesExhaustedError` | Transient/rate-limit budget ran out | Rerun later |
200
+ | `SyncFailuresError` | One or more endpoints failed inside a sync run | Inspect `failures`, act per member |
201
+
202
+ Everything else is internal. Rate limits are respected automatically — a
203
+ shared token-bucket limiter sits at the transport boundary and a 429's
204
+ `Retry-After` pauses the whole quota scope.
205
+
206
+ ## Documentation
207
+
208
+ - [ENDPOINTS.md](ENDPOINTS.md) — every shipped endpoint, its mechanics, and
209
+ the port queue.
210
+ - [DESIGN.md](DESIGN.md) — the design of record: architecture, invariants,
211
+ and the probe-captured provider behaviors every binding encodes.
212
+ - [CLAUDE.md](CLAUDE.md) — engineering standards and verification gates.
213
+
214
+ ## Contributing
215
+
216
+ Contributions are welcome and encouraged — a new endpoint, a bug fix, a
217
+ sharper docstring, or a provider quirk you've hit in the wild. Start with
218
+ [CONTRIBUTING.md](CONTRIBUTING.md); the short version:
219
+
220
+ ```bash
221
+ uv sync --group dev
222
+ uv run ruff format . && uv run ruff check . \
223
+ && uv run mypy src/ tests/ \
224
+ && uv run lint-imports \
225
+ && uv run pytest
226
+ ```
227
+
228
+ These five gates are exactly what CI runs on every pull request, so a green
229
+ local run is a green CI run. Tests never hit real provider APIs; new
230
+ endpoints are built probe-first from live captures — the port discipline is
231
+ in [ENDPOINTS.md](ENDPOINTS.md), and the engineering standards are in
232
+ [CLAUDE.md](CLAUDE.md).
233
+
234
+ ## Acknowledgements
235
+
236
+ Built on [Polars](https://pola.rs), [Pydantic](https://pydantic.dev),
237
+ [httpx](https://www.python-httpx.org), and
238
+ [truststore](https://truststore.readthedocs.io) — fleetpull is a thin, rigorous
239
+ layer over their work.
240
+
241
+ ## Author
242
+
243
+ By Andrew Jordan. Questions, bugs, and endpoint requests are best raised as
244
+ [GitHub issues](https://github.com/andrewjordan3/fleetpull/issues).
245
+
246
+ ## License
247
+
248
+ [Apache License 2.0](LICENSE).
@@ -0,0 +1,252 @@
1
+ fleetpull/__init__.py,sha256=XrA7uvMq-xLhaEf9Q604-3EwuazwzLYLaav82emoMog,1084
2
+ fleetpull/cli.py,sha256=It39rvuJVmNm7Fazasq6rQxzLH8HRB4ROho4coIWEi8,4772
3
+ fleetpull/exceptions.py,sha256=Cve9v7TPM3cl29VvxRfuuZsx-oHI_zYwfgtJGtF4cEQ,10571
4
+ fleetpull/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
+ fleetpull/api/__init__.py,sha256=2CaJaR9pNEhhS3Do3c3o-QuCl1Les3ATcTnDmlfZ3Jc,939
6
+ fleetpull/api/auth_ingress.py,sha256=d9JO7WGKryYARcbG9mzqth1lD1CsDE91lzvWRfLWa2c,9109
7
+ fleetpull/api/catalog.py,sha256=xbcy23znA_XZdg0jytQqhA3NQXpl3nK4UrhZXY3TIrQ,6266
8
+ fleetpull/api/fetch.py,sha256=P2hygw_bD-tfgW4GC6O9kvaxibpXg5rciynXlX4iFL0,10104
9
+ fleetpull/api/identity.py,sha256=trIp7uMlS1C6CT0ERuYmzJzlQWf_jlBHQ0eI9Zl1Prw,3071
10
+ fleetpull/api/sync.py,sha256=fH_fKDSLQML9MOmLiJL4DSkFOb58EWfUWgKpDh1GFOw,31014
11
+ fleetpull/config/__init__.py,sha256=n-N91FKm_0wixm1xFRFy2NRSJbFbetZTQ2Tv6IdL0kE,1364
12
+ fleetpull/config/base.py,sha256=KnLpphDpqDf_LmTrq-CoXSg378YnmABj1SWlz6bm4jk,660
13
+ fleetpull/config/example.py,sha256=fO69W_4XT4eGii7FxC3rxrSCi7oHM2-KMFXmLNB_Bco,3089
14
+ fleetpull/config/geotab.py,sha256=aZJiHefUA225sbM0K683RGD6ZS2jHGWiZBY7hoxIgbY,3041
15
+ fleetpull/config/http.py,sha256=6oF8JDWiQF2aZzCKM-yKsicRrXobVzIJqpol7aFf6hc,1146
16
+ fleetpull/config/loading.py,sha256=vEK8AhwwjyT_Nmqo9DRzRbUy3aqUAb_VWRVjvDDVwBQ,7623
17
+ fleetpull/config/logger.py,sha256=j1ukso5_sCYYZCI-OR_yqBQjGGovWvkCrrYFLgagdxo,5627
18
+ fleetpull/config/providers.py,sha256=ihKA7X4neaxrZ7x1CAMS6Lc1rKMVcA9IrOUAm0Wd4iA,23517
19
+ fleetpull/config/rate_limit.py,sha256=qlYw46yGBldZ0RNlz3gVQItKUs49_rs6v4M7GiHSHMU,1973
20
+ fleetpull/config/resolution.py,sha256=GrVJsXPXed62uS7cOn-7Wj_W8cr4v_wTxwn9If4UV6g,6355
21
+ fleetpull/config/retry.py,sha256=V4WOPR5pPZqSq-8gMbOKcaN6x_yodJxkbQVzg2Kr86I,2818
22
+ fleetpull/config/root.py,sha256=wZ9EUSFwHaYaXbwx8OuhW2WsKiO6lCxcBCJYP-9B1BA,6673
23
+ fleetpull/config/sections.py,sha256=HGWR4p9PpfK7rJZYzemxAfuUqkmCVgc4PK9jZT_mT5U,7046
24
+ fleetpull/endpoints/__init__.py,sha256=fAEJDIol3qb4CY9kyt9QQtL7yI5HV0QWCHRnVYgPbSI,907
25
+ fleetpull/endpoints/registry.py,sha256=p4noN8SFQgfZT5N5_K0w0H9KRLbfx0jvEjOGmGv5eio,11329
26
+ fleetpull/endpoints/geotab/__init__.py,sha256=OatzH37ce4-Iz6we-GZuHH-M5EKna70orowBfrRqLEM,502
27
+ fleetpull/endpoints/geotab/_requests.py,sha256=_96B9buvTfwegsbjLejLTWzWACJqVZr-lOBWnzqyKWY,16628
28
+ fleetpull/endpoints/geotab/annotation_logs.py,sha256=JbgSn6XOViX_rmhjF_9lfHLLN_M8c8DqSWzRBvkT-xE,3163
29
+ fleetpull/endpoints/geotab/audits.py,sha256=a83_siFw58F0E6McXdifQ_S3QzyCW5nf_HLVfjafkM0,2818
30
+ fleetpull/endpoints/geotab/devices.py,sha256=HYf3ZqtTE07U3_S3aBIa69d-QNQlsoMTdb8JCeq3zck,3035
31
+ fleetpull/endpoints/geotab/driver_changes.py,sha256=4CCiY6R4vD_ayTetaV6iAYEh6HYHLI48gs-aMrG0sHg,3123
32
+ fleetpull/endpoints/geotab/duty_status_logs.py,sha256=v_6KS03CqoL-1-wURJC1CQ030Oq8etnkLN9pc1Sur-s,3229
33
+ fleetpull/endpoints/geotab/dvir_logs.py,sha256=QrmhZYkwFFsiDnJr-atr7oGcwYrY3yh2mrI00AyXsnw,3200
34
+ fleetpull/endpoints/geotab/exception_events.py,sha256=emHSrJnr78OF_tx93Mn8bbDJRG07gi-vtrgS0qzJOq4,5168
35
+ fleetpull/endpoints/geotab/fault_data.py,sha256=ep3aqzeLp_OK_cti-mlCV2SYhoAguEbf2L3xDtJmm_A,2948
36
+ fleetpull/endpoints/geotab/fill_ups.py,sha256=YRando0KNS8Jz9nR8x4hZgNmwZNNF6JPdEinBe_2ZWg,3423
37
+ fleetpull/endpoints/geotab/fuel_and_energy_used.py,sha256=kyBNzmngqSs3Ejd6VX_WDlnZouRztQtkKBeYox5mD30,3217
38
+ fleetpull/endpoints/geotab/fuel_tax_details.py,sha256=pS4mY_XEaBaMgWx5V21krbtZ9-SnTQ1nnFnK6pQCrxQ,3246
39
+ fleetpull/endpoints/geotab/log_records.py,sha256=CbCiIaCC5CEVJH6vqc59WHIanr9yhPgchg-vrgOJY84,3179
40
+ fleetpull/endpoints/geotab/media_files.py,sha256=6j0XjSJijxzT7RA6XYsI9IIzYalrNvagFbIW_iXgadQ,3193
41
+ fleetpull/endpoints/geotab/shipment_logs.py,sha256=cax7LI8G3CzXrPebyZvxLA-lKH1RGgaYlcVrsk1Zg-E,2976
42
+ fleetpull/endpoints/geotab/status_data.py,sha256=12mH9D-lMU5ITJF7cYpGLrTW-LaYESgHyvok8jNGkpQ,2887
43
+ fleetpull/endpoints/geotab/text_messages.py,sha256=35Ab5L30UuBy2mk9WGTUOVW7VjheS6JL0A5XCzCFujE,3286
44
+ fleetpull/endpoints/geotab/trips.py,sha256=M1ttoE9hF7CMf3Ixtwk8nMVbv-7xhPWNNq5zbnbegLU,4349
45
+ fleetpull/endpoints/geotab/users.py,sha256=u-MPzp5yN0hlLtSY9HqyI8GgZjLwv5eYr3QWSYuqanE,3163
46
+ fleetpull/endpoints/motive/__init__.py,sha256=0_XE4oLRVaxskDTu7-N8tIl3dcCjcKC4jpOQt3fdJUE,503
47
+ fleetpull/endpoints/motive/_spec_builders.py,sha256=0YaCSZr2qsGXCrZZF0gyzxb6Eb1JlTYydFGQg4f3wOM,4033
48
+ fleetpull/endpoints/motive/driver_idle_rollups.py,sha256=ld61B37bY2s9KfwVYcaPWK-dhn3IjFHEMieiAqUYrWg,5237
49
+ fleetpull/endpoints/motive/driving_periods.py,sha256=DjE0G0reD64asCUnveVZgyg6j3oXRkhryXh_cHDKibQ,3530
50
+ fleetpull/endpoints/motive/groups.py,sha256=2dbOvn474hwZNaFuWkSdjna0TdtWTY-Jpzoc0TeEKkY,2161
51
+ fleetpull/endpoints/motive/idle_events.py,sha256=9qE0VNS6sLBSb84N9pC5f4Eh1QQZ-umgy4yX8UkziJA,3962
52
+ fleetpull/endpoints/motive/users.py,sha256=TU7W3alhTWpKiY0Xa7dsF8V2DgvbYpXcSFlTpALcXAI,2373
53
+ fleetpull/endpoints/motive/vehicle_locations.py,sha256=NU0RZmYVD7lorvoBQ3I7por_dajXn7d1JiABSKMt3yI,7867
54
+ fleetpull/endpoints/motive/vehicle_utilizations.py,sha256=3-o_0btgSbmyc015yFe-zTBf0dk364uNaBpWC8XoWNg,5868
55
+ fleetpull/endpoints/motive/vehicles.py,sha256=rnKEG90HkiJVKj7pXv44rCnjBXZrmdcmdkS7FMgRTzU,4526
56
+ fleetpull/endpoints/samsara/__init__.py,sha256=aNSFJY86x8XriLMLCqlf9THmtsMB0Z8SDJR-NsjeOSQ,507
57
+ fleetpull/endpoints/samsara/_spec_builders.py,sha256=lKqnzjQRIOlwYpSZLEzvNNXVVY242tRth8_MD5PF13I,8386
58
+ fleetpull/endpoints/samsara/addresses.py,sha256=Fl_DsFAy5hWecngxlFiYZ5pjBaVKfP8udQmqr9hNCqA,3106
59
+ fleetpull/endpoints/samsara/asset_locations.py,sha256=tYl7PxuEmjbh3EdLv3Wazch1m9Xb8vPBfB6NYCem6Xk,9673
60
+ fleetpull/endpoints/samsara/driver_fuel_energy_reports.py,sha256=A5qHTazctO9gahkzPeb-Go3SE6lPmev9M-dB8JS3FhM,5593
61
+ fleetpull/endpoints/samsara/driver_vehicle_assignments.py,sha256=mfV5EVIDsr-n3f_fpJw3Zt4OJhjh5fI0rwZ_W7mcXvE,9379
62
+ fleetpull/endpoints/samsara/drivers.py,sha256=hHiqKG1pnx_fcEI5pUQnFXaV8t92fkwnpKM2Y2j5Yq8,7064
63
+ fleetpull/endpoints/samsara/engine_states.py,sha256=8LYnOLsGlVyKzCuoK5v7l3o9OWP372tKyy_I39OxCTA,5005
64
+ fleetpull/endpoints/samsara/gps_readings.py,sha256=fNtsQaX5DvKI8HtgZJmMRR8qkCQ3p3HhbahZhcNSLr8,4958
65
+ fleetpull/endpoints/samsara/idling_events.py,sha256=O0looJL_gaCcA0o-h6Ag8xn9wWjso1gubwa_e1xf3ZQ,8454
66
+ fleetpull/endpoints/samsara/odometer_readings.py,sha256=I7dCPdUURymuWGps_X3m3JSDCBzAihyswLPZ8VT_aeY,5065
67
+ fleetpull/endpoints/samsara/trips.py,sha256=iuNG-13CXW0jIze-C5K516MnQWkGQTCiFdsoVDTiswc,9258
68
+ fleetpull/endpoints/samsara/vehicle_fuel_energy_reports.py,sha256=HJXAOwDTYXkC-iR8p6OwvrsCJW7K2wrJWz-mK6vT0HE,6441
69
+ fleetpull/endpoints/samsara/vehicles.py,sha256=E_4YAKJcCt0unPuHj0ZQ0_zHNjC3P4J2PvyJa6XmMm4,5445
70
+ fleetpull/endpoints/shared/__init__.py,sha256=e1uYfImdUnMefmkO57KC2pElHEFEpdcIfBVAwzgm-OE,1558
71
+ fleetpull/endpoints/shared/base.py,sha256=OluhqH_Z4f-RDG6AE5wPVvQF42piHB7r1Z3QpEEY7Sk,24847
72
+ fleetpull/endpoints/shared/request_shape.py,sha256=Ec7ZRWETBVBWQh5J2InSRcBIQJkMlbProjpbBcnBCNA,9815
73
+ fleetpull/endpoints/shared/resume.py,sha256=jENOPW9wlQHk7Ht1kSQuc_HXJnnMvMH5LlYl0iex91M,2650
74
+ fleetpull/endpoints/shared/spec_builders.py,sha256=OOSc97rOrebKY98LAzyFcEgI3oYUbWdf1GTAL1jOtIk,2305
75
+ fleetpull/endpoints/shared/sync_mode.py,sha256=KasCdRF72dUy232H5lI_UNB1SWD5FPj7wYW7nAbdCbE,7718
76
+ fleetpull/endpoints/shared/url_paths.py,sha256=_Qz2XDIqIYjBoXeascbTNpyz-CfxLenT_Bt5-APPOvg,6062
77
+ fleetpull/incremental/__init__.py,sha256=i2HqCAKwMrqalDwN94A_hCad2EWfiObn8s6G2WlMKaQ,757
78
+ fleetpull/incremental/cursor.py,sha256=IZk9QviG3TEUnx5MgkQAEhTV_1LtPaisLAavlC_fPS4,2260
79
+ fleetpull/incremental/resolution.py,sha256=O7cw-fHAQ7DsVRQvozt21NVyrA082bEUOT1XVtrNzJ0,6974
80
+ fleetpull/incremental/seed.py,sha256=E4GZqm0O29gOzJldkOg7afNRMfPLuJ6bfjOWmVbxqPE,2204
81
+ fleetpull/incremental/window.py,sha256=ayVemhiCkzutIObcLok0FppBYZ6WHc_pel8L4fLKeTg,4393
82
+ fleetpull/logger/__init__.py,sha256=HwchJQAVutimHmQeEkf_Vf119gUx4bASWojBXC31hCo,153
83
+ fleetpull/logger/setup.py,sha256=oTm3f8u-6zJIHv1XpUx-JAPihR1rNJHG-T2v5Iu8OGs,5964
84
+ fleetpull/model_contract/__init__.py,sha256=QMEwcAkOcWnf07lRz3smnf4ZDEi4wi1DEsp97n1ZEFU,273
85
+ fleetpull/model_contract/coercions.py,sha256=94PoUUSOR2ZV1WRNEjm-v_xf7uYljkbCHjij-2OP2HA,1313
86
+ fleetpull/model_contract/response.py,sha256=lPbHNCEmLWhYunnjkIEu59SgI4cg-XDYb4XCDB6YVJU,1933
87
+ fleetpull/models/__init__.py,sha256=h_Y3qwrndyYPp9feTfmpOgb-gvKtDWYlpluRhqfcAQs,225
88
+ fleetpull/models/geotab/__init__.py,sha256=qmYRVhSMb6lzk4g_Sx0VZ_uKjy4YXzOf9zrizvXrYPE,4246
89
+ fleetpull/models/geotab/annotation_log.py,sha256=d3SYptAx8C6EwkVyfakc6lwZqUKSgWzPdeLxCppHiVU,4129
90
+ fleetpull/models/geotab/audit.py,sha256=2H9I9LqLdD-lYP7Yo2C3OrAL5Vu1cvlGZlkCIC3tmnE,2059
91
+ fleetpull/models/geotab/device.py,sha256=VlX1ut7GcqyzjeA7SD99whhJLJ0b9vx6GuVKxwz-o7w,9590
92
+ fleetpull/models/geotab/driver_change.py,sha256=Q1PMR0O-ro9hIUH7bQ201FadWgW3qy8watEPJM60if4,3763
93
+ fleetpull/models/geotab/duty_status_log.py,sha256=cR8CcKbjdQKRXpn6-ntiO6kvkI4VTHY-qZ52rZM7R7s,8328
94
+ fleetpull/models/geotab/dvir_log.py,sha256=n1pLEQrjLoKGDCjNW9HZWpTnB8ExJqNBd4OVXjV21do,7888
95
+ fleetpull/models/geotab/exception_event.py,sha256=hCweniOivnomuYl0dE1hYAOfjBmO_830HXsoTR_1LjE,4953
96
+ fleetpull/models/geotab/fault_data.py,sha256=Qyk7bIxcwCO3lPim607Hks4q7Cmid6WmhjBQPC_QccE,6450
97
+ fleetpull/models/geotab/fill_up.py,sha256=W0aWOWEH3EWcvEcDB6ykHfdcJKna-Oa3rj3RyfNAlBs,7233
98
+ fleetpull/models/geotab/fuel_and_energy_used.py,sha256=ja8XbpWoqCHBAWvZuvvZjrU3Nb57ZgXIs2n0f5QpP7U,3351
99
+ fleetpull/models/geotab/fuel_tax_detail.py,sha256=jEjDTHYMntelCgDu8rvu_GaPwGYNaPgzCpZyoXEhmyo,6198
100
+ fleetpull/models/geotab/log_record.py,sha256=WoeSyqTBV72NmC-zi4QY_Nx2BuSCdKO6dUpsdcq-IUo,2764
101
+ fleetpull/models/geotab/media_file.py,sha256=p9JaH0qtEwtrPoDvnxEKjvzPjtwnNOuDMdwAU3UGVHU,5307
102
+ fleetpull/models/geotab/shared.py,sha256=pTeEwD9yIgvGkRbNibtESMxlQPF1lmJkhxDwU4vUmhA,8771
103
+ fleetpull/models/geotab/shipment_log.py,sha256=dPm9e5ehG2C0P_rlRKFEo7JjWY21E7CraRie_7iAljQ,3853
104
+ fleetpull/models/geotab/status_data.py,sha256=N4326d6FeXSbEaX_67qBER1OGHk8zQP5u7h5jMx9pQI,4072
105
+ fleetpull/models/geotab/text_message.py,sha256=gSoLA9V9SevnBHwrbeljemI1BPRLoKA1kWWT-PkWnyw,5161
106
+ fleetpull/models/geotab/trip.py,sha256=KwhpNawol-N9YVF7FTPnv3mBqbYRey6B0_KCfmUg9ww,6352
107
+ fleetpull/models/geotab/user.py,sha256=_eFRM8ooyr0MosM5OKZHHv3tqrzaDhPYusJFdrxqhJM,7355
108
+ fleetpull/models/motive/__init__.py,sha256=Dmcj1kGLeb56u-_AqVoZ36VBy6MrbPfyzTh0sh5Ilhc,1168
109
+ fleetpull/models/motive/driver_idle_rollup.py,sha256=GJtgodBiWF_yhny2AZg2Pb7cfYbVcupdD2rJJRimxsc,5375
110
+ fleetpull/models/motive/driving_period.py,sha256=Ecggj6AlgZoKKNjod0J5k871WN8MpjXF9qrbLPwsCKA,3778
111
+ fleetpull/models/motive/group.py,sha256=RwpsXUZyDS_kCDR9KTTUZw5jX6kk6yjPriw0msF6W_w,1885
112
+ fleetpull/models/motive/idle_event.py,sha256=nmbq7zw106LPTcOv-HI4xxsbSxw4F0c5Sm7CsTG8EuY,2983
113
+ fleetpull/models/motive/shared.py,sha256=EtbTSzcYlvZjLUA1hWQN4xW7ZmxdH4f6HhW7HUMLVUg,8413
114
+ fleetpull/models/motive/user.py,sha256=YjZk3te9kzZ89OwEIhhjKp5gfE9kj-Z7PEwfz_ci0fw,10039
115
+ fleetpull/models/motive/vehicle.py,sha256=pluQzPXqY95QBVN7U9v9emQoDUPyHv6qYcxIPNd8TYg,6504
116
+ fleetpull/models/motive/vehicle_location.py,sha256=yvvelntfX78UKQJlPrstPBi9eWSEAjBr2guRAU_Rvro,5625
117
+ fleetpull/models/motive/vehicle_utilization.py,sha256=CBuxKkhTvrBUwqvqW8t2lpNAw12MRBGODb6Xa09ZK8I,6411
118
+ fleetpull/models/samsara/__init__.py,sha256=fBoC8IbO8xe_EMTQM_IeIaVNX9k8i2mHfBvqNHC-VGQ,2793
119
+ fleetpull/models/samsara/address.py,sha256=QLcmLQCdBLw6g05E67lR0enSuvho-miwM4z0A7KTNq0,5545
120
+ fleetpull/models/samsara/asset_location.py,sha256=wjDGpBgXPWzQXE1rhDTMK4zY0VpRY8fpr2ZhCafJv_M,5198
121
+ fleetpull/models/samsara/driver.py,sha256=-wr7SQ9dlkfHHw2p-SAxK9P1xbgXhsZCiTvMokpPOYM,9103
122
+ fleetpull/models/samsara/driver_fuel_energy_report.py,sha256=ORjDxfEzjpL7VoeDsRLBEnGFRZH2euwibj_mbEEH0-s,6240
123
+ fleetpull/models/samsara/driver_vehicle_assignment.py,sha256=7CDcmMY0DSkAC1aL_PXLYSvG5bveeoTY4zjNGdPvZ-U,7227
124
+ fleetpull/models/samsara/engine_state.py,sha256=fTQxog1HEXxKsQDrWUCrdvLSE5oD0pmRK70iPaUfOp0,4066
125
+ fleetpull/models/samsara/gps_reading.py,sha256=SRrJMfl9ArSU2tOqwh_bU4IOFZfowLYasoJwRuSq9iA,5876
126
+ fleetpull/models/samsara/idling_event.py,sha256=7X3LgAiYohxnbwyl6G90CFs7zvHxTfNQO_5jFczMO-Q,6605
127
+ fleetpull/models/samsara/odometer_reading.py,sha256=VBEvJpaKVqhPIGbA8qDy4X5aijIY5CK4nEXCBE2HXJQ,3973
128
+ fleetpull/models/samsara/trip.py,sha256=i-uV8I66XcTHAMLkj3sUzOqV9_Y9oEZbvT_H9JosgdU,8112
129
+ fleetpull/models/samsara/vehicle.py,sha256=s62BMJZhRS5oMKW0qxiogjEWncoW40DW6mkV3M26lCY,6501
130
+ fleetpull/models/samsara/vehicle_fuel_energy_report.py,sha256=MgW5KJ9Y2YSN1YumAYbU3T1OVs0o_tTG597gZOa5Jr4,8376
131
+ fleetpull/network/__init__.py,sha256=tlg5OZoUwWAze2cgZL25WUfFyxNRqt080SAxVLBMEZw,308
132
+ fleetpull/network/auth/__init__.py,sha256=upgowKuvYmhCke9iIbs5W4tB3NqYZoAhhizHQwtBYm0,554
133
+ fleetpull/network/auth/authenticate.py,sha256=o4N7YSIFl_uRpe76SHejWj71eA7AYVfXj-gUMsrUBxg,10146
134
+ fleetpull/network/auth/manager.py,sha256=py9YGWek3e06H8eOnKNPmyDQ4QpDs6P32DyZX-_b7kE,9490
135
+ fleetpull/network/auth/models.py,sha256=quHzoPU5nRmRVBJJfL07gr8TkPzBRCw1CEoklTKI-mc,1866
136
+ fleetpull/network/auth/strategies.py,sha256=LjRhQ5CfwHI462DZQ_u4pb0GeXQ6jfvldMcQFAdbo0I,6716
137
+ fleetpull/network/classifiers/__init__.py,sha256=QNlj-_2N4wPPNVqONEczNmvp6pNDyHN43Q0HRU1_Rzw,389
138
+ fleetpull/network/classifiers/geotab.py,sha256=4wHKoMFFXlNw5i9cnDKpArnJcIK-bpkMtlqMfyPAMp4,5629
139
+ fleetpull/network/classifiers/motive.py,sha256=NSntGGQafZQZyA2C-lx2Of6KNlDMmVCg1pPxe53Sf8U,3047
140
+ fleetpull/network/classifiers/samsara.py,sha256=P_LzGQJPkVW75lIgj6K4JzBmEDJBuAuJl_RQYCEpQqI,3096
141
+ fleetpull/network/client/__init__.py,sha256=NOT6I8PM_b91Zwc-xYehZj_rEVUNzm-ow2gIgkmxoQQ,1098
142
+ fleetpull/network/client/page.py,sha256=nE9yg7D_lv9zhKxuXTCAyDeKfBPMovNoXRdFsx1FH2E,1177
143
+ fleetpull/network/client/profile.py,sha256=VZLvQaSUZXe98G1pNywjidaaS3caEhuxGCMV_EVtRyY,883
144
+ fleetpull/network/client/registry.py,sha256=-BSxvgDt1CK7ZVy-1uCcs2feaZBjLaDirVeHE3HnE6U,4291
145
+ fleetpull/network/client/registry_base.py,sha256=zkt_ui-XmceR0C5cZdx_F9CiS7xDNqNFNObkHpMDsLA,6254
146
+ fleetpull/network/client/runtime.py,sha256=9aA3YzBHLzjSzCeft0i_CY83Ij5j_h7TcMnrO2iM48A,1896
147
+ fleetpull/network/client/transport.py,sha256=xSbTsZLhB-3vBWDfKVcQCcLxYmi3qeCAKECOrxcd6N0,16444
148
+ fleetpull/network/contract/__init__.py,sha256=Iecqprhpsw9YVgkHsN-4KjIAFTyxjiV4Hj5kn2U0xXI,1501
149
+ fleetpull/network/contract/auth.py,sha256=oDZ5Ed6M9ybJAR8EDqtpAVbkyIIxa4-YtysmYY6js2c,1602
150
+ fleetpull/network/contract/classifier.py,sha256=8cUfET_rYBb-EX64yw3NHvVuYkNM-gZdOQJuOi_HYfo,6589
151
+ fleetpull/network/contract/envelope_fetcher.py,sha256=pupoOf17S5RYLVCPeNYidreTHgLEn7MLiKFnIFVz8Os,1277
152
+ fleetpull/network/contract/envelopes.py,sha256=A9pk7NAKZlQFpLmBAS1Dnumb7FC9EgwyLG4vXDrt5sg,6578
153
+ fleetpull/network/contract/outcome.py,sha256=dWmqJ8bUWmtB3OvKj-0matrmIh_hCgpuVeLHmVmFrfM,1660
154
+ fleetpull/network/contract/page_decoder.py,sha256=SyXbgHTeNQYWUw8QAKQZ_iImGNs8fh-yV5yd5aoB0G8,3533
155
+ fleetpull/network/contract/request.py,sha256=dNxqERzK2BP8XEPMl7qVnJw894RgUZJdaqW_pMnTwj4,2864
156
+ fleetpull/network/decoders/__init__.py,sha256=RqHLWcMe4eQu3OirV8QQY9qXn5d3PxcvrcAyl675BoU,1504
157
+ fleetpull/network/decoders/_window_stamp.py,sha256=WfJFfbMafQ_g5cuyluB5HrDKTN6-ECHl4PKmkieFe80,3176
158
+ fleetpull/network/decoders/geotab.py,sha256=YvfGa6NKqoUvifrbzw-bYSyoxZWok_ObpCGUjfbHCgM,12071
159
+ fleetpull/network/decoders/motive.py,sha256=blsX3mZOPFFKSkN2RTu6QgomGChSGQyWt9NFO6NZlgE,7276
160
+ fleetpull/network/decoders/motive_reports.py,sha256=k94Rs7YPNARwz2Qj21lbqUICv6w14AdNlty15xOKewk,5434
161
+ fleetpull/network/decoders/samsara.py,sha256=Qh6yxDYJoeRaUdMGKlcxZjzF4TuXkmn2LZHqAEL_Ci8,14197
162
+ fleetpull/network/decoders/samsara_reports.py,sha256=NAi2yo5tqeB1NC06qg1Gv270L-eZGSJP5EoD2A7Db0E,5666
163
+ fleetpull/network/decoders/single_page.py,sha256=B9jpjsc-ZUnSIi4-SAC4B1jHv4hiTsLAQQiSxjCdyKU,1653
164
+ fleetpull/network/limits/__init__.py,sha256=KHo0mKPBMVtLdn1eV36ViHY0UCz26rRD5QAU65aa4pw,356
165
+ fleetpull/network/limits/bucket_math.py,sha256=ROBea1CngCscHfgQtINNrOaMQzjXV_m4jHIsjptWq4I,2068
166
+ fleetpull/network/limits/limiter.py,sha256=ARVJqW6afrdPhmpB1gZq7THng5M_8lD5hxQ04mhSFds,6473
167
+ fleetpull/network/limits/registry.py,sha256=UExF2t2bnBqhPC3V3d8_Ug_6oh_6jJBSvzwgb9EFDAM,3990
168
+ fleetpull/network/posture/__init__.py,sha256=Dx1M2UinOaHA2pi1JiMlZCNFd_Pr_-3AwOFEAP_PUqc,234
169
+ fleetpull/network/posture/client_options.py,sha256=InKeJxI6j3p-s9Jq90BFHHFGeRzRmK3QJxhOqTfME98,3129
170
+ fleetpull/network/retry/__init__.py,sha256=tarB62lZ0d0CzgFdM4ZcPBftmL4506IPQXxDGEaHLcM,302
171
+ fleetpull/network/retry/decision.py,sha256=XNZuAbozf6FcjbOIG0TcwCOxklrmMPVMMU58sYbzKg0,5913
172
+ fleetpull/network/tls/__init__.py,sha256=HYT4B4IeVe8Ec1UUHbn-_36wDGbFMABxANLy1OEkkIA,207
173
+ fleetpull/network/tls/truststore_context.py,sha256=658UBEpP1WWHtVsvQax3f82jw3jBXfIEKkY_0YrP9SM,1334
174
+ fleetpull/orchestrator/__init__.py,sha256=pcQHSeXdPT7kZl9t-ZTBdY0MwzS-GEO6oq0IhYAwzDk,1465
175
+ fleetpull/orchestrator/backfill.py,sha256=2739AI2QVCFqnPKzOTOc6TMYV0xZUCRg5zUF6xQb-m0,5461
176
+ fleetpull/orchestrator/batch.py,sha256=Gner158j2y4ijETu4bmvU3lRoc1B2G7vSLIlJVMEr-E,6016
177
+ fleetpull/orchestrator/bisection.py,sha256=-ZElJ7mHABh3rm79reT8T9Hm21T-2B03p8RFjrF_-To,10873
178
+ fleetpull/orchestrator/drivers.py,sha256=RhDteUayvGquWzVHnjCcvmRp5LFyWeIVN-wYEIR3rM0,15673
179
+ fleetpull/orchestrator/entry.py,sha256=ZCNWad5rPu7asZIzSNVgKcl8v07RTm_SVROgzJ3tLKA,15136
180
+ fleetpull/orchestrator/executors.py,sha256=UwzRVsSempf5nJH7rOdCJEqhHeH3uLaKfDmZwMSyIYo,5633
181
+ fleetpull/orchestrator/fanout.py,sha256=ks05NJ0ajmGNsyI7J0_i8tgU935f1kX1WyLAeLnMekw,7146
182
+ fleetpull/orchestrator/feed_drive.py,sha256=Eru_D3lAtfpnt6ZDt9KMWyv1barL7OfoggyNLcYIOwc,11242
183
+ fleetpull/orchestrator/metadata_projection.py,sha256=3B1BVw05D06x_knONr_dW0n9rwO3SRqXibaTlWuLf_E,7314
184
+ fleetpull/orchestrator/outcome.py,sha256=-bZ0af9LiUGe6emPgtoaiFCfurrXaEwgwO-BJ2ZW7fA,2087
185
+ fleetpull/orchestrator/recording.py,sha256=BrgzsEfnEsrJ_XUX7_iBU1LgnbXqfHtQKOyNcGw3OUQ,3070
186
+ fleetpull/orchestrator/resume.py,sha256=uyL6hzHwKULHaqjpu9FsWPv6OiYeDSXlyII8IEFIL1M,5811
187
+ fleetpull/orchestrator/roster_harvest.py,sha256=EoxO47Xb64_gPzgWyZH9PstN1IuHsn_fSV0ocvvPdoU,5151
188
+ fleetpull/orchestrator/roster_refresh.py,sha256=EctqaLdnb3uuJZ9qkc7KfwjI6VhCn-5j-R7EXeucCac,17618
189
+ fleetpull/orchestrator/runner.py,sha256=3b2shZVKcshAXznFx3bkTBmMiX4NFU1sNX_kkvxEVGI,11480
190
+ fleetpull/orchestrator/shape_resolution.py,sha256=_hu6R1jBln1lmFgy45ro6WGEPfDnbmzeAvgXMW3kZNo,9338
191
+ fleetpull/orchestrator/spine.py,sha256=fnEK2w0-HyZ_BBh-32zivICwBWNdkebuDH3J0MeBqfI,6074
192
+ fleetpull/orchestrator/streaming.py,sha256=JRA0nuEGJH775LjDCTznOhPfR2aIuDAT0arEQVsfHfc,6330
193
+ fleetpull/orchestrator/unit_loop.py,sha256=AJ-0QSnjr7tS_XSUQGnwI7kV6eXoPtMUIivuJvFvILk,12533
194
+ fleetpull/orchestrator/watermark_drive.py,sha256=_xS5EYph0rP5upu_tNG9PqSPhPcdT43u7ncoVjW3E4Q,20031
195
+ fleetpull/paths/__init__.py,sha256=zDcawQBJDXGTC5g3O9UgllQBm3vPFz4baK4BTnuE9d4,413
196
+ fleetpull/paths/datasets.py,sha256=uUubxAVb4HqK9We_TIybMTVcUlYYPg5jrU8ZN2-OYKk,1639
197
+ fleetpull/paths/partitions.py,sha256=C9QoVyLyhdsqEyiMq6UVUSVar-wNqXI4J5Y-0S50jN8,1600
198
+ fleetpull/paths/resolution.py,sha256=0O53CG-W6uRSdqKprMBt6Tz3SXIR17g_8_1qvsD8qno,3508
199
+ fleetpull/polars_typing/__init__.py,sha256=RVhRde18Oq0yAc6mDBajvFKdo2ZCkochCKZI5hMrzbQ,1010
200
+ fleetpull/records/__init__.py,sha256=O_bvCxvSypoPvt6lHmzKDPOEQYQxlGPlWSq3Bklmq3o,827
201
+ fleetpull/records/convert.py,sha256=6Xal1AAwt_l3-xBJ6ASVNQ_0jCPvn-ruHf_LNcIWQf8,2139
202
+ fleetpull/records/dataframe.py,sha256=LaTz98HgzOeP3NIOwvxomj7MzTSZGFjcLBWBDyUUyhk,2077
203
+ fleetpull/records/event_time.py,sha256=o9R0XNmTcDxzyFWw9z5T-gPASXoNYU-Mei1mAyhvlDQ,3162
204
+ fleetpull/records/fields.py,sha256=IxoWneiM2JTk3qM-72VbtczRSokTt-ktm8CJCIcNnlo,7265
205
+ fleetpull/records/flatten.py,sha256=nDxaD4hO-C5DnN7xEGN-cnf__nfZwHZKMLvKjfYuaIk,2170
206
+ fleetpull/records/roster_members.py,sha256=3Sw9IoODdfod9Puw1NvQY8_GUArVAoPww5Wx88gndxo,3401
207
+ fleetpull/records/schema.py,sha256=jadsvwYriBX9ipFBUczVCJ3KA-b2RpadAD23f37XSUY,2936
208
+ fleetpull/records/validation.py,sha256=NoCFh39xDzwg_zMhSxeQtpujGzijYA0XsfbsokNqlr4,2283
209
+ fleetpull/resources/__init__.py,sha256=S2n56HNkvyEZ23GUeKWFuu60-OEaNamLcTcZMFIHQUM,393
210
+ fleetpull/resources/config.example.yaml,sha256=jcN1Q2KTdvcxePd77yDma8oJXJBQL-X8ydYgkIs1fas,8716
211
+ fleetpull/roster/__init__.py,sha256=Z_MmMtXHnvPr36U-1j2PSRmPL3SG6UpzoW0qF1wkikY,844
212
+ fleetpull/roster/definition.py,sha256=-UfSKWaclPxnN_TmMgy_HSIVfLhH6BNskK9saLi-nV8,1997
213
+ fleetpull/roster/key.py,sha256=rMAZxQ3ZU3RYgAZVWMTgEcz2HcXz42DkORBBV-zfHeE,1709
214
+ fleetpull/roster/registry.py,sha256=fTjKMjNKBWO_ow6rTtEVajEu6KjttawTsR5ahyDnOps,3639
215
+ fleetpull/state/__init__.py,sha256=kAMbo_NGYoEMCwJ_zp1IMvgmkXDFy3NYbtN255DOHYo,1090
216
+ fleetpull/state/cursors.py,sha256=mTKQK2I_B1ngEhU0HbpXhqtefGhWlKDwQSy2IuBMeuA,18497
217
+ fleetpull/state/database.py,sha256=zojxpQ5AnR69Uc7QsSsOEeGVQ_3vF3tJm2w5Tkk2zgc,18938
218
+ fleetpull/state/migrations.py,sha256=ymx3jrpG0BQeIE4w9bMqvZ2_XPVwvhATyPRliZG9cLg,18028
219
+ fleetpull/state/reconcile.py,sha256=-LDn6R5Z7rNIMHjrHnFnHoENwo6Z7F31jrA20Gh9agM,5255
220
+ fleetpull/state/rosters.py,sha256=7vOeXjw3RwZGLTdKKUALLI4tkk597qfGsUGwjTRf0fQ,5872
221
+ fleetpull/state/run_ledger.py,sha256=dzjgq053KbDh8QlnAvMOQfGTZs_5djX90JLjg6W8sKM,23506
222
+ fleetpull/state/work_units.py,sha256=7mf1BST1yv1a02ENQjSaa8e2ptj2gAbXB1BREmLLQjY,26148
223
+ fleetpull/storage/__init__.py,sha256=p1QMADq4x9jnFRQuoS23yDi-xRJ8P6EXfczjxB-G-qU,1144
224
+ fleetpull/storage/append.py,sha256=4RbsyLERioYdZmQ7EWsYVn0l9VcEbpLYaTC9t18RLNk,8414
225
+ fleetpull/storage/atomic.py,sha256=m8yfj62F1QmEw0S0aE8xgtzMjjc_tgJNICXusvS6mWY,6174
226
+ fleetpull/storage/files.py,sha256=VWgr5bKSdUYAcYN_ObfxKBdQ7ol6FJimFJAtDGUY2x4,6277
227
+ fleetpull/storage/frames.py,sha256=RqwmR8UEKcuX9w4RiMCLloblaUq0FwahPYrPH9tac_I,4362
228
+ fleetpull/storage/metadata.py,sha256=g5DbuWM8SJiVaCYaYRcFA7C9uVLz8ES3WwEoByk4-C0,6282
229
+ fleetpull/storage/partitioned.py,sha256=vLkol7r7w3P3yZ7pAk4EpNP_Pm0XSn_pWk4MGEKHzSY,8887
230
+ fleetpull/storage/pruning.py,sha256=aNTfgF0ZBMsv1gx-rh44CVtqarh-PYpjK9rNoT2oNP8,7362
231
+ fleetpull/storage/read.py,sha256=q0ui538MFr5G437DvdBzlFsX5Ylc4MzvSbdpJxKVQ-A,1186
232
+ fleetpull/storage/result.py,sha256=BVz8KKFwlJ28HJhnT3rahJMM0H8j32ISraXjjgPJkTo,1255
233
+ fleetpull/storage/single_file.py,sha256=Y6PPBvNDCiiN7ELot9T_PXZ_2SKYBG_0GL1Ac5e6nAE,4788
234
+ fleetpull/storage/splitting.py,sha256=ZmmBbXqhr2i2byeQYggOPgp93DwU5_v6mYfnmRE-Cac,4332
235
+ fleetpull/storage/staging.py,sha256=GC-CF65WW0uhGHD3TNOPII5AM1TJkkwfz2Ah8ifap10,7583
236
+ fleetpull/storage/writers.py,sha256=P_eIFD32o5By1sJ0FpxaOF41cHrui3PkijRqKQTnQmE,6124
237
+ fleetpull/timing/__init__.py,sha256=ZfUr5i7Mcl6Ylu1jp7RdxOueeHXny8usb2juyZONubE,657
238
+ fleetpull/timing/canon.py,sha256=L1ex_L9lI-CFXOf2l-K02HaJD98KVhsIFxHcoraI8G4,3598
239
+ fleetpull/timing/clock.py,sha256=RRR5-iwDCmFEf9c-CaiCVEYgu93p37URKMLdPO18C9w,5919
240
+ fleetpull/timing/codec.py,sha256=K8r6kzXrVXUhjSvDTNC5D_jUiDv6tDsQ4tMFhnqaSks,4606
241
+ fleetpull/timing/sleeper.py,sha256=Wx66OECOwxUmD0v8WrS5x_mk07P29GKg-lJVkhRbXCg,1907
242
+ fleetpull/vocabulary/__init__.py,sha256=sFdyu4CpzYzJUk38qgBmW4mANccaQj9YCQj4JAQs6A4,480
243
+ fleetpull/vocabulary/json_types.py,sha256=kdhZeZfAUKGBqeyuS8d8szaqByUloMIDYfmD-Rqh51s,1056
244
+ fleetpull/vocabulary/provider.py,sha256=l9Bqs1blTx50_bWIJDVTdYXCXKXSo5yz-fjxtfGZeeU,873
245
+ fleetpull/vocabulary/quota_scope.py,sha256=sQ9jmgzF_Mix7Et5M81-b5cYNrKp1TtnQbBrHTA8H-0,2141
246
+ fleetpull/vocabulary/response_category.py,sha256=50Y29EfYvMPWk28OsyxyFwUzapud7r2IBJeTTAf_78A,1127
247
+ fleetpull-0.1.0.dist-info/licenses/LICENSE,sha256=slaLMVe8BZ4G4i6f3E1v7j3w3v8Y4wza6_eQes7jQ4Y,11344
248
+ fleetpull-0.1.0.dist-info/METADATA,sha256=Q90u5wTrWo2MRF8hG7JkNQYJO2Uilu5O6vzLhW5oL-c,9537
249
+ fleetpull-0.1.0.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
250
+ fleetpull-0.1.0.dist-info/entry_points.txt,sha256=F9c7C14dXv7k0D99ePunKpp2dhGQB7niPpyMMU5dkSY,49
251
+ fleetpull-0.1.0.dist-info/top_level.txt,sha256=rES5-1Bq4kwS2crMdI8hYnVzvQdfggJ0PQelCALpUts,10
252
+ fleetpull-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (83.0.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ fleetpull = fleetpull.cli:main