Skip to content

Commit

Permalink
style: pylint and fix panda warning
Browse files Browse the repository at this point in the history
  • Loading branch information
leehanchung authored and hurshd0 committed Apr 26, 2020
1 parent 8fe6568 commit 8895bb9
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 30 deletions.
112 changes: 87 additions & 25 deletions api/endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,11 @@
# Starts the FastAPI Router to be used by the FastAPI app.
router = APIRouter()
_logger = get_logger(logger_name=__name__)
tm = TwitterMongo(app_config.DB_NAME, app_config.COLLECTION_TWITTER, verbose=False)
tm = TwitterMongo(
app_config.DB_NAME,
app_config.COLLECTION_TWITTER,
verbose=False,
)


###############################################################################
Expand Down Expand Up @@ -77,7 +81,11 @@ class NewsOut(BaseModel):
message: List[News]


@router.get("/news", response_model=NewsOut, responses={404: {"model": Message}})
@router.get(
"/news",
response_model=NewsOut,
responses={404: {"model": Message}},
)
async def get_gnews() -> JSONResponse:
"""Fetch US news from Google News API and return the results in JSON
"""
Expand All @@ -95,7 +103,11 @@ async def get_gnews() -> JSONResponse:
return json_data


@router.post("/news", response_model=NewsOut, responses={404: {"model": Message}})
@router.post(
"/news",
response_model=NewsOut,
responses={404: {"model": Message}},
)
async def post_gnews(news: NewsInput) -> JSONResponse:
"""Fetch specific state and topic news from Google News API and return the
results in JSON
Expand All @@ -109,7 +121,8 @@ async def post_gnews(news: NewsInput) -> JSONResponse:
except DataReadingError as ex:
_logger.warning(f"Endpoint: /news --- POST --- {ex}")
return JSONResponse(
status_code=404, content={"message": f"[Error] post /News API: {ex}"}
status_code=404,
content={"message": f"[Error] post /News API: {ex}"}
)

return json_data
Expand Down Expand Up @@ -142,7 +155,9 @@ class TwitterOutput(BaseModel):


@router.get(
"/twitter", response_model=TwitterOutput, responses={404: {"model": Message}}
"/twitter",
response_model=TwitterOutput,
responses={404: {"model": Message}}
)
async def get_twitter() -> JSONResponse:
"""Fetch and return Twitter data from MongoDB connection."""
Expand All @@ -158,19 +173,26 @@ async def get_twitter() -> JSONResponse:

json_data = {
"success": True,
"message": {"username": username, "full_name": full_name, "tweets": tweets},
"message": {
"username": username,
"full_name": full_name,
"tweets": tweets,
},
}
del tweets
gc.collect()
except Exception as ex:
_logger.warning(f"Endpoint: /twitter --- GET --- {ex}")
raise HTTPException(status_code=404, detail=f"[Error] get /twitter API: {ex}")
raise HTTPException(status_code=404,
detail=f"[Error] get /twitter API: {ex}")

return json_data


@router.post(
"/twitter", response_model=TwitterOutput, responses={404: {"model": Message}}
"/twitter",
response_model=TwitterOutput,
responses={404: {"model": Message}}
)
async def post_twitter(twyuser: TwitterInput) -> JSONResponse:
"""Fetch and return Twitter data from MongoDB connection."""
Expand All @@ -184,14 +206,19 @@ async def post_twitter(twyuser: TwitterInput) -> JSONResponse:
tweets = sorted(tweets, key=lambda i: i["created_at"], reverse=True)
json_data = {
"success": True,
"message": {"username": username, "full_name": full_name, "tweets": tweets},
"message": {
"username": username,
"full_name": full_name,
"tweets": tweets,
},
}

del tweets
gc.collect()
except Exception as ex:
_logger.warning(f"Endpoint: /twitter --- POST --- {ex}")
raise HTTPException(status_code=404, detail=f"[Error] post /twitter API: {ex}")
raise HTTPException(status_code=404,
detail=f"[Error] post /twitter API: {ex}")

return json_data

Expand Down Expand Up @@ -225,7 +252,11 @@ class CountyOut(BaseModel):


@cached(cache=TTLCache(maxsize=1, ttl=3600))
@router.get("/county", response_model=CountyOut, responses={404: {"model": Message}})
@router.get(
"/county",
response_model=CountyOut,
responses={404: {"model": Message}}
)
async def get_county_data() -> JSONResponse:
"""Get all US county data and return it as a big fat json string. Respond
with 404 if run into error.
Expand All @@ -238,12 +269,18 @@ async def get_county_data() -> JSONResponse:
gc.collect()
except Exception as ex:
_logger.warning(f"Endpoint: /county --- GET --- {ex}")
raise HTTPException(status_code=404, detail=f"[Error] get '/county' API: {ex}")
raise HTTPException(
status_code=404,
detail=f"[Error] get '/county' API: {ex}")

