Coverage for polar/email/schemas.py: 98%
189 statements
« prev ^ index » next coverage.py v7.10.6, created at 2025-12-05 17:15 +0000
« prev ^ index » next coverage.py v7.10.6, created at 2025-12-05 17:15 +0000
1import json 1a
2import sys 1a
3from enum import StrEnum 1a
4from typing import Annotated, Literal 1a
6from pydantic import BaseModel, Discriminator, TypeAdapter 1a
8from polar.notifications.notification import ( 1a
9 MaintainerCreateAccountNotificationPayload,
10 MaintainerNewPaidSubscriptionNotificationPayload,
11 MaintainerNewProductSaleNotificationPayload,
12)
13from polar.order.schemas import OrderBase, OrderItemSchema 1a
14from polar.organization.schemas import Organization 1a
15from polar.product.schemas import BenefitList, ProductBase 1a
16from polar.subscription.schemas import SubscriptionBase 1a
19class EmailTemplate(StrEnum): 1a
20 login_code = "login_code" 1a
21 customer_session_code = "customer_session_code" 1a
22 email_update = "email_update" 1a
23 oauth2_leaked_client = "oauth2_leaked_client" 1a
24 oauth2_leaked_token = "oauth2_leaked_token" 1a
25 order_confirmation = "order_confirmation" 1a
26 organization_access_token_leaked = "organization_access_token_leaked" 1a
27 organization_invite = "organization_invite" 1a
28 organization_account_unlink = "organization_account_unlink" 1a
29 organization_under_review = "organization_under_review" 1a
30 organization_reviewed = "organization_reviewed" 1a
31 personal_access_token_leaked = "personal_access_token_leaked" 1a
32 seat_invitation = "seat_invitation" 1a
33 subscription_cancellation = "subscription_cancellation" 1a
34 subscription_confirmation = "subscription_confirmation" 1a
35 subscription_cycled = "subscription_cycled" 1a
36 subscription_past_due = "subscription_past_due" 1a
37 subscription_revoked = "subscription_revoked" 1a
38 subscription_uncanceled = "subscription_uncanceled" 1a
39 subscription_updated = "subscription_updated" 1a
40 webhook_endpoint_disabled = "webhook_endpoint_disabled" 1a
41 notification_new_sale = "notification_new_sale" 1a
42 notification_new_subscription = "notification_new_subscription" 1a
43 notification_create_account = "notification_create_account" 1a
46class SubscriptionEmail(SubscriptionBase): ... 1a
49class ProductEmail(ProductBase): 1a
50 benefits: BenefitList 1a
53class OrderEmail(OrderBase): 1a
54 description: str 1a
55 items: list[OrderItemSchema] 1a
58class EmailProps(BaseModel): 1a
59 email: str 1a
62class LoginCodeProps(EmailProps): 1a
63 code: str 1a
64 code_lifetime_minutes: int 1a
67class LoginCodeEmail(BaseModel): 1a
68 template: Literal[EmailTemplate.login_code] = EmailTemplate.login_code 1a
69 props: LoginCodeProps 1a
72class CustomerSessionCodeProps(EmailProps): 1a
73 organization: Organization 1a
74 code: str 1a
75 code_lifetime_minutes: int 1a
76 url: str 1a
79class CustomerSessionCodeEmail(BaseModel): 1a
80 template: Literal[EmailTemplate.customer_session_code] = ( 1a
81 EmailTemplate.customer_session_code
82 )
83 props: CustomerSessionCodeProps 1a
86class EmailUpdateProps(EmailProps): 1a
87 token_lifetime_minutes: int 1a
88 url: str 1a
91class EmailUpdateEmail(BaseModel): 1a
92 template: Literal[EmailTemplate.email_update] = EmailTemplate.email_update 1a
93 props: EmailUpdateProps 1a
96class OAuth2LeakedClientProps(EmailProps): 1a
97 token_type: str 1a
98 client_name: str 1a
99 notifier: str 1a
100 url: str 1a
103class OAuth2LeakedClientEmail(BaseModel): 1a
104 template: Literal[EmailTemplate.oauth2_leaked_client] = ( 1a
105 EmailTemplate.oauth2_leaked_client
106 )
107 props: OAuth2LeakedClientProps 1a
110class OAuth2LeakedTokenProps(EmailProps): 1a
111 client_name: str 1a
112 notifier: str 1a
113 url: str 1a
116class OAuth2LeakedTokenEmail(BaseModel): 1a
117 template: Literal[EmailTemplate.oauth2_leaked_token] = ( 1a
118 EmailTemplate.oauth2_leaked_token
119 )
120 props: OAuth2LeakedTokenProps 1a
123class OrderConfirmationProps(EmailProps): 1a
124 organization: Organization 1a
125 product: ProductEmail | None 1a
126 order: OrderEmail 1a
127 url: str 1a
130class OrderConfirmationEmail(BaseModel): 1a
131 template: Literal[EmailTemplate.order_confirmation] = ( 1a
132 EmailTemplate.order_confirmation
133 )
134 props: OrderConfirmationProps 1a
137class OrganizationAccessTokenLeakedProps(EmailProps): 1a
138 organization_access_token: str 1a
139 notifier: str 1a
140 url: str 1a
143class OrganizationAccessTokenLeakedEmail(BaseModel): 1a
144 template: Literal[EmailTemplate.organization_access_token_leaked] = ( 1a
145 EmailTemplate.organization_access_token_leaked
146 )
147 props: OrganizationAccessTokenLeakedProps 1a
150class OrganizationInviteProps(EmailProps): 1a
151 organization_name: str 1a
152 inviter_email: str 1a
153 invite_url: str 1a
156class OrganizationInviteEmail(BaseModel): 1a
157 template: Literal[EmailTemplate.organization_invite] = ( 1a
158 EmailTemplate.organization_invite
159 )
160 props: OrganizationInviteProps 1a
163class OrganizationUnderReviewProps(EmailProps): 1a
164 organization: Organization 1a
167class OrganizationUnderReviewEmail(BaseModel): 1a
168 template: Literal[EmailTemplate.organization_under_review] = ( 1a
169 EmailTemplate.organization_under_review
170 )
171 props: OrganizationUnderReviewProps 1a
174class OrganizationReviewedProps(EmailProps): 1a
175 organization: Organization 1a
178class OrganizationReviewedEmail(BaseModel): 1a
179 template: Literal[EmailTemplate.organization_reviewed] = ( 1a
180 EmailTemplate.organization_reviewed
181 )
182 props: OrganizationReviewedProps 1a
185class PersonalAccessTokenLeakedProps(EmailProps): 1a
186 personal_access_token: str 1a
187 notifier: str 1a
188 url: str 1a
191class PersonalAccessTokenLeakedEmail(BaseModel): 1a
192 template: Literal[EmailTemplate.personal_access_token_leaked] = ( 1a
193 EmailTemplate.personal_access_token_leaked
194 )
195 props: PersonalAccessTokenLeakedProps 1a
198class SeatInvitationProps(EmailProps): 1a
199 organization: Organization 1a
200 product_name: str 1a
201 billing_manager_email: str 1a
202 claim_url: str 1a
205class SeatInvitationEmail(BaseModel): 1a
206 template: Literal[EmailTemplate.seat_invitation] = EmailTemplate.seat_invitation 1a
207 props: SeatInvitationProps 1a
210class SubscriptionPropsBase(EmailProps): 1a
211 organization: Organization 1a
212 product: ProductEmail 1a
213 subscription: SubscriptionEmail 1a
214 url: str 1a
217class SubscriptionCancellationProps(SubscriptionPropsBase): ... 1a
220class SubscriptionCancellationEmail(BaseModel): 1a
221 template: Literal[EmailTemplate.subscription_cancellation] = ( 1a
222 EmailTemplate.subscription_cancellation
223 )
224 props: SubscriptionCancellationProps 1a
227class SubscriptionConfirmationProps(SubscriptionPropsBase): 1a
228 order: OrderEmail 1a
231class SubscriptionConfirmationEmail(BaseModel): 1a
232 template: Literal[EmailTemplate.subscription_confirmation] = ( 1a
233 EmailTemplate.subscription_confirmation
234 )
235 props: SubscriptionConfirmationProps 1a
238class SubscriptionCycledProps(SubscriptionPropsBase): 1a
239 order: OrderEmail 1a
242class SubscriptionCycledEmail(BaseModel): 1a
243 template: Literal[EmailTemplate.subscription_cycled] = ( 1a
244 EmailTemplate.subscription_cycled
245 )
246 props: SubscriptionCycledProps 1a
249class SubscriptionPastDueProps(SubscriptionPropsBase): 1a
250 payment_url: str | None = None 1a
253class SubscriptionPastDueEmail(BaseModel): 1a
254 template: Literal[EmailTemplate.subscription_past_due] = ( 1a
255 EmailTemplate.subscription_past_due
256 )
257 props: SubscriptionPastDueProps 1a
260class SubscriptionRevokedProps(SubscriptionPropsBase): ... 1a
263class SubscriptionRevokedEmail(BaseModel): 1a
264 template: Literal[EmailTemplate.subscription_revoked] = ( 1a
265 EmailTemplate.subscription_revoked
266 )
267 props: SubscriptionRevokedProps 1a
270class SubscriptionUncanceledProps(SubscriptionPropsBase): ... 1a
273class SubscriptionUncanceledEmail(BaseModel): 1a
274 template: Literal[EmailTemplate.subscription_uncanceled] = ( 1a
275 EmailTemplate.subscription_uncanceled
276 )
277 props: SubscriptionUncanceledProps 1a
280class SubscriptionUpdatedProps(SubscriptionPropsBase): 1a
281 order: OrderEmail | None 1a
284class SubscriptionUpdatedEmail(BaseModel): 1a
285 template: Literal[EmailTemplate.subscription_updated] = ( 1a
286 EmailTemplate.subscription_updated
287 )
288 props: SubscriptionUpdatedProps 1a
291class WebhookEndpointDisabledProps(EmailProps): 1a
292 organization: Organization 1a
293 webhook_endpoint_url: str 1a
294 dashboard_url: str 1a
297class WebhookEndpointDisabledEmail(BaseModel): 1a
298 template: Literal[EmailTemplate.webhook_endpoint_disabled] = ( 1a
299 EmailTemplate.webhook_endpoint_disabled
300 )
301 props: WebhookEndpointDisabledProps 1a
304class NotificationNewSaleEmail(BaseModel): 1a
305 template: Literal[EmailTemplate.notification_new_sale] = ( 1a
306 EmailTemplate.notification_new_sale
307 )
308 props: MaintainerNewProductSaleNotificationPayload 1a
311class NotificationNewSubscriptionEmail(BaseModel): 1a
312 template: Literal[EmailTemplate.notification_new_subscription] = ( 1a
313 EmailTemplate.notification_new_subscription
314 )
315 props: MaintainerNewPaidSubscriptionNotificationPayload 1a
318class NotificationCreateAccountEmail(BaseModel): 1a
319 template: Literal[EmailTemplate.notification_create_account] = ( 1a
320 EmailTemplate.notification_create_account
321 )
322 props: MaintainerCreateAccountNotificationPayload 1a
325class OrganizationAccountUnlinkProps(EmailProps): 1a
326 organization_kept_name: str 1a
327 organizations_unlinked: list[str] 1a
330class OrganizationAccountUnlinkEmail(BaseModel): 1a
331 template: Literal[EmailTemplate.organization_account_unlink] = ( 1a
332 EmailTemplate.organization_account_unlink
333 )
334 props: OrganizationAccountUnlinkProps 1a
337Email = Annotated[ 1a
338 LoginCodeEmail
339 | CustomerSessionCodeEmail
340 | EmailUpdateEmail
341 | OAuth2LeakedClientEmail
342 | OAuth2LeakedTokenEmail
343 | OrderConfirmationEmail
344 | OrganizationAccessTokenLeakedEmail
345 | OrganizationInviteEmail
346 | OrganizationAccountUnlinkEmail
347 | OrganizationUnderReviewEmail
348 | OrganizationReviewedEmail
349 | PersonalAccessTokenLeakedEmail
350 | SeatInvitationEmail
351 | SubscriptionCancellationEmail
352 | SubscriptionConfirmationEmail
353 | SubscriptionCycledEmail
354 | SubscriptionPastDueEmail
355 | SubscriptionRevokedEmail
356 | SubscriptionUncanceledEmail
357 | SubscriptionUpdatedEmail
358 | WebhookEndpointDisabledEmail
359 | NotificationNewSaleEmail
360 | NotificationNewSubscriptionEmail
361 | NotificationCreateAccountEmail,
362 Discriminator("template"),
363]
365EmailAdapter: TypeAdapter[Email] = TypeAdapter(Email) 1a
368if __name__ == "__main__": 368 ↛ 369line 368 didn't jump to line 369 because the condition on line 368 was never true1a
369 openapi_schema = {
370 "openapi": "3.1.0",
371 "paths": {},
372 "components": {
373 "schemas": EmailAdapter.json_schema(
374 mode="serialization", ref_template="#/components/schemas/{model}"
375 )["$defs"]
376 },
377 }
378 sys.stdout.write(json.dumps(openapi_schema, indent=2))