fal 0.11.1__py3-none-any.whl → 0.11.3__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.

Potentially problematic release.


This version of fal might be problematic. Click here for more details.

Files changed (58) hide show
  1. fal/api.py +51 -19
  2. fal/auth/__init__.py +1 -2
  3. fal/auth/auth0.py +2 -5
  4. fal/cli.py +92 -108
  5. fal/rest_client.py +1 -0
  6. fal/sdk.py +49 -129
  7. fal/sync.py +3 -2
  8. fal/toolkit/file/file.py +6 -5
  9. fal/toolkit/file/providers/gcp.py +4 -1
  10. fal/toolkit/file/providers/r2.py +83 -0
  11. fal/toolkit/file/types.py +1 -1
  12. fal/toolkit/image/image.py +2 -2
  13. fal/toolkit/utils/download_utils.py +1 -1
  14. {fal-0.11.1.dist-info → fal-0.11.3.dist-info}/METADATA +40 -3
  15. {fal-0.11.1.dist-info → fal-0.11.3.dist-info}/RECORD +58 -44
  16. openapi_fal_rest/api/admin/get_usage_per_user.py +199 -0
  17. openapi_fal_rest/api/admin/handle_user_lock.py +6 -2
  18. openapi_fal_rest/api/applications/get_status_applications_app_user_id_app_alias_or_id_status_get.py +6 -2
  19. openapi_fal_rest/api/billing/delete_payment_method.py +9 -3
  20. openapi_fal_rest/api/billing/get_setup_intent_key.py +6 -2
  21. openapi_fal_rest/api/billing/get_user_price.py +6 -2
  22. openapi_fal_rest/api/billing/get_user_spending.py +6 -2
  23. openapi_fal_rest/api/billing/handle_stripe_webhook.py +21 -7
  24. openapi_fal_rest/api/billing/upcoming_invoice.py +6 -2
  25. openapi_fal_rest/api/billing/update_customer_budget.py +6 -2
  26. openapi_fal_rest/api/files/check_dir_hash.py +9 -3
  27. openapi_fal_rest/api/files/delete.py +6 -2
  28. openapi_fal_rest/api/files/download.py +6 -2
  29. openapi_fal_rest/api/files/file_exists.py +6 -2
  30. openapi_fal_rest/api/files/upload_from_url.py +6 -2
  31. openapi_fal_rest/api/files/upload_local_file.py +9 -3
  32. openapi_fal_rest/api/keys/create_key.py +6 -2
  33. openapi_fal_rest/api/keys/delete_key.py +6 -2
  34. openapi_fal_rest/api/{usage/get_request_stats_by_time.py → requests/requests.py} +33 -18
  35. openapi_fal_rest/api/storage/get_file_link.py +200 -0
  36. openapi_fal_rest/api/storage/initiate_upload.py +172 -0
  37. openapi_fal_rest/api/tokens/__init__.py +0 -0
  38. openapi_fal_rest/api/{application/get_status_application_status_user_id_alias_get.py → tokens/create_token.py} +41 -48
  39. openapi_fal_rest/api/usage/get_gateway_request_stats.py +49 -1
  40. openapi_fal_rest/api/usage/get_gateway_request_stats_by_time.py +270 -0
  41. openapi_fal_rest/api/usage/per_machine_usage_details.py +3 -1
  42. openapi_fal_rest/models/__init__.py +18 -0
  43. openapi_fal_rest/models/body_create_token.py +68 -0
  44. openapi_fal_rest/models/body_upload_file.py +4 -1
  45. openapi_fal_rest/models/body_upload_local_file.py +4 -1
  46. openapi_fal_rest/models/gateway_stats_by_time.py +27 -27
  47. openapi_fal_rest/models/gateway_usage_stats.py +58 -31
  48. openapi_fal_rest/models/get_gateway_request_stats_by_time_response_get_gateway_request_stats_by_time.py +80 -0
  49. openapi_fal_rest/models/initiate_upload_info.py +64 -0
  50. openapi_fal_rest/models/presigned_upload_url.py +64 -0
  51. openapi_fal_rest/models/request_io.py +112 -0
  52. openapi_fal_rest/models/request_io_json_input.py +43 -0
  53. openapi_fal_rest/models/request_io_json_output.py +43 -0
  54. openapi_fal_rest/models/stats_timeframe.py +1 -0
  55. openapi_fal_rest/models/usage_per_user.py +71 -0
  56. {fal-0.11.1.dist-info → fal-0.11.3.dist-info}/WHEEL +0 -0
  57. {fal-0.11.1.dist-info → fal-0.11.3.dist-info}/entry_points.txt +0 -0
  58. /openapi_fal_rest/api/{application → requests}/__init__.py +0 -0