return json_data


@router.post("/county", response_model=CountyOut, responses={404: {"model": Message}})
@router.post(
"/county",
response_model=CountyOut,
responses={404: {"model": Message}}
)
def post_county(county: CountyInput) -> JSONResponse:
"""Get all US county data and return it as a big fat json string. Respond
with 404 if run into error.
Expand All @@ -255,7 +292,8 @@ def post_county(county: CountyInput) -> JSONResponse:
gc.collect()
except Exception as ex:
_logger.warning(f"Endpoint: /county --- POST --- {ex}")
raise HTTPException(status_code=404, detail=f"[Error] get '/county' API: {ex}")
raise HTTPException(status_code=404,
detail=f"[Error] get '/county' API: {ex}")

return json_data

Expand All @@ -281,7 +319,11 @@ class StateOutput(BaseModel):


@cached(cache=TTLCache(maxsize=3, ttl=3600))
@router.post("/state", response_model=StateOutput, responses={404: {"model": Message}})
@router.post(
"/state",
response_model=StateOutput,
responses={404: {"model": Message}}
)
async def post_state(state: StateInput) -> JSONResponse:
"""Fetch state level data time series for a single state, ignoring the
unattributed and out of state cases.
Expand All @@ -295,7 +337,8 @@ async def post_state(state: StateInput) -> JSONResponse:
gc.collect()
except Exception as ex:
_logger.warning(f"Endpoint: /state --- POST --- {ex}")
raise HTTPException(status_code=404, detail=f"[Error] get /country API: {ex}")
raise HTTPException(status_code=404,
detail=f"[Error] get /country API: {ex}")

return json_data

Expand All @@ -322,7 +365,9 @@ class CountryOutput(BaseModel):

@cached(cache=TTLCache(maxsize=3, ttl=3600))
@router.post(
"/country", response_model=CountryOutput, responses={404: {"model": Message}}
"/country",
response_model=CountryOutput,
responses={404: {"model": Message}},
)
async def get_country(country: CountryInput) -> JSONResponse:
"""Fetch country level data time series for a single country.
Expand All @@ -334,7 +379,8 @@ async def get_country(country: CountryInput) -> JSONResponse:
json_data = {"success": True, "message": data}
except Exception as ex:
_logger.warning(f"Endpoint: /country --- GET --- {ex}")
raise HTTPException(status_code=404, detail=f"[Error] get /country API: {ex}")
raise HTTPException(status_code=404,
detail=f"[Error] get /country API: {ex}")

return json_data

Expand Down Expand Up @@ -362,7 +408,11 @@ class StatsOutput(BaseModel):
message: Stats


@router.get("/stats", response_model=StatsOutput, responses={404: {"model": Message}})
@router.get(
"/stats",
response_model=StatsOutput,
responses={404: {"model": Message}}
)
async def get_stats() -> JSONResponse:
"""Get overall tested, confirmed, and deaths stats from the database
and return it as a JSON string.
Expand All @@ -372,11 +422,16 @@ async def get_stats() -> JSONResponse:
json_data = {"success": True, "message": data}
except Exception as ex:
_logger.warning(f"Endpoint: /stats --- GET --- {ex}")
raise HTTPException(status_code=404, detail=f"[Error] get /stats API: {ex}")
raise HTTPException(status_code=404,
detail=f"[Error] get /stats API: {ex}")
return json_data


@router.post("/stats", response_model=StatsOutput, responses={404: {"model": Message}})
@router.post(
"/stats",
response_model=StatsOutput,
responses={404: {"model": Message}}
)
async def post_stats(stats: StatsInput) -> JSONResponse:
"""Get overall tested, confirmed, and deaths stats from the database
and return it as a JSON string.
Expand All @@ -386,7 +441,8 @@ async def post_stats(stats: StatsInput) -> JSONResponse:
json_data = {"success": True, "message": data}
except Exception as ex:
_logger.warning(f"Endpoint: /stats --- POST --- {ex}")
raise HTTPException(status_code=404, detail=f"[Error] post /stats API: {ex}")
raise HTTPException(status_code=404,
detail=f"[Error] post /stats API: {ex}")
return json_data


Expand Down Expand Up @@ -417,15 +473,20 @@ class ZIPOutput(BaseModel):
message: ZIPStats


@router.post("/zip", response_model=ZIPOutput, responses={404: {"model": Message}})
@router.post(
"/zip",
response_model=ZIPOutput,
responses={404: {"model": Message}}
)
def post_zip(zip_code: ZIPInput) -> JSONResponse:
"""Returns county stats for the zip code input.
"""

try:
zip_info = zipcodes.matching(zip_code.zip_code)[0]
except Exception as ex:
message = f"ZIP code {zip_code.zip_code}" " not found in US Zipcode database."
message = (f"ZIP code {zip_code.zip_code}"
" not found in US Zipcode database.")
_logger.warning(f"Endpoint: /zip --- POST --- {ex} {message}")
raise HTTPException(
status_code=422, detail=f"[Error] POST '/zip' {ex} {message}"
Expand Down Expand Up @@ -453,6 +514,7 @@ def post_zip(zip_code: ZIPInput) -> JSONResponse:
gc.collect()
except Exception as ex:
_logger.warning(f"Endpoint: /zip --- POST --- {ex}")
raise HTTPException(status_code=404, detail=f"[Error] get '/zip' API: {ex}")
raise HTTPException(status_code=404,
detail=f"[Error] get '/zip' API: {ex}")

return json_data
9 changes: 7 additions & 2 deletions api/utils/county.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ def read_county_stats(state: str, county: str) -> Dict:
territories = ["DC", "GU", "AS", "PR", "MP"]

# Fetch state data
full_state_name = state
try:
full_state_name = reverse_states_map[state]
df = df[df["state_name"] == full_state_name]
Expand All @@ -108,7 +109,10 @@ def read_county_stats(state: str, county: str) -> Dict:
# Now fetch county data
try:
if state in territories:
df["county_name"] = full_state_name
df = df.reset_index(drop=True)
df.loc[0, "county_name"] = full_state_name
# 2020-04-26 pandanmic
# df["county_name"] == full_state_name
else:
df = df[df["county_name"] == county]
if len(df) == 0:
Expand All @@ -117,7 +121,8 @@ def read_county_stats(state: str, county: str) -> Dict:
)
except:
raise DataValidationError(
f"Can't find State: {full_state_name}, and County: {county} combination."
f"Can't find State: {full_state_name},"
f" and County: {county} combination."
)
df = pd.DataFrame.to_dict(df, orient="records")
return df
Expand Down
14 changes: 11 additions & 3 deletions api/utils/gnews.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
from api.config import app_config


def get_state_topic_google_news(state: str, topic: str, max_rows: int = 10) -> Dict:
def get_state_topic_google_news(state: str,
topic: str,
max_rows: int = 10) -> Dict:
"""This function takes a US State name (string dtype) and a topic of
interest (string dtype). The output is a pandas DataFrame with articles,
urls, and publishing times for articles containing the state and topic
Expand Down Expand Up @@ -45,7 +47,12 @@ def get_state_topic_google_news(state: str, topic: str, max_rows: int = 10) -> D
state_id_for_articles.append(state)

df = pd.DataFrame(
[list_of_titles, list_of_article_links, list_of_pubdates, state_id_for_articles]
[
list_of_titles,
list_of_article_links,
list_of_pubdates,
state_id_for_articles
]
).T
df.columns = ["title", "url", "published", "state"]
df["source"] = df["title"].str.split("-").str[-1]
Expand All @@ -72,7 +79,8 @@ def get_us_news(max_rows: int = 50) -> Dict:
df = pd.DataFrame(df[["title", "url", "publishedAt"]])
df = df.rename(columns={"publishedAt": "published"})
# Infer datetime
df["published"] = pd.to_datetime(df["published"], infer_datetime_format=True)
df["published"] = pd.to_datetime(df["published"],
infer_datetime_format=True)
# Assuming timedelta of 5 hr based on what comparison between CNN and API.
df["published"] = df["published"] - pd.Timedelta("5 hours")

Expand Down

0 comments on commit 8895bb9

Please sign in to comment.