Skip to content
Open
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
46 changes: 42 additions & 4 deletions parserator_web/templates/parserator_web/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ <h3 id="usaddress-parser"><i class="fa fa-fw fa-map-marker-alt"></i> U.S. addres
<p>Dealing with some messy or unstructured addresses? We can parse them for you.</p>
<div class="card card-body bg-light">
<p><strong>Try it out!</strong> Parse an address in the United States into fields like <code>AddressNumber</code>, <code>StreetName</code> and <code>ZipCode</code>.</p>
<form class="form" role="form">
<form class="form" role="form" id="address-form">
{% csrf_token %}
<input name="address" type="text" class="form-control" id="address" placeholder="123 Main St. Suite 100 Chicago, IL">
<button id="submit" type="submit" class="btn btn-success mt-3">Parse!</button>
</form>
</div>
<!-- TODO: Display parsed address components here. -->
<!-- Display parsed address components here. -->
<div id="address-results" style="display:none">
<h4>Parsing results</h4>
<p>Address type: <strong><span id="parse-type"></span></strong></p>
Expand All @@ -28,7 +28,7 @@ <h4>Parsing results</h4>
<th>Tag</th>
</tr>
</thead>
<tbody>
<tbody id="results-body">
</tbody>
</table>
</div>
Expand All @@ -38,5 +38,43 @@ <h4>Parsing results</h4>
{% endblock %}

{% block extra_js %}
<script src="{% static 'js/index.js' %}"></script>
<script>
document.getElementById('address-form').addEventListener('submit', function(event) {
event.preventDefault();

var addressInput = document.getElementById('address').value;
var csrfToken = document.querySelector('input[name="csrfmiddlewaretoken"]').value;

fetch(`/api/parse_address?address=${encodeURIComponent(addressInput)}`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': csrfToken
}
})
.then(response => response.json())
.then(data => {
if (data.error) {
alert(data.error);
} else {
document.getElementById('address-results').style.display = 'block';
document.getElementById('parse-type').innerText = data.address_type;

var resultsBody = document.getElementById('results-body');
resultsBody.innerHTML = '';
for (var part in data.address_components) {
var row = `<tr>
<td>${part}</td>
<td>${data.address_components[part]}</td>
</tr>`;
resultsBody.insertAdjacentHTML('beforeend', row);
}
}
})
.catch(error => {
console.error('Error:', error);
alert('An error occurred while parsing the address.');
});
});
</script>
{% endblock %}
25 changes: 19 additions & 6 deletions parserator_web/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,24 @@ class AddressParse(APIView):
renderer_classes = [JSONRenderer]

def get(self, request):
# TODO: Flesh out this method to parse an address string using the
# parse() method and return the parsed components to the frontend.
return Response({})
address_string = request.query_params.get('address', None)
if not address_string:
raise ParseError(detail="No address provided")

address_components, address_type = self.parse(address_string)

if address_components is None:
raise ParseError(detail="Invalid address format")

return Response({
"input_string": address_string,
"address_components": address_components,
"address_type": address_type
})

def parse(self, address):
# TODO: Implement this method to return the parsed components of a
# given address using usaddress: https://github.com/datamade/usaddress
return address_components, address_type
try:
parsed_address, address_type = usaddress.tag(address)
return parsed_address, address_type
except usaddress.RepeatedLabelError:
return None, None
28 changes: 20 additions & 8 deletions tests/test_views.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,27 @@
import pytest
from django.urls import reverse


@pytest.mark.django_db
def test_api_parse_succeeds(client):
# TODO: Finish this test. Send a request to the API and confirm that the
# data comes back in the appropriate format.
# This test verifies that the API successfully parses a valid address
address_string = '123 main st chicago il'
pytest.fail()

response = client.get(reverse('parse_address'), {'address': address_string})

assert response.status_code == 200
data = response.json()
assert 'input_string' in data
assert data['input_string'] == address_string
assert 'address_components' in data
assert 'address_type' in data
assert len(data['address_components']) > 0 # Ensure some components are parsed

@pytest.mark.django_db
def test_api_parse_raises_error(client):
# TODO: Finish this test. The address_string below will raise a
# RepeatedLabelError, so ParseAddress.parse() will not be able to parse it.
# This test verifies that the API returns an error for an invalid address
address_string = '123 main st chicago il 123 main st'
pytest.fail()
response = client.get(reverse('parse_address'), {'address': address_string})

assert response.status_code == 400
data = response.json()
assert 'error' in data
assert data['error'] == 'Invalid address format'