22import io
33import re
44
5- from flask import (
6- Blueprint ,
7- abort ,
8- jsonify ,
9- make_response ,
10- redirect ,
11- render_template ,
12- request ,
13- url_for ,
14- )
5+ from fastapi import APIRouter , Request
6+ from fastapi .responses import JSONResponse , RedirectResponse
157
168from findthatpostcode .blueprints .utils import return_result
179from findthatpostcode .controllers .areas import Area , get_all_areas
18- from findthatpostcode .db import get_db
10+ from findthatpostcode .db import ElasticsearchDep
11+ from findthatpostcode .utils import CSVResponse , templates
1912
20- bp = Blueprint ( "areas" , __name__ , url_prefix = "/areas" )
13+ bp = APIRouter ( prefix = "/areas" )
2114
2215
23- @bp .route ("/search" )
24- @bp .route ("/search.<filetype>" )
25- def area_search (filetype = "json" ):
26- return redirect (url_for ("search.search_index" , q = request .values .get ("q" )), code = 301 )
16+ @bp .get ("/search" )
17+ @bp .get ("/search.<filetype>" )
18+ def area_search (request : Request , filetype = "json" , q : str | None = None ):
19+ return RedirectResponse (
20+ request .url_for ("search.search_index" , q = q ), status_code = 301
21+ )
2722
2823
29- @bp .route ("/names.csv" )
30- def all_names ():
24+ @bp .get ("/names.csv" )
25+ def all_names (es : ElasticsearchDep , types : str = "" ):
3126 areas = get_all_areas (
32- get_db (),
33- areatypes = [
34- a .strip ().lower () for a in request .values .get ("types" , "" ).split ("," ) if a
35- ],
27+ es ,
28+ areatypes = [a .strip ().lower () for a in types .split ("," ) if a ],
3629 )
3730 return areas_csv (areas , "names.csv" )
3831
@@ -49,15 +42,14 @@ def areas_csv(areas, filename):
4942 if re .match (r"[A-Z][0-9]{8}" , row .get ("code" )):
5043 writer .writerow (row )
5144
52- output = make_response (si .getvalue ())
45+ output = CSVResponse (si .getvalue ())
5346 output .headers ["Content-Disposition" ] = "attachment; filename={}" .format (filename )
5447 output .headers ["Content-type" ] = "text/csv"
5548 return output
5649
5750
58- @bp .route ("/<areacodes>.geojson" )
59- def get_area_boundary (areacodes ):
60- es = get_db ()
51+ @bp .get ("/<areacodes>.geojson" )
52+ def get_area_boundary (areacodes : str , es : ElasticsearchDep ):
6153 areacodes = areacodes .split ("+" )
6254 features = []
6355 for areacode in areacodes :
@@ -66,13 +58,12 @@ def get_area_boundary(areacodes):
6658 if status == 200 :
6759 features .extend (r .get ("features" ))
6860 if status != 200 :
69- return abort ( make_response ( jsonify ( message = r ), status ) )
70- return jsonify ({"type" : "FeatureCollection" , "features" : features })
61+ return JSONResponse ( message = r , status_code = status )
62+ return JSONResponse ({"type" : "FeatureCollection" , "features" : features })
7163
7264
73- @bp .route ("/<areacode>/children/<areatype>.geojson" )
74- def get_area_children_boundary (areacode , areatype ):
75- es = get_db ()
65+ @bp .get ("/<areacode>/children/<areatype>.geojson" )
66+ def get_area_children_boundary (areacode : str , areatype : str , es : ElasticsearchDep ):
7667 area = Area .get_from_es (areacode , es , boundary = False , examples_count = 0 )
7768 features = []
7869 errors = {}
@@ -84,31 +75,36 @@ def get_area_children_boundary(areacode, areatype):
8475 else :
8576 errors [child_area .id ] = r
8677 if not features :
87- return abort ( make_response ( jsonify ( message = errors ), status ) )
88- return jsonify ({"type" : "FeatureCollection" , "features" : features })
78+ return JSONResponse ( message = errors , status_code = status )
79+ return JSONResponse ({"type" : "FeatureCollection" , "features" : features })
8980
9081
9182@bp .route ("/<areacode>" )
9283@bp .route ("/<areacode>.<filetype>" )
93- def get_area (areacode , filetype = "json" ):
84+ def get_area (
85+ areacode : str ,
86+ filetype : str = "json" ,
87+ es : ElasticsearchDep = None ,
88+ child : str | None = None ,
89+ ):
9490 result = Area .get_from_es (
9591 areacode ,
96- get_db () ,
92+ es ,
9793 boundary = (filetype == "geojson" ),
9894 examples_count = (0 if filetype == "geojson" else 5 ),
9995 )
10096
10197 if filetype == "geojson" :
10298 status , r = result .geoJSON ()
10399 if status != 200 :
104- return abort ( make_response ( jsonify ( message = r ), status ) )
105- return jsonify (r )
100+ return JSONResponse ( message = r , status_code = status )
101+ return JSONResponse (r )
106102
107103 return return_result (
108104 result ,
109105 filetype ,
110106 "area.html.j2" ,
111- child = request . values . get ( " child" ) ,
107+ child = child ,
112108 example_postcode_json = [
113109 p .attributes .get ("location" )
114110 for p in result .relationships ["example_postcodes" ]
@@ -119,4 +115,4 @@ def get_area(areacode, filetype="json"):
119115
120116@bp .route ("/<areacodes>/map" )
121117def get_area_map (areacodes ):
122- return render_template ("area_map.html.j2" , areacodes = areacodes )
118+ return templates . TemplateResponse ("area_map.html.j2" , { " areacodes" : areacodes } )
0 commit comments