Skip to content
This repository was archived by the owner on Jan 18, 2023. It is now read-only.

Commit 28e1492

Browse files
committed
Add economic NFIP product
1 parent 0383272 commit 28e1492

File tree

12 files changed

+780
-606
lines changed

12 files changed

+780
-606
lines changed

firststreet/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@
1313
from firststreet.api.location import Location
1414
from firststreet.api.probability import Probability
1515
from firststreet.api.tile import Tile
16-
from firststreet.api.aal import AAL
17-
from firststreet.api.avm import AVM
16+
from firststreet.api.economic import AAL, AVM, Economic
1817
from firststreet.errors import MissingAPIKeyError
1918
from firststreet.http_util import Http
2019

@@ -61,3 +60,4 @@ def __init__(self, api_key=None, connection_limit=100, rate_limit=20000, rate_pe
6160
self.tile = Tile(self.http)
6261
self.aal = AAL(self.http)
6362
self.avm = AVM(self.http)
63+
self.economic = Economic(self.http)

firststreet/__main__.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@
6666
'tile.get_historic_event',
6767
'aal.get_summary',
6868
'avm.get_avm',
69-
'avm.get_provider']:
69+
'avm.get_provider',
70+
'economic.get_property_nfip']:
7071
logging.error("Product not found. Please check that the argument"
7172
" provided is correct: {}".format(argument.product))
7273
input("Press Enter to continue...")
@@ -387,6 +388,12 @@
387388
output_dir=argument.output_dir,
388389
extra_param=formatted_params)
389390

391+
elif argument.product == 'economic.get_property_nfip':
392+
fs.economic.get_property_nfip(search_items,
393+
csv=True,
394+
output_dir=argument.output_dir,
395+
extra_param=formatted_params)
396+
390397
else:
391398
logging.error("Product not found. Please check that the argument"
392399
" provided is correct: {}".format(argument.product))

firststreet/api/aal.py

Lines changed: 0 additions & 65 deletions
This file was deleted.

firststreet/api/avm.py

Lines changed: 0 additions & 76 deletions
This file was deleted.

firststreet/api/csv_format.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,15 @@ def to_csv(data, product, product_subtype, location_type=None, output_dir=None):
171171
else:
172172
raise NotImplementedError
173173

174+
elif product == 'economic':
175+
176+
if product_subtype == 'nfip':
177+
178+
df = format_economic_nfip_premium(data)
179+
180+
else:
181+
raise NotImplementedError
182+
174183
else:
175184
raise NotImplementedError
176185

@@ -1280,3 +1289,29 @@ def format_avm_provider(data):
12801289
df['provider_id'] = df['provider_id'].astype('Int64').apply(str)
12811290

12821291
return df[['provider_id', 'valid_id', 'provider_name', "provider_logo", 'error']]
1292+
1293+
1294+
def format_economic_nfip_premium(data):
1295+
"""Reformat the list of data to AVM Provider format
1296+
1297+
Args:
1298+
data (list): A list of FSF object
1299+
Returns:
1300+
A pandas formatted DataFrame
1301+
"""
1302+
df = pd.json_normalize([vars(o) for o in data]).explode("data")
1303+
1304+
if not df[['data']].isna().values.all():
1305+
df = pd.concat([df.drop(['data'], axis=1), df['data'].apply(pd.Series)], axis=1)
1306+
else:
1307+
df.drop(['data'], axis=1, inplace=True)
1308+
df['estimate'] = pd.NA
1309+
df['building'] = pd.NA
1310+
df['contents'] = pd.NA
1311+
1312+
df['fsid'] = df['fsid'].apply(str)
1313+
df['estimate'] = df['estimate'].astype('Int64').apply(str)
1314+
df['building'] = df['building'].astype('Int64').apply(str)
1315+
df['contents'] = df['contents'].astype('Int64').apply(str)
1316+
1317+
return df[['fsid', 'valid_id', 'estimate', "building", 'contents', 'error']]

