-
-
Notifications
You must be signed in to change notification settings - Fork 300
Expand file tree
/
Copy pathstatistics.py
More file actions
202 lines (181 loc) · 5.74 KB
/
statistics.py
File metadata and controls
202 lines (181 loc) · 5.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
import io
from typing import Optional
from databases import Database
from fastapi import APIRouter, Depends, Query
from fastapi.responses import StreamingResponse
from backend.db import get_db
from backend.exceptions import BadRequest
from backend.services.mapswipe_service import MapswipeService
from backend.services.partner_service import PartnerService
MAPSWIPE_GROUP_EMPTY_SUBCODE = "EMPTY_MAPSWIPE_GROUP"
MAPSWIPE_GROUP_EMPTY_MESSAGE = "Mapswipe group is not set for this partner."
def is_valid_group_id(group_id: Optional[str]) -> bool:
return group_id is not None and len(group_id) > 0
router = APIRouter(
prefix="/partners",
tags=["partners"],
responses={404: {"description": "Not found"}},
)
@router.get("/{permalink:str}/filtered-statistics/")
async def get_filtered_statistics(
permalink: str,
from_date: str | None = Query(
default=None,
alias="fromDate",
description="Fetch partner statistics from date as yyyy-mm-dd",
example="2024-01-01",
),
to_date: str | None = Query(
default=None,
alias="toDate",
description="Fetch partner statistics to date as yyyy-mm-dd",
example="2024-09-01",
),
db: Database = Depends(get_db),
):
"""
Get partner statistics by id and time range
---
tags:
- partners
produces:
- application/json
parameters:
- in: query
name: fromDate
type: string
description: Fetch partner statistics from date as yyyy-mm-dd
example: "2024-01-01"
- in: query
name: toDate
type: string
example: "2024-09-01"
description: Fetch partner statistics to date as yyyy-mm-dd
- name: partner_id
in: path
- name: permalink
in: path
description: The permalink of the partner
required: true
type: string
responses:
200:
description: Partner found
401:
description: Unauthorized - Invalid credentials
404:
description: Partner not found
500:
description: Internal Server Error
"""
if from_date is None:
raise BadRequest(
sub_code="INVALID_TIME_RANGE",
message="fromDate is missing",
from_date=from_date,
to_date=to_date,
)
if to_date is None:
raise BadRequest(
sub_code="INVALID_TIME_RANGE",
message="toDate is missing",
from_date=from_date,
to_date=to_date,
)
if from_date > to_date:
raise BadRequest(
sub_code="INVALID_TIME_RANGE",
message="fromDate should be less than toDate",
from_date=from_date,
to_date=to_date,
)
partner = await PartnerService.get_partner_by_permalink(permalink, db)
if not is_valid_group_id(partner.mapswipe_group_id):
raise BadRequest(
sub_code=MAPSWIPE_GROUP_EMPTY_SUBCODE,
message=MAPSWIPE_GROUP_EMPTY_MESSAGE,
)
mapswipe = MapswipeService()
try:
result = await mapswipe.fetch_filtered_partner_stats(
partner.id, partner.mapswipe_group_id, from_date, to_date
)
finally:
await mapswipe.aclose()
return result
@router.get("/{permalink:str}/general-statistics/")
async def get_general_statistics(
permalink: str,
limit: int = Query(10, description="The number of partner members to fetch"),
offset: int = Query(
0, description="The starting index from which to fetch partner members"
),
download_as_csv: bool = Query(
False, alias="downloadAsCSV", description="Download users in this group as CSV"
),
db: Database = Depends(get_db),
):
"""
Get partner statistics by id and broken down by each contributor.
This API is paginated with limit and offset query parameters.
---
tags:
- partners
produces:
- application/json
parameters:
- in: query
name: limit
description: The number of partner members to fetch
type: integer
example: 10
- in: query
name: offset
description: The starting index from which to fetch partner members
type: integer
example: 0
- in: query
name: downloadAsCSV
description: Download users in this group as CSV
type: boolean
example: false
- name: permalink
in: path
description: The permalink of the partner
required: true
type: string
responses:
200:
description: Partner found
401:
description: Unauthorized - Invalid credentials
404:
description: Partner not found
500:
description: Internal Server Error
"""
partner = await PartnerService.get_partner_by_permalink(permalink, db)
if not is_valid_group_id(partner.mapswipe_group_id):
raise BadRequest(
sub_code=MAPSWIPE_GROUP_EMPTY_SUBCODE,
message=MAPSWIPE_GROUP_EMPTY_MESSAGE,
)
mapswipe = MapswipeService()
try:
group_dto = await mapswipe.fetch_grouped_partner_stats(
partner.id,
partner.mapswipe_group_id,
limit,
offset,
download_as_csv,
)
finally:
await mapswipe.aclose()
if download_as_csv:
csv_content = group_dto.to_csv()
return StreamingResponse(
content=io.StringIO(csv_content),
media_type="text/csv",
headers={"Content-Disposition": "attachment; filename=partner_members.csv"},
)
return group_dto