From ef0dc73a3c8c4cb0c2968dd59ff5bb06ee154d19 Mon Sep 17 00:00:00 2001 From: johnfn Date: Sat, 16 Apr 2011 19:05:31 -0700 Subject: [PATCH 1/4] Broadband API abstracted and passing tests --- broadband_api.py | 7 +++---- generic_api.py | 3 --- license_view_api.py | 2 -- tests/testcases.py | 8 ++++---- 4 files changed, 7 insertions(+), 13 deletions(-) diff --git a/broadband_api.py b/broadband_api.py index 69d7592..febdb69 100644 --- a/broadband_api.py +++ b/broadband_api.py @@ -2,13 +2,12 @@ # Simple Python wrapper around the Broadband API provided by the FCC. -class BroadbandApi(GenericLatLongAPI): +class BroadbandApi(GenericAPI): def __init__(self): - GenericLatLongAPI.__init__(self, "http://data.fcc.gov/api/speedtest/find") - + GenericAPI.__init__(self, [("get_data", "http://data.fcc.gov/api/speedtest/find")]) # Sample use of BroadbandApi if __name__ == "__main__": bb = BroadbandApi() - print bb.request(latitude=37, longitude=-122) # (Should be San Francisco) \ No newline at end of file + print bb.get_data(latitude=37, longitude=-122) # (Should be San Francisco) \ No newline at end of file diff --git a/generic_api.py b/generic_api.py index da36aed..be39663 100644 --- a/generic_api.py +++ b/generic_api.py @@ -75,9 +75,6 @@ def generic_api_call(**kwargs): - - - # Wraps any API that just uses Latitude and Longitude. #TODO: This is no longer necessary... diff --git a/license_view_api.py b/license_view_api.py index 38181ac..6819253 100644 --- a/license_view_api.py +++ b/license_view_api.py @@ -2,9 +2,7 @@ # Simple Python wrapper around the License View API provided by the FCC. - apis = [ ("get_licenses", "http://data.fcc.gov/api/license-view/basicSearch/getLicenses" ) - , ("get_common_names", "http://data.fcc.gov/api/license-view/licenses/getCommonNames") ] # Sample use of BlockConversionAPI diff --git a/tests/testcases.py b/tests/testcases.py index 263116b..02696f2 100644 --- a/tests/testcases.py +++ b/tests/testcases.py @@ -26,19 +26,19 @@ def test_Sweep(self): results = [ True , True , False , False , False , False , False , False , False , False , ] for x in range(10): - self.assertTrue((self.bb.request(latitude=41, longitude=-86 + x * 10)['status'] == 'OK') == results[x]) + self.assertTrue((self.bb.get_data(latitude=41, longitude=-86 + x * 10)['status'] == 'OK') == results[x]) # Does SF exist? def test_SF(self): - result = self.bb.request(latitude=37, longitude=-122) + result = self.bb.get_data(latitude=37, longitude=-122) self.assertTrue(result['status'] == 'OK') self.assertTrue('SpeedTestCounty' in result) # Does Chicago exist? def test_Chicago(self): - result = self.bb.request(latitude=41, longitude=-87) + result = self.bb.get_data(latitude=41, longitude=-87) self.assertTrue(result['status'] == 'OK') @@ -46,7 +46,7 @@ def test_Chicago(self): # Test the middle of nowhere (Disclaimer: I have no idea where # this is, so it may not be in the middle of nowhere) def test_Nowhere(self): - result = self.bb.request(latitude=35, longitude=35) + result = self.bb.get_data(latitude=35, longitude=35) self.assertTrue(result['status'] == 'Fail') From 8c3138decedacff998730392d55cdbd4389c3080 Mon Sep 17 00:00:00 2001 From: johnfn Date: Sat, 16 Apr 2011 19:09:10 -0700 Subject: [PATCH 2/4] Converted block conversion --- tests/testcases.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/testcases.py b/tests/testcases.py index 02696f2..6f6699e 100644 --- a/tests/testcases.py +++ b/tests/testcases.py @@ -80,7 +80,7 @@ def setUp(self): # Does SF exist? def test_SF(self): - result = self.bb.request(latitude=37, longitude=-122) + result = self.bb.get_block(latitude=37, longitude=-122) self.assertTrue(result['status'] == 'OK') self.assertTrue(result['State']['code'] == 'CA') @@ -89,7 +89,7 @@ def test_SF(self): # Does (somewhere near) Chicago exist? def test_Chicago(self): - result = self.bb.request(latitude=41, longitude=-87) + result = self.bb.get_block(latitude=41, longitude=-87) self.assertTrue(result['Block']['FIPS'] == '180739908004112') @@ -97,7 +97,7 @@ def test_Chicago(self): # Test the middle of nowhere (Disclaimer: I have no idea where # this is, so it may not be in the middle of nowhere) def test_Nowhere(self): - result = self.bb.request(latitude=35, longitude=35) + result = self.bb.get_block(latitude=35, longitude=35) self.assertTrue(result['status'] == 'Fail') From e33f38ef21d46a64f4a1c8a835eb6f8526bcfc27 Mon Sep 17 00:00:00 2001 From: johnfn Date: Sat, 16 Apr 2011 19:13:45 -0700 Subject: [PATCH 3/4] This all becomes so trivial --- license_view_api.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/license_view_api.py b/license_view_api.py index 6819253..afa9201 100644 --- a/license_view_api.py +++ b/license_view_api.py @@ -2,10 +2,21 @@ # Simple Python wrapper around the License View API provided by the FCC. -apis = [ ("get_licenses", "http://data.fcc.gov/api/license-view/basicSearch/getLicenses" ) +APIS = [ ("get_licenses", "http://data.fcc.gov/api/license-view/basicSearch/getLicenses" ) + , ("get_common_names", "http://data.fcc.gov/api/license-view/licenses/getCommonNames") + , ("get_statuses", "http://data.fcc.gov/api/license-view/licenses/getStatuses") + , ("get_categories", "http://data.fcc.gov/api/license-view/licenses/getCategories") + , ("get_entities", "http://data.fcc.gov/api/license-view/licenses/getEntities") + , ("get_renewals", "http://data.fcc.gov/api/license-view/licenses/getRenewals") + , ("get_issued", "http://data.fcc.gov/api/license-view/licenses/getIssued") ] + +class LicenseViewAPI(GenericAPI): + def __init__(self): + GenericAPI.__init__(self, APIS) + # Sample use of BlockConversionAPI if __name__ == "__main__": - bc = GenericAPI(apis) + bc = LicenseViewAPI() print bc.get_licenses(searchValue = "Verizon Wireless") \ No newline at end of file From 91592549aed93897b85b982577619e87968876fe Mon Sep 17 00:00:00 2001 From: johnfn Date: Sat, 16 Apr 2011 19:19:03 -0700 Subject: [PATCH 4/4] Code cleanup --- block_conversion_api.py | 7 +++---- generic_api.py | 40 +++++++++++++++++----------------------- 2 files changed, 20 insertions(+), 27 deletions(-) diff --git a/block_conversion_api.py b/block_conversion_api.py index 40d3281..cf8c837 100644 --- a/block_conversion_api.py +++ b/block_conversion_api.py @@ -2,13 +2,12 @@ # Simple Python wrapper around the Block Conversion API provided by the FCC. -class BlockConversionAPI(GenericLatLongAPI): +class BlockConversionAPI(GenericAPI): def __init__(self): - GenericLatLongAPI.__init__(self, "http://data.fcc.gov/api/block/find") - + GenericAPI.__init__(self, [("get_block", "http://data.fcc.gov/api/block/find")]) # Sample use of BlockConversionAPI if __name__ == "__main__": bc = BlockConversionAPI() - print bc.request(lat=41, long=-87) # (Should be San Francisco) \ No newline at end of file + print bc.get_block(lat=41, long=-87) # (Should be San Francisco) \ No newline at end of file diff --git a/generic_api.py b/generic_api.py index be39663..812ca7e 100644 --- a/generic_api.py +++ b/generic_api.py @@ -10,13 +10,13 @@ def __str__(self): return "The returned JSON was invalid." -# Inheritable class to perform requests to generic APIs. +# Perform requests to generic APIs. class BaseAPIRequest: def __init__(self, url): self.url = url - #Inherit this method to describe how to format URLs. + # Formats a URL with the provided keyword arguments. def format_url(self, **args): if args is None: raise NoArgumentsException @@ -36,51 +36,45 @@ def request(self, **args): if t.startswith("callback("): t=t[t.index("(")+1:-1] - return json.loads(t) - - """ try: - + return json.loads(t) + except: raise BadJSONException return None - """ - - #object = json.loads("".join([l for l in urllib.urlopen(self.formatted_url)])) class GenericAPI: + + # __init__ + # Parameters: APIS, a list of tuples of form (FUNCTIONNAME, LINK). + # + # Creates functions of name FUNCTIONNAME that perform an API call to LINK + # when called, giving back the response as JSON. + # + # Returns: Nothing + def __init__(self, apis): self.api_objects = [] self.api_functions = [] self.functions = [] - #Who writes normal functions when you can use CLOSURES?!? + # Who writes normal functions when you can use CLOSURES?!? number = 0 + # Bind each function to the class. for api in apis: self.api_objects.append(BaseAPIRequest(api[1])) self.bind_closure(number) setattr(self, api[0], self.api_functions[number]) number += 1 + # Creates a function on the current class. def bind_closure(self, number): def generic_api_call(**kwargs): self.api_objects[number].format_url(**kwargs) return self.api_objects[number].request(**kwargs) - self.api_functions.append(generic_api_call) - - - -# Wraps any API that just uses Latitude and Longitude. - -#TODO: This is no longer necessary... -class GenericLatLongAPI(BaseAPIRequest): - def __init__(self, url): - self.url = url - - def request(self, **args): - return BaseAPIRequest.request(self, **args) + self.api_functions.append(generic_api_call) \ No newline at end of file