Skip to content

Instantly share code, notes, and snippets.

@quierati
Created September 24, 2021 14:16
Show Gist options
  • Save quierati/d78c91a326569f7b754c21d5de6ec241 to your computer and use it in GitHub Desktop.
Save quierati/d78c91a326569f7b754c21d5de6ec241 to your computer and use it in GitHub Desktop.
Example Module FindCEP API Localidades for Python 3 with doctest
# -*- coding: utf-8 -*-
"""
Example Module FindCEP API Localidades for Python 3 with doctest
>>> import localidades
"""
import os
import urllib.parse
import requests
__all__ = [
'call_api',
'make_url_states',
'make_url_cities_by_state',
'make_url_neighborhood_by_city_hash',
'make_url_neighborhood_by_state_and_city',
'make_url_ibge_code_by_city_hash',
'make_url_ibge_code_by_state_and_city',
'CLIENT_ID',
'FID',
'MY_REFERER',
'SCHEME',
]
# Set User Config
CLIENT_ID = os.getenv('CLIENT_ID', 'trial')
FID = os.getenv('FID', 'XXXXXXXXXXX')
REFERER = os.getenv('REFERER',f'{FID}.{CLIENT_ID}')
SCHEME = os.getenv('SCHEME', 'http')
# Do not change
_API_SERVER = f'{SCHEME}://{CLIENT_ID}.api.findcep.com'
_API_LOCALIDADES = f'{_API_SERVER}/v1/localidades'
_API_HEADERS = {'Referer': REFERER}
class FindCEPInvalidField(Exception):
""" Custom Error FindCEP
>>> FindCEPInvalidField("Field")
FindCEPInvalidField('Field')
"""
pass
def _transform_city_hash(state_code, city)->str:
""" Returns a City Name Hashed
>>> _transform_city_hash("SP", "São João do Pau d'Alho")
'bdbeb93289'
"""
import hashlib
key = f'{state_code}|{city}'.encode()
return hashlib.shake_128(key).hexdigest(5)
def _transform_city(field: str)->str:
""" Returns Modified Field {url_key} For Use In The FindCEP API.
>>> _transform_city("São João do Pau d'Alho")
's%C3%A3o-jo%C3%A3o-do-pau-d%27alho'
"""
_validate_city(field)
# Transform space " " to dash "-"
url_key = "-".join(field.split())
# Transform text in lowercase
url_key = url_key.lower()
# Transform accents and special chars to html encode.
url_key = urllib.parse.quote(url_key)
return url_key
def _transform_state(field: str)->str:
""" Returns Modified Field {state_code} For Use In The FindCEP API.
>>> _transform_state('SP')
'sp'
"""
_validate_state(field)
return field.lower()
def _validate_city(field):
""" Field value can't be empty or is not a text
>>> _validate_city("Bebedouro")
True
>>> _validate_city("")
Traceback (most recent call last):
...
FindCEPInvalidField: City
"""
if not field or not isinstance(field, str):
raise FindCEPInvalidField('City')
return True
def _validate_state(field):
""" The field value cannot be empty,
or it is not text,
or it does not have two characters.
>>> _validate_state("SP")
True
>>> _validate_state("00")
Traceback (most recent call last):
...
FindCEPInvalidField: State
"""
if (len(field) != 2
or not isinstance(field, str)
or not field.isalpha()):
raise FindCEPInvalidField('State')
return True
def call_api(endpoint, only_json=True):
""" Returns a JSON Response from FindCEP API LOCALIDADES
>>> call_api('/estado/sp/cidade/bebedouro/ibge')
{'codigo_ibge': '3506102', 'cidade': 'Bebedouro', 'uf': 'SP', 'hash_key': 'ce474f7c7f', 'url_key': 'bebedouro', 'extras': []}
>>> call_api('/cidade/ce474f7c7f/ibge')
{'codigo_ibge': '3506102', 'cidade': 'Bebedouro', 'uf': 'SP', 'hash_key': 'ce474f7c7f', 'url_key': 'bebedouro', 'extras': []}
"""
response = requests.get(f'{_API_LOCALIDADES}{endpoint}', headers=_API_HEADERS)
if only_json:
return response.json()
return response
def make_url_states():
""" Returns a endpoint path
>>> make_url_states()
'/estados'
"""
return '/estados'
def make_url_cities_by_state(state_code):
""" Returns a endpoint path
>>> make_url_cities_by_state('SP')
'/estado/sp/cidades'
"""
state_code = _transform_state(state_code)
return f'/estado/{state_code}/cidades'
def make_url_neighborhood_by_state_and_city(state_code, city):
""" Returns a endpoint path
>>> make_url_neighborhood_by_state_and_city('SP', 'Bebedouro')
'/estado/sp/cidade/bebedouro/bairros'
"""
state_code = _transform_state(state_code)
city = _transform_city(city)
return f'/estado/{state_code}/cidade/{city}/bairros'
def make_url_neighborhood_by_city_hash(state_code, city):
""" Returns a endpoint path
>>> make_url_neighborhood_by_city_hash('SP', 'Bebedouro')
'/cidade/ce474f7c7f/bairros'
"""
city_hash = _transform_city_hash(state_code, city)
return f'/cidade/{city_hash}/bairros'
def make_url_ibge_code_by_state_and_city(state_code, city):
""" Returns a endpoint path
>>> make_url_ibge_code_by_state_and_city('SP', 'Bebedouro')
'/estado/sp/cidade/bebedouro/ibge'
"""
state_code = _transform_state(state_code)
city = _transform_city(city)
return f'/estado/{state_code}/cidade/{city}/ibge'
def make_url_ibge_code_by_city_hash(state_code, city):
""" Returns a endpoint path
>>> make_url_ibge_code_by_city_hash('SP','Bebedouro')
'/cidade/ce474f7c7f/ibge'
"""
city_hash = _transform_city_hash(state_code, city)
return f'/cidade/{city_hash}/ibge'
if __name__ == "__main__":
""" run python3 localidades.py -v """
import doctest
doctest.testmod()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment