kard-financial-sdk 0.0.82__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 (302) hide show
  1. kard/__init__.py +579 -0
  2. kard/auth/__init__.py +34 -0
  3. kard/auth/client.py +121 -0
  4. kard/auth/raw_client.py +108 -0
  5. kard/auth/types/__init__.py +34 -0
  6. kard/auth/types/token_response.py +25 -0
  7. kard/client.py +416 -0
  8. kard/commons/__init__.py +120 -0
  9. kard/commons/errors/__init__.py +44 -0
  10. kard/commons/errors/conflict_error.py +11 -0
  11. kard/commons/errors/does_not_exist_error.py +11 -0
  12. kard/commons/errors/internal_server_error.py +11 -0
  13. kard/commons/errors/invalid_request.py +11 -0
  14. kard/commons/errors/unauthorized_error.py +11 -0
  15. kard/commons/types/__init__.py +107 -0
  16. kard/commons/types/category_option.py +26 -0
  17. kard/commons/types/commission_type.py +5 -0
  18. kard/commons/types/commission_value.py +28 -0
  19. kard/commons/types/commission_value_type.py +5 -0
  20. kard/commons/types/empty_object.py +17 -0
  21. kard/commons/types/enrolled_rewards_type.py +5 -0
  22. kard/commons/types/error_object.py +43 -0
  23. kard/commons/types/error_response.py +20 -0
  24. kard/commons/types/error_source.py +32 -0
  25. kard/commons/types/job.py +24 -0
  26. kard/commons/types/job_response.py +27 -0
  27. kard/commons/types/job_status.py +5 -0
  28. kard/commons/types/links.py +27 -0
  29. kard/commons/types/mongo_id.py +3 -0
  30. kard/commons/types/notification_type.py +19 -0
  31. kard/commons/types/organization_id.py +3 -0
  32. kard/commons/types/purchase_channel.py +5 -0
  33. kard/commons/types/relationship_data.py +24 -0
  34. kard/commons/types/relationship_multiple.py +20 -0
  35. kard/commons/types/relationship_single.py +20 -0
  36. kard/commons/types/resource_type.py +3 -0
  37. kard/commons/types/state.py +68 -0
  38. kard/commons/types/subscription_id.py +3 -0
  39. kard/commons/types/user_id.py +3 -0
  40. kard/core/__init__.py +105 -0
  41. kard/core/api_error.py +23 -0
  42. kard/core/client_wrapper.py +97 -0
  43. kard/core/datetime_utils.py +28 -0
  44. kard/core/file.py +67 -0
  45. kard/core/force_multipart.py +18 -0
  46. kard/core/http_client.py +613 -0
  47. kard/core/http_response.py +55 -0
  48. kard/core/http_sse/__init__.py +42 -0
  49. kard/core/http_sse/_api.py +112 -0
  50. kard/core/http_sse/_decoders.py +61 -0
  51. kard/core/http_sse/_exceptions.py +7 -0
  52. kard/core/http_sse/_models.py +17 -0
  53. kard/core/jsonable_encoder.py +100 -0
  54. kard/core/oauth_token_provider.py +73 -0
  55. kard/core/pydantic_utilities.py +260 -0
  56. kard/core/query_encoder.py +58 -0
  57. kard/core/remove_none_from_dict.py +11 -0
  58. kard/core/request_options.py +35 -0
  59. kard/core/serialization.py +276 -0
  60. kard/environment.py +8 -0
  61. kard/files/__init__.py +58 -0
  62. kard/files/client.py +213 -0
  63. kard/files/errors/__init__.py +34 -0
  64. kard/files/errors/forbidden_error.py +11 -0
  65. kard/files/raw_client.py +278 -0
  66. kard/files/types/__init__.py +53 -0
  67. kard/files/types/file_metadata_attribute.py +39 -0
  68. kard/files/types/file_metadata_with_url.py +34 -0
  69. kard/files/types/file_type.py +13 -0
  70. kard/files/types/files_metadata_sort_options.py +5 -0
  71. kard/files/types/get_files_metadata_response.py +71 -0
  72. kard/files/types/pagination_meta.py +29 -0
  73. kard/notifications/__init__.py +279 -0
  74. kard/notifications/client.py +63 -0
  75. kard/notifications/raw_client.py +13 -0
  76. kard/notifications/subscriptions/__init__.py +97 -0
  77. kard/notifications/subscriptions/client.py +372 -0
  78. kard/notifications/subscriptions/raw_client.py +581 -0
  79. kard/notifications/subscriptions/types/__init__.py +94 -0
  80. kard/notifications/subscriptions/types/create_subscription_union.py +27 -0
  81. kard/notifications/subscriptions/types/create_subscriptions_response_object.py +43 -0
  82. kard/notifications/subscriptions/types/created_subscription.py +23 -0
  83. kard/notifications/subscriptions/types/subscription.py +25 -0
  84. kard/notifications/subscriptions/types/subscription_attributes.py +35 -0
  85. kard/notifications/subscriptions/types/subscription_request.py +20 -0
  86. kard/notifications/subscriptions/types/subscription_request_attributes.py +35 -0
  87. kard/notifications/subscriptions/types/subscription_request_body.py +42 -0
  88. kard/notifications/subscriptions/types/subscription_request_union.py +26 -0
  89. kard/notifications/subscriptions/types/subscription_union.py +27 -0
  90. kard/notifications/subscriptions/types/subscriptions_response_object.py +43 -0
  91. kard/notifications/subscriptions/types/update_subscription_request.py +20 -0
  92. kard/notifications/subscriptions/types/update_subscription_request_attributes.py +39 -0
  93. kard/notifications/subscriptions/types/update_subscription_request_body.py +40 -0
  94. kard/notifications/subscriptions/types/update_subscription_request_union.py +26 -0
  95. kard/notifications/subscriptions/types/update_subscriptions_response_object.py +41 -0
  96. kard/notifications/types/__init__.py +214 -0
  97. kard/notifications/types/audit_update_attributes.py +88 -0
  98. kard/notifications/types/audit_update_data.py +27 -0
  99. kard/notifications/types/audit_update_relationships.py +21 -0
  100. kard/notifications/types/broker_amount.py +28 -0
  101. kard/notifications/types/broker_amount_type.py +5 -0
  102. kard/notifications/types/broker_asset.py +33 -0
  103. kard/notifications/types/broker_asset_type.py +5 -0
  104. kard/notifications/types/broker_operation_hours.py +30 -0
  105. kard/notifications/types/broker_operation_period.py +28 -0
  106. kard/notifications/types/broker_purchase_channel.py +5 -0
  107. kard/notifications/types/broker_reward.py +28 -0
  108. kard/notifications/types/broker_reward_type.py +5 -0
  109. kard/notifications/types/clawback_data.py +27 -0
  110. kard/notifications/types/earned_reward_approved_data.py +27 -0
  111. kard/notifications/types/earned_reward_attributes.py +18 -0
  112. kard/notifications/types/earned_reward_relationships.py +21 -0
  113. kard/notifications/types/earned_reward_settled_attributes.py +23 -0
  114. kard/notifications/types/earned_reward_settled_data.py +27 -0
  115. kard/notifications/types/failed_transaction_attributes.py +41 -0
  116. kard/notifications/types/failed_transaction_data.py +27 -0
  117. kard/notifications/types/failed_transaction_relationships.py +22 -0
  118. kard/notifications/types/location_address.py +39 -0
  119. kard/notifications/types/location_coordinates.py +27 -0
  120. kard/notifications/types/location_status.py +5 -0
  121. kard/notifications/types/merchant_source.py +5 -0
  122. kard/notifications/types/notification_data_union.py +203 -0
  123. kard/notifications/types/notification_metadata.py +22 -0
  124. kard/notifications/types/notification_payload.py +65 -0
  125. kard/notifications/types/offer_status.py +5 -0
  126. kard/notifications/types/offer_type.py +5 -0
  127. kard/notifications/types/reward_notification_attributes.py +48 -0
  128. kard/notifications/types/time_period.py +27 -0
  129. kard/notifications/types/transaction_relationships.py +22 -0
  130. kard/notifications/types/user_offer_status.py +5 -0
  131. kard/notifications/types/valid_transaction_attributes.py +25 -0
  132. kard/notifications/types/valid_transaction_commission_earned.py +21 -0
  133. kard/notifications/types/valid_transaction_data.py +27 -0
  134. kard/notifications/types/webhook_locations_attributes.py +71 -0
  135. kard/notifications/types/webhook_locations_data.py +27 -0
  136. kard/notifications/types/webhook_locations_relationships.py +20 -0
  137. kard/notifications/types/webhook_merchant_attributes.py +67 -0
  138. kard/notifications/types/webhook_merchant_data.py +27 -0
  139. kard/notifications/types/webhook_merchant_relationships.py +20 -0
  140. kard/notifications/types/webhook_offer_attributes.py +143 -0
  141. kard/notifications/types/webhook_offer_data.py +27 -0
  142. kard/notifications/types/webhook_offer_relationships.py +20 -0
  143. kard/notifications/types/webhook_user_offer_attributes.py +41 -0
  144. kard/notifications/types/webhook_user_offer_data.py +27 -0
  145. kard/notifications/types/webhook_user_offer_relationships.py +21 -0
  146. kard/ping/__init__.py +39 -0
  147. kard/ping/client.py +100 -0
  148. kard/ping/errors/__init__.py +34 -0
  149. kard/ping/errors/network_blocked_error.py +11 -0
  150. kard/ping/raw_client.py +113 -0
  151. kard/ping/types/__init__.py +38 -0
  152. kard/ping/types/network_blocked_error_body.py +34 -0
  153. kard/ping/types/ping_response_object.py +46 -0
  154. kard/py.typed +0 -0
  155. kard/transactions/__init__.py +212 -0
  156. kard/transactions/client.py +639 -0
  157. kard/transactions/errors/__init__.py +40 -0
  158. kard/transactions/errors/create_audit_multi_status.py +11 -0
  159. kard/transactions/errors/create_incoming_transactions_multi_status.py +11 -0
  160. kard/transactions/errors/fraud_multi_status.py +11 -0
  161. kard/transactions/raw_client.py +925 -0
  162. kard/transactions/types/__init__.py +199 -0
  163. kard/transactions/types/audit_attributes.py +44 -0
  164. kard/transactions/types/audit_request_data.py +20 -0
  165. kard/transactions/types/audit_response_attributes.py +24 -0
  166. kard/transactions/types/audit_response_data.py +25 -0
  167. kard/transactions/types/audit_status.py +5 -0
  168. kard/transactions/types/card_network.py +5 -0
  169. kard/transactions/types/commission_earned_details.py +21 -0
  170. kard/transactions/types/create_audit_multi_status_response.py +21 -0
  171. kard/transactions/types/create_audit_request_body.py +43 -0
  172. kard/transactions/types/create_audit_request_data_union.py +26 -0
  173. kard/transactions/types/create_audit_response_body.py +41 -0
  174. kard/transactions/types/create_audit_response_data_union.py +27 -0
  175. kard/transactions/types/direction_type.py +5 -0
  176. kard/transactions/types/fraudulent_transaction_attributes.py +24 -0
  177. kard/transactions/types/fraudulent_transaction_data.py +30 -0
  178. kard/transactions/types/fraudulent_transaction_object.py +42 -0
  179. kard/transactions/types/fraudulent_transaction_request_body.py +45 -0
  180. kard/transactions/types/fraudulent_transaction_response.py +21 -0
  181. kard/transactions/types/get_earned_rewards_response.py +133 -0
  182. kard/transactions/types/matched_transactions_attributes.py +156 -0
  183. kard/transactions/types/matched_transactions_request.py +25 -0
  184. kard/transactions/types/merchant.py +82 -0
  185. kard/transactions/types/payment_status.py +5 -0
  186. kard/transactions/types/payment_type.py +5 -0
  187. kard/transactions/types/processor_mid.py +26 -0
  188. kard/transactions/types/receipt_medium_type.py +5 -0
  189. kard/transactions/types/rewarded_transaction.py +27 -0
  190. kard/transactions/types/rewarded_transaction_attributes.py +74 -0
  191. kard/transactions/types/rewarded_transaction_relationships.py +22 -0
  192. kard/transactions/types/rewarded_transaction_status.py +5 -0
  193. kard/transactions/types/rewarded_transaction_union.py +29 -0
  194. kard/transactions/types/states.py +68 -0
  195. kard/transactions/types/transaction_included_resource.py +47 -0
  196. kard/transactions/types/transaction_merchant_attributes.py +22 -0
  197. kard/transactions/types/transaction_merchant_resource.py +28 -0
  198. kard/transactions/types/transaction_offer_attributes.py +26 -0
  199. kard/transactions/types/transaction_offer_resource.py +28 -0
  200. kard/transactions/types/transaction_payment_type.py +5 -0
  201. kard/transactions/types/transaction_status.py +5 -0
  202. kard/transactions/types/transactions.py +46 -0
  203. kard/transactions/types/transactions_attributes.py +198 -0
  204. kard/transactions/types/transactions_multi_response.py +21 -0
  205. kard/transactions/types/transactions_request.py +25 -0
  206. kard/transactions/types/transactions_request_body.py +90 -0
  207. kard/transactions/types/transactions_response.py +38 -0
  208. kard/transactions/types/transactions_response_data.py +27 -0
  209. kard/transactions/types/visa_mid.py +23 -0
  210. kard/transactions/types/visa_mid_details.py +27 -0
  211. kard/users/__init__.py +293 -0
  212. kard/users/attributions/__init__.py +73 -0
  213. kard/users/attributions/client.py +229 -0
  214. kard/users/attributions/raw_client.py +215 -0
  215. kard/users/attributions/types/__init__.py +73 -0
  216. kard/users/attributions/types/create_attribution_request_object.py +75 -0
  217. kard/users/attributions/types/create_attribution_request_union.py +45 -0
  218. kard/users/attributions/types/create_attribution_response.py +38 -0
  219. kard/users/attributions/types/event_code.py +5 -0
  220. kard/users/attributions/types/notification_attribution_attributes.py +35 -0
  221. kard/users/attributions/types/notification_attribution_request.py +20 -0
  222. kard/users/attributions/types/notification_medium.py +5 -0
  223. kard/users/attributions/types/offer_attribution_attributes.py +35 -0
  224. kard/users/attributions/types/offer_attribution_request.py +20 -0
  225. kard/users/attributions/types/offer_medium.py +5 -0
  226. kard/users/client.py +512 -0
  227. kard/users/errors/__init__.py +34 -0
  228. kard/users/errors/multi_status.py +11 -0
  229. kard/users/raw_client.py +783 -0
  230. kard/users/rewards/__init__.py +133 -0
  231. kard/users/rewards/client.py +448 -0
  232. kard/users/rewards/raw_client.py +587 -0
  233. kard/users/rewards/types/__init__.py +130 -0
  234. kard/users/rewards/types/amount.py +21 -0
  235. kard/users/rewards/types/amount_type.py +5 -0
  236. kard/users/rewards/types/asset.py +28 -0
  237. kard/users/rewards/types/category_data.py +18 -0
  238. kard/users/rewards/types/category_fields.py +23 -0
  239. kard/users/rewards/types/category_identifier.py +24 -0
  240. kard/users/rewards/types/category_included.py +21 -0
  241. kard/users/rewards/types/category_relationship.py +20 -0
  242. kard/users/rewards/types/category_relationship_object.py +20 -0
  243. kard/users/rewards/types/commission.py +21 -0
  244. kard/users/rewards/types/coordinates.py +20 -0
  245. kard/users/rewards/types/eligibility_location_address.py +24 -0
  246. kard/users/rewards/types/eligibility_location_included.py +8 -0
  247. kard/users/rewards/types/eligibility_offer_included.py +7 -0
  248. kard/users/rewards/types/eligibility_offer_relationship.py +7 -0
  249. kard/users/rewards/types/location_attributes.py +28 -0
  250. kard/users/rewards/types/location_data.py +32 -0
  251. kard/users/rewards/types/location_relationships.py +18 -0
  252. kard/users/rewards/types/location_sort_options.py +5 -0
  253. kard/users/rewards/types/locations_response_object.py +215 -0
  254. kard/users/rewards/types/offer_common_fields.py +103 -0
  255. kard/users/rewards/types/offer_data_union.py +30 -0
  256. kard/users/rewards/types/offer_relationship.py +21 -0
  257. kard/users/rewards/types/offer_sort_options.py +7 -0
  258. kard/users/rewards/types/offers_response_object.py +130 -0
  259. kard/users/rewards/types/operation_hours.py +23 -0
  260. kard/users/rewards/types/operation_period.py +21 -0
  261. kard/users/rewards/types/operation_time.py +20 -0
  262. kard/users/rewards/types/standard_offer.py +21 -0
  263. kard/users/rewards/types/standard_offer_core.py +26 -0
  264. kard/users/rewards/types/standard_offer_fields.py +18 -0
  265. kard/users/types/__init__.py +66 -0
  266. kard/users/types/create_users_multi_status_response.py +21 -0
  267. kard/users/types/create_users_object.py +42 -0
  268. kard/users/types/delete_user_response_object.py +34 -0
  269. kard/users/types/update_user_object.py +40 -0
  270. kard/users/types/user_request_attributes.py +60 -0
  271. kard/users/types/user_request_data.py +22 -0
  272. kard/users/types/user_request_data_union.py +28 -0
  273. kard/users/types/user_response_no_data.py +22 -0
  274. kard/users/types/user_response_union_no_data.py +28 -0
  275. kard/users/uploads/__init__.py +112 -0
  276. kard/users/uploads/client.py +484 -0
  277. kard/users/uploads/errors/__init__.py +34 -0
  278. kard/users/uploads/errors/upload_part_multi_status.py +13 -0
  279. kard/users/uploads/raw_client.py +625 -0
  280. kard/users/uploads/types/__init__.py +119 -0
  281. kard/users/uploads/types/create_upload_part_data_union.py +27 -0
  282. kard/users/uploads/types/create_upload_part_multi_status_response.py +21 -0
  283. kard/users/uploads/types/create_upload_part_request_object.py +74 -0
  284. kard/users/uploads/types/create_upload_part_response_data.py +25 -0
  285. kard/users/uploads/types/create_upload_part_response_data_union.py +27 -0
  286. kard/users/uploads/types/create_upload_part_response_object.py +39 -0
  287. kard/users/uploads/types/create_upload_request_data_union.py +26 -0
  288. kard/users/uploads/types/create_upload_request_object.py +36 -0
  289. kard/users/uploads/types/create_upload_response_data.py +25 -0
  290. kard/users/uploads/types/create_upload_response_data_union.py +27 -0
  291. kard/users/uploads/types/create_upload_response_object.py +37 -0
  292. kard/users/uploads/types/historical_transaction_complete_no_data.py +25 -0
  293. kard/users/uploads/types/start_historical_upload_no_data.py +20 -0
  294. kard/users/uploads/types/update_upload_request_data_union.py +27 -0
  295. kard/users/uploads/types/update_upload_request_object.py +37 -0
  296. kard/users/uploads/types/update_upload_response_data.py +25 -0
  297. kard/users/uploads/types/update_upload_response_data_union.py +27 -0
  298. kard/users/uploads/types/update_upload_response_object.py +37 -0
  299. kard/version.py +3 -0
  300. kard_financial_sdk-0.0.82.dist-info/METADATA +238 -0
  301. kard_financial_sdk-0.0.82.dist-info/RECORD +302 -0
  302. kard_financial_sdk-0.0.82.dist-info/WHEEL +4 -0
@@ -0,0 +1,215 @@
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 ...commons.errors.internal_server_error import InternalServerError
7
+ from ...commons.errors.invalid_request import InvalidRequest
8
+ from ...commons.errors.unauthorized_error import UnauthorizedError
9
+ from ...commons.types.error_response import ErrorResponse
10
+ from ...commons.types.organization_id import OrganizationId
11
+ from ...commons.types.user_id import UserId
12
+ from ...core.api_error import ApiError
13
+ from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
14
+ from ...core.http_response import AsyncHttpResponse, HttpResponse
15
+ from ...core.jsonable_encoder import jsonable_encoder
16
+ from ...core.pydantic_utilities import parse_obj_as
17
+ from ...core.request_options import RequestOptions
18
+ from ...core.serialization import convert_and_respect_annotation_metadata
19
+ from .types.create_attribution_request_union import CreateAttributionRequestUnion
20
+ from .types.create_attribution_response import CreateAttributionResponse
21
+
22
+ # this is used as the default value for optional parameters
23
+ OMIT = typing.cast(typing.Any, ...)
24
+
25
+
26
+ class RawAttributionsClient:
27
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
28
+ self._client_wrapper = client_wrapper
29
+
30
+ def create(
31
+ self,
32
+ organization_id: OrganizationId,
33
+ user_id: UserId,
34
+ *,
35
+ data: typing.Sequence[CreateAttributionRequestUnion],
36
+ request_options: typing.Optional[RequestOptions] = None,
37
+ ) -> HttpResponse[CreateAttributionResponse]:
38
+ """
39
+ Call this endpoint to send attribution events made by a single enrolled user for processing. A maximum of 100 events can be included in a single request.
40
+
41
+ <b>Required scopes:</b> `attributions:write`
42
+
43
+ Parameters
44
+ ----------
45
+ organization_id : OrganizationId
46
+
47
+ user_id : UserId
48
+
49
+ data : typing.Sequence[CreateAttributionRequestUnion]
50
+ Discriminated union representing the request body for submitting attribution events.
51
+ Use `type` to distinguish between the two:
52
+ - `offerAttribution`: Events related to viewing or interacting with an offer.
53
+ - `notificationAttribution`: Events related to viewing or interacting with a notification.
54
+
55
+ request_options : typing.Optional[RequestOptions]
56
+ Request-specific configuration.
57
+
58
+ Returns
59
+ -------
60
+ HttpResponse[CreateAttributionResponse]
61
+ """
62
+ _response = self._client_wrapper.httpx_client.request(
63
+ f"v2/issuers/{jsonable_encoder(organization_id)}/users/{jsonable_encoder(user_id)}/attributions",
64
+ method="POST",
65
+ json={
66
+ "data": convert_and_respect_annotation_metadata(
67
+ object_=data, annotation=typing.Sequence[CreateAttributionRequestUnion], direction="write"
68
+ ),
69
+ },
70
+ request_options=request_options,
71
+ omit=OMIT,
72
+ )
73
+ try:
74
+ if 200 <= _response.status_code < 300:
75
+ _data = typing.cast(
76
+ CreateAttributionResponse,
77
+ parse_obj_as(
78
+ type_=CreateAttributionResponse, # type: ignore
79
+ object_=_response.json(),
80
+ ),
81
+ )
82
+ return HttpResponse(response=_response, data=_data)
83
+ if _response.status_code == 401:
84
+ raise UnauthorizedError(
85
+ headers=dict(_response.headers),
86
+ body=typing.cast(
87
+ ErrorResponse,
88
+ parse_obj_as(
89
+ type_=ErrorResponse, # type: ignore
90
+ object_=_response.json(),
91
+ ),
92
+ ),
93
+ )
94
+ if _response.status_code == 500:
95
+ raise InternalServerError(
96
+ headers=dict(_response.headers),
97
+ body=typing.cast(
98
+ ErrorResponse,
99
+ parse_obj_as(
100
+ type_=ErrorResponse, # type: ignore
101
+ object_=_response.json(),
102
+ ),
103
+ ),
104
+ )
105
+ if _response.status_code == 400:
106
+ raise InvalidRequest(
107
+ headers=dict(_response.headers),
108
+ body=typing.cast(
109
+ ErrorResponse,
110
+ parse_obj_as(
111
+ type_=ErrorResponse, # type: ignore
112
+ object_=_response.json(),
113
+ ),
114
+ ),
115
+ )
116
+ _response_json = _response.json()
117
+ except JSONDecodeError:
118
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
119
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
120
+
121
+
122
+ class AsyncRawAttributionsClient:
123
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
124
+ self._client_wrapper = client_wrapper
125
+
126
+ async def create(
127
+ self,
128
+ organization_id: OrganizationId,
129
+ user_id: UserId,
130
+ *,
131
+ data: typing.Sequence[CreateAttributionRequestUnion],
132
+ request_options: typing.Optional[RequestOptions] = None,
133
+ ) -> AsyncHttpResponse[CreateAttributionResponse]:
134
+ """
135
+ Call this endpoint to send attribution events made by a single enrolled user for processing. A maximum of 100 events can be included in a single request.
136
+
137
+ <b>Required scopes:</b> `attributions:write`
138
+
139
+ Parameters
140
+ ----------
141
+ organization_id : OrganizationId
142
+
143
+ user_id : UserId
144
+
145
+ data : typing.Sequence[CreateAttributionRequestUnion]
146
+ Discriminated union representing the request body for submitting attribution events.
147
+ Use `type` to distinguish between the two:
148
+ - `offerAttribution`: Events related to viewing or interacting with an offer.
149
+ - `notificationAttribution`: Events related to viewing or interacting with a notification.
150
+
151
+ request_options : typing.Optional[RequestOptions]
152
+ Request-specific configuration.
153
+
154
+ Returns
155
+ -------
156
+ AsyncHttpResponse[CreateAttributionResponse]
157
+ """
158
+ _response = await self._client_wrapper.httpx_client.request(
159
+ f"v2/issuers/{jsonable_encoder(organization_id)}/users/{jsonable_encoder(user_id)}/attributions",
160
+ method="POST",
161
+ json={
162
+ "data": convert_and_respect_annotation_metadata(
163
+ object_=data, annotation=typing.Sequence[CreateAttributionRequestUnion], direction="write"
164
+ ),
165
+ },
166
+ request_options=request_options,
167
+ omit=OMIT,
168
+ )
169
+ try:
170
+ if 200 <= _response.status_code < 300:
171
+ _data = typing.cast(
172
+ CreateAttributionResponse,
173
+ parse_obj_as(
174
+ type_=CreateAttributionResponse, # type: ignore
175
+ object_=_response.json(),
176
+ ),
177
+ )
178
+ return AsyncHttpResponse(response=_response, data=_data)
179
+ if _response.status_code == 401:
180
+ raise UnauthorizedError(
181
+ headers=dict(_response.headers),
182
+ body=typing.cast(
183
+ ErrorResponse,
184
+ parse_obj_as(
185
+ type_=ErrorResponse, # type: ignore
186
+ object_=_response.json(),
187
+ ),
188
+ ),
189
+ )
190
+ if _response.status_code == 500:
191
+ raise InternalServerError(
192
+ headers=dict(_response.headers),
193
+ body=typing.cast(
194
+ ErrorResponse,
195
+ parse_obj_as(
196
+ type_=ErrorResponse, # type: ignore
197
+ object_=_response.json(),
198
+ ),
199
+ ),
200
+ )
201
+ if _response.status_code == 400:
202
+ raise InvalidRequest(
203
+ headers=dict(_response.headers),
204
+ body=typing.cast(
205
+ ErrorResponse,
206
+ parse_obj_as(
207
+ type_=ErrorResponse, # type: ignore
208
+ object_=_response.json(),
209
+ ),
210
+ ),
211
+ )
212
+ _response_json = _response.json()
213
+ except JSONDecodeError:
214
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
215
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
@@ -0,0 +1,73 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ # isort: skip_file
4
+
5
+ import typing
6
+ from importlib import import_module
7
+
8
+ if typing.TYPE_CHECKING:
9
+ from .create_attribution_request_object import CreateAttributionRequestObject
10
+ from .create_attribution_request_union import (
11
+ CreateAttributionRequestUnion,
12
+ CreateAttributionRequestUnion_NotificationAttribution,
13
+ CreateAttributionRequestUnion_OfferAttribution,
14
+ )
15
+ from .create_attribution_response import CreateAttributionResponse
16
+ from .event_code import EventCode
17
+ from .notification_attribution_attributes import NotificationAttributionAttributes
18
+ from .notification_attribution_request import NotificationAttributionRequest
19
+ from .notification_medium import NotificationMedium
20
+ from .offer_attribution_attributes import OfferAttributionAttributes
21
+ from .offer_attribution_request import OfferAttributionRequest
22
+ from .offer_medium import OfferMedium
23
+ _dynamic_imports: typing.Dict[str, str] = {
24
+ "CreateAttributionRequestObject": ".create_attribution_request_object",
25
+ "CreateAttributionRequestUnion": ".create_attribution_request_union",
26
+ "CreateAttributionRequestUnion_NotificationAttribution": ".create_attribution_request_union",
27
+ "CreateAttributionRequestUnion_OfferAttribution": ".create_attribution_request_union",
28
+ "CreateAttributionResponse": ".create_attribution_response",
29
+ "EventCode": ".event_code",
30
+ "NotificationAttributionAttributes": ".notification_attribution_attributes",
31
+ "NotificationAttributionRequest": ".notification_attribution_request",
32
+ "NotificationMedium": ".notification_medium",
33
+ "OfferAttributionAttributes": ".offer_attribution_attributes",
34
+ "OfferAttributionRequest": ".offer_attribution_request",
35
+ "OfferMedium": ".offer_medium",
36
+ }
37
+
38
+
39
+ def __getattr__(attr_name: str) -> typing.Any:
40
+ module_name = _dynamic_imports.get(attr_name)
41
+ if module_name is None:
42
+ raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}")
43
+ try:
44
+ module = import_module(module_name, __package__)
45
+ if module_name == f".{attr_name}":
46
+ return module
47
+ else:
48
+ return getattr(module, attr_name)
49
+ except ImportError as e:
50
+ raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e
51
+ except AttributeError as e:
52
+ raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e
53
+
54
+
55
+ def __dir__():
56
+ lazy_attrs = list(_dynamic_imports.keys())
57
+ return sorted(lazy_attrs)
58
+
59
+
60
+ __all__ = [
61
+ "CreateAttributionRequestObject",
62
+ "CreateAttributionRequestUnion",
63
+ "CreateAttributionRequestUnion_NotificationAttribution",
64
+ "CreateAttributionRequestUnion_OfferAttribution",
65
+ "CreateAttributionResponse",
66
+ "EventCode",
67
+ "NotificationAttributionAttributes",
68
+ "NotificationAttributionRequest",
69
+ "NotificationMedium",
70
+ "OfferAttributionAttributes",
71
+ "OfferAttributionRequest",
72
+ "OfferMedium",
73
+ ]
@@ -0,0 +1,75 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ import pydantic
6
+ from ....core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
7
+ from .create_attribution_request_union import CreateAttributionRequestUnion
8
+
9
+
10
+ class CreateAttributionRequestObject(UniversalBaseModel):
11
+ """
12
+ Examples
13
+ --------
14
+ import datetime
15
+
16
+ from kard.users.attributions import (
17
+ CreateAttributionRequestObject,
18
+ CreateAttributionRequestUnion_NotificationAttribution,
19
+ CreateAttributionRequestUnion_OfferAttribution,
20
+ NotificationAttributionAttributes,
21
+ OfferAttributionAttributes,
22
+ )
23
+
24
+ CreateAttributionRequestObject(
25
+ data=[
26
+ CreateAttributionRequestUnion_OfferAttribution(
27
+ attributes=OfferAttributionAttributes(
28
+ entity_id="60e4ba1da31c5a22a144c075",
29
+ event_code="VIEW",
30
+ medium="SEARCH",
31
+ event_date=datetime.datetime.fromisoformat(
32
+ "2025-01-01 00:00:00+00:00",
33
+ ),
34
+ ),
35
+ ),
36
+ CreateAttributionRequestUnion_OfferAttribution(
37
+ attributes=OfferAttributionAttributes(
38
+ entity_id="60e4ba1da31c5a22a144c077",
39
+ event_code="IMPRESSION",
40
+ medium="EMAIL",
41
+ event_date=datetime.datetime.fromisoformat(
42
+ "2025-01-01 00:00:00+00:00",
43
+ ),
44
+ ),
45
+ ),
46
+ CreateAttributionRequestUnion_NotificationAttribution(
47
+ attributes=NotificationAttributionAttributes(
48
+ entity_id="60e4ba1da31c5a22a144c076",
49
+ event_code="IMPRESSION",
50
+ medium="PUSH",
51
+ event_date=datetime.datetime.fromisoformat(
52
+ "2025-01-01 00:00:00+00:00",
53
+ ),
54
+ ),
55
+ ),
56
+ ],
57
+ )
58
+ """
59
+
60
+ data: typing.List[CreateAttributionRequestUnion] = pydantic.Field()
61
+ """
62
+ Discriminated union representing the request body for submitting attribution events.
63
+ Use `type` to distinguish between the two:
64
+ - `offerAttribution`: Events related to viewing or interacting with an offer.
65
+ - `notificationAttribution`: Events related to viewing or interacting with a notification.
66
+ """
67
+
68
+ if IS_PYDANTIC_V2:
69
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
70
+ else:
71
+
72
+ class Config:
73
+ frozen = True
74
+ smart_union = True
75
+ extra = pydantic.Extra.allow
@@ -0,0 +1,45 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ from __future__ import annotations
4
+
5
+ import typing
6
+
7
+ import pydantic
8
+ import typing_extensions
9
+ from ....core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
10
+ from .notification_attribution_attributes import NotificationAttributionAttributes
11
+ from .offer_attribution_attributes import OfferAttributionAttributes
12
+
13
+
14
+ class CreateAttributionRequestUnion_OfferAttribution(UniversalBaseModel):
15
+ type: typing.Literal["offerAttribution"] = "offerAttribution"
16
+ attributes: OfferAttributionAttributes
17
+
18
+ if IS_PYDANTIC_V2:
19
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
20
+ else:
21
+
22
+ class Config:
23
+ frozen = True
24
+ smart_union = True
25
+ extra = pydantic.Extra.allow
26
+
27
+
28
+ class CreateAttributionRequestUnion_NotificationAttribution(UniversalBaseModel):
29
+ type: typing.Literal["notificationAttribution"] = "notificationAttribution"
30
+ attributes: NotificationAttributionAttributes
31
+
32
+ if IS_PYDANTIC_V2:
33
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
34
+ else:
35
+
36
+ class Config:
37
+ frozen = True
38
+ smart_union = True
39
+ extra = pydantic.Extra.allow
40
+
41
+
42
+ CreateAttributionRequestUnion = typing_extensions.Annotated[
43
+ typing.Union[CreateAttributionRequestUnion_OfferAttribution, CreateAttributionRequestUnion_NotificationAttribution],
44
+ pydantic.Field(discriminator="type"),
45
+ ]
@@ -0,0 +1,38 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ import pydantic
6
+ from ....commons.types.job_response import JobResponse
7
+ from ....core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
8
+
9
+
10
+ class CreateAttributionResponse(UniversalBaseModel):
11
+ """
12
+ Examples
13
+ --------
14
+ from kard.commons import Job, JobResponse
15
+ from kard.users.attributions import CreateAttributionResponse
16
+
17
+ CreateAttributionResponse(
18
+ data=JobResponse(
19
+ type="job",
20
+ id="c94a93a7-beb9-4e58-960c-2c812f849398",
21
+ attributes=Job(
22
+ status="queued",
23
+ message="Attribution events are queued for processing",
24
+ ),
25
+ ),
26
+ )
27
+ """
28
+
29
+ data: JobResponse
30
+
31
+ if IS_PYDANTIC_V2:
32
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
33
+ else:
34
+
35
+ class Config:
36
+ frozen = True
37
+ smart_union = True
38
+ extra = pydantic.Extra.allow
@@ -0,0 +1,5 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ EventCode = typing.Union[typing.Literal["IMPRESSION", "VIEW"], typing.Any]
@@ -0,0 +1,35 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import datetime as dt
4
+ import typing
5
+
6
+ import pydantic
7
+ import typing_extensions
8
+ from ....core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
9
+ from ....core.serialization import FieldMetadata
10
+ from .event_code import EventCode
11
+ from .notification_medium import NotificationMedium
12
+
13
+
14
+ class NotificationAttributionAttributes(UniversalBaseModel):
15
+ entity_id: typing_extensions.Annotated[str, FieldMetadata(alias="entityId")] = pydantic.Field()
16
+ """
17
+ The notification ID
18
+ """
19
+
20
+ event_code: typing_extensions.Annotated[EventCode, FieldMetadata(alias="eventCode")]
21
+ medium: NotificationMedium
22
+ event_date: typing_extensions.Annotated[dt.datetime, FieldMetadata(alias="eventDate")] = pydantic.Field()
23
+ """
24
+ The timestamp of the attribution event.
25
+ Must be in ISO 8601 format (e.g., "2025-01-01T00:00:00Z").
26
+ """
27
+
28
+ if IS_PYDANTIC_V2:
29
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
30
+ else:
31
+
32
+ class Config:
33
+ frozen = True
34
+ smart_union = True
35
+ extra = pydantic.Extra.allow
@@ -0,0 +1,20 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ import pydantic
6
+ from ....core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
7
+ from .notification_attribution_attributes import NotificationAttributionAttributes
8
+
9
+
10
+ class NotificationAttributionRequest(UniversalBaseModel):
11
+ attributes: NotificationAttributionAttributes
12
+
13
+ if IS_PYDANTIC_V2:
14
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
15
+ else:
16
+
17
+ class Config:
18
+ frozen = True
19
+ smart_union = True
20
+ extra = pydantic.Extra.allow
@@ -0,0 +1,5 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ NotificationMedium = typing.Union[typing.Literal["PUSH"], typing.Any]
@@ -0,0 +1,35 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import datetime as dt
4
+ import typing
5
+
6
+ import pydantic
7
+ import typing_extensions
8
+ from ....core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
9
+ from ....core.serialization import FieldMetadata
10
+ from .event_code import EventCode
11
+ from .offer_medium import OfferMedium
12
+
13
+
14
+ class OfferAttributionAttributes(UniversalBaseModel):
15
+ entity_id: typing_extensions.Annotated[str, FieldMetadata(alias="entityId")] = pydantic.Field()
16
+ """
17
+ The offer ID
18
+ """
19
+
20
+ event_code: typing_extensions.Annotated[EventCode, FieldMetadata(alias="eventCode")]
21
+ medium: OfferMedium
22
+ event_date: typing_extensions.Annotated[dt.datetime, FieldMetadata(alias="eventDate")] = pydantic.Field()
23
+ """
24
+ The timestamp of the attribution event.
25
+ Must be in ISO 8601 format (e.g., "2025-01-01T00:00:00Z").
26
+ """
27
+
28
+ if IS_PYDANTIC_V2:
29
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
30
+ else:
31
+
32
+ class Config:
33
+ frozen = True
34
+ smart_union = True
35
+ extra = pydantic.Extra.allow
@@ -0,0 +1,20 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ import pydantic
6
+ from ....core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
7
+ from .offer_attribution_attributes import OfferAttributionAttributes
8
+
9
+
10
+ class OfferAttributionRequest(UniversalBaseModel):
11
+ attributes: OfferAttributionAttributes
12
+
13
+ if IS_PYDANTIC_V2:
14
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
15
+ else:
16
+
17
+ class Config:
18
+ frozen = True
19
+ smart_union = True
20
+ extra = pydantic.Extra.allow
@@ -0,0 +1,5 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ OfferMedium = typing.Union[typing.Literal["BROWSE", "EMAIL", "MAP", "SEARCH"], typing.Any]