Source code for publicdata.census.censusreporter.url
# Copyright (c) 2017 Civic Knowledge. This file is licensed under the terms of the
# MIT License, included in this distribution as LICENSE
"""
"""
import json
from os.path import dirname, join
import requests
from publicdata.census.appurl import CensusUrl
from rowgenerators import parse_app_url
from rowgenerators.appurl.web import WebUrl
from rowgenerators.exceptions import AppUrlError
from publicdata.census.censusreporter.jsonurl import CensusReporterJsonUrl
[docs]class CensusReporterUrl(CensusUrl):
"""A URL for censusreporter tables.
General form:
censusreporter:<table_id>/<summary_level>/<geoid>
for instance:
censusreporter:B17001/140/05000US06073
"""
api_host = 'api.censusreporter.org/1.0'
def __init__(self, url=None, downloader=None, **kwargs):
self._proto = 'censusreporter'
super().__init__(url, downloader, **kwargs)
@property
def geo_url(self):
"""Return the geo version of this URL"""
return CensusReporterShapeURL(str(self), downloader=self._downloader)
@classmethod
def _match(cls, url, **kwargs):
return url.scheme.startswith('censusreporter')
@property
def resource_url(self):
return WebUrl("http://{host}/data/show/latest?table_ids={table_id}&geo_ids={sl}|{geoid}" \
.format(host=self.api_host,table_id=self.tableid, sl=self.summary_level, geoid=self.geoid),
downloader=self.downloader)
[docs] def get_resource(self):
cache = self.downloader.cache
if cache and cache.exists(self.cache_key):
pass
else:
r = requests.get(self.resource_url)
r.raise_for_status()
data = r.json()
if cache:
cache.makedirs(dirname(self.cache_key), recreate=True)
cache.settext(self.cache_key, json.dumps(data, indent=4))
pu = parse_app_url(cache.getsyspath(self.cache_key),
target_file=join(*self.path_parts),
).as_type(CensusReporterJsonUrl)
return pu
[docs] def get_target(self):
# get_resource returns a CensusReporterJsonUrl so this should never be called
raise NotImplementedError()
CensusReporterURL = CensusReporterUrl # Legacy Name
[docs]class CensusReporterShapeURL(CensusReporterURL):
"""A URL for censusreporter tables.
General form:
censusreportergeo:<table_id>/<summary_level>/<geoid>
for instance:
censusreportergeo:B17001/140/05000US06073
"""
api_host = 'api.censusreporter.org'
def __init__(self, url=None, downloader=None, **kwargs):
super().__init__(url, downloader, **kwargs)
self.scheme = 'censusreportergeo'
@classmethod
def _match(cls, url, **kwargs):
return url.scheme.startswith('censusreporter')
@property
def resource_url(self):
return parse_app_url("http://{host}/1.0/data/download/latest?table_ids={table_id}&geo_ids={sl}|{geoid}&format=shp" \
.format(host=self.api_host,table_id=self.tableid, sl=self.summary_level, geoid=self.geoid),
downloader=self.downloader)
[docs] def get_resource(self):
from os import symlink, remove
from os.path import exists
from rowgenerators.appurl.file.shapefile import ShapefileUrl
r = ShapefileUrl(self.resource_url.get_resource())
# The downloaded file doesn't have a .zip extension, so Fiona won't recognize
# it as a Shapeilfe ZIP archive. So, just make a link.
p = r.inner.fspath
pz = p.with_suffix('.zip')
if exists(pz):
remove(pz)
symlink(p, pz)
return ShapefileUrl(pz)
[docs] def get_target(self):
raise NotImplementedError()
[docs] def join(self, s):
raise NotImplementedError()
[docs] def join_dir(self, s):
raise NotImplementedError()
[docs] def join_target(self, tf):
raise NotImplementedError()