Skip to content

Commit

Permalink
Backend: add month as a filter with lower precedence than day
Browse files Browse the repository at this point in the history
  • Loading branch information
rabinadk1 committed Apr 13, 2022
1 parent 7d7cfad commit cacb243
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 12 deletions.
4 changes: 3 additions & 1 deletion server/app/pseudo_tweets/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
TweetRead,
TweetUpdate,
)
from ..tweets_common.types import Month
from . import router


Expand All @@ -45,13 +46,14 @@ def read_pseudo_tweets(
limit: conint(le=10, gt=0) = 10,
topics: Optional[List[Topics]] = Query(None),
day: Optional[date] = None,
month: Optional[Month] = Query(None, description="Month in %Y-%m format"),
maximize_labels: bool = False,
session: Session = Depends(get_session),
):
"""
Read pseudo tweets within the offset and limit
"""
selection = get_filtered_selection(topics, day, PseudoTweet)
selection = get_filtered_selection(topics, day, month, PseudoTweet)

# others should be exclusively provided, hence the last check
is_others = topics is not None and len(topics) and topics[0] == Topics.others
Expand Down
4 changes: 3 additions & 1 deletion server/app/tweets/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
make_tweet_read,
)
from ..tweets_common.models import Overview, Topics, Tweet, TweetRead, TweetUpdate
from ..tweets_common.types import Month
from . import router


Expand All @@ -35,12 +36,13 @@ def read_tweets(
limit: conint(le=10, gt=0) = 10,
topics: Optional[List[Topics]] = Query(None),
day: Optional[date] = None,
month: Optional[Month] = Query(None, description="Month in %Y-%m format"),
session: Session = Depends(get_session),
):
"""
Read tweets within the offset and limit
"""
selection = get_filtered_selection(topics, day, Tweet)
selection = get_filtered_selection(topics, day, month, Tweet)

tweets = session.exec(
selection.order_by(Tweet.id.desc()).offset(offset).limit(limit)
Expand Down
15 changes: 11 additions & 4 deletions server/app/tweets_common/helper_functions.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
from datetime import date
from typing import Any, Callable, List, Optional, Tuple, TypeVar
from typing import Callable, List, Optional, Tuple, TypeVar

from fastapi import HTTPException
from pydantic import PositiveInt
from sqlmodel import Integer, Session, and_, func, not_, select, text, union_all
from sqlmodel.sql.expression import Select

from .models import PseudoTweet, Topics, Tweet, TweetRead, TweetUpdate
from .types import Month

# Make a Generic Type to get the original type completion back
ModelType = TypeVar("ModelType", Tweet, PseudoTweet)
Expand All @@ -15,6 +16,7 @@
def get_filtered_selection(
topics: Optional[List[Topics]],
day: Optional[date],
month: Optional[Month],
Model: ModelType,
):
"""
Expand All @@ -31,13 +33,18 @@ def get_filtered_selection(
# Since others is defined in the selection, directly provide the column
filter = text(Topics.others)
else:

filter = and_(*tuple(getattr(Model, topic) for topic in topics))

selection = selection.filter(filter)

if day is not None:
selection = selection.filter(func.date(Model.created_at) == day)
if day is not None or month is not None:
# If both specified, use day only
filter = (
func.date(Model.created_at) == day
if day is not None
else func.strftime("%Y-%m", Model.created_at) == month
)
selection = selection.filter(filter)

return selection

Expand Down
43 changes: 43 additions & 0 deletions server/app/tweets_common/types.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
class Month(str):
"""
Month with the year corresponding to it.
It is epected in the format of %Y-%m.
"""

@classmethod
def __get_validators__(cls):
# one or more validators may be yielded which will be called in the
# order to validate the input, each validator will receive as an input
# the value returned from the previous validator
yield cls.validate

@classmethod
def validate(cls, v):
if not isinstance(v, str):
raise TypeError("string required")

splits = v.strip().split("-", 1)

if len(splits) != 2:
raise ValueError("Month Format should be: %Y-%m")

for s in splits:
if not s.isdecimal():
raise ValueError(f"{s} is not a number.")

year, month = tuple(map(int, splits))

# Twitter was established in 2006
if year < 2006 or year > 2100:
raise ValueError(f"{year} is not a valid year.")

if month < 1 or month > 12:
raise ValueError(f"{month} is not a valid month.")

# you could also return a string here pydantic won't care
# but you could end up with some confusion since the
# value's type won't match the type annotation exactly
return cls(f"{year}-{month:02}")

def __repr__(self):
return f"Month: {super().__repr__()}"
7 changes: 3 additions & 4 deletions server/test/test_utils.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
from typing import List

from app.tweets_common.models import PseudoTweet, Tweet
from sqlalchemy.exc import OperationalError
from sqlmodel import Session

from app.tweets_common.models import PseudoTweet, Tweet
from utils.load_labels import load_database as load_label
from utils.load_pseudo_labels import load_database as load_pseudo_label

from sqlmodel import Session
from sqlalchemy.exc import OperationalError


def test_labels(session: Session):
# Test suite may not contain the database to get the verifier id
Expand Down
3 changes: 1 addition & 2 deletions server/utils/load_labels.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@
from sqlmodel import Session, select

from app.auth.models import User
from app.tweets_common.models import Tweet

from app.database import get_session
from app.tweets_common.models import Tweet


def load_database(write_session: Session):
Expand Down

0 comments on commit cacb243

Please sign in to comment.