Last active
December 20, 2015 08:59
-
-
Save chrislaskey/6104165 to your computer and use it in GitHub Desktop.
A real world example of a Python Flask utility class used in the simpledocs.co and chrisandgitte.com projects. The gist shows the progression from a minimum viable product first, to a refactored library class for general use. The unit tests used in the refactor are appended in a final commit for completeness.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# | |
# File lib/requestparser.py | |
# | |
class RequestParser: | |
def parse(self, flask_request): | |
self.request = flask_request | |
return self._parse_request() | |
def _parse_request(self): | |
self.parsed = {} | |
self.parsing = self.request.base_url.__str__() | |
self._validate_url() | |
self._parse_protocol() | |
self._parse_domain() | |
self._parse_uri_segments() | |
self._parse_uri() | |
return self.parsed | |
def _validate_url(self): | |
has_protocol_string = (self.parsing.find('://') != -1) | |
if not has_protocol_string: | |
raise Exception('Invalid URL') | |
def _parse_protocol(self): | |
protocol, self.parsing = self.parsing.split('://') | |
self.parsed['protocol'] = protocol | |
def _parse_domain(self): | |
self._parse_into_segments() | |
self.parsed['domain'] = self._segments[0] | |
def _parse_into_segments(self): | |
segments = self.parsing.split('/') | |
filtered_segments = [x for x in segments if x] | |
self._segments = filtered_segments | |
def _parse_uri_segments(self): | |
self.parsed['uri_segments'] = self._segments[1:] | |
def _parse_uri(self): | |
uri_segments = self.parsed.get('uri_segments') | |
self.parsed['uri'] = '/' + '/'.join(uri_segments) | |
# | |
# File: tests/test-lib/test-requestparser.py | |
# | |
# -*- coding: utf8 -*- | |
# nosetests --with-coverage --cover-package=<package> \ | |
# --nocapture ./tests | |
import os | |
from lib.environment import Environment | |
base_dir = '{0}/../../'.format(__file__) | |
abs_base_dir = os.path.abspath(base_dir) | |
Environment().add_virtualenv_site_packages_to_path(abs_base_dir) | |
from nose.tools import * | |
from lib.requestparser import RequestParser | |
class TestRequestParser: | |
def setup(self): | |
"Set up test fixtures" | |
def teardown(self): | |
"Tear down test fixtures" | |
def test_empty_url_raises_exception(self): | |
url = '' | |
request = RequestStub().create(url) | |
assert_raises(Exception, RequestParser.parse, request) | |
def test_invalid_url_raises_exception(self): | |
url = 'www.example.com/test/uri.html?one=two' | |
request = RequestStub().create(url) | |
assert_raises(Exception, RequestParser.parse, request) | |
def test_valid_url(self): | |
url = 'http://www.example.com/test/uri.html?one=two' | |
expected = { | |
'protocol': 'http', | |
'domain': 'www.example.com', | |
'uri': '/test/uri.html', | |
'uri_segments': ['test', 'uri.html'] | |
} | |
request = RequestStub().create(url) | |
result = RequestParser().parse(request) | |
assert_equal(result, expected) | |
class RequestStub: | |
class Object(object): | |
" See: http://stackoverflow.com/questions/2827623 " | |
pass | |
def create(self, url): | |
stub = self.Object() | |
stub.url = url | |
stub.base_url = url.split('?')[0] | |
return stub |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment