Skip to content
This repository was archived by the owner on Mar 22, 2022. It is now read-only.

Commit ba0c0b1

Browse files
authored
Version 1.2.0
* Added exception for 429 status code and improved tests * Updated gitignore * Renamed exception classes * Updated README files * Flake8 and version bump
1 parent e311f21 commit ba0c0b1

File tree

15 files changed

+149
-121
lines changed

15 files changed

+149
-121
lines changed

.editorconfig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,13 @@ end_of_line = lf
33
charset = utf-8
44
trim_trailing_whitespace = true
55
insert_final_newline = true
6+
7+
[*.py]
8+
max_line_length = 80
9+
10+
[*.json]
11+
indent_size = 2
12+
insert_final_newline = ignore
13+
14+
[Makefile]
15+
indent_style = tab

.gitignore

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,10 @@ __pycache__/
88
build/
99
dist/
1010

11-
# OS generated files
12-
.idea
13-
1411
# Unit test / coverage reports
1512
htmlcov/
1613
.coverage
1714

1815
# IDE
1916
.vscode
17+
.idea

README.md

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# postcodeapi
22

3-
`postcodeapi` is a tiny Python wrapper around the Postcode API V2.
3+
`postcodeapi` is an unofficial Python wrapper around the Postcode API V2.
44

