spatialflow 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 (404) hide show
  1. spatialflow/__init__.py +91 -0
  2. spatialflow/_generated/.github/workflows/python.yml +31 -0
  3. spatialflow/_generated/.gitignore +66 -0
  4. spatialflow/_generated/.gitlab-ci.yml +31 -0
  5. spatialflow/_generated/.openapi-generator/FILES +390 -0
  6. spatialflow/_generated/.openapi-generator/VERSION +1 -0
  7. spatialflow/_generated/.openapi-generator-ignore +23 -0
  8. spatialflow/_generated/.spec-hash +1 -0
  9. spatialflow/_generated/.travis.yml +17 -0
  10. spatialflow/_generated/README.md +537 -0
  11. spatialflow/_generated/__init__.py +1 -0
  12. spatialflow/_generated/docs/APIUsageStats.md +32 -0
  13. spatialflow/_generated/docs/AccountApi.md +1751 -0
  14. spatialflow/_generated/docs/ActionDeliverySuccessMetrics.md +32 -0
  15. spatialflow/_generated/docs/ActionResponse.md +32 -0
  16. spatialflow/_generated/docs/ActionRetryConfigSchema.md +32 -0
  17. spatialflow/_generated/docs/ActivitySummary.md +30 -0
  18. spatialflow/_generated/docs/AdminApi.md +1787 -0
  19. spatialflow/_generated/docs/ApiKeyCreateRequest.md +31 -0
  20. spatialflow/_generated/docs/ApiKeyCreateResponse.md +31 -0
  21. spatialflow/_generated/docs/ApiKeyResponse.md +38 -0
  22. spatialflow/_generated/docs/ApiKeyUpdateRequest.md +33 -0
  23. spatialflow/_generated/docs/AsyncUploadGeofencesResponse.md +33 -0
  24. spatialflow/_generated/docs/AuthTypeEnum.md +17 -0
  25. spatialflow/_generated/docs/AuthenticationApi.md +1289 -0
  26. spatialflow/_generated/docs/BatchLocationUpdateIn.md +30 -0
  27. spatialflow/_generated/docs/BillingApi.md +925 -0
  28. spatialflow/_generated/docs/BulkGeofenceRequest.md +29 -0
  29. spatialflow/_generated/docs/ChangePasswordSchema.md +30 -0
  30. spatialflow/_generated/docs/CheckoutSessionRequest.md +32 -0
  31. spatialflow/_generated/docs/CheckoutSessionResponse.md +31 -0
  32. spatialflow/_generated/docs/CircuitBreakerSchema.md +33 -0
  33. spatialflow/_generated/docs/ConfigFieldDefinitionRequest.md +41 -0
  34. spatialflow/_generated/docs/ConfigFieldDefinitionResponse.md +43 -0
  35. spatialflow/_generated/docs/ConfirmPasswordResetSchema.md +31 -0
  36. spatialflow/_generated/docs/CreateFromTemplateIn.md +30 -0
  37. spatialflow/_generated/docs/CreateGeofenceRequest.md +36 -0
  38. spatialflow/_generated/docs/CreateIntegrationSchema.md +33 -0
  39. spatialflow/_generated/docs/CreateUserSchema.md +35 -0
  40. spatialflow/_generated/docs/CreateWebhookRequest.md +43 -0
  41. spatialflow/_generated/docs/DashboardComparisonMetrics.md +32 -0
  42. spatialflow/_generated/docs/DashboardMetricsResponse.md +36 -0
  43. spatialflow/_generated/docs/DefaultApi.md +585 -0
  44. spatialflow/_generated/docs/DeleteFileResponse.md +30 -0
  45. spatialflow/_generated/docs/DeliveryStatusEnum.md +15 -0
  46. spatialflow/_generated/docs/DeviceIn.md +32 -0
  47. spatialflow/_generated/docs/DeviceOut.md +37 -0
  48. spatialflow/_generated/docs/DevicesApi.md +1213 -0
  49. spatialflow/_generated/docs/E2ETestApi.md +271 -0
  50. spatialflow/_generated/docs/EmailApi.md +541 -0
  51. spatialflow/_generated/docs/EmailHealthResponse.md +31 -0
  52. spatialflow/_generated/docs/EmailQueueStats.md +34 -0
  53. spatialflow/_generated/docs/EmailStats.md +31 -0
  54. spatialflow/_generated/docs/EmailStatusResponse.md +36 -0
  55. spatialflow/_generated/docs/ErrorResponse.md +32 -0
  56. spatialflow/_generated/docs/ExecutionOut.md +38 -0
  57. spatialflow/_generated/docs/ExportIntegrationSchema.md +35 -0
  58. spatialflow/_generated/docs/FileListResponse.md +31 -0
  59. spatialflow/_generated/docs/ForgotPasswordSchema.md +29 -0
  60. spatialflow/_generated/docs/GPXPlaybackOut.md +42 -0
  61. spatialflow/_generated/docs/GPXRouteOut.md +40 -0
  62. spatialflow/_generated/docs/GPXSimulatorApi.md +883 -0
  63. spatialflow/_generated/docs/GeoJSONPoint.md +31 -0
  64. spatialflow/_generated/docs/GeofenceListResponse.md +31 -0
  65. spatialflow/_generated/docs/GeofenceResponse.md +43 -0
  66. spatialflow/_generated/docs/GeofenceStats.md +30 -0
  67. spatialflow/_generated/docs/GeofenceTestResult.md +33 -0
  68. spatialflow/_generated/docs/GeofencesApi.md +1524 -0
  69. spatialflow/_generated/docs/HealthCheckResponse.md +31 -0
  70. spatialflow/_generated/docs/HealthResponse.md +32 -0
  71. spatialflow/_generated/docs/ImportIntegrationSchema.md +32 -0
  72. spatialflow/_generated/docs/ImportResultSchema.md +33 -0
  73. spatialflow/_generated/docs/IntegrationDetailSchema.md +44 -0
  74. spatialflow/_generated/docs/IntegrationResponseSchema.md +42 -0
  75. spatialflow/_generated/docs/IntegrationStatsSchema.md +36 -0
  76. spatialflow/_generated/docs/IntegrationTypeListResponse.md +34 -0
  77. spatialflow/_generated/docs/IntegrationTypeRequest.md +40 -0
  78. spatialflow/_generated/docs/IntegrationTypeResponse.md +45 -0
  79. spatialflow/_generated/docs/IntegrationsApi.md +2008 -0
  80. spatialflow/_generated/docs/InvoiceLineItem.md +33 -0
  81. spatialflow/_generated/docs/InvoiceListResponse.md +31 -0
  82. spatialflow/_generated/docs/InvoiceResponse.md +40 -0
  83. spatialflow/_generated/docs/LocationBatchIn.md +31 -0
  84. spatialflow/_generated/docs/LocationImportResponse.md +41 -0
  85. spatialflow/_generated/docs/LocationIngestResponse.md +35 -0
  86. spatialflow/_generated/docs/LocationPointIn.md +38 -0
  87. spatialflow/_generated/docs/LocationUpdateIn.md +36 -0
  88. spatialflow/_generated/docs/LocationUpdateOut.md +32 -0
  89. spatialflow/_generated/docs/LoginResponse.md +33 -0
  90. spatialflow/_generated/docs/LoginSchema.md +30 -0
  91. spatialflow/_generated/docs/MemberActionResponse.md +33 -0
  92. spatialflow/_generated/docs/MemberSummary.md +36 -0
  93. spatialflow/_generated/docs/MethodEnum.md +17 -0
  94. spatialflow/_generated/docs/OAuthAuthorizeResponse.md +29 -0
  95. spatialflow/_generated/docs/OAuthCallbackQuery.md +32 -0
  96. spatialflow/_generated/docs/OAuthLinkResponse.md +31 -0
  97. spatialflow/_generated/docs/OAuthProvidersResponse.md +29 -0
  98. spatialflow/_generated/docs/OnboardingProgressResponse.md +37 -0
  99. spatialflow/_generated/docs/PaymentMethodResponse.md +37 -0
  100. spatialflow/_generated/docs/PingResponse.md +31 -0
  101. spatialflow/_generated/docs/PlanChangePreviewResponse.md +35 -0
  102. spatialflow/_generated/docs/PlanFeatures.md +36 -0
  103. spatialflow/_generated/docs/PlanLimits.md +34 -0
  104. spatialflow/_generated/docs/PlanResponse.md +37 -0
  105. spatialflow/_generated/docs/PortalSessionRequest.md +30 -0
  106. spatialflow/_generated/docs/PortalSessionResponse.md +30 -0
  107. spatialflow/_generated/docs/PresignedUrlRequest.md +31 -0
  108. spatialflow/_generated/docs/PresignedUrlResponse.md +35 -0
  109. spatialflow/_generated/docs/PrivacyErasureRequest.md +35 -0
  110. spatialflow/_generated/docs/PrivacyErasureResponse.md +36 -0
  111. spatialflow/_generated/docs/PublicApi.md +389 -0
  112. spatialflow/_generated/docs/PublicLocationIngestApi.md +249 -0
  113. spatialflow/_generated/docs/RateLimitResponse.md +32 -0
  114. spatialflow/_generated/docs/RecentActivity.md +31 -0
  115. spatialflow/_generated/docs/RefreshTokenSchema.md +29 -0
  116. spatialflow/_generated/docs/RegisterSchema.md +37 -0
  117. spatialflow/_generated/docs/ResendVerificationSchema.md +29 -0
  118. spatialflow/_generated/docs/ResetPasswordSchema.md +31 -0
  119. spatialflow/_generated/docs/RetryPolicyResponseSchema.md +32 -0
  120. spatialflow/_generated/docs/RetryPolicySchema.md +35 -0
  121. spatialflow/_generated/docs/RetryStrategyEnum.md +14 -0
  122. spatialflow/_generated/docs/SeedDataResponseSchema.md +31 -0
  123. spatialflow/_generated/docs/SendEmailRequest.md +33 -0
  124. spatialflow/_generated/docs/SetupIntentResponse.md +30 -0
  125. spatialflow/_generated/docs/SignupRequest.md +40 -0
  126. spatialflow/_generated/docs/StartPlaybackRequest.md +30 -0
  127. spatialflow/_generated/docs/StorageApi.md +494 -0
  128. spatialflow/_generated/docs/SubscriptionActionResponse.md +32 -0
  129. spatialflow/_generated/docs/SubscriptionResponse.md +36 -0
  130. spatialflow/_generated/docs/SubscriptionsApi.md +677 -0
  131. spatialflow/_generated/docs/SuccessResponse.md +31 -0
  132. spatialflow/_generated/docs/SystemApi.md +137 -0
  133. spatialflow/_generated/docs/TemplateOut.md +35 -0
  134. spatialflow/_generated/docs/TestEventRequest.md +29 -0
  135. spatialflow/_generated/docs/TestIntegrationResponseSchema.md +31 -0
  136. spatialflow/_generated/docs/TestPointRequest.md +34 -0
  137. spatialflow/_generated/docs/TestPointResponse.md +33 -0
  138. spatialflow/_generated/docs/TestWebhookRequest.md +32 -0
  139. spatialflow/_generated/docs/TestWorkflowIn.md +29 -0
  140. spatialflow/_generated/docs/TileMetadata.md +36 -0
  141. spatialflow/_generated/docs/TilesApi.md +462 -0
  142. spatialflow/_generated/docs/UnsubscribeRequest.md +29 -0
  143. spatialflow/_generated/docs/UnsubscribeResponse.md +31 -0
  144. spatialflow/_generated/docs/UpdateGeofenceRequest.md +37 -0
  145. spatialflow/_generated/docs/UpdateIntegrationSchema.md +33 -0
  146. spatialflow/_generated/docs/UpdateMemberRoleRequest.md +30 -0
  147. spatialflow/_generated/docs/UpdateOnboardingProgressRequest.md +30 -0
  148. spatialflow/_generated/docs/UpdateProfileRequest.md +45 -0
  149. spatialflow/_generated/docs/UpdateUserWorkspaceRequest.md +31 -0
  150. spatialflow/_generated/docs/UpdateWebhookRequest.md +43 -0
  151. spatialflow/_generated/docs/UploadGeofencesRequest.md +31 -0
  152. spatialflow/_generated/docs/UploadJobStatus.md +42 -0
  153. spatialflow/_generated/docs/UsageMetrics.md +33 -0
  154. spatialflow/_generated/docs/UsageResponse.md +36 -0
  155. spatialflow/_generated/docs/UsageStats.md +32 -0
  156. spatialflow/_generated/docs/UserActionResponse.md +35 -0
  157. spatialflow/_generated/docs/UserApprovalRequest.md +30 -0
  158. spatialflow/_generated/docs/UserInviteRequest.md +33 -0
  159. spatialflow/_generated/docs/UserInviteResponse.md +36 -0
  160. spatialflow/_generated/docs/UserListResponse.md +34 -0
  161. spatialflow/_generated/docs/UserProfileResponse.md +55 -0
  162. spatialflow/_generated/docs/UserRejectionRequest.md +30 -0
  163. spatialflow/_generated/docs/UserResponse.md +44 -0
  164. spatialflow/_generated/docs/UserSummary.md +41 -0
  165. spatialflow/_generated/docs/UserUsageResponse.md +38 -0
  166. spatialflow/_generated/docs/UserWorkspaceResponse.md +34 -0
  167. spatialflow/_generated/docs/WebhookDeliveryDetailResponse.md +49 -0
  168. spatialflow/_generated/docs/WebhookDeliveryListResponse.md +31 -0
  169. spatialflow/_generated/docs/WebhookDeliveryResponse.md +46 -0
  170. spatialflow/_generated/docs/WebhookListResponse.md +31 -0
  171. spatialflow/_generated/docs/WebhookMetricsResponse.md +31 -0
  172. spatialflow/_generated/docs/WebhookResponse.md +50 -0
  173. spatialflow/_generated/docs/WebhookTestResponse.md +36 -0
  174. spatialflow/_generated/docs/WebhooksApi.md +1384 -0
  175. spatialflow/_generated/docs/WorkflowImportSchema.md +30 -0
  176. spatialflow/_generated/docs/WorkflowIn.md +32 -0
  177. spatialflow/_generated/docs/WorkflowListOut.md +39 -0
  178. spatialflow/_generated/docs/WorkflowListResponse.md +32 -0
  179. spatialflow/_generated/docs/WorkflowOut.md +42 -0
  180. spatialflow/_generated/docs/WorkflowRetryPolicyUpdateSchema.md +32 -0
  181. spatialflow/_generated/docs/WorkflowStepRetrySchema.md +33 -0
  182. spatialflow/_generated/docs/WorkflowUpdate.md +33 -0
  183. spatialflow/_generated/docs/WorkflowsApi.md +2599 -0
  184. spatialflow/_generated/docs/WorkspaceDeleteResponse.md +33 -0
  185. spatialflow/_generated/docs/WorkspaceDetail.md +37 -0
  186. spatialflow/_generated/docs/WorkspaceDetailResponse.md +41 -0
  187. spatialflow/_generated/docs/WorkspaceIn.md +34 -0
  188. spatialflow/_generated/docs/WorkspaceListItem.md +39 -0
  189. spatialflow/_generated/docs/WorkspaceListResponse.md +34 -0
  190. spatialflow/_generated/docs/WorkspaceMembersResponse.md +35 -0
  191. spatialflow/_generated/docs/WorkspaceOut.md +38 -0
  192. spatialflow/_generated/docs/WorkspaceSummary.md +32 -0
  193. spatialflow/_generated/docs/WorkspaceUpdateRequest.md +34 -0
  194. spatialflow/_generated/docs/WorkspaceUpdateResponse.md +33 -0
  195. spatialflow/_generated/docs/WorkspacesApi.md +241 -0
  196. spatialflow/_generated/git_push.sh +57 -0
  197. spatialflow/_generated/pyproject.toml +91 -0
  198. spatialflow/_generated/requirements.txt +6 -0
  199. spatialflow/_generated/setup.cfg +2 -0
  200. spatialflow/_generated/setup.py +51 -0
  201. spatialflow/_generated/spatialflow_generated/__init__.py +216 -0
  202. spatialflow/_generated/spatialflow_generated/api/__init__.py +24 -0
  203. spatialflow/_generated/spatialflow_generated/api/account_api.py +5675 -0
  204. spatialflow/_generated/spatialflow_generated/api/admin_api.py +6173 -0
  205. spatialflow/_generated/spatialflow_generated/api/authentication_api.py +4753 -0
  206. spatialflow/_generated/spatialflow_generated/api/billing_api.py +3151 -0
  207. spatialflow/_generated/spatialflow_generated/api/default_api.py +2157 -0
  208. spatialflow/_generated/spatialflow_generated/api/devices_api.py +3965 -0
  209. spatialflow/_generated/spatialflow_generated/api/e2_e_test_api.py +1049 -0
  210. spatialflow/_generated/spatialflow_generated/api/email_api.py +1879 -0
  211. spatialflow/_generated/spatialflow_generated/api/geofences_api.py +4899 -0
  212. spatialflow/_generated/spatialflow_generated/api/gpx_simulator_api.py +2824 -0
  213. spatialflow/_generated/spatialflow_generated/api/integrations_api.py +6952 -0
  214. spatialflow/_generated/spatialflow_generated/api/public_api.py +1506 -0
  215. spatialflow/_generated/spatialflow_generated/api/public_location_ingest_api.py +845 -0
  216. spatialflow/_generated/spatialflow_generated/api/storage_api.py +1642 -0
  217. spatialflow/_generated/spatialflow_generated/api/subscriptions_api.py +2356 -0
  218. spatialflow/_generated/spatialflow_generated/api/system_api.py +529 -0
  219. spatialflow/_generated/spatialflow_generated/api/tiles_api.py +1626 -0
  220. spatialflow/_generated/spatialflow_generated/api/webhooks_api.py +4579 -0
  221. spatialflow/_generated/spatialflow_generated/api/workflows_api.py +8334 -0
  222. spatialflow/_generated/spatialflow_generated/api/workspaces_api.py +813 -0
  223. spatialflow/_generated/spatialflow_generated/api_client.py +800 -0
  224. spatialflow/_generated/spatialflow_generated/api_response.py +21 -0
  225. spatialflow/_generated/spatialflow_generated/configuration.py +599 -0
  226. spatialflow/_generated/spatialflow_generated/exceptions.py +199 -0
  227. spatialflow/_generated/spatialflow_generated/models/__init__.py +180 -0
  228. spatialflow/_generated/spatialflow_generated/models/action_delivery_success_metrics.py +96 -0
  229. spatialflow/_generated/spatialflow_generated/models/action_response.py +96 -0
  230. spatialflow/_generated/spatialflow_generated/models/action_retry_config_schema.py +114 -0
  231. spatialflow/_generated/spatialflow_generated/models/activity_summary.py +89 -0
  232. spatialflow/_generated/spatialflow_generated/models/api_key_create_request.py +95 -0
  233. spatialflow/_generated/spatialflow_generated/models/api_key_create_response.py +89 -0
  234. spatialflow/_generated/spatialflow_generated/models/api_key_response.py +109 -0
  235. spatialflow/_generated/spatialflow_generated/models/api_key_update_request.py +114 -0
  236. spatialflow/_generated/spatialflow_generated/models/api_usage_stats.py +98 -0
  237. spatialflow/_generated/spatialflow_generated/models/async_upload_geofences_response.py +93 -0
  238. spatialflow/_generated/spatialflow_generated/models/auth_type_enum.py +39 -0
  239. spatialflow/_generated/spatialflow_generated/models/batch_location_update_in.py +97 -0
  240. spatialflow/_generated/spatialflow_generated/models/bulk_geofence_request.py +95 -0
  241. spatialflow/_generated/spatialflow_generated/models/change_password_schema.py +89 -0
  242. spatialflow/_generated/spatialflow_generated/models/checkout_session_request.py +91 -0
  243. spatialflow/_generated/spatialflow_generated/models/checkout_session_response.py +89 -0
  244. spatialflow/_generated/spatialflow_generated/models/circuit_breaker_schema.py +94 -0
  245. spatialflow/_generated/spatialflow_generated/models/config_field_definition_request.py +134 -0
  246. spatialflow/_generated/spatialflow_generated/models/config_field_definition_response.py +138 -0
  247. spatialflow/_generated/spatialflow_generated/models/confirm_password_reset_schema.py +89 -0
  248. spatialflow/_generated/spatialflow_generated/models/create_from_template_in.py +94 -0
  249. spatialflow/_generated/spatialflow_generated/models/create_geofence_request.py +125 -0
  250. spatialflow/_generated/spatialflow_generated/models/create_integration_schema.py +106 -0
  251. spatialflow/_generated/spatialflow_generated/models/create_user_schema.py +99 -0
  252. spatialflow/_generated/spatialflow_generated/models/create_webhook_request.py +136 -0
  253. spatialflow/_generated/spatialflow_generated/models/dashboard_comparison_metrics.py +96 -0
  254. spatialflow/_generated/spatialflow_generated/models/dashboard_metrics_response.py +108 -0
  255. spatialflow/_generated/spatialflow_generated/models/delete_file_response.py +89 -0
  256. spatialflow/_generated/spatialflow_generated/models/delivery_status_enum.py +38 -0
  257. spatialflow/_generated/spatialflow_generated/models/device_in.py +98 -0
  258. spatialflow/_generated/spatialflow_generated/models/device_out.py +114 -0
  259. spatialflow/_generated/spatialflow_generated/models/email_health_response.py +92 -0
  260. spatialflow/_generated/spatialflow_generated/models/email_queue_stats.py +97 -0
  261. spatialflow/_generated/spatialflow_generated/models/email_stats.py +91 -0
  262. spatialflow/_generated/spatialflow_generated/models/email_status_response.py +112 -0
  263. spatialflow/_generated/spatialflow_generated/models/error_response.py +101 -0
  264. spatialflow/_generated/spatialflow_generated/models/execution_out.py +126 -0
  265. spatialflow/_generated/spatialflow_generated/models/export_integration_schema.py +97 -0
  266. spatialflow/_generated/spatialflow_generated/models/file_list_response.py +91 -0
  267. spatialflow/_generated/spatialflow_generated/models/forgot_password_schema.py +87 -0
  268. spatialflow/_generated/spatialflow_generated/models/geo_json_point.py +97 -0
  269. spatialflow/_generated/spatialflow_generated/models/geofence_list_response.py +97 -0
  270. spatialflow/_generated/spatialflow_generated/models/geofence_response.py +139 -0
  271. spatialflow/_generated/spatialflow_generated/models/geofence_stats.py +89 -0
  272. spatialflow/_generated/spatialflow_generated/models/geofence_test_result.py +98 -0
  273. spatialflow/_generated/spatialflow_generated/models/gpx_playback_out.py +128 -0
  274. spatialflow/_generated/spatialflow_generated/models/gpx_route_out.py +119 -0
  275. spatialflow/_generated/spatialflow_generated/models/health_check_response.py +91 -0
  276. spatialflow/_generated/spatialflow_generated/models/health_response.py +91 -0
  277. spatialflow/_generated/spatialflow_generated/models/import_integration_schema.py +100 -0
  278. spatialflow/_generated/spatialflow_generated/models/import_result_schema.py +103 -0
  279. spatialflow/_generated/spatialflow_generated/models/integration_detail_schema.py +125 -0
  280. spatialflow/_generated/spatialflow_generated/models/integration_response_schema.py +123 -0
  281. spatialflow/_generated/spatialflow_generated/models/integration_stats_schema.py +116 -0
  282. spatialflow/_generated/spatialflow_generated/models/integration_type_list_response.py +103 -0
  283. spatialflow/_generated/spatialflow_generated/models/integration_type_request.py +117 -0
  284. spatialflow/_generated/spatialflow_generated/models/integration_type_response.py +128 -0
  285. spatialflow/_generated/spatialflow_generated/models/invoice_line_item.py +93 -0
  286. spatialflow/_generated/spatialflow_generated/models/invoice_list_response.py +97 -0
  287. spatialflow/_generated/spatialflow_generated/models/invoice_response.py +120 -0
  288. spatialflow/_generated/spatialflow_generated/models/location_batch_in.py +102 -0
  289. spatialflow/_generated/spatialflow_generated/models/location_import_response.py +120 -0
  290. spatialflow/_generated/spatialflow_generated/models/location_ingest_response.py +117 -0
  291. spatialflow/_generated/spatialflow_generated/models/location_point_in.py +129 -0
  292. spatialflow/_generated/spatialflow_generated/models/location_update_in.py +132 -0
  293. spatialflow/_generated/spatialflow_generated/models/location_update_out.py +93 -0
  294. spatialflow/_generated/spatialflow_generated/models/login_response.py +95 -0
  295. spatialflow/_generated/spatialflow_generated/models/login_schema.py +89 -0
  296. spatialflow/_generated/spatialflow_generated/models/member_action_response.py +98 -0
  297. spatialflow/_generated/spatialflow_generated/models/member_summary.py +114 -0
  298. spatialflow/_generated/spatialflow_generated/models/method_enum.py +39 -0
  299. spatialflow/_generated/spatialflow_generated/models/o_auth_authorize_response.py +87 -0
  300. spatialflow/_generated/spatialflow_generated/models/o_auth_callback_query.py +103 -0
  301. spatialflow/_generated/spatialflow_generated/models/o_auth_link_response.py +91 -0
  302. spatialflow/_generated/spatialflow_generated/models/o_auth_providers_response.py +87 -0
  303. spatialflow/_generated/spatialflow_generated/models/onboarding_progress_response.py +112 -0
  304. spatialflow/_generated/spatialflow_generated/models/payment_method_response.py +116 -0
  305. spatialflow/_generated/spatialflow_generated/models/ping_response.py +91 -0
  306. spatialflow/_generated/spatialflow_generated/models/plan_change_preview_response.py +104 -0
  307. spatialflow/_generated/spatialflow_generated/models/plan_features.py +109 -0
  308. spatialflow/_generated/spatialflow_generated/models/plan_limits.py +95 -0
  309. spatialflow/_generated/spatialflow_generated/models/plan_response.py +114 -0
  310. spatialflow/_generated/spatialflow_generated/models/portal_session_request.py +87 -0
  311. spatialflow/_generated/spatialflow_generated/models/portal_session_response.py +87 -0
  312. spatialflow/_generated/spatialflow_generated/models/presigned_url_request.py +91 -0
  313. spatialflow/_generated/spatialflow_generated/models/presigned_url_response.py +99 -0
  314. spatialflow/_generated/spatialflow_generated/models/privacy_erasure_request.py +118 -0
  315. spatialflow/_generated/spatialflow_generated/models/privacy_erasure_response.py +110 -0
  316. spatialflow/_generated/spatialflow_generated/models/rate_limit_response.py +91 -0
  317. spatialflow/_generated/spatialflow_generated/models/recent_activity.py +91 -0
  318. spatialflow/_generated/spatialflow_generated/models/refresh_token_schema.py +87 -0
  319. spatialflow/_generated/spatialflow_generated/models/register_schema.py +133 -0
  320. spatialflow/_generated/spatialflow_generated/models/resend_verification_schema.py +87 -0
  321. spatialflow/_generated/spatialflow_generated/models/reset_password_schema.py +91 -0
  322. spatialflow/_generated/spatialflow_generated/models/retry_policy_response_schema.py +95 -0
  323. spatialflow/_generated/spatialflow_generated/models/retry_policy_schema.py +99 -0
  324. spatialflow/_generated/spatialflow_generated/models/retry_strategy_enum.py +38 -0
  325. spatialflow/_generated/spatialflow_generated/models/seed_data_response_schema.py +91 -0
  326. spatialflow/_generated/spatialflow_generated/models/send_email_request.py +100 -0
  327. spatialflow/_generated/spatialflow_generated/models/setup_intent_response.py +87 -0
  328. spatialflow/_generated/spatialflow_generated/models/signup_request.py +164 -0
  329. spatialflow/_generated/spatialflow_generated/models/start_playback_request.py +89 -0
  330. spatialflow/_generated/spatialflow_generated/models/subscription_action_response.py +100 -0
  331. spatialflow/_generated/spatialflow_generated/models/subscription_response.py +113 -0
  332. spatialflow/_generated/spatialflow_generated/models/success_response.py +94 -0
  333. spatialflow/_generated/spatialflow_generated/models/template_out.py +104 -0
  334. spatialflow/_generated/spatialflow_generated/models/test_event_request.py +92 -0
  335. spatialflow/_generated/spatialflow_generated/models/test_integration_response_schema.py +91 -0
  336. spatialflow/_generated/spatialflow_generated/models/test_point_request.py +125 -0
  337. spatialflow/_generated/spatialflow_generated/models/test_point_response.py +101 -0
  338. spatialflow/_generated/spatialflow_generated/models/test_webhook_request.py +106 -0
  339. spatialflow/_generated/spatialflow_generated/models/test_workflow_in.py +87 -0
  340. spatialflow/_generated/spatialflow_generated/models/tile_metadata.py +99 -0
  341. spatialflow/_generated/spatialflow_generated/models/unsubscribe_request.py +87 -0
  342. spatialflow/_generated/spatialflow_generated/models/unsubscribe_response.py +91 -0
  343. spatialflow/_generated/spatialflow_generated/models/update_geofence_request.py +142 -0
  344. spatialflow/_generated/spatialflow_generated/models/update_integration_schema.py +121 -0
  345. spatialflow/_generated/spatialflow_generated/models/update_member_role_request.py +87 -0
  346. spatialflow/_generated/spatialflow_generated/models/update_onboarding_progress_request.py +87 -0
  347. spatialflow/_generated/spatialflow_generated/models/update_profile_request.py +208 -0
  348. spatialflow/_generated/spatialflow_generated/models/update_user_workspace_request.py +89 -0
  349. spatialflow/_generated/spatialflow_generated/models/update_webhook_request.py +186 -0
  350. spatialflow/_generated/spatialflow_generated/models/upload_geofences_request.py +95 -0
  351. spatialflow/_generated/spatialflow_generated/models/upload_job_status.py +137 -0
  352. spatialflow/_generated/spatialflow_generated/models/usage_metrics.py +93 -0
  353. spatialflow/_generated/spatialflow_generated/models/usage_response.py +105 -0
  354. spatialflow/_generated/spatialflow_generated/models/usage_stats.py +91 -0
  355. spatialflow/_generated/spatialflow_generated/models/user_action_response.py +119 -0
  356. spatialflow/_generated/spatialflow_generated/models/user_approval_request.py +92 -0
  357. spatialflow/_generated/spatialflow_generated/models/user_invite_request.py +110 -0
  358. spatialflow/_generated/spatialflow_generated/models/user_invite_response.py +99 -0
  359. spatialflow/_generated/spatialflow_generated/models/user_list_response.py +110 -0
  360. spatialflow/_generated/spatialflow_generated/models/user_profile_response.py +158 -0
  361. spatialflow/_generated/spatialflow_generated/models/user_rejection_request.py +87 -0
  362. spatialflow/_generated/spatialflow_generated/models/user_response.py +142 -0
  363. spatialflow/_generated/spatialflow_generated/models/user_summary.py +140 -0
  364. spatialflow/_generated/spatialflow_generated/models/user_usage_response.py +152 -0
  365. spatialflow/_generated/spatialflow_generated/models/user_workspace_response.py +110 -0
  366. spatialflow/_generated/spatialflow_generated/models/webhook_delivery_detail_response.py +182 -0
  367. spatialflow/_generated/spatialflow_generated/models/webhook_delivery_list_response.py +97 -0
  368. spatialflow/_generated/spatialflow_generated/models/webhook_delivery_response.py +161 -0
  369. spatialflow/_generated/spatialflow_generated/models/webhook_list_response.py +97 -0
  370. spatialflow/_generated/spatialflow_generated/models/webhook_metrics_response.py +89 -0
  371. spatialflow/_generated/spatialflow_generated/models/webhook_response.py +148 -0
  372. spatialflow/_generated/spatialflow_generated/models/webhook_test_response.py +114 -0
  373. spatialflow/_generated/spatialflow_generated/models/workflow_import_schema.py +89 -0
  374. spatialflow/_generated/spatialflow_generated/models/workflow_in.py +98 -0
  375. spatialflow/_generated/spatialflow_generated/models/workflow_list_out.py +118 -0
  376. spatialflow/_generated/spatialflow_generated/models/workflow_list_response.py +101 -0
  377. spatialflow/_generated/spatialflow_generated/models/workflow_out.py +129 -0
  378. spatialflow/_generated/spatialflow_generated/models/workflow_retry_policy_update_schema.py +109 -0
  379. spatialflow/_generated/spatialflow_generated/models/workflow_step_retry_schema.py +103 -0
  380. spatialflow/_generated/spatialflow_generated/models/workflow_update.py +120 -0
  381. spatialflow/_generated/spatialflow_generated/models/workspace_delete_response.py +93 -0
  382. spatialflow/_generated/spatialflow_generated/models/workspace_detail.py +116 -0
  383. spatialflow/_generated/spatialflow_generated/models/workspace_detail_response.py +143 -0
  384. spatialflow/_generated/spatialflow_generated/models/workspace_in.py +122 -0
  385. spatialflow/_generated/spatialflow_generated/models/workspace_list_item.py +130 -0
  386. spatialflow/_generated/spatialflow_generated/models/workspace_list_response.py +103 -0
  387. spatialflow/_generated/spatialflow_generated/models/workspace_members_response.py +109 -0
  388. spatialflow/_generated/spatialflow_generated/models/workspace_out.py +132 -0
  389. spatialflow/_generated/spatialflow_generated/models/workspace_summary.py +91 -0
  390. spatialflow/_generated/spatialflow_generated/models/workspace_update_request.py +120 -0
  391. spatialflow/_generated/spatialflow_generated/models/workspace_update_response.py +93 -0
  392. spatialflow/_generated/spatialflow_generated/py.typed +0 -0
  393. spatialflow/_generated/spatialflow_generated/rest.py +215 -0
  394. spatialflow/_generated/test-requirements.txt +6 -0
  395. spatialflow/_generated/tox.ini +9 -0
  396. spatialflow/client.py +137 -0
  397. spatialflow/exceptions.py +234 -0
  398. spatialflow/jobs.py +204 -0
  399. spatialflow/pagination.py +142 -0
  400. spatialflow/uploads.py +166 -0
  401. spatialflow/webhooks.py +126 -0
  402. spatialflow-0.1.0.dist-info/METADATA +249 -0
  403. spatialflow-0.1.0.dist-info/RECORD +404 -0
  404. spatialflow-0.1.0.dist-info/WHEEL +4 -0