@@ -1,7 +1,13 @@
1
- from typing import Any, Dict, List, Type, TypeVar
1
+ from typing import TYPE_CHECKING, Any, Dict, List, Type, TypeVar, Union
2
2
 
3
3
  import attr
4
4
 
5
+ from ..types import UNSET, Unset
6
+
7
+ if TYPE_CHECKING:
8
+ from ..models.gateway_stats_by_time import GatewayStatsByTime
9
+
10
+
5
11
  T = TypeVar("T", bound="GatewayUsageStats")
6
12
 
7
13
 
@@ -12,38 +18,47 @@ class GatewayUsageStats:
12
18
  request_count (int):
13
19
  success_count (int):
14
20
  error_count (int):
15
- total_billable_duration (int):
16
- p25_duration (float):
17
- p50_duration (float):
18
- p75_duration (float):
19
- p90_duration (float):
20
- application_id (str):
21
- application_alias (str):
21
+ application_name (str):
22
+ total_billable_duration (float):
23
+ p25_duration (Union[Unset, None, float]):
24
+ p50_duration (Union[Unset, None, float]):
25
+ p75_duration (Union[Unset, None, float]):
26
+ p90_duration (Union[Unset, None, float]):
27
+ time_stats (Union[Unset, None, List['GatewayStatsByTime']]):
22
28
  """
23
29
 
24
30
  request_count: int
25
31
  success_count: int
26
32
  error_count: int
27
- total_billable_duration: int
28
- p25_duration: float
29
- p50_duration: float
30
- p75_duration: float
31
- p90_duration: float
32
- application_id: str
33
- application_alias: str
33
+ application_name: str
34
+ total_billable_duration: float
35
+ p25_duration: Union[Unset, None, float] = UNSET
36
+ p50_duration: Union[Unset, None, float] = UNSET
37
+ p75_duration: Union[Unset, None, float] = UNSET
38
+ p90_duration: Union[Unset, None, float] = UNSET
39
+ time_stats: Union[Unset, None, List["GatewayStatsByTime"]] = UNSET
34
40
  additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict)
35
41
 
36
42
  def to_dict(self) -> Dict[str, Any]:
37
43
  request_count = self.request_count
38
44
  success_count = self.success_count
39
45
  error_count = self.error_count
46
+ application_name = self.application_name
40
47
  total_billable_duration = self.total_billable_duration
41
48
  p25_duration = self.p25_duration
42
49
  p50_duration = self.p50_duration
43
50
  p75_duration = self.p75_duration
44
51
  p90_duration = self.p90_duration
45
- application_id = self.application_id
46
- application_alias = self.application_alias
52
+ time_stats: Union[Unset, None, List[Dict[str, Any]]] = UNSET
53
+ if not isinstance(self.time_stats, Unset):
54
+ if self.time_stats is None:
55
+ time_stats = None
56
+ else:
57
+ time_stats = []
58
+ for time_stats_item_data in self.time_stats:
59
+ time_stats_item = time_stats_item_data.to_dict()
60
+
61
+ time_stats.append(time_stats_item)
47
62
 
48
63
  field_dict: Dict[str, Any] = {}
49
64
  field_dict.update(self.additional_properties)
@@ -52,20 +67,27 @@ class GatewayUsageStats:
52
67
  "request_count": request_count,
53
68
  "success_count": success_count,
54
69
  "error_count": error_count,
70
+ "application_name": application_name,
55
71
  "total_billable_duration": total_billable_duration,
56
- "p25_duration": p25_duration,
57
- "p50_duration": p50_duration,
58
- "p75_duration": p75_duration,
59
- "p90_duration": p90_duration,
60
- "application_id": application_id,
61
- "application_alias": application_alias,
62
72
  }
63
73
  )
74
+ if p25_duration is not UNSET:
75
+ field_dict["p25_duration"] = p25_duration
76
+ if p50_duration is not UNSET:
77
+ field_dict["p50_duration"] = p50_duration
78
+ if p75_duration is not UNSET:
79
+ field_dict["p75_duration"] = p75_duration
80
+ if p90_duration is not UNSET:
81
+ field_dict["p90_duration"] = p90_duration
82
+ if time_stats is not UNSET:
83
+ field_dict["time_stats"] = time_stats
64
84
 
65
85
  return field_dict
66
86
 
67
87
  @classmethod
68
88
  def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T:
89
+ from ..models.gateway_stats_by_time import GatewayStatsByTime
90
+
69
91
  d = src_dict.copy()
70
92
  request_count = d.pop("request_count")
71
93
 
@@ -73,31 +95,36 @@ class GatewayUsageStats:
73
95
 
74
96
  error_count = d.pop("error_count")
75
97
 
98
+ application_name = d.pop("application_name")
99
+
76
100
  total_billable_duration = d.pop("total_billable_duration")
77
101
 
78
- p25_duration = d.pop("p25_duration")
102
+ p25_duration = d.pop("p25_duration", UNSET)
79
103
 
80
- p50_duration = d.pop("p50_duration")
104
+ p50_duration = d.pop("p50_duration", UNSET)
81
105
 
82
- p75_duration = d.pop("p75_duration")
106
+ p75_duration = d.pop("p75_duration", UNSET)
83
107
 
84
- p90_duration = d.pop("p90_duration")
108
+ p90_duration = d.pop("p90_duration", UNSET)
85
109
 
86
- application_id = d.pop("application_id")
110
+ time_stats = []
111
+ _time_stats = d.pop("time_stats", UNSET)
112
+ for time_stats_item_data in _time_stats or []:
113
+ time_stats_item = GatewayStatsByTime.from_dict(time_stats_item_data)
87
114
 
88
- application_alias = d.pop("application_alias")
115
+ time_stats.append(time_stats_item)
89
116
 
90
117
  gateway_usage_stats = cls(
91
118
  request_count=request_count,
92
119
  success_count=success_count,
93
120
  error_count=error_count,
121
+ application_name=application_name,
94
122
  total_billable_duration=total_billable_duration,
95
123
  p25_duration=p25_duration,
96
124
  p50_duration=p50_duration,
97
125
  p75_duration=p75_duration,
98
126
  p90_duration=p90_duration,
99
- application_id=application_id,
100
- application_alias=application_alias,
127
+ time_stats=time_stats,
101
128
  )
102
129
 
103
130
  gateway_usage_stats.additional_properties = d
@@ -0,0 +1,80 @@
1
+ from typing import TYPE_CHECKING, Any, Dict, List, Type, TypeVar
2
+
3
+ import attr
4
+
5
+ if TYPE_CHECKING:
6
+ from ..models.gateway_stats_by_time import GatewayStatsByTime
7
+
8
+
9
+ T = TypeVar(
10
+ "T", bound="GetGatewayRequestStatsByTimeResponseGetGatewayRequestStatsByTime"
11
+ )
12
+
13
+
14
+ @attr.s(auto_attribs=True)
15
+ class GetGatewayRequestStatsByTimeResponseGetGatewayRequestStatsByTime:
16
+ """ """
17
+
18
+ additional_properties: Dict[str, List["GatewayStatsByTime"]] = attr.ib(
19
+ init=False, factory=dict
20
+ )
21
+
22
+ def to_dict(self) -> Dict[str, Any]:
23
+ pass
24
+
25
+ field_dict: Dict[str, Any] = {}
26
+ for prop_name, prop in self.additional_properties.items():
27
+ field_dict[prop_name] = []
28
+ for additional_property_item_data in prop:
29
+ additional_property_item = additional_property_item_data.to_dict()
30
+
31
+ field_dict[prop_name].append(additional_property_item)
32
+
33
+ field_dict.update({})
34
+
35
+ return field_dict
36
+
37
+ @classmethod
38
+ def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T:
39
+ from ..models.gateway_stats_by_time import GatewayStatsByTime
40
+
41
+ d = src_dict.copy()
42
+ get_gateway_request_stats_by_time_response_get_gateway_request_stats_by_time = (
43
+ cls()
44
+ )
45
+
46
+ additional_properties = {}
47
+ for prop_name, prop_dict in d.items():
48
+ additional_property = []
49
+ _additional_property = prop_dict
50
+ for additional_property_item_data in _additional_property:
51
+ additional_property_item = GatewayStatsByTime.from_dict(
52
+ additional_property_item_data
53
+ )
54
+
55
+ additional_property.append(additional_property_item)
56
+
57
+ additional_properties[prop_name] = additional_property
58
+
59
+ get_gateway_request_stats_by_time_response_get_gateway_request_stats_by_time.additional_properties = (
60
+ additional_properties
61
+ )
62
+ return (
63
+ get_gateway_request_stats_by_time_response_get_gateway_request_stats_by_time
64
+ )
65
+
66
+ @property
67
+ def additional_keys(self) -> List[str]:
68
+ return list(self.additional_properties.keys())
69
+
70
+ def __getitem__(self, key: str) -> List["GatewayStatsByTime"]:
71
+ return self.additional_properties[key]
72
+
73
+ def __setitem__(self, key: str, value: List["GatewayStatsByTime"]) -> None:
74
+ self.additional_properties[key] = value
75
+
76
+ def __delitem__(self, key: str) -> None:
77
+ del self.additional_properties[key]
78
+
79
+ def __contains__(self, key: str) -> bool:
80
+ return key in self.additional_properties
@@ -0,0 +1,64 @@
1
+ from typing import Any, Dict, List, Type, TypeVar
2
+
3
+ import attr
4
+
5
+ T = TypeVar("T", bound="InitiateUploadInfo")
6
+
7
+
8
+ @attr.s(auto_attribs=True)
9
+ class InitiateUploadInfo:
10
+ """
11
+ Attributes:
12
+ file_name (str):
13
+ content_type (str):
14
+ """
15
+
16
+ file_name: str
17
+ content_type: str
18
+ additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict)
19
+
20
+ def to_dict(self) -> Dict[str, Any]:
21
+ file_name = self.file_name
22
+ content_type = self.content_type
23
+
24
+ field_dict: Dict[str, Any] = {}
25
+ field_dict.update(self.additional_properties)
26
+ field_dict.update(
27
+ {
28
+ "file_name": file_name,
29
+ "content_type": content_type,
30
+ }
31
+ )
32
+
33
+ return field_dict
34
+
35
+ @classmethod
36
+ def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T:
37
+ d = src_dict.copy()
38
+ file_name = d.pop("file_name")
39
+
40
+ content_type = d.pop("content_type")
41
+
42
+ initiate_upload_info = cls(
43
+ file_name=file_name,
44
+ content_type=content_type,
45
+ )
46
+
47
+ initiate_upload_info.additional_properties = d
48
+ return initiate_upload_info
49
+
50
+ @property
51
+ def additional_keys(self) -> List[str]:
52
+ return list(self.additional_properties.keys())
53
+
54
+ def __getitem__(self, key: str) -> Any:
55
+ return self.additional_properties[key]
56
+
57
+ def __setitem__(self, key: str, value: Any) -> None:
58
+ self.additional_properties[key] = value
59
+
60
+ def __delitem__(self, key: str) -> None:
61
+ del self.additional_properties[key]
62
+
63
+ def __contains__(self, key: str) -> bool:
64
+ return key in self.additional_properties
@@ -0,0 +1,64 @@
1
+ from typing import Any, Dict, List, Type, TypeVar
2
+
3
+ import attr
4
+
5
+ T = TypeVar("T", bound="PresignedUploadUrl")
6
+
7
+
8
+ @attr.s(auto_attribs=True)
9
+ class PresignedUploadUrl:
10
+ """
11
+ Attributes:
12
+ file_url (str):
13
+ upload_url (str):
14
+ """
15
+
16
+ file_url: str
17
+ upload_url: str
18
+ additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict)
19
+
20
+ def to_dict(self) -> Dict[str, Any]:
21
+ file_url = self.file_url
22
+ upload_url = self.upload_url
23
+
24
+ field_dict: Dict[str, Any] = {}
25
+ field_dict.update(self.additional_properties)
26
+ field_dict.update(
27
+ {
28
+ "file_url": file_url,
29
+ "upload_url": upload_url,
30
+ }
31
+ )
32
+
33
+ return field_dict
34
+
35
+ @classmethod
36
+ def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T:
37
+ d = src_dict.copy()
38
+ file_url = d.pop("file_url")
39
+
40
+ upload_url = d.pop("upload_url")
41
+
42
+ presigned_upload_url = cls(
43
+ file_url=file_url,
44
+ upload_url=upload_url,
45
+ )
46
+
47
+ presigned_upload_url.additional_properties = d
48
+ return presigned_upload_url
49
+
50
+ @property
51
+ def additional_keys(self) -> List[str]:
52
+ return list(self.additional_properties.keys())
53
+
54
+ def __getitem__(self, key: str) -> Any:
55
+ return self.additional_properties[key]
56
+
57
+ def __setitem__(self, key: str, value: Any) -> None:
58
+ self.additional_properties[key] = value
59
+
60
+ def __delitem__(self, key: str) -> None:
61
+ del self.additional_properties[key]
62
+
63
+ def __contains__(self, key: str) -> bool:
64
+ return key in self.additional_properties
@@ -0,0 +1,112 @@
1
+ import datetime
2
+ from typing import TYPE_CHECKING, Any, Dict, List, Type, TypeVar
3
+
4
+ import attr
5
+ from dateutil.parser import isoparse
6
+
7
+ if TYPE_CHECKING:
8
+ from ..models.request_io_json_input import RequestIOJsonInput
9
+ from ..models.request_io_json_output import RequestIOJsonOutput
10
+
11
+
12
+ T = TypeVar("T", bound="RequestIO")
13
+
14
+
15
+ @attr.s(auto_attribs=True)
16
+ class RequestIO:
17
+ """
18
+ Attributes:
19
+ request_id (str):
20
+ date (datetime.datetime):
21
+ json_input (RequestIOJsonInput):
22
+ json_output (RequestIOJsonOutput):
23
+ status_code (int):
24
+ logs (str):
25
+ duration_in_seconds (int):
26
+ """
27
+
28
+ request_id: str
29
+ date: datetime.datetime
30
+ json_input: "RequestIOJsonInput"
31
+ json_output: "RequestIOJsonOutput"
32
+ status_code: int
33
+ logs: str
34
+ duration_in_seconds: int
35
+ additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict)
36
+
37
+ def to_dict(self) -> Dict[str, Any]:
38
+ request_id = self.request_id
39
+ date = self.date.isoformat()
40
+
41
+ json_input = self.json_input.to_dict()
42
+
43
+ json_output = self.json_output.to_dict()
44
+
45
+ status_code = self.status_code
46
+ logs = self.logs
47
+ duration_in_seconds = self.duration_in_seconds
48
+
49
+ field_dict: Dict[str, Any] = {}
50
+ field_dict.update(self.additional_properties)
51
+ field_dict.update(
52
+ {
53
+ "request_id": request_id,
54
+ "date": date,
55
+ "json_input": json_input,
56
+ "json_output": json_output,
57
+ "status_code": status_code,
58
+ "logs": logs,
59
+ "duration_in_seconds": duration_in_seconds,
60
+ }
61
+ )
62
+
63
+ return field_dict
64
+
65
+ @classmethod
66
+ def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T:
67
+ from ..models.request_io_json_input import RequestIOJsonInput
68
+ from ..models.request_io_json_output import RequestIOJsonOutput
69
+
70
+ d = src_dict.copy()
71
+ request_id = d.pop("request_id")
72
+
73
+ date = isoparse(d.pop("date"))
74
+
75
+ json_input = RequestIOJsonInput.from_dict(d.pop("json_input"))
76
+
77
+ json_output = RequestIOJsonOutput.from_dict(d.pop("json_output"))
78
+
79
+ status_code = d.pop("status_code")
80
+
81
+ logs = d.pop("logs")
82
+
83
+ duration_in_seconds = d.pop("duration_in_seconds")
84
+
85
+ request_io = cls(
86
+ request_id=request_id,
87
+ date=date,
88
+ json_input=json_input,
89
+ json_output=json_output,
90
+ status_code=status_code,
91
+ logs=logs,
92
+ duration_in_seconds=duration_in_seconds,
93
+ )
94
+
95
+ request_io.additional_properties = d
96
+ return request_io
97
+
98
+ @property
99
+ def additional_keys(self) -> List[str]:
100
+ return list(self.additional_properties.keys())
101
+
102
+ def __getitem__(self, key: str) -> Any:
103
+ return self.additional_properties[key]
104
+
105
+ def __setitem__(self, key: str, value: Any) -> None:
106
+ self.additional_properties[key] = value
107
+
108
+ def __delitem__(self, key: str) -> None:
109
+ del self.additional_properties[key]
110
+
111
+ def __contains__(self, key: str) -> bool:
112
+ return key in self.additional_properties
@@ -0,0 +1,43 @@
1
+ from typing import Any, Dict, List, Type, TypeVar
2
+
3
+ import attr
4
+
5
+ T = TypeVar("T", bound="RequestIOJsonInput")
6
+
7
+
8
+ @attr.s(auto_attribs=True)
9
+ class RequestIOJsonInput:
10
+ """ """
11
+
12
+ additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict)
13
+
14
+ def to_dict(self) -> Dict[str, Any]:
15
+ field_dict: Dict[str, Any] = {}
16
+ field_dict.update(self.additional_properties)
17
+ field_dict.update({})
18
+
19
+ return field_dict
20
+
21
+ @classmethod
22
+ def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T:
23
+ d = src_dict.copy()
24
+ request_io_json_input = cls()
25
+
26
+ request_io_json_input.additional_properties = d
27
+ return request_io_json_input
28
+
29
+ @property
30
+ def additional_keys(self) -> List[str]:
31
+ return list(self.additional_properties.keys())
32
+
33
+ def __getitem__(self, key: str) -> Any:
34
+ return self.additional_properties[key]
35
+
36
+ def __setitem__(self, key: str, value: Any) -> None:
37
+ self.additional_properties[key] = value
38
+
39
+ def __delitem__(self, key: str) -> None:
40
+ del self.additional_properties[key]
41
+
42
+ def __contains__(self, key: str) -> bool:
43
+ return key in self.additional_properties
@@ -0,0 +1,43 @@
1
+ from typing import Any, Dict, List, Type, TypeVar
2
+
3
+ import attr
4
+
5
+ T = TypeVar("T", bound="RequestIOJsonOutput")
6
+
7
+
8
+ @attr.s(auto_attribs=True)
9
+ class RequestIOJsonOutput:
10
+ """ """
11
+
12
+ additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict)
13
+
14
+ def to_dict(self) -> Dict[str, Any]:
15
+ field_dict: Dict[str, Any] = {}
16
+ field_dict.update(self.additional_properties)
17
+ field_dict.update({})
18
+
19
+ return field_dict
20
+
21
+ @classmethod
22
+ def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T:
23
+ d = src_dict.copy()
24
+ request_io_json_output = cls()
25
+
26
+ request_io_json_output.additional_properties = d
27
+ return request_io_json_output
28
+
29
+ @property
30
+ def additional_keys(self) -> List[str]:
31
+ return list(self.additional_properties.keys())
32
+
33
+ def __getitem__(self, key: str) -> Any:
34
+ return self.additional_properties[key]
35
+
36
+ def __setitem__(self, key: str, value: Any) -> None:
37
+ self.additional_properties[key] = value
38
+
39
+ def __delitem__(self, key: str) -> None:
40
+ del self.additional_properties[key]
41
+
42
+ def __contains__(self, key: str) -> bool:
43
+ return key in self.additional_properties
@@ -4,6 +4,7 @@ from enum import Enum
4
4
  class StatsTimeframe(str, Enum):
5
5
  DAY = "day"
6
6
  HOUR = "hour"
7
+ MINUTE = "minute"
7
8
  MONTH = "month"
8
9
  WEEK = "week"
9
10
 
@@ -0,0 +1,71 @@
1
+ from typing import Any, Dict, List, Type, TypeVar
2
+
3
+ import attr
4
+
5
+ T = TypeVar("T", bound="UsagePerUser")
6
+
7
+
8
+ @attr.s(auto_attribs=True)
9
+ class UsagePerUser:
10
+ """
11
+ Attributes:
12
+ user_id (str):
13
+ machine_type (str):
14
+ total_billable_duration (int):
15
+ """
16
+
17
+ user_id: str
18
+ machine_type: str
19
+ total_billable_duration: int
20
+ additional_properties: Dict[str, Any] = attr.ib(init=False, factory=dict)
21
+
22
+ def to_dict(self) -> Dict[str, Any]:
23
+ user_id = self.user_id
24
+ machine_type = self.machine_type
25
+ total_billable_duration = self.total_billable_duration
26
+
27
+ field_dict: Dict[str, Any] = {}
28
+ field_dict.update(self.additional_properties)
29
+ field_dict.update(
30
+ {
31
+ "user_id": user_id,
32
+ "machine_type": machine_type,
33
+ "total_billable_duration": total_billable_duration,
34
+ }
35
+ )
36
+
37
+ return field_dict
38
+
39
+ @classmethod
40
+ def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T:
41
+ d = src_dict.copy()
42
+ user_id = d.pop("user_id")
43
+
44
+ machine_type = d.pop("machine_type")
45
+
46
+ total_billable_duration = d.pop("total_billable_duration")
47
+
48
+ usage_per_user = cls(
49
+ user_id=user_id,
50
+ machine_type=machine_type,
51
+ total_billable_duration=total_billable_duration,
52
+ )
53
+
54
+ usage_per_user.additional_properties = d
55
+ return usage_per_user
56
+
57
+ @property
58
+ def additional_keys(self) -> List[str]:
59
+ return list(self.additional_properties.keys())
60
+
61
+ def __getitem__(self, key: str) -> Any:
62
+ return self.additional_properties[key]
63
+
64
+ def __setitem__(self, key: str, value: Any) -> None:
65
+ self.additional_properties[key] = value
66
+
67
+ def __delitem__(self, key: str) -> None:
68
+ del self.additional_properties[key]
69
+
70
+ def __contains__(self, key: str) -> bool:
71
+ return key in self.additional_properties
File without changes