firststreet/api/economic.py

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
# Author: Kelvin Lai <kelvin@firststreet.org>
2+
# Copyright: This module is owned by First Street Foundation
3+
4+
# Standard Imports
5+
import logging
6+
7+
# Internal Imports
8+
from firststreet.api import csv_format
9+
from firststreet.api.api import Api
10+
from firststreet.errors import InvalidArgument
11+
from firststreet.models.economic import AVMProperty, AVMProvider, AALSummaryProperty, AALSummaryOther, NFIPPremium
12+
13+
14+
class AAL(Api):
15+
"""This class receives a list of search_items and handles the creation of an aal product from the request.
16+
17+
Methods:
18+
get_summary: Retrieves a list of AAL Summary for the given list of IDs
19+
"""
20+
21+
def get_summary(self, search_items, location_type, csv=False, output_dir=None, extra_param=None):
22+
"""Retrieves AAL summary product data from the First Street Foundation API given a list of search_items and
23+
returns a list of AAL Summary objects.
24+
25+
Args:
26+
search_items (list/file): A First Street Foundation IDs, lat/lng pair, address, or a
27+
file of First Street Foundation IDs
28+
location_type (str): The location lookup type
29+
csv (bool): To output extracted data to a csv or not
30+
output_dir (str): The output directory to save the generated csvs
31+
extra_param (dict): Extra parameter to be added to the url
32+
33+
Returns:
34+
A list of AAL Summary
35+
Raises:
36+
InvalidArgument: The location provided is empty
37+
TypeError: The location provided is not a string
38+
"""
39+
40+
if not location_type:
41+
raise InvalidArgument(location_type)
42+
elif not isinstance(location_type, str):
43+
raise TypeError("location is not a string")
44+
45+
# Get data from api and create objects
46+
if extra_param and "depths" in extra_param:
47+
extra_param["depths"] = ','.join(map(str, extra_param["depths"]))
48+
49+
api_datas = self.call_api(search_items, "economic/aal", "summary", location_type, extra_param=extra_param)
50+
51+
product = []
52+
for api_data, fsid in api_datas:
53+
api_data["fsid"] = fsid
54+
55+
if location_type == "property":
56+
product.append(AALSummaryProperty(api_data))
57+
else:
58+
product.append(AALSummaryOther(api_data))
59+
60+
if csv:
61+
csv_format.to_csv(product, "economic_aal", "summary", location_type, output_dir=output_dir)
62+
63+
logging.info("AAL Summary Data Ready.")
64+
65+
return product
66+
67+
68+
class AVM(Api):
69+
"""This class receives a list of search_items and handles the creation of an AVM product from the request.
70+
71+
Methods:
72+
get_avm: Retrieves a list of AVM for the given list of IDs
73+
get_provider: Retrieves a list of AVM providers for the given list of IDs
74+
"""
75+
76+
def get_avm(self, search_items, csv=False, output_dir=None, extra_param=None):
77+
"""Retrieves AVM product data from the First Street Foundation API given a list of search_items and
78+
returns a list of AVM objects.
79+
80+
Args:
81+
search_items (list/file): A First Street Foundation IDs, lat/lng pair, address, or a
82+
file of First Street Foundation IDs
83+
csv (bool): To output extracted data to a csv or not
84+
output_dir (str): The output directory to save the generated csvs
85+
extra_param (dict): Extra parameter to be added to the url
86+
87+
Returns:
88+
A list of AVM
89+
"""
90+
# Get data from api and create objects
91+
api_datas = self.call_api(search_items, "economic", "avm", "property", extra_param=extra_param)
92+
93+
product = [AVMProperty(api_data) for api_data in api_datas]
94+
95+
if csv:
96+
csv_format.to_csv(product, "economic_avm", "avm", "property", output_dir=output_dir)
97+
98+
logging.info("AVM Data Ready.")
99+
100+
return product
101+
102+
def get_provider(self, search_items, csv=False, output_dir=None, extra_param=None):
103+
"""Retrieves AVM provider product data from the First Street Foundation API given a list of search_items and
104+
returns a list of AVM provider objects.
105+
106+
Args:
107+
search_items (list/file): A First Street Foundation IDs, lat/lng pair, address, or a
108+
file of First Street Foundation IDs
109+
csv (bool): To output extracted data to a csv or not
110+
output_dir (str): The output directory to save the generated csvs
111+
extra_param (dict): Extra parameter to be added to the url
112+
113+
Returns:
114+
A list of AVM Provider
115+
"""
116+
# Get data from api and create objects
117+
api_datas = self.call_api(search_items, "economic/avm", "provider", extra_param=extra_param)
118+
119+
product = [AVMProvider(api_data) for api_data in api_datas]
120+
121+
if csv:
122+
csv_format.to_csv(product, "economic_avm", "provider", output_dir=output_dir)
123+
124+
logging.info("AVM Provider Data Ready.")
125+
126+
return product
127+
128+
129+
class Economic(Api):
130+
"""This class receives a list of search_items and handles the creation of an economic product from the request.
131+
132+
Methods:
133+
get_property_nfip: Retrieves a list of property nfip premiums for the given list of IDs
134+
"""
135+
136+
def get_property_nfip(self, search_items, csv=False, output_dir=None, extra_param=None):
137+
"""Retrieves AVM product data from the First Street Foundation API given a list of search_items and
138+
returns a list of AVM objects.
139+
140+
Args:
141+
search_items (list/file): A First Street Foundation IDs, lat/lng pair, address, or a
142+
file of First Street Foundation IDs
143+
csv (bool): To output extracted data to a csv or not
144+
output_dir (str): The output directory to save the generated csvs
145+
extra_param (dict): Extra parameter to be added to the url
146+
147+
Returns:
148+
A list of property NFIP premiums
149+
"""
150+
# Get data from api and create objects
151+
api_datas = self.call_api(search_items, "economic", "nfip", "property", extra_param=extra_param)
152+
153+
product = [NFIPPremium(api_data) for api_data in api_datas]
154+
155+
if csv:
156+
csv_format.to_csv(product, "economic", "nfip", "property", output_dir=output_dir)
157+
158+
logging.info("NFIP Premium Data Ready.")
159+
160+
return product

0 commit comments

Comments
 (0)