samsara-api 0.0.2__py3-none-any.whl → 0.0.4__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.
samsara/__init__.py CHANGED
@@ -2347,7 +2347,6 @@ from .attributes import (
2347
2347
  UpdateAttributeRequestAttributeValueQuantity,
2348
2348
  UpdateAttributeRequestEntityType,
2349
2349
  )
2350
- from .auth import GetTokenResponse
2351
2350
  from .client import AsyncSamsara, Samsara
2352
2351
  from .documents import DocumentsPostDocumentRequestBodyState
2353
2352
  from .driver_vehicle_assignments import (
@@ -3351,7 +3350,6 @@ __all__ = [
3351
3350
  "GetDriverTrailerAssignmentsResponseBodyResponseBody",
3352
3351
  "GetMediaRetrievalObjectResponseBody",
3353
3352
  "GetResponseWorkflowConfigurationObjectResponseBody",
3354
- "GetTokenResponse",
3355
3353
  "GetWorkflowIncidentResponseObjectResponseBody",
3356
3354
  "GoaAddressTinyResponseResponseBody",
3357
3355
  "GoaAttributeTinyRequestBody",
samsara/auth/__init__.py CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  # isort: skip_file
4
4
 
5
- from .types import GetTokenResponse
5
+ from . import tokens
6
+ from .tokens import CreateTokensResponse
6
7
 
7
- __all__ = ["GetTokenResponse"]
8
+ __all__ = ["CreateTokensResponse", "tokens"]
samsara/auth/client.py CHANGED
@@ -1,19 +1,14 @@
1
1
  # This file was auto-generated by Fern from our API Definition.
2
2
 
3
- import typing
4
-
5
3
  from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
6
- from ..core.request_options import RequestOptions
7
4
  from .raw_client import AsyncRawAuthClient, RawAuthClient
8
- from .types.get_token_response import GetTokenResponse
9
-
10
- # this is used as the default value for optional parameters
11
- OMIT = typing.cast(typing.Any, ...)
5
+ from .tokens.client import AsyncTokensClient, TokensClient
12
6
 
13
7
 
14
8
  class AuthClient:
15
9
  def __init__(self, *, client_wrapper: SyncClientWrapper):
16
10
  self._raw_client = RawAuthClient(client_wrapper=client_wrapper)
11
+ self.tokens = TokensClient(client_wrapper=client_wrapper)
17
12
 
18
13
  @property
19
14
  def with_raw_response(self) -> RawAuthClient:
@@ -26,49 +21,11 @@ class AuthClient:
26
21
  """
27
22
  return self._raw_client
28
23
 
29
- def get_token(
30
- self, *, client_id: str, client_secret: str, request_options: typing.Optional[RequestOptions] = None
31
- ) -> GetTokenResponse:
32
- """
33
- Obtain an OAuth2 access token using client credentials
34
-
35
- Parameters
36
- ----------
37
- client_id : str
38
- The client ID of the application
39
-
40
- client_secret : str
41
- The client secret of the application
42
-
43
- request_options : typing.Optional[RequestOptions]
44
- Request-specific configuration.
45
-
46
- Returns
47
- -------
48
- GetTokenResponse
49
- Successful response
50
-
51
- Examples
52
- --------
53
- from samsara import Samsara
54
-
55
- client = Samsara(
56
- token="YOUR_TOKEN",
57
- )
58
- client.auth.get_token(
59
- client_id="client_id",
60
- client_secret="client_secret",
61
- )
62
- """
63
- _response = self._raw_client.get_token(
64
- client_id=client_id, client_secret=client_secret, request_options=request_options
65
- )
66
- return _response.data
67
-
68
24
 
69
25
  class AsyncAuthClient:
70
26
  def __init__(self, *, client_wrapper: AsyncClientWrapper):
71
27
  self._raw_client = AsyncRawAuthClient(client_wrapper=client_wrapper)
28
+ self.tokens = AsyncTokensClient(client_wrapper=client_wrapper)
72
29
 
73
30
  @property
74
31
  def with_raw_response(self) -> AsyncRawAuthClient:
@@ -80,50 +37,3 @@ class AsyncAuthClient:
80
37
  AsyncRawAuthClient
81
38
  """
82
39
  return self._raw_client
83
-
84
- async def get_token(
85
- self, *, client_id: str, client_secret: str, request_options: typing.Optional[RequestOptions] = None
86
- ) -> GetTokenResponse:
87
- """
88
- Obtain an OAuth2 access token using client credentials
89
-
90
- Parameters
91
- ----------
92
- client_id : str
93
- The client ID of the application
94
-
95
- client_secret : str
96
- The client secret of the application
97
-
98
- request_options : typing.Optional[RequestOptions]
99
- Request-specific configuration.
100
-
101
- Returns
102
- -------
103
- GetTokenResponse
104
- Successful response
105
-
106
- Examples
107
- --------
108
- import asyncio
109
-
110
- from samsara import AsyncSamsara
111
-
112
- client = AsyncSamsara(
113
- token="YOUR_TOKEN",
114
- )
115
-
116
-
117
- async def main() -> None:
118
- await client.auth.get_token(
119
- client_id="client_id",
120
- client_secret="client_secret",
121
- )
122
-
123
-
124
- asyncio.run(main())
125
- """
126
- _response = await self._raw_client.get_token(
127
- client_id=client_id, client_secret=client_secret, request_options=request_options
128
- )
129
- return _response.data
@@ -1,128 +1,13 @@
1
1
  # This file was auto-generated by Fern from our API Definition.
2
2
 
3
- import typing
4
- from json.decoder import JSONDecodeError
5
-
6
- from ..core.api_error import ApiError
7
3
  from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
8
- from ..core.http_response import AsyncHttpResponse, HttpResponse
9
- from ..core.pydantic_utilities import parse_obj_as
10
- from ..core.request_options import RequestOptions
11
- from .types.get_token_response import GetTokenResponse
12
-
13
- # this is used as the default value for optional parameters
14
- OMIT = typing.cast(typing.Any, ...)
15
4
 
16
5
 
17
6
  class RawAuthClient:
18
7
  def __init__(self, *, client_wrapper: SyncClientWrapper):
19
8
  self._client_wrapper = client_wrapper
20
9
 
21
- def get_token(
22
- self, *, client_id: str, client_secret: str, request_options: typing.Optional[RequestOptions] = None
23
- ) -> HttpResponse[GetTokenResponse]:
24
- """
25
- Obtain an OAuth2 access token using client credentials
26
-
27
- Parameters
28
- ----------
29
- client_id : str
30
- The client ID of the application
31
-
32
- client_secret : str
33
- The client secret of the application
34
-
35
- request_options : typing.Optional[RequestOptions]
36
- Request-specific configuration.
37
-
38
- Returns
39
- -------
40
- HttpResponse[GetTokenResponse]
41
- Successful response
42
- """
43
- _response = self._client_wrapper.httpx_client.request(
44
- "oauth/token",
45
- method="POST",
46
- json={
47
- "client_id": client_id,
48
- "client_secret": client_secret,
49
- "audience": "https://api.samsara.com",
50
- "grant_type": "authorization_code",
51
- },
52
- headers={
53
- "content-type": "application/json",
54
- },
55
- request_options=request_options,
56
- omit=OMIT,
57
- )
58
- try:
59
- if 200 <= _response.status_code < 300:
60
- _data = typing.cast(
61
- GetTokenResponse,
62
- parse_obj_as(
63
- type_=GetTokenResponse, # type: ignore
64
- object_=_response.json(),
65
- ),
66
- )
67
- return HttpResponse(response=_response, data=_data)
68
- _response_json = _response.json()
69
- except JSONDecodeError:
70
- raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
71
- raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
72
-
73
10
 
74
11
  class AsyncRawAuthClient:
75
12
  def __init__(self, *, client_wrapper: AsyncClientWrapper):
76
13
  self._client_wrapper = client_wrapper
77
-
78
- async def get_token(
79
- self, *, client_id: str, client_secret: str, request_options: typing.Optional[RequestOptions] = None
80
- ) -> AsyncHttpResponse[GetTokenResponse]:
81
- """
82
- Obtain an OAuth2 access token using client credentials
83
-
84
- Parameters
85
- ----------
86
- client_id : str
87
- The client ID of the application
88
-
89
- client_secret : str
90
- The client secret of the application
91
-
92
- request_options : typing.Optional[RequestOptions]
93
- Request-specific configuration.
94
-
95
- Returns
96
- -------
97
- AsyncHttpResponse[GetTokenResponse]
98
- Successful response
99
- """
100
- _response = await self._client_wrapper.httpx_client.request(
101
- "oauth/token",
102
- method="POST",
103
- json={
104
- "client_id": client_id,
105
- "client_secret": client_secret,
106
- "audience": "https://api.samsara.com",
107
- "grant_type": "authorization_code",
108
- },
109
- headers={
110
- "content-type": "application/json",
111
- },
112
- request_options=request_options,
113
- omit=OMIT,
114
- )
115
- try:
116
- if 200 <= _response.status_code < 300:
117
- _data = typing.cast(
118
- GetTokenResponse,
119
- parse_obj_as(
120
- type_=GetTokenResponse, # type: ignore
121
- object_=_response.json(),
122
- ),
123
- )
124
- return AsyncHttpResponse(response=_response, data=_data)
125
- _response_json = _response.json()
126
- except JSONDecodeError:
127
- raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
128
- raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
@@ -2,6 +2,6 @@
2
2
 
3
3
  # isort: skip_file
4
4
 
5
- from .get_token_response import GetTokenResponse
5
+ from .types import CreateTokensResponse
6
6
 
7
- __all__ = ["GetTokenResponse"]
7
+ __all__ = ["CreateTokensResponse"]
@@ -0,0 +1,185 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
6
+ from ...core.request_options import RequestOptions
7
+ from .raw_client import AsyncRawTokensClient, RawTokensClient
8
+ from .types.create_tokens_response import CreateTokensResponse
9
+
10
+ # this is used as the default value for optional parameters
11
+ OMIT = typing.cast(typing.Any, ...)
12
+
13
+
14
+ class TokensClient:
15
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
16
+ self._raw_client = RawTokensClient(client_wrapper=client_wrapper)
17
+
18
+ @property
19
+ def with_raw_response(self) -> RawTokensClient:
20
+ """
21
+ Retrieves a raw implementation of this client that returns raw responses.
22
+
23
+ Returns
24
+ -------
25
+ RawTokensClient
26
+ """
27
+ return self._raw_client
28
+
29
+ def create(
30
+ self, *, code: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None
31
+ ) -> CreateTokensResponse:
32
+ """
33
+ Exchange an authorization code for access and refresh tokens.
34
+
35
+ Parameters
36
+ ----------
37
+ code : typing.Optional[str]
38
+ The client secret of the application
39
+
40
+ request_options : typing.Optional[RequestOptions]
41
+ Request-specific configuration.
42
+
43
+ Returns
44
+ -------
45
+ CreateTokensResponse
46
+ Successful response
47
+
48
+ Examples
49
+ --------
50
+ from samsara import Samsara
51
+
52
+ client = Samsara(
53
+ token="YOUR_TOKEN",
54
+ )
55
+ client.auth.tokens.create()
56
+ """
57
+ _response = self._raw_client.create(code=code, request_options=request_options)
58
+ return _response.data
59
+
60
+ def revoke(self, *, token: str, request_options: typing.Optional[RequestOptions] = None) -> CreateTokensResponse:
61
+ """
62
+ Invalidates access tokens and refresh tokens for that organization
63
+
64
+ Parameters
65
+ ----------
66
+ token : str
67
+ The token to revoke
68
+
69
+ request_options : typing.Optional[RequestOptions]
70
+ Request-specific configuration.
71
+
72
+ Returns
73
+ -------
74
+ CreateTokensResponse
75
+ Successful response
76
+
77
+ Examples
78
+ --------
79
+ from samsara import Samsara
80
+
81
+ client = Samsara(
82
+ token="YOUR_TOKEN",
83
+ )
84
+ client.auth.tokens.revoke(
85
+ token="token",
86
+ )
87
+ """
88
+ _response = self._raw_client.revoke(token=token, request_options=request_options)
89
+ return _response.data
90
+
91
+
92
+ class AsyncTokensClient:
93
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
94
+ self._raw_client = AsyncRawTokensClient(client_wrapper=client_wrapper)
95
+
96
+ @property
97
+ def with_raw_response(self) -> AsyncRawTokensClient:
98
+ """
99
+ Retrieves a raw implementation of this client that returns raw responses.
100
+
101
+ Returns
102
+ -------
103
+ AsyncRawTokensClient
104
+ """
105
+ return self._raw_client
106
+
107
+ async def create(
108
+ self, *, code: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None
109
+ ) -> CreateTokensResponse:
110
+ """
111
+ Exchange an authorization code for access and refresh tokens.
112
+
113
+ Parameters
114
+ ----------
115
+ code : typing.Optional[str]
116
+ The client secret of the application
117
+
118
+ request_options : typing.Optional[RequestOptions]
119
+ Request-specific configuration.
120
+
121
+ Returns
122
+ -------
123
+ CreateTokensResponse
124
+ Successful response
125
+
126
+ Examples
127
+ --------
128
+ import asyncio
129
+
130
+ from samsara import AsyncSamsara
131
+
132
+ client = AsyncSamsara(
133
+ token="YOUR_TOKEN",
134
+ )
135
+
136
+
137
+ async def main() -> None:
138
+ await client.auth.tokens.create()
139
+
140
+
141
+ asyncio.run(main())
142
+ """
143
+ _response = await self._raw_client.create(code=code, request_options=request_options)
144
+ return _response.data
145
+
146
+ async def revoke(
147
+ self, *, token: str, request_options: typing.Optional[RequestOptions] = None
148
+ ) -> CreateTokensResponse:
149
+ """
150
+ Invalidates access tokens and refresh tokens for that organization
151
+
152
+ Parameters
153
+ ----------
154
+ token : str
155
+ The token to revoke
156
+
157
+ request_options : typing.Optional[RequestOptions]
158
+ Request-specific configuration.
159
+
160
+ Returns
161
+ -------
162
+ CreateTokensResponse
163
+ Successful response
164
+
165
+ Examples
166
+ --------
167
+ import asyncio
168
+
169
+ from samsara import AsyncSamsara
170
+
171
+ client = AsyncSamsara(
172
+ token="YOUR_TOKEN",
173
+ )
174
+
175
+
176
+ async def main() -> None:
177
+ await client.auth.tokens.revoke(
178
+ token="token",
179
+ )
180
+
181
+
182
+ asyncio.run(main())
183
+ """
184
+ _response = await self._raw_client.revoke(token=token, request_options=request_options)
185
+ return _response.data
@@ -0,0 +1,210 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+ from json.decoder import JSONDecodeError
5
+
6
+ from ...core.api_error import ApiError
7
+ from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
8
+ from ...core.http_response import AsyncHttpResponse, HttpResponse
9
+ from ...core.pydantic_utilities import parse_obj_as
10
+ from ...core.request_options import RequestOptions
11
+ from .types.create_tokens_response import CreateTokensResponse
12
+
13
+ # this is used as the default value for optional parameters
14
+ OMIT = typing.cast(typing.Any, ...)
15
+
16
+
17
+ class RawTokensClient:
18
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
19
+ self._client_wrapper = client_wrapper
20
+
21
+ def create(
22
+ self, *, code: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None
23
+ ) -> HttpResponse[CreateTokensResponse]:
24
+ """
25
+ Exchange an authorization code for access and refresh tokens.
26
+
27
+ Parameters
28
+ ----------
29
+ code : typing.Optional[str]
30
+ The client secret of the application
31
+
32
+ request_options : typing.Optional[RequestOptions]
33
+ Request-specific configuration.
34
+
35
+ Returns
36
+ -------
37
+ HttpResponse[CreateTokensResponse]
38
+ Successful response
39
+ """
40
+ _response = self._client_wrapper.httpx_client.request(
41
+ "oauth2/token",
42
+ method="POST",
43
+ json={
44
+ "code": code,
45
+ "grant_type": "authorization_code",
46
+ },
47
+ headers={
48
+ "content-type": "application/json",
49
+ },
50
+ request_options=request_options,
51
+ omit=OMIT,
52
+ )
53
+ try:
54
+ if 200 <= _response.status_code < 300:
55
+ _data = typing.cast(
56
+ CreateTokensResponse,
57
+ parse_obj_as(
58
+ type_=CreateTokensResponse, # type: ignore
59
+ object_=_response.json(),
60
+ ),
61
+ )
62
+ return HttpResponse(response=_response, data=_data)
63
+ _response_json = _response.json()
64
+ except JSONDecodeError:
65
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
66
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
67
+
68
+ def revoke(
69
+ self, *, token: str, request_options: typing.Optional[RequestOptions] = None
70
+ ) -> HttpResponse[CreateTokensResponse]:
71
+ """
72
+ Invalidates access tokens and refresh tokens for that organization
73
+
74
+ Parameters
75
+ ----------
76
+ token : str
77
+ The token to revoke
78
+
79
+ request_options : typing.Optional[RequestOptions]
80
+ Request-specific configuration.
81
+
82
+ Returns
83
+ -------
84
+ HttpResponse[CreateTokensResponse]
85
+ Successful response
86
+ """
87
+ _response = self._client_wrapper.httpx_client.request(
88
+ "oauth2/revoke",
89
+ method="POST",
90
+ json={
91
+ "token": token,
92
+ },
93
+ headers={
94
+ "content-type": "application/json",
95
+ },
96
+ request_options=request_options,
97
+ omit=OMIT,
98
+ )
99
+ try:
100
+ if 200 <= _response.status_code < 300:
101
+ _data = typing.cast(
102
+ CreateTokensResponse,
103
+ parse_obj_as(
104
+ type_=CreateTokensResponse, # type: ignore
105
+ object_=_response.json(),
106
+ ),
107
+ )
108
+ return HttpResponse(response=_response, data=_data)
109
+ _response_json = _response.json()
110
+ except JSONDecodeError:
111
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
112
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
113
+
114
+
115
+ class AsyncRawTokensClient:
116
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
117
+ self._client_wrapper = client_wrapper
118
+
119
+ async def create(
120
+ self, *, code: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None
121
+ ) -> AsyncHttpResponse[CreateTokensResponse]:
122
+ """
123
+ Exchange an authorization code for access and refresh tokens.
124
+
125
+ Parameters
126
+ ----------
127
+ code : typing.Optional[str]
128
+ The client secret of the application
129
+
130
+ request_options : typing.Optional[RequestOptions]
131
+ Request-specific configuration.
132
+
133
+ Returns
134
+ -------
135
+ AsyncHttpResponse[CreateTokensResponse]
136
+ Successful response
137
+ """
138
+ _response = await self._client_wrapper.httpx_client.request(
139
+ "oauth2/token",
140
+ method="POST",
141
+ json={
142
+ "code": code,
143
+ "grant_type": "authorization_code",
144
+ },
145
+ headers={
146
+ "content-type": "application/json",
147
+ },
148
+ request_options=request_options,
149
+ omit=OMIT,
150
+ )
151
+ try:
152
+ if 200 <= _response.status_code < 300:
153
+ _data = typing.cast(
154
+ CreateTokensResponse,
155
+ parse_obj_as(
156
+ type_=CreateTokensResponse, # type: ignore
157
+ object_=_response.json(),
158
+ ),
159
+ )
160
+ return AsyncHttpResponse(response=_response, data=_data)
161
+ _response_json = _response.json()
162
+ except JSONDecodeError:
163
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
164
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
165
+
166
+ async def revoke(
167
+ self, *, token: str, request_options: typing.Optional[RequestOptions] = None
168
+ ) -> AsyncHttpResponse[CreateTokensResponse]:
169
+ """
170
+ Invalidates access tokens and refresh tokens for that organization
171
+
172
+ Parameters
173
+ ----------
174
+ token : str
175
+ The token to revoke
176
+
177
+ request_options : typing.Optional[RequestOptions]
178
+ Request-specific configuration.
179
+
180
+ Returns
181
+ -------
182
+ AsyncHttpResponse[CreateTokensResponse]
183
+ Successful response
184
+ """
185
+ _response = await self._client_wrapper.httpx_client.request(
186
+ "oauth2/revoke",
187
+ method="POST",
188
+ json={
189
+ "token": token,
190
+ },
191
+ headers={
192
+ "content-type": "application/json",
193
+ },
194
+ request_options=request_options,
195
+ omit=OMIT,
196
+ )
197
+ try:
198
+ if 200 <= _response.status_code < 300:
199
+ _data = typing.cast(
200
+ CreateTokensResponse,
201
+ parse_obj_as(
202
+ type_=CreateTokensResponse, # type: ignore
203
+ object_=_response.json(),
204
+ ),
205
+ )
206
+ return AsyncHttpResponse(response=_response, data=_data)
207
+ _response_json = _response.json()
208
+ except JSONDecodeError:
209
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
210
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
@@ -0,0 +1,7 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ # isort: skip_file
4
+
5
+ from .create_tokens_response import CreateTokensResponse
6
+
7
+ __all__ = ["CreateTokensResponse"]
@@ -3,13 +3,15 @@
3
3
  import typing
4
4
 
5
5
  import pydantic
6
- from ...core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
6
+ from ....core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
7
7
 
8
8
 
9
- class GetTokenResponse(UniversalBaseModel):
9
+ class CreateTokensResponse(UniversalBaseModel):
10
10
  access_token: str
11
11
  token_type: str
12
12
  expires_in: int
13
+ refresh_token: str
14
+ scope: str
13
15
 
14
16
  if IS_PYDANTIC_V2:
15
17
  model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
samsara/client.py CHANGED
@@ -160,8 +160,8 @@ class Samsara:
160
160
  self.users = UsersClient(client_wrapper=self._client_wrapper)
161
161
  self.v_1_messages = V1MessagesClient(client_wrapper=self._client_wrapper)
162
162
  self.webhooks = WebhooksClient(client_wrapper=self._client_wrapper)
163
- self.auth = AuthClient(client_wrapper=self._client_wrapper)
164
163
  self.alerts = AlertsClient(client_wrapper=self._client_wrapper)
164
+ self.auth = AuthClient(client_wrapper=self._client_wrapper)
165
165
  self.cameras = CamerasClient(client_wrapper=self._client_wrapper)
166
166
  self.coaching = CoachingClient(client_wrapper=self._client_wrapper)
167
167
  self.ifta = IftaClient(client_wrapper=self._client_wrapper)
@@ -273,8 +273,8 @@ class AsyncSamsara:
273
273
  self.users = AsyncUsersClient(client_wrapper=self._client_wrapper)
274
274
  self.v_1_messages = AsyncV1MessagesClient(client_wrapper=self._client_wrapper)
275
275
  self.webhooks = AsyncWebhooksClient(client_wrapper=self._client_wrapper)
276
- self.auth = AsyncAuthClient(client_wrapper=self._client_wrapper)
277
276
  self.alerts = AsyncAlertsClient(client_wrapper=self._client_wrapper)
277
+ self.auth = AsyncAuthClient(client_wrapper=self._client_wrapper)
278
278
  self.cameras = AsyncCamerasClient(client_wrapper=self._client_wrapper)
279
279
  self.coaching = AsyncCoachingClient(client_wrapper=self._client_wrapper)
280
280
  self.ifta = AsyncIftaClient(client_wrapper=self._client_wrapper)
@@ -20,10 +20,10 @@ class BaseClientWrapper:
20
20
 
21
21
  def get_headers(self) -> typing.Dict[str, str]:
22
22
  headers: typing.Dict[str, str] = {
23
- "User-Agent": "samsara-api/0.0.2",
23
+ "User-Agent": "samsara-api/0.0.4",
24
24
  "X-Fern-Language": "Python",
25
25
  "X-Fern-SDK-Name": "samsara-api",
26
- "X-Fern-SDK-Version": "0.0.2",
26
+ "X-Fern-SDK-Version": "0.0.4",
27
27
  }
28
28
  headers["Authorization"] = f"Bearer {self._get_token()}"
29
29
  return headers
@@ -19,7 +19,7 @@ class WorkOrderItemObjectRequestBody(UniversalBaseModel):
19
19
 
20
20
  type: WorkOrderItemObjectRequestBodyType = pydantic.Field()
21
21
  """
22
- The type of item. Valid values: `DVIR`, `FAULT`, `FORM`, `ISSUE`, `ITEM_TYPE_UNSPECIFIED`, `SCHEDULED_MAINTENANCE`
22
+ The type of item. Valid values: `DVIR`, `FAULT`, `FORM`, `ISSUE`, `ITEM_TYPE_UNSPECIFIED`, `MAINTENANCE_PREDICTION_EVENT`, `SCHEDULED_MAINTENANCE`
23
23
  """
24
24
 
25
25
  if IS_PYDANTIC_V2:
@@ -3,5 +3,14 @@
3
3
  import typing
4
4
 
5
5
  WorkOrderItemObjectRequestBodyType = typing.Union[
6
- typing.Literal["DVIR", "FAULT", "FORM", "ISSUE", "ITEM_TYPE_UNSPECIFIED", "SCHEDULED_MAINTENANCE"], typing.Any
6
+ typing.Literal[
7
+ "DVIR",
8
+ "FAULT",
9
+ "FORM",
10
+ "ISSUE",
11
+ "ITEM_TYPE_UNSPECIFIED",
12
+ "MAINTENANCE_PREDICTION_EVENT",
13
+ "SCHEDULED_MAINTENANCE",
14
+ ],
15
+ typing.Any,
7
16
  ]
@@ -19,7 +19,7 @@ class WorkOrderItemObjectResponseBody(UniversalBaseModel):
19
19
 
20
20
  type: WorkOrderItemObjectResponseBodyType = pydantic.Field()
21
21
  """
22
- The type of item. Valid values: `DVIR`, `FAULT`, `FORM`, `ISSUE`, `ITEM_TYPE_UNSPECIFIED`, `SCHEDULED_MAINTENANCE`
22
+ The type of item. Valid values: `DVIR`, `FAULT`, `FORM`, `ISSUE`, `ITEM_TYPE_UNSPECIFIED`, `MAINTENANCE_PREDICTION_EVENT`, `SCHEDULED_MAINTENANCE`
23
23
  """
24
24
 
25
25
  if IS_PYDANTIC_V2:
@@ -3,5 +3,14 @@
3
3
  import typing
4
4
 
5
5
  WorkOrderItemObjectResponseBodyType = typing.Union[
6
- typing.Literal["DVIR", "FAULT", "FORM", "ISSUE", "ITEM_TYPE_UNSPECIFIED", "SCHEDULED_MAINTENANCE"], typing.Any
6
+ typing.Literal[
7
+ "DVIR",
8
+ "FAULT",
9
+ "FORM",
10
+ "ISSUE",
11
+ "ITEM_TYPE_UNSPECIFIED",
12
+ "MAINTENANCE_PREDICTION_EVENT",
13
+ "SCHEDULED_MAINTENANCE",
14
+ ],
15
+ typing.Any,
7
16
  ]
@@ -0,0 +1,52 @@
1
+ import base64
2
+ import hashlib
3
+ import hmac
4
+
5
+
6
+ def verify_signature(
7
+ *,
8
+ request_body: str,
9
+ signature_header: str,
10
+ signature_key: str,
11
+ notification_url: str,
12
+ ) -> bool:
13
+ """
14
+ Verifies and validates an event notification. See the `documentation`_ for more details.
15
+
16
+ Args:
17
+ request_body: The JSON body of the request.
18
+ signature_header: The value for the `x-samsara-hmacsha256-signature` header.
19
+ signature_key: The signature key from the Samsara Developer portal for the webhook subscription.
20
+ notification_url: The notification endpoint URL as defined in the Samsara Developer portal for the webhook
21
+ subscription.
22
+
23
+ Returns:
24
+ bool: True if the signature is valid, indicating that the event can be trusted as it came from Samsara.
25
+ False if the signature validation fails, indicating that the event did not come from Samsara, so it may
26
+ be malicious and should be discarded.
27
+
28
+ Raises:
29
+ ValueError: if `signature_key` or `notification_url` are empty.
30
+ """
31
+ if not request_body:
32
+ return False
33
+ if not signature_key:
34
+ raise ValueError("signature_key is empty")
35
+ if not notification_url:
36
+ raise ValueError("notification_url is empty")
37
+
38
+ # Perform UTF-8 encoding to bytes
39
+ payload = notification_url + request_body
40
+ payload_bytes = payload.encode("utf-8")
41
+ signature_header_bytes = signature_header.encode("utf-8")
42
+ signature_key_bytes = signature_key.encode("utf-8")
43
+
44
+ # Compute the hash value
45
+ hashing_obj = hmac.new(
46
+ key=signature_key_bytes, msg=payload_bytes, digestmod=hashlib.sha256
47
+ )
48
+ hash_bytes = hashing_obj.digest()
49
+
50
+ # Compare the computed hash vs the value in the signature header
51
+ hash_base64 = base64.b64encode(hash_bytes)
52
+ return hmac.compare_digest(hash_base64, signature_header_bytes)
@@ -0,0 +1,238 @@
1
+ Metadata-Version: 2.1
2
+ Name: samsara-api
3
+ Version: 0.0.4
4
+ Summary:
5
+ License: MIT
6
+ Requires-Python: >=3.8,<4.0
7
+ Classifier: Intended Audience :: Developers
8
+ Classifier: License :: OSI Approved :: MIT License
9
+ Classifier: Operating System :: MacOS
10
+ Classifier: Operating System :: Microsoft :: Windows
11
+ Classifier: Operating System :: OS Independent
12
+ Classifier: Operating System :: POSIX
13
+ Classifier: Operating System :: POSIX :: Linux
14
+ Classifier: Programming Language :: Python
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.8
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
22
+ Classifier: Typing :: Typed
23
+ Requires-Dist: httpx (>=0.21.2)
24
+ Requires-Dist: pydantic (>=1.9.2)
25
+ Requires-Dist: pydantic-core (>=2.18.2,<3.0.0)
26
+ Requires-Dist: typing_extensions (>=4.0.0)
27
+ Description-Content-Type: text/markdown
28
+
29
+ # Samsara Python Library
30
+
31
+ [![fern shield](https://img.shields.io/badge/%F0%9F%8C%BF-Built%20with%20Fern-brightgreen)](https://buildwithfern.com?utm_source=github&utm_medium=github&utm_campaign=readme&utm_source=https%3A%2F%2Fgithub.com%2Fsamsarahq%2Fsamsara-python-sdk)
32
+ [![pypi](https://img.shields.io/pypi/v/samsara-api)](https://pypi.python.org/pypi/samsara-api)
33
+
34
+ The Samsara Python library provides convenient access to the Samsara API from Python.
35
+
36
+ ## Documentation
37
+
38
+ API reference documentation is available [here](https://developers.samsara.com/reference/overview).
39
+
40
+ ## Installation
41
+
42
+ ```sh
43
+ pip install samsara-api
44
+ ```
45
+
46
+ ## Reference
47
+
48
+ A full reference for this library is available [here](https://github.com/samsarahq/samsara-python-sdk/blob/HEAD/./reference.md).
49
+
50
+ ## Usage
51
+
52
+ Instantiate and use the client with the following:
53
+
54
+ ```python
55
+ from samsara import Samsara
56
+
57
+ client = Samsara(
58
+ token="YOUR_TOKEN",
59
+ )
60
+ response = client.vehicles.stats.list()
61
+ for item in response:
62
+ yield item
63
+ # alternatively, you can paginate page-by-page
64
+ for page in response.iter_pages():
65
+ yield page
66
+ ```
67
+
68
+ ## Async Client
69
+
70
+ The SDK also exports an `async` client so that you can make non-blocking calls to our API.
71
+
72
+ ```python
73
+ import asyncio
74
+
75
+ from samsara import AsyncSamsara
76
+
77
+ client = AsyncSamsara(
78
+ token="YOUR_TOKEN",
79
+ )
80
+
81
+
82
+ async def main() -> None:
83
+ response = await client.vehicles.stats.list()
84
+ async for item in response:
85
+ yield item
86
+
87
+ # alternatively, you can paginate page-by-page
88
+ async for page in response.iter_pages():
89
+ yield page
90
+
91
+
92
+ asyncio.run(main())
93
+ ```
94
+
95
+ ## Exception Handling
96
+
97
+ When the API returns a non-success status code (4xx or 5xx response), a subclass of the following error
98
+ will be thrown.
99
+
100
+ ```python
101
+ from samsara.core.api_error import ApiError
102
+
103
+ try:
104
+ client.vehicles.stats.list(...)
105
+ except ApiError as e:
106
+ print(e.status_code)
107
+ print(e.body)
108
+ ```
109
+
110
+ ## Pagination
111
+
112
+ Paginated requests will return a `SyncPager` or `AsyncPager`, which can be used as generators for the underlying object.
113
+
114
+ ```python
115
+ from samsara import Samsara
116
+
117
+ client = Samsara(
118
+ token="YOUR_TOKEN",
119
+ )
120
+ response = client.addresses.list()
121
+ for item in response:
122
+ yield item
123
+ # alternatively, you can paginate page-by-page
124
+ for page in response.iter_pages():
125
+ yield page
126
+ ```
127
+
128
+ ## Webhook Signature Verification
129
+
130
+ The SDK provides utility methods that allow you to verify webhook signatures and ensure
131
+ that all webhook events originate from Samsara. The `verify_signature` method will verify
132
+ the signature.
133
+
134
+ ```python
135
+ from samsara.utils.webhooks_helper import verify_signature
136
+
137
+ is_valid = verify_signature(
138
+ request_body=request_body,
139
+ signature_header=request.headers['x-samsara-hmacsha256-signature'],
140
+ signature_key="YOUR_SIGNATURE_KEY",
141
+ notification_url="https://example.com/webhook", # The URL where event notifications are sent.
142
+ )
143
+ ```
144
+
145
+ ## Advanced
146
+
147
+ ### Access Raw Response Data
148
+
149
+ The SDK provides access to raw response data, including headers, through the `.with_raw_response` property.
150
+ The `.with_raw_response` property returns a "raw" client that can be used to access the `.headers` and `.data` attributes.
151
+
152
+ ```python
153
+ from samsara import Samsara
154
+
155
+ client = Samsara(
156
+ ...,
157
+ )
158
+ response = client.vehicles.stats.with_raw_response.list(...)
159
+ print(response.headers) # access the response headers
160
+ print(response.data) # access the underlying object
161
+ pager = client.addresses.list(...)
162
+ print(pager.response.headers) # access the response headers for the first page
163
+ for item in pager:
164
+ print(item) # access the underlying object(s)
165
+ for page in pager.iter_pages():
166
+ print(page.response.headers) # access the response headers for each page
167
+ for item in page:
168
+ print(item) # access the underlying object(s)
169
+ ```
170
+
171
+ ### Retries
172
+
173
+ The SDK is instrumented with automatic retries with exponential backoff. A request will be retried as long
174
+ as the request is deemed retryable and the number of retry attempts has not grown larger than the configured
175
+ retry limit (default: 2).
176
+
177
+ A request is deemed retryable when any of the following HTTP status codes is returned:
178
+
179
+ - [408](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/408) (Timeout)
180
+ - [429](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/429) (Too Many Requests)
181
+ - [5XX](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/500) (Internal Server Errors)
182
+
183
+ Use the `max_retries` request option to configure this behavior.
184
+
185
+ ```python
186
+ client.vehicles.stats.list(..., request_options={
187
+ "max_retries": 1
188
+ })
189
+ ```
190
+
191
+ ### Timeouts
192
+
193
+ The SDK defaults to a 60 second timeout. You can configure this with a timeout option at the client or request level.
194
+
195
+ ```python
196
+
197
+ from samsara import Samsara
198
+
199
+ client = Samsara(
200
+ ...,
201
+ timeout=20.0,
202
+ )
203
+
204
+
205
+ # Override timeout for a specific method
206
+ client.vehicles.stats.list(..., request_options={
207
+ "timeout_in_seconds": 1
208
+ })
209
+ ```
210
+
211
+ ### Custom Client
212
+
213
+ You can override the `httpx` client to customize it for your use-case. Some common use-cases include support for proxies
214
+ and transports.
215
+
216
+ ```python
217
+ import httpx
218
+ from samsara import Samsara
219
+
220
+ client = Samsara(
221
+ ...,
222
+ httpx_client=httpx.Client(
223
+ proxies="http://my.test.proxy.example.com",
224
+ transport=httpx.HTTPTransport(local_address="0.0.0.0"),
225
+ ),
226
+ )
227
+ ```
228
+
229
+ ## Contributing
230
+
231
+ While we value open-source contributions to this SDK, this library is generated programmatically.
232
+ Additions made directly to this library would have to be moved over to our generation code,
233
+ otherwise they would be overwritten upon the next generated release. Feel free to open a PR as
234
+ a proof of concept, but know that we will not be able to merge it as-is. We suggest opening
235
+ an issue first to discuss with us!
236
+
237
+ On the other hand, contributions to the README are always very welcome!
238
+
@@ -1,4 +1,4 @@
1
- samsara/__init__.py,sha256=HRhnyJ-x92KjlApCf6lfvtKrk4M3InEH9viRqJvQxvw,243440
1
+ samsara/__init__.py,sha256=92NvaQpSlOyKeuVpidF-8CqSBNqs-mUz8-ISlOKTWA4,243381
2
2
  samsara/addresses/__init__.py,sha256=VwNk87ydCDVCvXs50iVyOtmRChWMryj-qaD37dmXEHE,271
3
3
  samsara/addresses/client.py,sha256=NmZDd3Q5xZsNDD-NlBZ6dIxIxHNQUVs9DDZ-3b38qQQ,31432
4
4
  samsara/addresses/raw_client.py,sha256=dF0VKXWrRMpZ_FYBwT5Z58StWm1nE7VCQVE4NouRvF0,39437
@@ -41,11 +41,14 @@ samsara/attributes/types/create_attribute_request_entity_type.py,sha256=YVWNyZIS
41
41
  samsara/attributes/types/update_attribute_request_attribute_type.py,sha256=nmtbsmoh3lh6NkGW6UVDbrwLSf_Kyp0FmJJyzC60yfY,179
42
42
  samsara/attributes/types/update_attribute_request_attribute_value_quantity.py,sha256=UIX4mHT8iNREa_H6CuXcpgIH42KKKQRpnUgxpoYy_P4,187
43
43
  samsara/attributes/types/update_attribute_request_entity_type.py,sha256=O3P4cbLmICVFdTzcEUWq4HSpheSpWE-TZfz4HElX9bM,175
44
- samsara/auth/__init__.py,sha256=18OnM9Fc3eM8ONstdOBjtrf6crsICGrbrJrXs7s6nYw,153
45
- samsara/auth/client.py,sha256=mVAxQrlLNrX4BVQ-hLm5nK_7P8t6HfMspkberB5uroY,3517
46
- samsara/auth/raw_client.py,sha256=MFyDhlQ7UFDnSI1e42i04ldoJtvheRStKKossYkU0gc,4574
47
- samsara/auth/types/__init__.py,sha256=5Tq3eLsH_mAnAdBhkIT7OOx8uJWr1nxusbXq2XdQwlo,166
48
- samsara/auth/types/get_token_response.py,sha256=P3VDAqNPv_l8HoUWuveV3SHKqhcADcdbxn1xtLnK5Mo,572
44
+ samsara/auth/__init__.py,sha256=9yWTBw0ONdi-3tmC4kjbCpApiVniv2aK5csdVnHOI20,193
45
+ samsara/auth/client.py,sha256=iGRrTmTAyBspdf_-HcGqn0Pb0s1HQwco4PoSphDFwEU,1236
46
+ samsara/auth/raw_client.py,sha256=Xjah5juxJ0L8FfHyZBKMoOVHWxzvqTv4qtQixxA3jDc,405
47
+ samsara/auth/tokens/__init__.py,sha256=gbhdUVQ3-j2WiNIQN0-h_5RODBZ4gvJgteMmSdgtscQ,161
48
+ samsara/auth/tokens/client.py,sha256=g6AlGPqOt3gHPDrz2q9Glemm7jEGHFiGFnijUY4a66Q,4959
49
+ samsara/auth/tokens/raw_client.py,sha256=ZEnP5Xi8DkY-SEsiQkNAsB3b06AIoal5_cmRcW_Zuxo,7528
50
+ samsara/auth/tokens/types/__init__.py,sha256=XmB_JdsWYwBG-Tz8M8Qj3rfQJWmQtPXDtsFiqy_VuNs,178
51
+ samsara/auth/tokens/types/create_tokens_response.py,sha256=wcHMN9xNW0DfH4-wXKa1l1mY14BmMxl6UDLJGLwNDsY,615
49
52
  samsara/cameras/__init__.py,sha256=6oUbRWZI3I0mSd4P2kGnp-bNVIQoyoR6J4_1OXzluws,361
50
53
  samsara/cameras/client.py,sha256=HdYw4W_X5eIuR9zOYL9IyIrIyeYRIicK9RNdsKPnKJg,1259
51
54
  samsara/cameras/media/__init__.py,sha256=bXxa72UiJqERML9R4PL4PCNWKFZhTCrly5ZvF7__7rA,634
@@ -65,7 +68,7 @@ samsara/cameras/raw_client.py,sha256=X7YzaI5nwgwczR-A4OwhSK54TQW6VfCzs00pgNTMuUU
65
68
  samsara/carrier_proposed_assignments/__init__.py,sha256=_VhToAyIt_5axN6CLJwtxg3-CO7THa_23pbUzqhXJa4,85
66
69
  samsara/carrier_proposed_assignments/client.py,sha256=UDeSIJ17UU_TboofUe-Y8uIY1zBNNtt9Ss7msqIiLac,17860
67
70
  samsara/carrier_proposed_assignments/raw_client.py,sha256=NW9vhF3XwbYEK5nQDzhGYzxkEx4a_wIqL4gqU-npmn0,22836
68
- samsara/client.py,sha256=rsL4dfA2Li863oRh2IJ-zypCEhCJLN8yyOnKW_Os_bU,17115
71
+ samsara/client.py,sha256=852-56uS8ECcrGvhCp-ykxHYJLSuy7VRe0F1iVPk4tw,17115
69
72
  samsara/coaching/__init__.py,sha256=LfmwpXue7wsY-q1lfvX-AYcU4JdP1x0zVtofVAh4pAA,186
70
73
  samsara/coaching/client.py,sha256=ULolm0GnWQmfOVzY1FE8vBMaLl-m0InJutgkQJ4lfps,1606
71
74
  samsara/coaching/driver_coach_assignments/__init__.py,sha256=_VhToAyIt_5axN6CLJwtxg3-CO7THa_23pbUzqhXJa4,85
@@ -80,7 +83,7 @@ samsara/contacts/client.py,sha256=-DvPNxYQZboAYekVkG22JH8GLN5Pb441W0pD7amZue8,19
80
83
  samsara/contacts/raw_client.py,sha256=nMFcdeS_I53QS01zxF2yeY6-t6cbQ7ZeZeqUxKcH7yI,27530
81
84
  samsara/core/__init__.py,sha256=4POYbbRlgR7TwGFY5nmHpaa7nFgXOX_pYHcN1Ezh2p8,1643
82
85
  samsara/core/api_error.py,sha256=44vPoTyWN59gonCIZMdzw7M1uspygiLnr3GNFOoVL2Q,614
83
- samsara/core/client_wrapper.py,sha256=tylN7Z47lS0PcCy8T0aZZcteEYdsU7dLfM9oTf7mQ9k,2236
86
+ samsara/core/client_wrapper.py,sha256=9ANX-olJY3Lv-BmJeGdRh408Cu9mhWO74esp7VjH7jI,2236
84
87
  samsara/core/datetime_utils.py,sha256=nBys2IsYrhPdszxGKCNRPSOCwa-5DWOHG95FB8G9PKo,1047
85
88
  samsara/core/file.py,sha256=d4NNbX8XvXP32z8KpK2Xovv33nFfruIrpz0QWxlgpZk,2663
86
89
  samsara/core/force_multipart.py,sha256=awxh5MtcRYe74ehY8U76jzv6fYM_w_D3Rur7KQQzSDk,429
@@ -2514,10 +2517,10 @@ samsara/types/work_order_attachment_object_response_body.py,sha256=Ce66d8VXVdpVL
2514
2517
  samsara/types/work_order_attachment_object_response_body_processing_status.py,sha256=w82JZVehbfKHNKnX6yGJ4ZioPLQeU-Yl5g5-LDdVe80,220
2515
2518
  samsara/types/work_order_discount_object_request_body.py,sha256=ypiPPoF0rkmdpYsBjq0rF-Q9e7w4uYEGnyXK9fspt5s,1074
2516
2519
  samsara/types/work_order_discount_object_response_body.py,sha256=Z2Xy7CmOcUAduOpIKSVR2l_WqqJIys1zxH_-e8M2-NA,1078
2517
- samsara/types/work_order_item_object_request_body.py,sha256=Y3cTjYnwDnb8URFotb3uKlsIchOOZJ96uTbvcNgtQ-A,933
2518
- samsara/types/work_order_item_object_request_body_type.py,sha256=VscZ6y43wrrUM6babjcrpryDyhTW7Fm0jN770scYuFw,248
2519
- samsara/types/work_order_item_object_response_body.py,sha256=bGvcAkoyQJhCgBLWhx4WAL77CcxT6MPTbrY1fDmq30s,937
2520
- samsara/types/work_order_item_object_response_body_type.py,sha256=hiB3lQvaJJrAiRCy73GRJN_hCFBg8u4j4nKQ45KqR5M,249
2520
+ samsara/types/work_order_item_object_request_body.py,sha256=IR7-f72UooE1Sz5NZtihDMmdZFwsrlj0nhKonrWfx_o,965
2521
+ samsara/types/work_order_item_object_request_body_type.py,sha256=vguZe7JH6HLX_7I0qaCErNPllbGiPw1COKxVnoBtYEg,348
2522
+ samsara/types/work_order_item_object_response_body.py,sha256=1amSCQKCs6IrqLv9UsSJmaQT4LprDgNVGA688RyqVxg,969
2523
+ samsara/types/work_order_item_object_response_body_type.py,sha256=aHS_rnbm5qvc3IghV3sGvE6qOV6057U6X8OLJ3YjOhM,349
2521
2524
  samsara/types/work_order_money_object_request_body.py,sha256=Urpvg5aIH9fx6VStIclHqVhUVp8brDi8_YgD2fb1JUE,816
2522
2525
  samsara/types/work_order_money_object_response_body.py,sha256=7u8dbgEpMRr7s4Yxe2RCEx7l676q7DR-rOkMoNsjkC4,817
2523
2526
  samsara/types/work_order_object_response_body.py,sha256=NXgUY522IAzRXhINXnDSc7L8PYh0Q1qRBAWyntbEEvI,5341
@@ -2610,6 +2613,7 @@ samsara/users/raw_client.py,sha256=aeoDOnJ4dMB4O3WocJXATsCiK-zNHodq09tBBYgaD8w,3
2610
2613
  samsara/users/types/__init__.py,sha256=yVRLnN-wUYfYcYWwrgJSM8GIRnVdqk207hLlDqal0GM,293
2611
2614
  samsara/users/types/create_user_request_auth_type.py,sha256=rdNs3jjJv7IY0koJ6vpgdE79OskOYbA6zUrYMijKmMw,168
2612
2615
  samsara/users/types/update_user_request_auth_type.py,sha256=E2r4bzBS0lwPCWrUwC37GfMlt8Hv-YGw_3abv6wNN-Q,168
2616
+ samsara/utils/webhooks_helper.py,sha256=oosLIOouDmGa7a6xj4sI_EfUSvtzfqB6uXXaUKaagP8,1911
2613
2617
  samsara/v_1_messages/__init__.py,sha256=_VhToAyIt_5axN6CLJwtxg3-CO7THa_23pbUzqhXJa4,85
2614
2618
  samsara/v_1_messages/client.py,sha256=rhUwhh0L3IcgD3sglfNtZMyeLM2j1ogrpMe4902yTos,9734
2615
2619
  samsara/v_1_messages/raw_client.py,sha256=3_5CVjrIRu2VREzYtcV7sQBz0K0F_tOwPDNcMSGDBOw,11896
@@ -2654,7 +2658,7 @@ samsara/webhooks/types/__init__.py,sha256=gZew8TwQaEiQWvSAewo9htvyM3UqVSZc1UJ2Aa
2654
2658
  samsara/webhooks/types/webhooks_patch_webhook_request_body_version.py,sha256=WaQrAnZGbaz7eQ6fpnX77L5nb8dLwuUkEQdvx5mCGAw,224
2655
2659
  samsara/webhooks/types/webhooks_post_webhooks_request_body_event_types_item.py,sha256=-whKIc9UjBEIXZUxwkDULLSxR0Dg_-6KxRUjcfyvTuQ,927
2656
2660
  samsara/webhooks/types/webhooks_post_webhooks_request_body_version.py,sha256=1HR1l6_Qc_jS_mf_UkguxgMiiIeAiwaX7jjOTQfG1bw,224
2657
- samsara_api-0.0.2.dist-info/LICENSE,sha256=uX-nl5hOEHp4uvQPCcpde-doNbQhV5uRQNwkB474IoQ,1064
2658
- samsara_api-0.0.2.dist-info/METADATA,sha256=mvat8gIq2ExK6kWTz_VALsf6nmMxPreEb0ovLOIGmdM,1067
2659
- samsara_api-0.0.2.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
2660
- samsara_api-0.0.2.dist-info/RECORD,,
2661
+ samsara_api-0.0.4.dist-info/LICENSE,sha256=uX-nl5hOEHp4uvQPCcpde-doNbQhV5uRQNwkB474IoQ,1064
2662
+ samsara_api-0.0.4.dist-info/METADATA,sha256=9uB-xryoMS0LeZ1qLICrPttG2gNMHa6AQ_nNQiyyI28,6831
2663
+ samsara_api-0.0.4.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
2664
+ samsara_api-0.0.4.dist-info/RECORD,,
@@ -1,29 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: samsara-api
3
- Version: 0.0.2
4
- Summary:
5
- License: MIT
6
- Requires-Python: >=3.8,<4.0
7
- Classifier: Intended Audience :: Developers
8
- Classifier: License :: OSI Approved :: MIT License
9
- Classifier: Operating System :: MacOS
10
- Classifier: Operating System :: Microsoft :: Windows
11
- Classifier: Operating System :: OS Independent
12
- Classifier: Operating System :: POSIX
13
- Classifier: Operating System :: POSIX :: Linux
14
- Classifier: Programming Language :: Python
15
- Classifier: Programming Language :: Python :: 3
16
- Classifier: Programming Language :: Python :: 3.8
17
- Classifier: Programming Language :: Python :: 3.9
18
- Classifier: Programming Language :: Python :: 3.10
19
- Classifier: Programming Language :: Python :: 3.11
20
- Classifier: Programming Language :: Python :: 3.12
21
- Classifier: Topic :: Software Development :: Libraries :: Python Modules
22
- Classifier: Typing :: Typed
23
- Requires-Dist: httpx (>=0.21.2)
24
- Requires-Dist: pydantic (>=1.9.2)
25
- Requires-Dist: pydantic-core (>=2.18.2,<3.0.0)
26
- Requires-Dist: typing_extensions (>=4.0.0)
27
- Description-Content-Type: text/markdown
28
-
29
-