def pagination(self): sortable_columns = [ "agency_name", "abbreviation", "toptier_code", "current_total_budget_authority_amount", "publication_date", ] default_sort_column = "current_total_budget_authority_amount" models = customize_pagination_with_sort_columns(sortable_columns, default_sort_column) models.extend([{"key": "fiscal_year", "name": "fiscal_year", "type": "integer", "optional": False}]) if self.request.query_params.get("sort") and "publication_date" in self.request.query_params.get("sort"): modified_query_params = deepcopy(self.request.query_params) modified_query_params.pop("sort") request_data = TinyShield(models).block(modified_query_params) request_data["sort"] = self.request.query_params.get("sort") else: request_data = TinyShield(models).block(self.request.query_params) # since publication_date requires a variable that we can't check for using the enum check, we're doing it separately return Pagination( page=request_data["page"], limit=request_data["limit"], lower_limit=(request_data["page"] - 1) * request_data["limit"], upper_limit=(request_data["page"] * request_data["limit"]), sort_key=request_data.get("sort", default_sort_column), sort_order=request_data["order"], )
def pagination(self): model = customize_pagination_with_sort_columns( self.sortable_columns, self.default_sort_column) request_data = TinyShield(model).block(self.request.query_params) return Pagination( page=request_data["page"], limit=request_data["limit"], lower_limit=(request_data["page"] - 1) * request_data["limit"], upper_limit=(request_data["page"] * request_data["limit"]), sort_key=request_data.get("sort", self.default_sort_column), sort_order=request_data["order"], )
def run_models(self, columns, default_sort_column="id"): model = customize_pagination_with_sort_columns(columns, default_sort_column) request_data = TinyShield(model).block(self.request.data.get("pagination", {})) return Pagination( page=request_data["page"], limit=request_data["limit"], lower_limit=(request_data["page"] - 1) * request_data["limit"], upper_limit=(request_data["page"] * request_data["limit"]), sort_key=request_data.get("sort", "obligation"), sort_order=request_data["order"], secondary_sort_key="id", )
def pagination(self): sortable_columns = ["name", "obligated_amount", "gross_outlay_amount"] default_sort_column = "obligated_amount" model = customize_pagination_with_sort_columns(sortable_columns, default_sort_column) request_data = TinyShield(model).block(self.request.query_params) return Pagination( page=request_data["page"], limit=request_data["limit"], lower_limit=(request_data["page"] - 1) * request_data["limit"], upper_limit=(request_data["page"] * request_data["limit"]), sort_key=request_data.get("sort", "obligated_amount"), sort_order=request_data["order"], )
def spending_type(self): model = [{ "key": "spending_type", "name": "spending_type", "type": "enum", "enum_values": ["total", "award"], "allow_nulls": False, "optional": False, }] return TinyShield(model).block(self.request.data)["spending_type"]
def filters(self): all_def_codes = sorted( DisasterEmergencyFundCode.objects.values_list("code", flat=True)) object_keys_lookup = { "def_codes": { "key": "filter|def_codes", "name": "def_codes", "type": "array", "array_type": "enum", "enum_values": all_def_codes, "allow_nulls": False, "optional": False, }, "query": { "key": "filter|query", "name": "query", "type": "text", "text_type": "search", "allow_nulls": True, "optional": True, }, "award_type_codes": { "key": "filter|award_type_codes", "name": "award_type_codes", "type": "array", "array_type": "enum", "enum_values": sorted(award_type_mapping.keys()), "allow_nulls": True, "optional": True, }, "_loan_award_type_codes": { "key": "filter|award_type_codes", "name": "award_type_codes", "type": "array", "array_type": "enum", "enum_values": sorted(loan_type_mapping.keys()), "allow_nulls": True, "optional": True, "default": list(loan_type_mapping.keys()), }, "_assistance_award_type_codes": { "key": "filter|award_type_codes", "name": "award_type_codes", "type": "array", "array_type": "enum", "enum_values": sorted(assistance_type_mapping.keys()), "allow_nulls": True, "optional": True, "default": list(assistance_type_mapping.keys()), }, } model = [object_keys_lookup[key] for key in self.required_filters] json_request = TinyShield(model).block(self.request.data) return json_request["filter"]
def post(self, request): additional_models = [ { "key": "filter|award_type", "name": "award_type", "type": "enum", "enum_values": ("assistance", "procurement"), "allow_nulls": False, "optional": True, } ] f = TinyShield(additional_models).block(self.request.data).get("filter") if f: self.filters["award_type"] = f.get("award_type") if all(x in self.filters for x in ["award_type_codes", "award_type"]): raise UnprocessableEntityException("Cannot provide both 'award_type_codes' and 'award_type'") if self.count_only: return Response({"count": self.aggregation["award_count"]}) else: return Response(self.aggregation)
def _parse_and_validate_request(request_dict) -> dict: sortable_columns = [ "difference", "file_a_obligation", "file_b_obligation", "tas" ] default_sort_column = "tas" models = customize_pagination_with_sort_columns( sortable_columns, default_sort_column) models.extend([ { "key": "fiscal_year", "name": "fiscal_year", "type": "integer", "optional": False }, { "key": "fiscal_period", "name": "fiscal_period", "type": "integer", "optional": False }, ]) validated_request_data = TinyShield(models).block(request_dict) return validated_request_data
def post(self, request: Request) -> Response: models = [ { "key": "geo_layer", "name": "geo_layer", "type": "enum", "enum_values": sorted([geo_layer.value for geo_layer in list(GeoLayer)]), "text_type": "search", "allow_nulls": False, "optional": False, }, { "key": "geo_layer_filters", "name": "geo_layer_filters", "type": "array", "array_type": "text", "text_type": "search", }, { "key": "spending_type", "name": "spending_type", "type": "enum", "enum_values": ["obligation", "outlay", "face_value_of_loan"], "allow_nulls": False, "optional": False, }, { "name": "scope", "key": "scope", "type": "enum", "optional": True, "enum_values": ["place_of_performance", "recipient_location"], "default": "recipient_location", }, ] # NOTE: filter object in request handled in base class: see self.filters json_request = TinyShield(models).block(request.data) agg_key_dict = { "county": "county_agg_key", "district": "congressional_agg_key", "state": "state_agg_key", } scope_dict = { "place_of_performance": "pop", "recipient_location": "recipient_location" } location_dict = { "county": "county_code", "district": "congressional_code", "state": "state_code" } self.geo_layer = GeoLayer(json_request["geo_layer"]) scope_field_name = scope_dict[json_request["scope"]] loc_field_name = location_dict[self.geo_layer.value] self.agg_key = f"{scope_field_name}_{agg_key_dict[json_request['geo_layer']]}" self.geo_layer_filters = json_request.get("geo_layer_filters") self.spending_type = json_request.get("spending_type") self.loc_lookup = f"{scope_field_name}_{loc_field_name}" # Set which field will be the aggregation amount if self.spending_type == "obligation": self.metric_field = "total_covid_obligation" elif self.spending_type == "outlay": self.metric_field = "total_covid_outlay" elif self.spending_type == "face_value_of_loan": self.metric_field = "total_loan_value" else: raise UnprocessableEntityException( f"Unrecognized value '{self.spending_type}' for field " f"'spending_type'") filter_query = QueryWithFilters.generate_awards_elasticsearch_query( self.filters) result = self.query_elasticsearch(filter_query) return Response({ "geo_layer": self.geo_layer.value, "spending_type": self.spending_type, "scope": json_request["scope"], "results": result, })
def _parse_and_validate_request(self, request_dict: dict) -> dict: return TinyShield(deepcopy( self._tiny_shield_models)).block(request_dict)