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

working functionality #54

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
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
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ RUN curl -sL https://deb.nodesource.com/setup_12.x | bash -
#
# Read more on Dockerfile best practices at the source:
# https://docs.docker.com/develop/develop-images/dockerfile_best-practices
RUN apt-get update && apt-get install -y --no-install-recommends postgresql-client nodejs
RUN apt-get update && apt-get install -y --no-install-recommends postgresql-client nodejs npm

# Inside the container, create an app directory and switch into it
RUN mkdir /app
Expand Down
3 changes: 3 additions & 0 deletions parserator_web/static/js/index.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
/* TODO: Flesh this out to connect the form to the API and render results
in the #address-results div. */

/*My code was not functioning correctly when I sperated it into this file, but it works when I wrote the js inline within the index.html */

60 changes: 56 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,12 @@ <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 id="address-form" class="form" role="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. -->
<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 +27,7 @@ <h4>Parsing results</h4>
<th>Tag</th>
</tr>
</thead>
<tbody>
<tbody id="results-body">
</tbody>
</table>
</div>
Expand All @@ -38,5 +37,58 @@ <h4>Parsing results</h4>
{% endblock %}

{% block extra_js %}
<script src="{% static 'js/index.js' %}"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.min.js"></script>
<script>
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
if (cookie.substring(0, name.length + 1) == (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}

document.getElementById('address-form').addEventListener('submit', function(event) {
event.preventDefault();
let address = document.getElementById('address').value;
let csrftoken = getCookie('csrftoken');

$.ajax({
url: 'api/parse/',
type: 'POST',
headers: {
'X-CSRFToken': csrftoken
},
data: {
'address': address
},
success: function(data) {
let resultDiv = document.getElementById('address-results');
let resultsBody = document.getElementById('results-body');
let parseType = document.getElementById('parse-type');
resultsBody.innerHTML = '';
if (data.status === 'success') {
parseType.innerText = data.address_type;
Object.entries(data.parsed).forEach(([key, value]) => {
resultsBody.innerHTML += `<tr><td>${key}</td><td>${value}</td></tr>`;
});
resultDiv.style.display = 'block';
} else {
resultDiv.style.display = 'none';
alert(`Error: ${data.message}`);
}
},
error: function(jqXHR, textStatus, errorThrown) {
alert(`Error: ${textStatus}`);
}
});
});
</script>
{% endblock %}
1 change: 0 additions & 1 deletion parserator_web/urls.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from django.urls import path

from parserator_web import views

urlpatterns = [
Expand Down
34 changes: 24 additions & 10 deletions parserator_web/views.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,38 @@
import usaddress
from django.views.generic import TemplateView
from rest_framework import status
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.renderers import JSONRenderer
from rest_framework.exceptions import ParseError


class Home(TemplateView):
template_name = 'parserator_web/index.html'
template_name = "parserator_web/index.html"


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({})
def post(self, request, *args, **kwargs):
address = request.data.get("address")
try:
parsed_address, address_type = usaddress.tag(address)
return Response(
{
"status": "success",
"parsed": parsed_address,
"address_type": address_type,
},
status=status.HTTP_200_OK,
)
except usaddress.RepeatedLabelError as e:
return Response(
{"status": "error", "message": str(e)},
status=status.HTTP_400_BAD_REQUEST,
)

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
def get(self, request, *args, **kwargs):
return Response(
{"message": "Send a POST request with an address to parse."},
status=status.HTTP_200_OK,
)
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ whitenoise==5.2.0
djangorestframework==3.11.1
usaddress==0.5.10
six
django-json-response==1.1.5
django-urls==1.1.3
32 changes: 22 additions & 10 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
from rest_framework.test import APIClient


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.
address_string = '123 main st chicago il'
pytest.fail()
@pytest.mark.django_db
def test_parse_address_success():
client = APIClient()
response = client.post(
reverse("address-parse"),
{"address": "123 Main St. Suite 100 Chicago, IL"},
format="json",
)
assert response.status_code == 200
assert response.data["status"] == "success"
assert "AddressNumber" in response.data["parsed"]


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.
address_string = '123 main st chicago il 123 main st'
pytest.fail()
@pytest.mark.django_db
def test_parse_address_failure():
client = APIClient()
response = client.post(
reverse("address-parse"), {"address": "123 main st chicago il 123 main st"},
format="json"
)
assert response.status_code == 400
assert response.data["status"] == "error"