55
[![PyPI version](https://badge.fury.io/py/postcodeapi.svg)](https://badge.fury.io/py/postcodeapi)
66
[![Build Status](https://travis-ci.org/roedesh/postcodeapi.svg?branch=master)](https://travis-ci.org/roedesh/postcodeapi)
@@ -11,7 +11,7 @@
1111

1212
### Installation
1313

14-
*postcodeapi* can be installed by running `pip install postcodeapi`.
14+
_postcodeapi_ can be installed by running `pip install postcodeapi`.
1515

1616
### Usage
1717

@@ -31,6 +31,7 @@ client = PostcodeAPIClient(api_key="YOUR_API_KEY")
3131
# The number parameter only works together with postal_code
3232
data = client.get_all_addresses(postal_code="5038EA", number=19)
3333
addresses = data["results"] # List of addresses
34+
next_id = data["next"] # Next ID to search from (used for pagination)
3435

3536
# Fetch a single address
3637
address = client.get_address(address_id="0855200000046355")
@@ -39,17 +40,31 @@ address = client.get_address(address_id="0855200000046355")
3940
# The area parameter is optional
4041
data = client.get_all_postal_codes(area="5038")
4142
postal_codes = data["results"] # List of postal codes
43+
next_postal_code = data["next"] # Next postal code to search from (used for pagination)
4244

4345
# Fetch a single postal code
4446
postal_code = client.get_postal_code("5038EA")
4547
```
4648

49+
### Exceptions
50+
51+
There are 5 exceptions that can occur:
52+
53+
- `NoAccessException`, which occurs when the current account does not have the required privileges to perform the action;
54+
- `ResourceNotFoundException`, which occurs when the returned status_code is 404. Limited to the *get_address* and *get_postal_code* methods;
55+
- `HouseNumberRequiresPostalCodeException`, which occurs when a house_number is given but not a postal_code. Limited to the *get_all_addresses* method;
56+
- `InvalidPostalCodeException`, which occurs when an invalid postal code is given;
57+
- `LimitExceededException`, which occurs when there are too many network requests or the limit has been exceeded
58+
4759
## Documentation
60+
4861
For more information about the data that is returned, please refer to the [official API documentation](https://www.postcodeapi.nu/docs/). It is written in Dutch.
4962

5063
## Running tests
51-
To run the tests, make sure you have the dev dependencies installed, and run `pytest` in the root of the project.
64+
65+
To run the tests, make sure you install the dev dependencies by running `pipenv install --dev`, and then run `pytest` in the root of the project.
5266

5367
## Issues
68+
5469
If you have any issues with the API wrapper, please post them [here](https://github.com/infoklik/postcodeapi/issues). If you have issues with the actual API,
5570
please post them in the [official issue tracker](https://github.com/postcodeapi/postcodeapi/issues) of Postcode API.

README.rst

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
postcodeapi
22
===========
33

4-
``postcodeapi`` is a tiny Python wrapper around the Postcode API V2.
4+
``postcodeapi`` is an unofficial Python wrapper around the Postcode API
5+
V2.
56

67
|PyPI version| |Build Status| |Requirements Status| |Coverage Status|
78

@@ -34,6 +35,7 @@ response converted to a Python dictionary.
3435
# The number parameter only works together with postal_code
3536
data = client.get_all_addresses(postal_code="5038EA", number=19)
3637
addresses = data["results"] # List of addresses
38+
next_id = data["next"] # Next ID to search from (used for pagination)
3739
3840
# Fetch a single address
3941
address = client.get_address(address_id="0855200000046355")
@@ -42,10 +44,29 @@ response converted to a Python dictionary.
4244
# The area parameter is optional
4345
data = client.get_all_postal_codes(area="5038")
4446
postal_codes = data["results"] # List of postal codes
47+
next_postal_code = data["next"] # Next postal code to search from (used for pagination)
4548
4649
# Fetch a single postal code
4750
postal_code = client.get_postal_code("5038EA")
4851
52+
Exceptions
53+
~~~~~~~~~~
54+
55+
There are 5 exceptions that can occur:
56+
57+
- ``NoAccessException``, which occurs when the current account does not
58+
have the required privileges to perform the action;
59+
- ``ResourceNotFoundException``, which occurs when the returned
60+
status_code is 404. Limited to the *get_address* and
61+
*get_postal_code* methods;
62+
- ``HouseNumberRequiresPostalCodeException``, which occurs when a
63+
house_number is given but not a postal_code. Limited to the
64+
*get_all_addresses* method;
65+
- ``InvalidPostalCodeException``, which occurs when an invalid postal
66+
code is given;
67+
- ``LimitExceededException``, which occurs when there are too many
68+
network requests or the limit has been exceeded
69+
4970
Documentation
5071
-------------
5172

@@ -55,19 +76,10 @@ the `official API documentation`_. It is written in Dutch.
5576
Running tests
5677
-------------
5778

58-
To run the tests, make sure you have the dev dependencies installed, and
59-
run ``pytest`` in the root of the project.
60-
61-
Issues
62-
------
63-
64-
If you have any issues with the API wrapper, please post them `here`_.
65-
If you have issues with the actual API, please post them in the
66-
`official issue tracker`_ of Postcode API.
79+
To run the tests, make sure you install the dev dependencies by running
80+
``pipenv install --dev``, and then run
6781

6882
.. _official API documentation: https://www.postcodeapi.nu/docs/
69-
.. _here: https://github.com/infoklik/postcodeapi/issues
70-
.. _official issue tracker: https://github.com/postcodeapi/postcodeapi/issues
7183

7284
.. |PyPI version| image:: https://badge.fury.io/py/postcodeapi.svg
7385
:target: https://badge.fury.io/py/postcodeapi

postcodeapi/client.py

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from urllib.parse import parse_qs, urlencode, urlparse
33

44
import requests
5+
56
from postcodeapi import exceptions
67
from postcodeapi.utils import is_valid_postal_code
78

@@ -35,13 +36,13 @@ def generate_list_result(data, identifier="addresses"):
3536
if next_url:
3637
parsed_qs = parse_qs(urlparse(next_url).query)
3738
if identifier == "addresses":
38-
next = parsed_qs.get("from[id]", None)
39+
next_val = parsed_qs.get("from[id]", None)
3940
else:
40-
next = parsed_qs.get("from[postcode]", None)
41+
next_val = parsed_qs.get("from[postcode]", None)
4142
else:
42-
next = None
43+
next_val = None
4344

44-
return {"results": results, "next": next}
45+
return {"results": results, "next": next_val}
4546

4647

4748
class PostcodeAPIClient:
@@ -78,9 +79,15 @@ def _do_request(self, endpoint, querystring=None):
7879
)
7980
data = response.text
8081
if response.status_code == 403:
81-
raise exceptions.NoAccess
82+
raise exceptions.NoAccessException(
83+
"The current account is not allowed to do this"
84+
)
8285
if response.status_code == 404:
83-
raise exceptions.ResourceNotFound
86+
raise exceptions.ResourceNotFoundException("Object not found")
87+
if response.status_code == 429:
88+
raise exceptions.LimitExceededException(
89+
"Limit exceeded or too many requests"
90+
)
8491
return json.loads(data)
8592

8693
def get_all_addresses(self, postal_code=None, number=0, from_id=None):
@@ -97,12 +104,16 @@ def get_all_addresses(self, postal_code=None, number=0, from_id=None):
97104

98105
if number:
99106
if not postal_code:
100-
raise exceptions.HouseNumberRequiresPostalCode
107+
raise exceptions.HouseNumberRequiresPostalCodeException(
108+
"Filtering on a house number requires a postal code"
109+
)
101110
querystring.update({"number": number})
102111

103112
if postal_code:
104113
if not is_valid_postal_code(postal_code):
105-
raise exceptions.InvalidPostalCode
114+
raise exceptions.InvalidPostalCodeException(
115+
"postal_code should be a valid Dutch postal code"
116+
)
106117
querystring.update({"postcode": postal_code})
107118

108119
if from_id:
@@ -129,7 +140,9 @@ def get_all_postal_codes(self, area=None, from_postal_code=None):
129140
:return: List of postal code dictionaries
130141
"""
131142
if from_postal_code and not is_valid_postal_code(from_postal_code):
132-
raise exceptions.InvalidPostalCode
143+
raise exceptions.InvalidPostalCodeException(
144+
"from_postal_code should be a valid Dutch postal code"
145+
)
133146

134147
querystring = {}
135148
if area:
@@ -155,5 +168,7 @@ def get_postal_code(self, postal_code):
155168
:return: Single postal code
156169
"""
157170
if not is_valid_postal_code(postal_code):
158-
raise exceptions.InvalidPostalCode
171+
raise exceptions.InvalidPostalCodeException(
172+
"postal_code should be a valid Dutch postal code"
173+
)
159174
return self._do_request(POSTCODE_API_POSTAL_CODE.format(postal_code))

postcodeapi/exceptions.py

Lines changed: 10 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,18 @@
1-
class NoAccess(Exception):
2-
"""
3-
This exception will be raised when a request is made which is not allowed.
4-
"""
1+
class NoAccessException(Exception):
2+
pass
53

6-
def __init__(self):
7-
super().__init__("The current account is not allowed to do this")
84

5+
class ResourceNotFoundException(Exception):
6+
pass
97

10-
class ResourceNotFound(Exception):
11-
"""
12-
This exception will be raised when a requested object cannot be found.
13-
"""
148

15-
def __init__(self):
16-
super().__init__("Object not found")
9+
class HouseNumberRequiresPostalCodeException(Exception):
10+
pass
1711

1812

19-
class HouseNumberRequiresPostalCode(Exception):
20-
"""
21-
This exception will be raised when attempting to filter on a house number without providing a postal code.
22-
"""
13+
class InvalidPostalCodeException(Exception):
14+
pass
2315

24-
def __init__(self):
25-
super().__init__("Filtering on a house number requires a postal code")
2616

27-
28-
class InvalidPostalCode(Exception):
29-
"""
30-
This exception will be raised when the user provides a value that doesn't pass the Dutch postal code regex.
31-
"""
32-
33-
def __init__(self):
34-
super().__init__("The given postal code is invalid")
17+
class LimitExceededException(Exception):
18+
pass

setup.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
setup(
44
name="postcodeapi",
5-
version="1.1.0",
6-
description="A tiny wrapper around the Postcode API v2",
5+
version="1.2.0",
6+
description="An unofficial Python wrapper around the Postcode API v2",
77
long_description=open("README.rst").read(),
88
url="http://github.com/roedesh/postcodeapi",
99
author="Ruud Schroën",

tests/unit_tests/conftest.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
11
import pytest
2+
23
from postcodeapi.client import PostcodeAPIClient
34

45

56
@pytest.fixture
67
def api_client():
78
return PostcodeAPIClient(api_key="YOUR_KEY")
8-
9-
10-
@pytest.fixture
11-
def api_client_without_key():
12-
return PostcodeAPIClient(api_key="")

tests/unit_tests/helpers.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,7 @@ def read_file(file_name, folder="mocks"):
55
file = join(dirname(realpath(__file__)), folder, file_name)
66
with open(file) as f:
77
return f.read()
8+
9+
10+
def get_api_url(path):
11+
return "https://api.postcodeapi.nu/v2/{}".format(path)

tests/unit_tests/mocks/error_forbidden.json

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

0 commit comments

Comments
 (0)