From 9b6319a07e566f1aedceee4caf61cfc9f88f34a8 Mon Sep 17 00:00:00 2001 From: Alexander Rubin Date: Mon, 22 Jul 2024 23:28:12 -0500 Subject: [PATCH 1/3] defined get and parse methods using usaddress --- Dockerfile | 2 +- parserator_web/views.py | 27 +++++++++++++++++++-------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/Dockerfile b/Dockerfile index 4c464fdf..ca25c192 100644 --- a/Dockerfile +++ b/Dockerfile @@ -36,7 +36,7 @@ RUN pip install --no-cache-dir -r requirements.txt # Install Node requirements COPY ./package.json /app/package.json -RUN npm install +# RUN npm install # Copy the contents of the current host directory (i.e., our app code) into # the container. diff --git a/parserator_web/views.py b/parserator_web/views.py index 0be3f4a9..e9d57430 100644 --- a/parserator_web/views.py +++ b/parserator_web/views.py @@ -5,20 +5,31 @@ from rest_framework.renderers import JSONRenderer from rest_framework.exceptions import ParseError - class Home(TemplateView): 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({}) + address = request.query_params.get('address', None) + if not address: + raise ParseError("No address provided") + + address_components, address_type = self.parse(address) + + return Response({ + 'input_string': address, + '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 = usaddress.tag(address) + address_components = parsed_address[0] + address_type = parsed_address[1] + except usaddress.RepeatedLabelError as e: + raise ParseError("Invalid address") + + return address_components, address_type \ No newline at end of file From 639408084e7c2365f32736061d6ccf0368f730cb Mon Sep 17 00:00:00 2001 From: Alexander Rubin Date: Mon, 22 Jul 2024 23:36:00 -0500 Subject: [PATCH 2/3] utilizing event listener, getting parsed data from server --- parserator_web/static/js/index.js | 47 +++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/parserator_web/static/js/index.js b/parserator_web/static/js/index.js index 492674cc..ddc1cb90 100644 --- a/parserator_web/static/js/index.js +++ b/parserator_web/static/js/index.js @@ -1,2 +1,45 @@ -/* TODO: Flesh this out to connect the form to the API and render results - in the #address-results div. */ +document.addEventListener('DOMContentLoaded', function() { + document.querySelector('form').addEventListener('submit', function(event) { + event.preventDefault(); + + var address = document.querySelector('#address').value; + + fetch('/api/parse?address=' + encodeURIComponent(address), { + headers: { + 'X-CSRFToken': document.querySelector('[name=csrfmiddlewaretoken]').value + } + }) + .then(response => response.json()) + .then(data => { + var resultsDiv = document.getElementById('address-results'); + var resultsTableBody = resultsDiv.querySelector('tbody'); + var parseType = document.getElementById('parse-type'); + + resultsTableBody.innerHTML = ''; // Clear previous results + + if (data.error) { + resultsDiv.style.display = 'block'; + parseType.innerText = 'Error'; + resultsTableBody.innerHTML = '' + data.error + ''; + } else { + resultsDiv.style.display = 'block'; + parseType.innerText = data.address_type; + + var components = data.address_components; + for (var part in components) { + var row = document.createElement('tr'); + var partCell = document.createElement('td'); + var tagCell = document.createElement('td'); + partCell.innerText = part; + tagCell.innerText = components[part]; + row.appendChild(partCell); + row.appendChild(tagCell); + resultsTableBody.appendChild(row); + } + } + }) + .catch(error => { + console.error('Error:', error); + }); + }); +}); From 0ab0d2907dbdd0d17f05d6a90a4d3dd25388de22 Mon Sep 17 00:00:00 2001 From: Alexander Rubin Date: Tue, 23 Jul 2024 00:02:30 -0500 Subject: [PATCH 3/3] test running with the correct api endpoint --- tests/conftest.py | 11 ++++++++++- tests/test_views.py | 39 +++++++++++++++++++++++++++++++++------ 2 files changed, 43 insertions(+), 7 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index ad27c36e..3c9c998e 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1 +1,10 @@ -# Define test fixtures here. +import os +import sys +import django + +# Add the parent directory to the sys.path +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) + +def pytest_configure(): + os.environ['DJANGO_SETTINGS_MODULE'] = 'parserator_web.settings' + django.setup() diff --git a/tests/test_views.py b/tests/test_views.py index bfd5d0b7..e0428f5c 100644 --- a/tests/test_views.py +++ b/tests/test_views.py @@ -1,15 +1,42 @@ import pytest +from rest_framework.test import APIClient +@pytest.fixture +def client(): + return 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. + # Send a request to the API with a valid address address_string = '123 main st chicago il' - pytest.fail() + response = client.get('/api/parse/', {'address': address_string}) + # Check if the response status code is 200 OK + assert response.status_code == 200 + + # Check if the response contains the expected data + data = response.json() + assert 'input_string' in data + assert data['input_string'] == address_string + assert 'address_components' in data + assert 'address_type' in data + + # Check some known components (example, update as needed) + assert 'AddressNumber' in data['address_components'] + assert data['address_components']['AddressNumber'] == '123' + assert 'PlaceName' in data['address_components'] + assert data['address_components']['PlaceName'] == 'chicago' + assert 'StateName' in data['address_components'] + assert data['address_components']['StateName'] == 'il' 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. + # Send a request to the API with an invalid address address_string = '123 main st chicago il 123 main st' - pytest.fail() + response = client.get('/api/parse/', {'address': address_string}) + + # Check if the response status code is 400 Bad Request + assert response.status_code == 400 + + # Check if the response contains the error message + data = response.json() + assert 'detail' in data + assert data['detail'] == 'Invalid address' \ No newline at end of file