Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mc type hinting and docstring resources #221

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion client/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 20 additions & 1 deletion resources/Agencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
from middleware.security import api_required
from utilities.common import convert_dates_to_strings
import json
from typing import Dict, Any, List


approved_columns = [
"name",
Expand Down Expand Up @@ -34,11 +36,28 @@


class Agencies(Resource):
"""Represents a resource for fetching approved agency data from the database."""

def __init__(self, **kwargs):
"""
Initializes the Agencies resource with a database connection.

Parameters:
- kwargs (dict): Keyword arguments containing 'psycopg2_connection' for database connection.
"""
self.psycopg2_connection = kwargs["psycopg2_connection"]

@api_required
def get(self, page):
def get(self, page: str) -> Dict[str, Any]:
"""
Retrieves a paginated list of approved agencies from the database.

Parameters:
- page (str): The page number of results to return.

Returns:
- dict: A dictionary containing the count of returned agencies and their data.
"""
try:
cursor = self.psycopg2_connection.cursor()
joined_column_names = ", ".join(approved_columns)
Expand Down
19 changes: 17 additions & 2 deletions resources/ApiKey.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,30 @@
from flask import request
from middleware.login_queries import login_results
import uuid
from typing import Dict, Any, Optional


class ApiKey(Resource):
"""Represents a resource for generating an API key for authenticated users."""

def __init__(self, **kwargs):
"""
Initializes the ApiKey resource with a database connection.

Parameters:
- kwargs (dict): Keyword arguments containing 'psycopg2_connection' for database connection.
"""
self.psycopg2_connection = kwargs["psycopg2_connection"]

def get(self):
def get(self) -> Optional[Dict[str, Any]]:
"""
Generate an API key for a user that successfully logs in
Authenticates a user based on provided credentials and generates an API key.

Reads the 'email' and 'password' from the JSON body of the request, validates the user,
and if successful, generates and returns a new API key.

Returns:
- dict: A dictionary containing the generated API key, or None if an error occurs.
"""
try:
data = request.get_json()
Expand Down
31 changes: 29 additions & 2 deletions resources/Archives.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,33 @@
from flask_restful import Resource, request

import json
from typing import Dict, Any, List


class Archives(Resource):
"""
A resource for managing archive data, allowing retrieval and update of archived data sources.
"""

def __init__(self, **kwargs):
"""
Initializes the Archives resource with a database connection.

Parameters:
- kwargs (dict): Keyword arguments containing 'psycopg2_connection' for database connection.
"""
self.psycopg2_connection = kwargs["psycopg2_connection"]

@api_required
def get(self):
def get(self) -> Any:
"""
Retrieves archived data sources from the database.

Uses an API-required middleware for security and a database connection to fetch archived data.

Returns:
- Any: The cleaned results of archives combined from the database query, or an error message if an exception occurs.
"""
try:
archives_combined_results_clean = archives_get_query(
test_query_results=[], conn=self.psycopg2_connection
Expand All @@ -24,7 +43,15 @@ def get(self):
return "There has been an error pulling data!"

@api_required
def put(self):
def put(self) -> Dict[str, str]:
"""
Updates the archive data based on the provided JSON payload.

Expects a JSON payload with archive data source identifiers and updates them in the database.

Returns:
- dict: A status message indicating success or an error message if an exception occurs.
"""
try:
json_data = request.get_json()
data = json.loads(json_data)
Expand Down
61 changes: 57 additions & 4 deletions resources/DataSources.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,35 @@
from datetime import datetime

import uuid
from typing import Dict, Any, Tuple


class DataSourceById(Resource):
"""
A resource for managing data source entities by their unique identifier.
Provides methods for retrieving and updating data source details.
"""

def __init__(self, **kwargs):
"""
Initializes the DataSourceById resource with a database connection.

Parameters:
- kwargs (dict): Keyword arguments containing 'psycopg2_connection' for database connection.
"""
self.psycopg2_connection = kwargs["psycopg2_connection"]

@api_required
def get(self, data_source_id):
def get(self, data_source_id: str) -> Tuple[Dict[str, Any], int]:
"""
Retrieves details of a specific data source by its ID.

Parameters:
- data_source_id (str): The unique identifier of the data source.

Returns:
- Tuple containing the response message with data source details if found, and the HTTP status code.
"""
try:
data_source_details = data_source_by_id_query(
conn=self.psycopg2_connection, data_source_id=data_source_id
Expand All @@ -32,7 +53,16 @@ def get(self, data_source_id):
return {"message": "There has been an error pulling data!"}, 500

@api_required
def put(self, data_source_id):
def put(self, data_source_id: str) -> Dict[str, str]:
"""
Updates a data source by its ID based on the provided JSON payload.

Parameters:
- data_source_id (str): The unique identifier of the data source to update.

Returns:
- A dictionary containing a message about the update operation.
"""
try:
data = request.get_json()

Expand Down Expand Up @@ -73,11 +103,28 @@ def put(self, data_source_id):


class DataSources(Resource):
"""
A resource for managing collections of data sources.
Provides methods for retrieving all data sources and adding new ones.
"""

def __init__(self, **kwargs):
"""
Initializes the DataSources resource with a database connection.

Parameters:
- kwargs (dict): Keyword arguments containing 'psycopg2_connection' for database connection.
"""
self.psycopg2_connection = kwargs["psycopg2_connection"]

@api_required
def get(self):
def get(self) -> Dict[str, Any]:
"""
Retrieves all data sources.

Returns:
- A dictionary containing the count of data sources and their details.
"""
try:
data_source_matches = data_sources_query(
self.psycopg2_connection, [], "approved"
Expand All @@ -96,7 +143,13 @@ def get(self):
return {"message": "There has been an error pulling data!"}, 500

@api_required
def post(self):
def post(self) -> Dict[str, str]:
"""
Adds a new data source based on the provided JSON payload.

Returns:
- A dictionary containing a message about the addition operation.
"""
try:
data = request.get_json()
cursor = self.psycopg2_connection.cursor()
Expand Down
19 changes: 16 additions & 3 deletions resources/Login.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,30 @@
from flask_restful import Resource
from flask import request
from middleware.login_queries import login_results, create_session_token
from typing import Dict, Any


class Login(Resource):
"""
A resource for authenticating users. Allows users to log in using their email and password.
"""

def __init__(self, **kwargs):
"""
Initializes the Login resource with a database connection.

Parameters:
- kwargs (dict): Keyword arguments containing 'psycopg2_connection' for database connection.
"""
self.psycopg2_connection = kwargs["psycopg2_connection"]

def post(self):
"""
Login function: allows a user to login using their email and password as credentials
The password is compared to the hashed password stored in the users table
Once the password is verified, an API key is generated, which is stored in the users table and sent to the verified user
Processes the login request. Validates user credentials against the stored hashed password and,
if successful, generates a session token for the user.

Returns:
- A dictionary containing a message of success or failure, and the session token if successful.
"""
try:
data = request.get_json()
Expand Down
26 changes: 25 additions & 1 deletion resources/QuickSearch.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,40 @@
import os
from middleware.initialize_psycopg2_connection import initialize_psycopg2_connection
from flask import request
from typing import Dict, Any, Optional


class QuickSearch(Resource):
"""
Provides a resource for performing quick searches in the database for data sources
based on user-provided search terms and location.
"""

def __init__(self, **kwargs):
"""
Initializes the QuickSearch resource with a database connection.

Parameters:
- kwargs (dict): Keyword arguments containing 'psycopg2_connection' for database connection.
"""
self.psycopg2_connection = kwargs["psycopg2_connection"]

# api_required decorator requires the request"s header to include an "Authorization" key with the value formatted as "Bearer [api_key]"
# A user can get an API key by signing up and logging in (see User.py)
@api_required
def get(self, search, location):
def get(self, search: str, location: str) -> Dict[str, Any]:
"""
Performs a quick search using the provided search terms and location. It attempts to find relevant
data sources in the database. If no results are found initially, it re-initializes the database
connection and tries again.

Parameters:
- search (str): The search term provided by the user.
- location (str): The location provided by the user.

Returns:
- A dictionary containing a message about the search results and the data found, if any.
"""
try:
data = request.get_json()
test = data.get("test_flag")
Expand Down
22 changes: 18 additions & 4 deletions resources/RefreshSession.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,31 @@
from flask import request
from middleware.login_queries import token_results, create_session_token
from datetime import datetime as dt
from typing import Dict, Any


class RefreshSession(Resource):
"""
Provides a resource for refreshing a user's session token.
If the provided session token is valid and not expired, it is replaced with a new one.
"""

def __init__(self, **kwargs):
"""
Initializes the RefreshSession resource with a database connection.

Parameters:
- kwargs (dict): Keyword arguments containing 'psycopg2_connection' for database connection.
"""
self.psycopg2_connection = kwargs["psycopg2_connection"]

def post(self):
def post(self) -> Dict[str, Any]:
"""
Login function: allows a user to login using their email and password as credentials
The password is compared to the hashed password stored in the users table
Once the password is verified, an API key is generated, which is stored in the users table and sent to the verified user
Processes the session token refresh request. If the provided session token is valid,
it generates a new session token, invalidates the old one, and returns the new token.

Returns:
- A dictionary containing a message of success or failure, and the new session token if successful.
"""
try:
data = request.get_json()
Expand Down
21 changes: 20 additions & 1 deletion resources/RequestResetPassword.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,32 @@
import os
import uuid
import requests
from typing import Dict, Any


class RequestResetPassword(Resource):
"""
Provides a resource for users to request a password reset. Generates a reset token
and sends an email to the user with instructions on how to reset their password.
"""

def __init__(self, **kwargs):
"""
Initializes the RequestResetPassword resource with a database connection.

Parameters:
- kwargs (dict): Keyword arguments containing 'psycopg2_connection' for database connection.
"""
self.psycopg2_connection = kwargs["psycopg2_connection"]

def post(self):
def post(self) -> Dict[str, Any]:
"""
Processes a password reset request. Checks if the user's email exists in the database,
generates a reset token, and sends an email with the reset link.

Returns:
- A dictionary containing a success message and the reset token, or an error message if an exception occurs.
"""
try:
data = request.get_json()
email = data.get("email")
Expand Down
Loading
Loading