Skip to content

Commit

Permalink
Add a PUT allowing overwriting extradata
Browse files Browse the repository at this point in the history
  • Loading branch information
cardoso-neto committed Nov 30, 2023
1 parent f3c6e4b commit 19421a9
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 2 deletions.
49 changes: 48 additions & 1 deletion api/memetrics/events/controllers.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,14 @@

from ..utils import DB, PyObjectId
from .models import EventsPerApp, EventsPerUser
from .schemas import Event, EventData, GeneratedFields, PatchEventData, PatchEventExtra
from .schemas import (
Event,
EventData,
GeneratedFields,
PatchEventData,
PatchEventExtra,
PartialAttribute,
)


def create_one(
Expand Down Expand Up @@ -83,6 +90,46 @@ def read_one(identifier: PyObjectId) -> Event:
return Event(**obj)


def replace_one(
identifier: PyObjectId, name: str, body: PartialAttribute, created_by: Creator
) -> tuple[bool, bool]:
db = DB.get()
filters = {
"_id": BsonObjectId(identifier),
"created_by.client_name": created_by.client_name,
"created_by.token_name": created_by.token_name,
"created_by.user_email": created_by.user_email,
}
res = db["events"].update_one(
filters,
{
"$set": {
f"data.extra.$[elem]": body.dict() | {"name": name},
},
},
array_filters=[{"elem.name": name}],
)
found = res.matched_count == 1
if not found:
raise HTTPException(
status_code=s.HTTP_404_NOT_FOUND,
detail=f"Event with ID '{identifier}' not found for user '{created_by}'.",
)
overwritten = res.modified_count == 1
created = False
if not overwritten:
res = db["events"].update_one(
filters,
{
"$addToSet": {
"data.extra": body.dict() | {"name": name},
},
},
)
created = res.modified_count == 1
return overwritten, created


def update_one(
identifier: PyObjectId, body: PatchEventExtra, created_by: Creator
) -> bool:
Expand Down
27 changes: 26 additions & 1 deletion api/memetrics/events/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

from . import controllers
from .helpers import help_user_edge_cases
from .schemas import EventData, GeneratedFields, PatchEventData, Event, PatchEventExtra
from .schemas import EventData, GeneratedFields, PatchEventData, Event, PatchEventExtra, PartialAttribute
from ..utils import PyObjectId, parse_sort

router = APIRouter(tags=["events"])
Expand Down Expand Up @@ -117,3 +117,28 @@ async def update_one(
if return_preference == "representation":
return controllers.read_one(identifier)
response.status_code = s.HTTP_204_NO_CONTENT


@router.put(
"/events/{identifier}/data/extra/{name}",
status_code=s.HTTP_200_OK,
responses={404: {}}, # TODO
)
async def replace_one(
request: Request,
identifier: PyObjectId,
name: str,
body: PartialAttribute = Body(..., examples=PartialAttribute.Config.examples),
):
"""
- 200: not modified (not using 304 due to PUT semantics).
- 201: created.
- 204: overwritten.
- 404: not found.
"""
overwritten, created = controllers.replace_one(identifier, name, body, request.state.creator)
if overwritten:
return Response(status_code=s.HTTP_204_NO_CONTENT)
if created:
return Response(status_code=s.HTTP_201_CREATED)
return Response(status_code=s.HTTP_200_OK)
14 changes: 14 additions & 0 deletions api/memetrics/events/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,20 @@ class Creator(BaseModel):
from ruson import PydanticObjectId as PyObjectId


class PartialAttribute(BaseModel):
type: Literal["string", "integer", "float", "dict", "list"]
value: str | int | float | dict | list

class Config:
examples = {
"string": {"value": {"type": "string", "value": "some string"}},
"integer": {"value": {"type": "integer", "value": 42}},
"float": {"value": {"type": "float", "value": 42.0}},
"dict": {"value": {"type": "dict", "value": {"key": "value"}}},
"list": {"value": {"type": "list", "value": ["item"]}},
}


class Attribute(BaseModel):
name: str
type: Literal["string", "integer", "float", "dict", "list"]
Expand Down

0 comments on commit 19421a9

Please sign in to comment.