Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new exceptions types and improve tests #99

Merged
merged 8 commits into from
Nov 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ setup:

.PHONY : test
test:
pytest
pytest -v

.PHONY : tox
tox:
Expand Down
40 changes: 35 additions & 5 deletions brazilcep/apicep.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,42 @@ def fetch_address(cep: str, timeout: Union[None, int], proxies: Union[None, dict
a REST API to query CEP requests.

Args:
cep: CEP to be searched.
timeout: How many seconds to wait for the server to return data before giving up.
proxies: Dictionary mapping protocol to the URL of the proxy.
cep: CEP to be searched
timeout: How many seconds to wait for the server to return data before giving up
proxies: Dictionary mapping protocol to the URL of the proxy

Raises:
exceptions.ConnectionError: raised by a connection error
exceptions.HTTPError: raised by HTTP error
exceptions.URLRequired: raised by using a invalid URL to make a request
exceptions.TooManyRedirects: raised by too many redirects
exceptions.Timeout: raised by request timed out
exceptions.InvalidCEP: raised to invalid CEP requests
exceptions.BlockedByFlood: raised by flood of requests
exceptions.CEPNotFound: raised to CEP not founded requests
exceptions.BrazilCEPException: Base class for exception

Returns:
Respective address data from CEP.
Address data from CEP
"""

response = requests.get(URL.format(cep), timeout=timeout, proxies=proxies)
try:
response = requests.get(URL.format(cep), timeout=timeout, proxies=proxies)

except requests.exceptions.ConnectionError as exc:
raise exceptions.ConnectionError(exc)

except requests.exceptions.HTTPError as exc:
raise exceptions.HTTPError(exc)

except requests.exceptions.URLRequired as exc:
raise exceptions.URLRequired(exc)

except requests.exceptions.TooManyRedirects as exc:
raise exceptions.TooManyRedirects(exc)

except requests.exceptions.Timeout as exc:
raise exceptions.Timeout(exc)

if response.status_code == 200:
address = json.loads(response.text)
Expand All @@ -54,4 +81,7 @@ def fetch_address(cep: str, timeout: Union[None, int], proxies: Union[None, dict
"complement": "",
}

elif response.status_code == 429:
raise exceptions.BlockedByFlood()

raise exceptions.BrazilCEPException(f"Other error. Status code: {response.status_code}")
21 changes: 9 additions & 12 deletions brazilcep/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,26 +44,23 @@ class WebService(enum.Enum):

def get_address_from_cep(
cep: str,
webservice: WebService = WebService.APICEP,
webservice: WebService = WebService.OPENCEP,
timeout: Optional[int] = None,
proxies: Optional[dict] = None,
) -> dict:
"""Returns the address corresponding to the zip (cep) code entered.
"""Returns the address corresponding to the zip (cep) code entered

Args:
cep: CEP to be queried.
timeout: How many seconds to wait for the server to return data before giving up.
proxies: Dictionary mapping protocol to the URL of the proxy.
cep: CEP to be queried
webservice: enum to webservice APIs
timeout: How many seconds to wait for the server to return data before giving up
proxies: Dictionary mapping protocol to the URL of the proxy

Raises:
RequestError: When connection error occurs in CEP query
Timeout: When occurs timeout of webservice response
HTTPError: Invalid HTTP format query
CEPNotFound: CEP not exist in API
Exception: When any error occurs in the CEP query
KeyError: raise if `webservice` parameter is a invalid webservice enum value

returns:
Address data of the queried CEP.
Returns:
Address data of the queried CEP
"""

if webservice == WebService.CORREIOS:
Expand Down
20 changes: 20 additions & 0 deletions brazilcep/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,23 @@ class CEPNotFound(BrazilCEPException):

class BlockedByFlood(BrazilCEPException):
"""Exception raised by flood of requests"""


class ConnectionError(BrazilCEPException):
"""Exception raised by a connection error"""


class HTTPError(BrazilCEPException):
"""Exception raised by HTTP error"""


class URLRequired(BrazilCEPException):
"""Exception raised by using a invalid URL to make a request"""


class TooManyRedirects(BrazilCEPException):
"""Exception raised by too many redirects"""


class Timeout(BrazilCEPException):
"""Exception raised by request timed out"""
37 changes: 32 additions & 5 deletions brazilcep/opencep.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,42 @@ def fetch_address(cep: str, timeout: Union[None, int], proxies: Union[None, dict
a REST API to query CEP requests.

Args:
cep: CEP to be searched.
timeout: How many seconds to wait for the server to return data before giving up.
proxies: Dictionary mapping protocol to the URL of the proxy.
cep: CEP to be searched
timeout: How many seconds to wait for the server to return data before giving up
proxies: Dictionary mapping protocol to the URL of the proxy

Raises:
exceptions.ConnectionError: raised by a connection error
exceptions.HTTPError: raised by HTTP error
exceptions.URLRequired: raised by using a invalid URL to make a request
exceptions.TooManyRedirects: raised by too many redirects
exceptions.Timeout: raised by request timed out
exceptions.InvalidCEP: raised to invalid CEP requests
exceptions.BlockedByFlood: raised by flood of requests
exceptions.CEPNotFound: raised to CEP not founded requests
exceptions.BrazilCEPException: Base class for exception

Returns:
Respective address data from CEP.
Address data from CEP
"""

response = requests.get(URL.format(cep), timeout=timeout, proxies=proxies)
try:
response = requests.get(URL.format(cep), timeout=timeout, proxies=proxies)

except requests.exceptions.ConnectionError as exc:
raise exceptions.ConnectionError(exc)

except requests.exceptions.HTTPError as exc:
raise exceptions.HTTPError(exc)

except requests.exceptions.URLRequired as exc:
raise exceptions.URLRequired(exc)

except requests.exceptions.TooManyRedirects as exc:
raise exceptions.TooManyRedirects(exc)

except requests.exceptions.Timeout as exc:
raise exceptions.Timeout(exc)

if response.status_code == 200:
address = json.loads(response.text)
Expand Down
37 changes: 32 additions & 5 deletions brazilcep/viacep.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,42 @@ def fetch_address(cep: str, timeout: Union[None, int], proxies: Union[None, dict
a REST API to query CEP requests.

Args:
cep: CEP to be searched.
timeout: How many seconds to wait for the server to return data before giving up.
proxies: Dictionary mapping protocol to the URL of the proxy.
cep: CEP to be searched
timeout: How many seconds to wait for the server to return data before giving up
proxies: Dictionary mapping protocol to the URL of the proxy

Raises:
exceptions.ConnectionError: raised by a connection error
exceptions.HTTPError: raised by HTTP error
exceptions.URLRequired: raised by using a invalid URL to make a request
exceptions.TooManyRedirects: raised by too many redirects
exceptions.Timeout: raised by request timed out
exceptions.InvalidCEP: raised to invalid CEP requests
exceptions.BlockedByFlood: raised by flood of requests
exceptions.CEPNotFound: raised to CEP not founded requests
exceptions.BrazilCEPException: Base class for exception

Returns:
Respective address data from CEP.
Address data from CEP
"""

response = requests.get(URL.format(cep), timeout=timeout, proxies=proxies)
try:
response = requests.get(URL.format(cep), timeout=timeout, proxies=proxies)

except requests.exceptions.ConnectionError as exc:
raise exceptions.ConnectionError(exc)

except requests.exceptions.HTTPError as exc:
raise exceptions.HTTPError(exc)

except requests.exceptions.URLRequired as exc:
raise exceptions.URLRequired(exc)

except requests.exceptions.TooManyRedirects as exc:
raise exceptions.TooManyRedirects(exc)

except requests.exceptions.Timeout as exc:
raise exceptions.Timeout(exc)

if response.status_code == 200:
# Transforma o objeto requests em um dict
Expand Down
8 changes: 5 additions & 3 deletions docs/source/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ Exceptions
----------

.. autoexception:: brazilcep.exceptions.BrazilCEPException
.. autoexception:: brazilcep.exceptions.ConnectionError
.. autoexception:: brazilcep.exceptions.HTTPError
.. autoexception:: brazilcep.exceptions.URLRequired
.. autoexception:: brazilcep.exceptions.TooManyRedirects
.. autoexception:: brazilcep.exceptions.Timeout
.. autoexception:: brazilcep.exceptions.InvalidCEP
.. autoexception:: brazilcep.exceptions.CEPNotFound
.. autoexception:: brazilcep.exceptions.BlockedByFlood
Expand Down Expand Up @@ -72,8 +77,5 @@ This is the new code::

The follow `Exceptions` have been removed:

* `ConnectionError`
* `Timeout`
* `HTTPError`
* `BaseException`

29 changes: 16 additions & 13 deletions docs/source/user/quickstart.rst
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,7 @@ Timeouts
You can tell BrazilCEP to stop waiting for a response after a given number of
seconds with the ``timeout`` parameter. Nearly all production code should use
this parameter in nearly all requests. Failure to do so can cause your program
to hang indefinitely::

>>> get_address_from_cep('37503-130', timeout=0.001)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
requests.exceptions.Timeout: HTTPConnectionPool(host='http://www.viacep.com.br/ws/37503130/json', port=80): Request timed out. (timeout=0.001)
to hang indefinitely.

Proxy
-----
Expand Down Expand Up @@ -87,7 +82,7 @@ Unsing differents API's
BrazilCEP is not responsible for the functioning, availability and support of any of these query API's. All of them are provided by third parties, and
this library just provides a handy way to centralize the CEP search on these services.

By default, BrazilCEP uses the API provided by the `ApiCEP <https://apicep.com>`_ service.
By default, BrazilCEP uses the API provided by the `OpenCEP <https://opencep.com>`_ service.

To use other services, we must indicate the desired service when calling the `get_address_from_cep`
function.
Expand Down Expand Up @@ -120,13 +115,21 @@ Errors and Exceptions
BrazilCEP also supports a group of exceptions that can be used to
handle any errors that occur during the query process.

If a invalid CEP request has be made, a :exc:`~brazilcep.exceptions.InvalidCEP` exception is
raised.
:exc:`~brazilcep.exceptions.InvalidCEP` exception raised by a request with invalid CEP.

:exc:`~brazilcep.exceptions.CEPNotFound` exception is raised when CEP is not find in selected API.

:exc:`~brazilcep.exceptions.BlockedByFlood`: exception raides by a large number of CEP requests in short range of time

:exc:`~brazilcep.exceptions.ConnectionError`: exception raised by a connection error.

:exc:`~brazilcep.exceptions.HTTPError`: exception raised by HTTP error.

:exc:`~brazilcep.exceptions.URLRequired`: exception raised by using a invalid URL to make a CEP request.

If a CEP request not find CEP address, a :exc:`~brazilcep.exceptions.CEPNotFound` exception is raised.
:exc:`~brazilcep.exceptions.TooManyRedirects`: Exception raised by too many redirects.

To a large number of CEP requests in short range of time, a :exc:`~brazilcep.exceptions.BlockedByFlood` exception is raised.
:exc:`~brazilcep.exceptions.Timeout`: exception raised by request timed out.

All exceptions that BrazilCEP explicitly raises inherit from
:exc:`brazilcep.exceptions.BrazilCEPException`.
All exceptions that BrazilCEP explicitly raises inherit from :exc:`brazilcep.exceptions.BrazilCEPException`.

10 changes: 0 additions & 10 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -117,17 +117,7 @@ skip = ["docs"]
[tool.pyright]
reportPrivateImportUsage = false

[tool.ruff]
line-length = 115
target-version = "py39"

[tool.lint.per-file-ignores]
"__init__.py" = ["F401"]

[tool.mypy]
# ignore_missing_imports = true
# no_site_packages = true
# check_untyped_defs = true
strict = false

[[tool.mypy.overrides]]
Expand Down
Loading
Loading