@@ -0,0 +1,215 @@
1
+ # coding: utf-8
2
+
3
+ """
4
+ SpatialFlow API
5
+
6
+ Real-time geospatial automation platform API. ## Authentication **API Key:** Include `X-API-Key` header **JWT Token:** Include `Authorization: Bearer <token>` header ## Rate Limits - Per API Key: 200 rps sustained, 1,000 rps burst - Per Organization: 1,000 rps aggregate ## Webhook Verification Outbound webhooks include HMAC-SHA256 signatures in `X-SF-Signature` header. ## Support - Documentation: https://docs.spatialflow.io - GitHub: https://github.com/spatialflow/spatialflow - Email: support@spatialflow.io
7
+
8
+ The version of the OpenAPI document: 1.0.0
9
+ Generated by OpenAPI Generator (https://openapi-generator.tech)
10
+
11
+ Do not edit the class manually.
12
+ """ # noqa: E501
13
+
14
+
15
+ import io
16
+ import json
17
+ import re
18
+ import ssl
19
+ from typing import Optional, Union
20
+
21
+ import aiohttp
22
+ import aiohttp_retry
23
+
24
+ from .exceptions import ApiException, ApiValueError
25
+
26
+ RESTResponseType = aiohttp.ClientResponse
27
+
28
+ ALLOW_RETRY_METHODS = frozenset({'DELETE', 'GET', 'HEAD', 'OPTIONS', 'PUT', 'TRACE'})
29
+
30
+ class RESTResponse(io.IOBase):
31
+
32
+ def __init__(self, resp) -> None:
33
+ self.response = resp
34
+ self.status = resp.status
35
+ self.reason = resp.reason
36
+ self.data = None
37
+
38
+ async def read(self):
39
+ if self.data is None:
40
+ self.data = await self.response.read()
41
+ return self.data
42
+
43
+ def getheaders(self):
44
+ """Returns a CIMultiDictProxy of the response headers."""
45
+ return self.response.headers
46
+
47
+ def getheader(self, name, default=None):
48
+ """Returns a given response header."""
49
+ return self.response.headers.get(name, default)
50
+
51
+
52
+ class RESTClientObject:
53
+
54
+ def __init__(self, configuration) -> None:
55
+
56
+ # maxsize is number of requests to host that are allowed in parallel
57
+ maxsize = configuration.connection_pool_maxsize
58
+
59
+ ssl_context = ssl.create_default_context(
60
+ cafile=configuration.ssl_ca_cert
61
+ )
62
+ if configuration.cert_file:
63
+ ssl_context.load_cert_chain(
64
+ configuration.cert_file, keyfile=configuration.key_file
65
+ )
66
+
67
+ if not configuration.verify_ssl:
68
+ ssl_context.check_hostname = False
69
+ ssl_context.verify_mode = ssl.CERT_NONE
70
+
71
+ connector = aiohttp.TCPConnector(
72
+ limit=maxsize,
73
+ ssl=ssl_context
74
+ )
75
+
76
+ self.proxy = configuration.proxy
77
+ self.proxy_headers = configuration.proxy_headers
78
+
79
+ # https pool manager
80
+ self.pool_manager = aiohttp.ClientSession(
81
+ connector=connector,
82
+ trust_env=True
83
+ )
84
+
85
+ retries = configuration.retries
86
+ self.retry_client: Optional[aiohttp_retry.RetryClient]
87
+ if retries is not None:
88
+ self.retry_client = aiohttp_retry.RetryClient(
89
+ client_session=self.pool_manager,
90
+ retry_options=aiohttp_retry.ExponentialRetry(
91
+ attempts=retries,
92
+ factor=2.0,
93
+ start_timeout=0.1,
94
+ max_timeout=120.0
95
+ )
96
+ )
97
+ else:
98
+ self.retry_client = None
99
+
100
+ async def close(self):
101
+ await self.pool_manager.close()
102
+ if self.retry_client is not None:
103
+ await self.retry_client.close()
104
+
105
+ async def request(
106
+ self,
107
+ method,
108
+ url,
109
+ headers=None,
110
+ body=None,
111
+ post_params=None,
112
+ _request_timeout=None
113
+ ):
114
+ """Execute request
115
+
116
+ :param method: http request method
117
+ :param url: http request url
118
+ :param headers: http request headers
119
+ :param body: request json body, for `application/json`
120
+ :param post_params: request post parameters,
121
+ `application/x-www-form-urlencoded`
122
+ and `multipart/form-data`
123
+ :param _request_timeout: timeout setting for this request. If one
124
+ number provided, it will be total request
125
+ timeout. It can also be a pair (tuple) of
126
+ (connection, read) timeouts.
127
+ """
128
+ method = method.upper()
129
+ assert method in [
130
+ 'GET',
131
+ 'HEAD',
132
+ 'DELETE',
133
+ 'POST',
134
+ 'PUT',
135
+ 'PATCH',
136
+ 'OPTIONS'
137
+ ]
138
+
139
+ if post_params and body:
140
+ raise ApiValueError(
141
+ "body parameter cannot be used with post_params parameter."
142
+ )
143
+
144
+ post_params = post_params or {}
145
+ headers = headers or {}
146
+ # url already contains the URL query string
147
+ timeout = _request_timeout or 5 * 60
148
+
149
+ if 'Content-Type' not in headers:
150
+ headers['Content-Type'] = 'application/json'
151
+
152
+ args = {
153
+ "method": method,
154
+ "url": url,
155
+ "timeout": timeout,
156
+ "headers": headers
157
+ }
158
+
159
+ if self.proxy:
160
+ args["proxy"] = self.proxy
161
+ if self.proxy_headers:
162
+ args["proxy_headers"] = self.proxy_headers
163
+
164
+ # For `POST`, `PUT`, `PATCH`, `OPTIONS`, `DELETE`
165
+ if method in ['POST', 'PUT', 'PATCH', 'OPTIONS', 'DELETE']:
166
+ if re.search('json', headers['Content-Type'], re.IGNORECASE):
167
+ if body is not None:
168
+ body = json.dumps(body)
169
+ args["data"] = body
170
+ elif headers['Content-Type'] == 'application/x-www-form-urlencoded':
171
+ args["data"] = aiohttp.FormData(post_params)
172
+ elif headers['Content-Type'] == 'multipart/form-data':
173
+ # must del headers['Content-Type'], or the correct
174
+ # Content-Type which generated by aiohttp
175
+ del headers['Content-Type']
176
+ data = aiohttp.FormData()
177
+ for param in post_params:
178
+ k, v = param
179
+ if isinstance(v, tuple) and len(v) == 3:
180
+ data.add_field(
181
+ k,
182
+ value=v[1],
183
+ filename=v[0],
184
+ content_type=v[2]
185
+ )
186
+ else:
187
+ # Ensures that dict objects are serialized
188
+ if isinstance(v, dict):
189
+ v = json.dumps(v)
190
+ elif isinstance(v, int):
191
+ v = str(v)
192
+ data.add_field(k, v)
193
+ args["data"] = data
194
+
195
+ # Pass a `bytes` or `str` parameter directly in the body to support
196
+ # other content types than Json when `body` argument is provided
197
+ # in serialized form
198
+ elif isinstance(body, str) or isinstance(body, bytes):
199
+ args["data"] = body
200
+ else:
201
+ # Cannot generate the request from given parameters
202
+ msg = """Cannot prepare a request message for provided
203
+ arguments. Please check that your arguments match
204
+ declared content type."""
205
+ raise ApiException(status=0, reason=msg)
206
+
207
+ pool_manager: Union[aiohttp.ClientSession, aiohttp_retry.RetryClient]
208
+ if self.retry_client is not None and method in ALLOW_RETRY_METHODS:
209
+ pool_manager = self.retry_client
210
+ else:
211
+ pool_manager = self.pool_manager
212
+
213
+ r = await pool_manager.request(**args)
214
+
215
+ return RESTResponse(r)
@@ -0,0 +1,6 @@
1
+ pytest >= 7.2.1
2
+ pytest-cov >= 2.8.1
3
+ tox >= 3.9.0
4
+ flake8 >= 4.0.0
5
+ types-python-dateutil >= 2.8.19.14
6
+ mypy >= 1.5
@@ -0,0 +1,9 @@
1
+ [tox]
2
+ envlist = py3
3
+
4
+ [testenv]
5
+ deps=-r{toxinidir}/requirements.txt
6
+ -r{toxinidir}/test-requirements.txt
7
+
8
+ commands=
9
+ pytest --cov=spatialflow_generated
spatialflow/client.py ADDED
@@ -0,0 +1,137 @@
1
+ """
2
+ SpatialFlow Python SDK Client
3
+
4
+ The main entry point for the SpatialFlow API.
5
+ """
6
+
7
+ from typing import Optional
8
+
9
+ # Import from the generated package using relative imports
10
+ # The generated code now uses relative imports internally
11
+ from ._generated.spatialflow_generated.api_client import ApiClient
12
+ from ._generated.spatialflow_generated.configuration import Configuration
13
+ from ._generated.spatialflow_generated.api.geofences_api import GeofencesApi
14
+ from ._generated.spatialflow_generated.api.workflows_api import WorkflowsApi
15
+ from ._generated.spatialflow_generated.api.webhooks_api import WebhooksApi
16
+ from ._generated.spatialflow_generated.api.devices_api import DevicesApi
17
+ from ._generated.spatialflow_generated.api.account_api import AccountApi
18
+
19
+ __all__ = ["SpatialFlow"]
20
+
21
+ # Host only - generated paths include /api/v1 prefix
22
+ DEFAULT_BASE_URL = "https://api.spatialflow.io"
23
+ DEFAULT_TIMEOUT = 30 # seconds
24
+ DEFAULT_MAX_RETRIES = 3
25
+ VERSION = "0.1.0"
26
+
27
+
28
+ class SpatialFlow:
29
+ """
30
+ SpatialFlow API client.
31
+
32
+ Provides access to geofences, workflows, webhooks, and devices.
33
+
34
+ Example:
35
+ >>> client = SpatialFlow(api_key="sf_xxx")
36
+ >>> geofences = await client.geofences.apps_geofences_api_list_geofences()
37
+
38
+ Args:
39
+ api_key: SpatialFlow API key (starts with "sf_")
40
+ access_token: JWT access token (alternative to api_key)
41
+ base_url: API base URL (default: https://api.spatialflow.io)
42
+ timeout: Request timeout in seconds (default: 30)
43
+ max_retries: Maximum retry attempts for failed requests (default: 3)
44
+ """
45
+
46
+ def __init__(
47
+ self,
48
+ *,
49
+ api_key: Optional[str] = None,
50
+ access_token: Optional[str] = None,
51
+ base_url: str = DEFAULT_BASE_URL,
52
+ timeout: int = DEFAULT_TIMEOUT,
53
+ max_retries: int = DEFAULT_MAX_RETRIES,
54
+ ) -> None:
55
+ if not api_key and not access_token:
56
+ raise ValueError("Either api_key or access_token must be provided")
57
+
58
+ if api_key and access_token:
59
+ raise ValueError("Provide either api_key or access_token, not both")
60
+
61
+ # Build configuration
62
+ config = Configuration(host=base_url)
63
+
64
+ # Configure authentication
65
+ if api_key:
66
+ config.api_key = {"APIKeyBearer": api_key}
67
+ elif access_token:
68
+ config.access_token = access_token
69
+
70
+ # Configure timeouts and retries
71
+ config.retries = max_retries
72
+
73
+ # Create API client
74
+ self._api_client = ApiClient(configuration=config)
75
+
76
+ # Set User-Agent
77
+ self._api_client.user_agent = f"spatialflow-python/{VERSION}"
78
+
79
+ # Store config for reference
80
+ self._base_url = base_url
81
+ self._timeout = timeout
82
+ self._max_retries = max_retries
83
+
84
+ # Initialize resource APIs (lazy initialization)
85
+ self._geofences: Optional[GeofencesApi] = None
86
+ self._workflows: Optional[WorkflowsApi] = None
87
+ self._webhooks: Optional[WebhooksApi] = None
88
+ self._devices: Optional[DevicesApi] = None
89
+ self._account: Optional[AccountApi] = None
90
+
91
+ @property
92
+ def geofences(self) -> GeofencesApi:
93
+ """Access geofence operations."""
94
+ if self._geofences is None:
95
+ self._geofences = GeofencesApi(self._api_client)
96
+ return self._geofences
97
+
98
+ @property
99
+ def workflows(self) -> WorkflowsApi:
100
+ """Access workflow operations."""
101
+ if self._workflows is None:
102
+ self._workflows = WorkflowsApi(self._api_client)
103
+ return self._workflows
104
+
105
+ @property
106
+ def webhooks(self) -> WebhooksApi:
107
+ """Access webhook operations."""
108
+ if self._webhooks is None:
109
+ self._webhooks = WebhooksApi(self._api_client)
110
+ return self._webhooks
111
+
112
+ @property
113
+ def devices(self) -> DevicesApi:
114
+ """Access device operations."""
115
+ if self._devices is None:
116
+ self._devices = DevicesApi(self._api_client)
117
+ return self._devices
118
+
119
+ @property
120
+ def account(self) -> AccountApi:
121
+ """Access account operations."""
122
+ if self._account is None:
123
+ self._account = AccountApi(self._api_client)
124
+ return self._account
125
+
126
+ async def close(self) -> None:
127
+ """Close the API client and release resources."""
128
+ if self._api_client:
129
+ await self._api_client.close()
130
+
131
+ async def __aenter__(self) -> "SpatialFlow":
132
+ """Async context manager entry."""
133
+ return self
134
+
135
+ async def __aexit__(self, exc_type, exc_val, exc_tb) -> None:
136
+ """Async context manager exit."""
137
+ await self.close()
@@ -0,0 +1,234 @@
1
+ """
2
+ SpatialFlow SDK Exceptions
3
+
4
+ Provides a clean exception hierarchy for handling API errors.
5
+ These wrap the generated exceptions with more user-friendly interfaces.
6
+ """
7
+
8
+ from typing import Any, Optional
9
+
10
+
11
+ class SpatialFlowError(Exception):
12
+ """Base exception for all SpatialFlow SDK errors."""
13
+
14
+ def __init__(
15
+ self,
16
+ message: str,
17
+ *,
18
+ status_code: Optional[int] = None,
19
+ detail: Optional[str] = None,
20
+ error_code: Optional[str] = None,
21
+ headers: Optional[dict[str, str]] = None,
22
+ ) -> None:
23
+ super().__init__(message)
24
+ self.message = message
25
+ self.status_code = status_code
26
+ self.detail = detail
27
+ self.error_code = error_code
28
+ self.headers = headers or {}
29
+
30
+ def __str__(self) -> str:
31
+ parts = [self.message]
32
+ if self.status_code:
33
+ parts.insert(0, f"[{self.status_code}]")
34
+ if self.detail and self.detail != self.message:
35
+ parts.append(f"- {self.detail}")
36
+ return " ".join(parts)
37
+
38
+
39
+ class AuthenticationError(SpatialFlowError):
40
+ """
41
+ Raised when authentication fails (401 Unauthorized).
42
+
43
+ This typically means:
44
+ - API key is invalid or expired
45
+ - JWT token is invalid or expired
46
+ - No authentication credentials provided
47
+ """
48
+
49
+ pass
50
+
51
+
52
+ class PermissionError(SpatialFlowError):
53
+ """
54
+ Raised when the authenticated user lacks permission (403 Forbidden).
55
+
56
+ This typically means:
57
+ - User doesn't have access to this resource
58
+ - API key doesn't have the required scope
59
+ - Organization limits exceeded
60
+ """
61
+
62
+ pass
63
+
64
+
65
+ class NotFoundError(SpatialFlowError):
66
+ """
67
+ Raised when a resource is not found (404 Not Found).
68
+
69
+ Check that:
70
+ - The resource ID is correct
71
+ - The resource hasn't been deleted
72
+ - You have access to the resource
73
+ """
74
+
75
+ pass
76
+
77
+
78
+ class ValidationError(SpatialFlowError):
79
+ """
80
+ Raised when request validation fails (400 Bad Request or 422 Unprocessable Entity).
81
+
82
+ Check that:
83
+ - Required fields are provided
84
+ - Field values match expected types/formats
85
+ - Geometry is valid GeoJSON
86
+ """
87
+
88
+ def __init__(
89
+ self,
90
+ message: str,
91
+ *,
92
+ status_code: Optional[int] = None,
93
+ detail: Optional[str] = None,
94
+ error_code: Optional[str] = None,
95
+ headers: Optional[dict[str, str]] = None,
96
+ errors: Optional[list[dict[str, Any]]] = None,
97
+ ) -> None:
98
+ super().__init__(
99
+ message,
100
+ status_code=status_code,
101
+ detail=detail,
102
+ error_code=error_code,
103
+ headers=headers,
104
+ )
105
+ self.errors = errors or []
106
+
107
+
108
+ class RateLimitError(SpatialFlowError):
109
+ """
110
+ Raised when rate limit is exceeded (429 Too Many Requests).
111
+
112
+ The `retry_after` property indicates when you can retry.
113
+ """
114
+
115
+ def __init__(
116
+ self,
117
+ message: str,
118
+ *,
119
+ status_code: int = 429,
120
+ detail: Optional[str] = None,
121
+ error_code: Optional[str] = None,
122
+ headers: Optional[dict[str, str]] = None,
123
+ retry_after: Optional[int] = None,
124
+ ) -> None:
125
+ super().__init__(
126
+ message,
127
+ status_code=status_code,
128
+ detail=detail,
129
+ error_code=error_code,
130
+ headers=headers,
131
+ )
132
+ self.retry_after = retry_after or self._parse_retry_after(headers)
133
+
134
+ def _parse_retry_after(self, headers: Optional[dict[str, str]]) -> Optional[int]:
135
+ if not headers:
136
+ return None
137
+ retry_after = headers.get("Retry-After") or headers.get("retry-after")
138
+ if retry_after:
139
+ try:
140
+ return int(retry_after)
141
+ except ValueError:
142
+ pass
143
+ return None
144
+
145
+
146
+ class ServerError(SpatialFlowError):
147
+ """
148
+ Raised when the server encounters an error (5xx status codes).
149
+
150
+ This is typically a temporary issue. Retry with exponential backoff.
151
+ """
152
+
153
+ pass
154
+
155
+
156
+ class ConflictError(SpatialFlowError):
157
+ """
158
+ Raised when there's a resource conflict (409 Conflict).
159
+
160
+ This typically means:
161
+ - Resource already exists with that name/identifier
162
+ - Concurrent modification conflict
163
+ """
164
+
165
+ pass
166
+
167
+
168
+ class TimeoutError(SpatialFlowError):
169
+ """Raised when a request times out."""
170
+
171
+ pass
172
+
173
+
174
+ class ConnectionError(SpatialFlowError):
175
+ """Raised when unable to connect to the API."""
176
+
177
+ pass
178
+
179
+
180
+ def raise_for_status(
181
+ status_code: int,
182
+ message: str = "API request failed",
183
+ *,
184
+ detail: Optional[str] = None,
185
+ error_code: Optional[str] = None,
186
+ headers: Optional[dict[str, str]] = None,
187
+ body: Optional[Any] = None,
188
+ ) -> None:
189
+ """
190
+ Raise the appropriate exception based on HTTP status code.
191
+
192
+ Args:
193
+ status_code: HTTP status code
194
+ message: Error message
195
+ detail: Additional error detail
196
+ error_code: Machine-readable error code
197
+ headers: Response headers
198
+ body: Response body (for extracting validation errors)
199
+ """
200
+ # Extract detail from body if not provided
201
+ if body and not detail:
202
+ if isinstance(body, dict):
203
+ detail = body.get("detail")
204
+ if isinstance(detail, list):
205
+ # Django Ninja validation error format
206
+ detail = "; ".join(str(e) for e in detail)
207
+ error_code = error_code or body.get("error_code")
208
+
209
+ kwargs = {
210
+ "status_code": status_code,
211
+ "detail": detail,
212
+ "error_code": error_code,
213
+ "headers": headers,
214
+ }
215
+
216
+ if status_code == 400 or status_code == 422:
217
+ errors = []
218
+ if isinstance(body, dict) and isinstance(body.get("detail"), list):
219
+ errors = body["detail"]
220
+ raise ValidationError(message, errors=errors, **kwargs)
221
+ elif status_code == 401:
222
+ raise AuthenticationError(message, **kwargs)
223
+ elif status_code == 403:
224
+ raise PermissionError(message, **kwargs)
225
+ elif status_code == 404:
226
+ raise NotFoundError(message, **kwargs)
227
+ elif status_code == 409:
228
+ raise ConflictError(message, **kwargs)
229
+ elif status_code == 429:
230
+ raise RateLimitError(message, **kwargs)
231
+ elif 500 <= status_code < 600:
232
+ raise ServerError(message, **kwargs)
233
+ elif status_code >= 400:
234
+ raise SpatialFlowError(message, **kwargs)