Coverage for polar/meter/schemas.py: 100%
35 statements
« prev ^ index » next coverage.py v7.10.6, created at 2025-12-05 15:52 +0000
« prev ^ index » next coverage.py v7.10.6, created at 2025-12-05 15:52 +0000
1from datetime import datetime 1a
2from typing import Annotated 1a
4from fastapi import Path 1a
5from pydantic import UUID4, Field 1a
7from polar.kit.metadata import ( 1a
8 MetadataInputMixin,
9 MetadataOutputMixin,
10)
11from polar.kit.schemas import IDSchema, Schema, TimestampedSchema 1a
12from polar.meter.aggregation import Aggregation 1a
13from polar.meter.filter import Filter 1a
14from polar.organization.schemas import OrganizationID 1a
16NAME_DESCRIPTION = ( 1a
17 "The name of the meter. Will be shown on customer's invoices and usage."
18)
19_filter_description = ( 1a
20 "The filter to apply on events that'll be used to calculate the meter."
21)
22_aggregation_description = ( 1a
23 "The aggregation to apply on the filtered events to calculate the meter."
24)
27class MeterCreate(Schema, MetadataInputMixin): 1a
28 name: str = Field(..., description=NAME_DESCRIPTION, min_length=3) 1a
29 filter: Filter = Field(..., description=_filter_description) 1a
30 aggregation: Aggregation = Field(..., description=_aggregation_description) 1a
31 organization_id: OrganizationID | None = Field( 1a
32 default=None,
33 description=(
34 "The ID of the organization owning the meter. "
35 "**Required unless you use an organization token.**"
36 ),
37 )
40class MeterUpdate(Schema, MetadataInputMixin): 1a
41 name: str | None = Field(None, description=NAME_DESCRIPTION, min_length=3) 1a
42 filter: Filter | None = Field(None, description=_filter_description) 1a
43 aggregation: Aggregation | None = Field(None, description=_aggregation_description) 1a
44 is_archived: bool | None = Field( 1a
45 None,
46 description=(
47 "Whether the meter is archived. "
48 "Archived meters are no longer used for billing."
49 ),
50 )
53class Meter(IDSchema, TimestampedSchema, MetadataOutputMixin): 1a
54 name: str = Field(..., description=NAME_DESCRIPTION) 1a
55 filter: Filter = Field(..., description=_filter_description) 1a
56 aggregation: Aggregation = Field(..., description=_aggregation_description) 1a
57 organization_id: UUID4 = Field( 1a
58 ..., description="The ID of the organization owning the meter."
59 )
60 archived_at: datetime | None = Field( 1a
61 None, description="Whether the meter is archived and the time it was archived."
62 )
65MeterID = Annotated[UUID4, Path(description="The meter ID.")] 1a
68class MeterQuantity(Schema): 1a
69 timestamp: datetime = Field(description="The timestamp for the current period.") 1a
70 quantity: float = Field( 1a
71 description="The quantity for the current period.", examples=[10.0]
72 )
75class MeterQuantities(Schema): 1a
76 quantities: list[MeterQuantity] 1a
77 total: float = Field( 1a
78 description="The total quantity for the period.", examples=[100.0]
79 )