Skip to content

Commit c4b73db

Browse files
rkorsakkeithrfung
authored andcommitted
🔀 Reorganized tally endpoints into tally and tally/append (#63)
1 parent e1cc706 commit c4b73db

File tree

2 files changed

+52
-36
lines changed

2 files changed

+52
-36
lines changed

app/api/v1/endpoints/tally.py

Lines changed: 46 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -11,58 +11,75 @@
1111
)
1212
from fastapi import APIRouter, Body, HTTPException
1313
from pydantic import BaseModel
14-
from typing import Any, List, Optional
14+
from typing import Any, List, Tuple
1515

1616
router = APIRouter()
1717

1818

19-
class AccumulateTallyRequest(BaseModel):
19+
class StartTallyRequest(BaseModel):
2020
ballots: List[Any]
21-
encrypted_tally: Optional[Any] = None
2221
description: Any
2322
context: Any
2423

2524

26-
@router.post("/accumulate")
27-
def accumulate_tally(request: AccumulateTallyRequest = Body(...)) -> Any:
25+
class AppendTallyRequest(StartTallyRequest):
26+
encrypted_tally: Any
27+
28+
29+
@router.post("")
30+
def start_tally(request: StartTallyRequest = Body(...)) -> Any:
2831
"""
29-
Accumulate ballots into a new or existing tally
32+
Start a new tally of a collection of ballots
3033
"""
3134

35+
ballots, description, context = parse_request(request)
36+
tally = CiphertextTally("election-results", description, context)
37+
38+
return tally_ballots(tally, ballots)
39+
40+
41+
@router.post("/append")
42+
def append_to_tally(request: AppendTallyRequest = Body(...)) -> Any:
43+
"""
44+
Append ballots into an existing tally
45+
"""
46+
47+
ballots, description, context = parse_request(request)
48+
49+
published_tally = PublishedCiphertextTally.from_json_object(request.encrypted_tally)
50+
tally = CiphertextTally(published_tally.object_id, description, context)
51+
tally.cast = published_tally.cast
52+
53+
return tally_ballots(tally, ballots)
54+
55+
56+
def parse_request(
57+
request: StartTallyRequest,
58+
) -> Tuple[
59+
List[CiphertextAcceptedBallot],
60+
InternalElectionDescription,
61+
CiphertextElectionContext,
62+
]:
63+
"""
64+
Deserialize common tally request values
65+
"""
3266
ballots = [
3367
CiphertextAcceptedBallot.from_json_object(ballot) for ballot in request.ballots
3468
]
3569
description = ElectionDescription.from_json_object(request.description)
3670
internal_description = InternalElectionDescription(description)
3771
context = CiphertextElectionContext.from_json_object(request.context)
38-
published_tally: Optional[PublishedCiphertextTally] = (
39-
PublishedCiphertextTally.from_json_object(request.encrypted_tally)
40-
if request.encrypted_tally
41-
else None
42-
)
4372

44-
tally = _get_new_or_existing_tally(internal_description, context, published_tally)
73+
return (ballots, internal_description, context)
4574

75+
76+
def tally_ballots(
77+
tally: CiphertextTally, ballots: List[CiphertextAcceptedBallot]
78+
) -> PublishedCiphertextTally:
4679
tally_succeeded = tally.batch_append(ballots)
4780

4881
if tally_succeeded:
4982
published_tally = publish_ciphertext_tally(tally)
5083
return published_tally.to_json_object()
5184
else:
52-
raise HTTPException(
53-
status_code=500, detail="Tally accumulation was unsuccessful"
54-
)
55-
56-
57-
def _get_new_or_existing_tally(
58-
description: ElectionDescription,
59-
context: CiphertextElectionContext,
60-
published_tally: PublishedCiphertextTally,
61-
) -> CiphertextTally:
62-
if not published_tally:
63-
return CiphertextTally("election-results", description, context)
64-
65-
full_tally = CiphertextTally(published_tally.object_id, description, context)
66-
full_tally.cast = published_tally.cast
67-
68-
return full_tally
85+
raise HTTPException(status_code=500, detail="Unable to tally ballots")

tests/ElectionGuard Web Api.postman_collection.json

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@
145145
"name": "Tally",
146146
"item": [
147147
{
148-
"name": "Accumulate Tally Step 1 (Start a new Tally)",
148+
"name": "Start a new Tally",
149149
"request": {
150150
"method": "POST",
151151
"header": [],
@@ -159,23 +159,22 @@
159159
}
160160
},
161161
"url": {
162-
"raw": "{{url}}/api/{{version}}/tally/accumulate",
162+
"raw": "{{url}}/api/{{version}}/tally",
163163
"host": [
164164
"{{url}}"
165165
],
166166
"path": [
167167
"api",
168168
"{{version}}",
169-
"tally",
170-
"accumulate"
169+
"tally"
171170
]
172171
},
173172
"description": "Start a tally by passing in a batch of ballots. This will return a tally that can be passed back in to accumulate further ballots."
174173
},
175174
"response": []
176175
},
177176
{
178-
"name": "Accumulate Tally Step 2 (Add to an existing Tally)",
177+
"name": "Append to an existing Tally",
179178
"request": {
180179
"method": "POST",
181180
"header": [],
@@ -189,15 +188,15 @@
189188
}
190189
},
191190
"url": {
192-
"raw": "{{url}}/api/{{version}}/tally/accumulate",
191+
"raw": "{{url}}/api/{{version}}/tally/append",
193192
"host": [
194193
"{{url}}"
195194
],
196195
"path": [
197196
"api",
198197
"{{version}}",
199198
"tally",
200-
"accumulate"
199+
"append"
201200
]
202201
},
203202
"description": "Add a batch of ballots to an existing tally."

0 commit comments

Comments
 (0)