-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
## Summary Fixes #3057 ### Time to review: 30 mins ## Changes proposed Add agencies API supporting pagination and basic filtering (future requirements around shape TBD) ## Context for reviewers Open question: What should the schema return? Right now we are returning all Agency model fields. Maybe we should make this payload smaller depending on the frontend needs. ## Additional information See attached unit test
- Loading branch information
1 parent
cee2bbb
commit fbd3544
Showing
9 changed files
with
500 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
from src.api.agencies_v1.agency_blueprint import agency_blueprint | ||
|
||
# import agency_routes module to register the API routes on the blueprint | ||
import src.api.agencies_v1.agency_routes # noqa: F401 E402 isort:skip | ||
|
||
__all__ = ["agency_blueprint"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
from apiflask import APIBlueprint | ||
|
||
agency_blueprint = APIBlueprint( | ||
"agency_v1", | ||
__name__, | ||
tag="Agency v1", | ||
cli_group="agency_v1", | ||
url_prefix="/v1", | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import logging | ||
|
||
import src.adapters.db as db | ||
import src.adapters.db.flask_db as flask_db | ||
import src.api.agencies_v1.agency_schema as agency_schema | ||
import src.api.response as response | ||
from src.api.agencies_v1.agency_blueprint import agency_blueprint | ||
from src.auth.api_key_auth import api_key_auth | ||
from src.logging.flask_logger import add_extra_data_to_current_request_logs | ||
from src.services.agencies_v1.get_agencies import AgencyListParams, get_agencies | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
examples = { | ||
"example1": { | ||
"summary": "No filters", | ||
"value": { | ||
"pagination": { | ||
"order_by": "created_at", | ||
"page_offset": 1, | ||
"page_size": 25, | ||
"sort_direction": "descending", | ||
}, | ||
}, | ||
}, | ||
} | ||
|
||
|
||
@agency_blueprint.post("/agencies") | ||
@agency_blueprint.input( | ||
agency_schema.AgencyListRequestSchema, | ||
arg_name="raw_list_params", | ||
examples=examples, | ||
) | ||
@agency_blueprint.output(agency_schema.AgencyListResponseSchema) | ||
@agency_blueprint.auth_required(api_key_auth) | ||
@flask_db.with_db_session() | ||
def agencies_get(db_session: db.Session, raw_list_params: dict) -> response.ApiResponse: | ||
list_params: AgencyListParams = AgencyListParams.model_validate(raw_list_params) | ||
|
||
# Call service with params to get results | ||
with db_session.begin(): | ||
results, pagination_info = get_agencies(db_session, list_params) | ||
|
||
add_extra_data_to_current_request_logs( | ||
{ | ||
"response.pagination.total_pages": pagination_info.total_pages, | ||
"response.pagination.total_records": pagination_info.total_records, | ||
} | ||
) | ||
logger.info("Successfully fetched agencies") | ||
|
||
# Serialize results | ||
return response.ApiResponse(message="Success", data=results, pagination_info=pagination_info) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
from src.api.schemas.extension import Schema, fields | ||
from src.api.schemas.response_schema import AbstractResponseSchema, PaginationMixinSchema | ||
from src.constants.lookup_constants import AgencyDownloadFileType | ||
from src.pagination.pagination_schema import generate_pagination_schema | ||
|
||
|
||
class AgencyFilterV1Schema(Schema): | ||
agency_id = fields.Integer() | ||
|
||
|
||
class AgencyListRequestSchema(Schema): | ||
filters = fields.Nested(AgencyFilterV1Schema()) | ||
pagination = fields.Nested( | ||
generate_pagination_schema( | ||
"AgencyPaginationV1Schema", | ||
["created_at"], | ||
), | ||
required=True, | ||
) | ||
|
||
|
||
class AgencyContactInfoSchema(Schema): | ||
"""Schema for agency contact information""" | ||
|
||
contact_name = fields.String(metadata={"description": "Full name of the agency contact person"}) | ||
address_line_1 = fields.String(metadata={"description": "Primary street address of the agency"}) | ||
address_line_2 = fields.String( | ||
allow_none=True, | ||
metadata={"description": "Additional address information (suite, unit, etc.)"}, | ||
) | ||
city = fields.String(metadata={"description": "City where the agency is located"}) | ||
state = fields.String(metadata={"description": "State where the agency is located"}) | ||
zip_code = fields.String(metadata={"description": "Postal code for the agency address"}) | ||
phone_number = fields.String(metadata={"description": "Contact phone number for the agency"}) | ||
primary_email = fields.String( | ||
metadata={"description": "Main email address for agency communications"} | ||
) | ||
secondary_email = fields.String( | ||
allow_none=True, | ||
metadata={"description": "Alternative email address for agency communications"}, | ||
) | ||
|
||
|
||
class AgencyResponseSchema(Schema): | ||
"""Schema for agency response""" | ||
|
||
agency_id = fields.Integer() | ||
agency_name = fields.String() | ||
agency_code = fields.String() | ||
sub_agency_code = fields.String(allow_none=True) | ||
assistance_listing_number = fields.String() | ||
agency_submission_notification_setting = fields.String() # Enum value | ||
|
||
top_level_agency = fields.Nested(lambda: AgencyResponseSchema(exclude=("top_level_agency",))) | ||
|
||
# Agency contact info as nested object | ||
agency_contact_info = fields.Nested(AgencyContactInfoSchema, allow_none=True) | ||
|
||
# File types as a list of strings | ||
agency_download_file_types = fields.List( | ||
fields.Enum(AgencyDownloadFileType), | ||
metadata={"description": "List of download file types supported by the agency"}, | ||
) | ||
|
||
# Add timestamps from TimestampMixin | ||
created_at = fields.DateTime() | ||
updated_at = fields.DateTime() | ||
|
||
|
||
class AgencyListResponseSchema(AbstractResponseSchema, PaginationMixinSchema): | ||
data = fields.List( | ||
fields.Nested(AgencyResponseSchema), | ||
metadata={"description": "A list of agency records"}, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.