From 27e700473e078fe7498a5196dffb69d53f26d0e1 Mon Sep 17 00:00:00 2001 From: tokumaru Date: Sat, 13 Oct 2018 17:05:47 -0700 Subject: [PATCH 1/3] Update python files with some moderately aggressive linting. --- project/api/admin.py | 2 +- project/api/filters.py | 2 + project/api/models.py | 44 +++++---- project/api/permissions.py | 13 ++- project/api/serializers.py | 14 +-- project/api/tests.py | 140 ++++++++++++----------------- project/api/user.py | 1 + project/api/views.py | 15 ++-- project/interactivemap/settings.py | 15 ++-- project/manage.py | 2 +- 10 files changed, 110 insertions(+), 138 deletions(-) diff --git a/project/api/admin.py b/project/api/admin.py index 9354dce..0f8eb24 100644 --- a/project/api/admin.py +++ b/project/api/admin.py @@ -1,6 +1,6 @@ from django.contrib import admin from simple_history.admin import SimpleHistoryAdmin -from .models import * +from .models import Territory, PoliticalEntity, DiplomaticRelation # Register your models here. admin.site.register(Territory, SimpleHistoryAdmin) diff --git a/project/api/filters.py b/project/api/filters.py index b53d1c5..de57c9e 100644 --- a/project/api/filters.py +++ b/project/api/filters.py @@ -18,10 +18,12 @@ class TerritoryFilter(FilterSet): ) def filter_bounds(self, queryset, field_name, value): + """Check the geometry.""" geom = Polygon(make_tuple(value), srid=4326) return queryset.filter(geo__intersects=geom) def filter_date(self, queryset, field_name, value): + """Check the time range.""" return queryset.filter(start_date__lte=value, end_date__gte=value) class Meta: diff --git a/project/api/models.py b/project/api/models.py index 4cb91d5..d31e1b0 100644 --- a/project/api/models.py +++ b/project/api/models.py @@ -11,23 +11,24 @@ class EntityManager(PolymorphicManager): - """ - Manager for the Nation model to handle lookups by url_id - """ + """Manager for the Nation model to handle lookups by url_id.""" def get_by_natural_key(self, url_id): + """Returns attributes by the given url_id.""" return self.get(url_id=url_id) class Entity(PolymorphicModel): - """ - Cultural/governmental entity. Serves as foreign key for most Territories + """Cultural/governmental entity. + + Serves as foreign key for most Territories. """ objects = EntityManager() name = models.TextField( max_length=100, - help_text="Canonical name, should not include any epithets, must be unique", + help_text="Canonical name, which should not include any epithets" + " and must be unique", unique=True) url_id = models.SlugField( max_length=75, @@ -53,6 +54,7 @@ class Entity(PolymorphicModel): ) def natural_key(self): + """Return the ID for lookups.""" return self.url_id def __str__(self): @@ -60,8 +62,9 @@ def __str__(self): class PoliticalEntity(Entity): - """ - Cultural/governmental entity. Serves as foreign key for most Territories + """Cultural/governmental entity. + + Serves as foreign key for most Territories. """ color = ColorField(help_text="Color to display on map", unique=True, @@ -83,16 +86,15 @@ class PoliticalEntity(Entity): # History fields - # Foreign key to auth.User which will be updated every time the model is changed, - # and is this stored in history as the user to update a specific revision - # Consider other metadata (DateTime) for the revision (may be handled by django-simple-history) + # Foreign key to auth.User which we update every time the model changes, + # and store in history as the user to update a specific revision. + # Consider other metadata (DateTime) for the revision + # (may be handled by django-simple-history). # TODO: implement this class Territory(models.Model): - """ - Defines the borders and controlled territories associated with an Entity. - """ + """Defines the borders and territories associated with an Entity.""" class Meta: verbose_name_plural = "territories" @@ -109,12 +111,14 @@ class Meta: history = HistoricalRecords() def clean(self, *args, **kwargs): + """Ensure that the input data is valid.""" if self.start_date > self.end_date: raise ValidationError("Start date cannot be later than end date") if loads(self.geo.json)["type"] != "Polygon" and loads( self.geo.json)["type"] != "MultiPolygon": raise ValidationError( - "Only Polygon and MultiPolygon objects are acceptable geometry types.") + "Only Polygon and MultiPolygon objects are acceptable geometry" + "types.") # This date check is inculsive. if Territory.objects.filter( @@ -122,11 +126,13 @@ def clean(self, *args, **kwargs): end_date__gte=self.start_date, entity__exact=self.entity).exists(): raise ValidationError( - "Another territory of this PoliticalEntity exists during this timeframe.") + "Another territory of this PoliticalEntity exists during this" + " timeframe.") super(Territory, self).clean(*args, **kwargs) def save(self, *args, **kwargs): + """Save the Territory data.""" self.full_clean() super(Territory, self).save(*args, **kwargs) @@ -137,9 +143,7 @@ def __str__(self): class DiplomaticRelation(models.Model): - """ - Defines political and diplomatic interactions between PoliticalEntitys. - """ + """Defines interactions between PoliticalEntitys.""" start_date = models.DateField(help_text="When this relation takes effect") end_date = models.DateField(help_text="When this relation ceases to exist") parent_parties = models.ManyToManyField( @@ -171,12 +175,14 @@ class DiplomaticRelation(models.Model): history = HistoricalRecords() def clean(self, *args, **kwargs): + """Ensure that the input data is valid.""" if self.start_date > self.end_date: raise ValidationError("Start date cannot be later than end date") super(DiplomaticRelation, self).clean(*args, **kwargs) def save(self, *args, **kwargs): + """Save the DiplomaticRelation data.""" self.full_clean() super(DiplomaticRelation, self).save(*args, **kwargs) diff --git a/project/api/permissions.py b/project/api/permissions.py index ff6dc55..9a17ce8 100644 --- a/project/api/permissions.py +++ b/project/api/permissions.py @@ -13,7 +13,7 @@ class IsStaffOrSpecificUser(permissions.BasePermission): """ - Permission to detect whether to user in question is staff or the target user + Permission to detect whether the user is staff or the target user. Example: John (regular user) should be able to access John's account Alice (staff) should be able to access John's account @@ -21,18 +21,16 @@ class IsStaffOrSpecificUser(permissions.BasePermission): """ def has_permission(self, request, view): - # allow user to list all users if logged in user is staff + """Allow user to list all users if logged in user is staff.""" return view.action == 'retrieve' or request.user.is_staff def has_object_permission(self, request, view, obj): - # allow all users to view specific user information + """Allow all users to view specific user information.""" return True def get_token_auth_header(request): - """ - Obtains the Access Token from the Authorization Header - """ + """Obtains the Access Token from the Authorization Header.""" auth = request.META.get("HTTP_AUTHORIZATION", None) parts = auth.split() token = parts[1] @@ -61,7 +59,8 @@ def decorated(*args, **kwargs): jwks['keys'][0]['x5c'][0], 0, re.DOTALL) - cert = '-----BEGIN CERTIFICATE-----\n' + body + '\n-----END CERTIFICATE-----' + cert = ('-----BEGIN CERTIFICATE-----\n' + body + + '\n-----END CERTIFICATE-----') certificate = load_pem_x509_certificate( cert.encode('utf-8'), default_backend()) public_key = certificate.public_key() diff --git a/project/api/serializers.py b/project/api/serializers.py index 0d6efbb..2709955 100644 --- a/project/api/serializers.py +++ b/project/api/serializers.py @@ -1,6 +1,5 @@ from json import loads, dumps -from django.contrib.auth.models import User from django.contrib.gis.geos import GEOSGeometry from rest_framework import serializers @@ -8,24 +7,21 @@ class PoliticalEntitySerializer(serializers.ModelSerializer): - """ - Serializes the PoliticalEntity model - """ + """Serializes the PoliticalEntity model.""" class Meta: model = PoliticalEntity exclude = ('polymorphic_ctype',) class TerritorySerializer(serializers.ModelSerializer): - """ - Serializes the Territory model as GeoJSON compatible data - """ + """Serializes the Territory model as GeoJSON compatible data.""" entity = serializers.SlugRelatedField( read_only=True, slug_field='url_id' ) def to_internal_value(self, data): + """Converts data to GeoJSON.""" ret = {} # Update ret to include passed in data @@ -59,9 +55,7 @@ class Meta: class DiplomaticRelationSerializer(serializers.ModelSerializer): - """ - Serializes the DiplomaticRelation model - """ + """Serializes the DiplomaticRelation model.""" entity = serializers.SlugRelatedField( read_only=True, slug_field='url_id' diff --git a/project/api/tests.py b/project/api/tests.py index 992bd33..b3361e4 100644 --- a/project/api/tests.py +++ b/project/api/tests.py @@ -8,14 +8,16 @@ from django.core.exceptions import ValidationError from rest_framework import status from rest_framework.test import APITestCase -from os import environ from .models import PoliticalEntity, Territory, DiplomaticRelation -from .factories import PoliticalEntityFactory, TerritoryFactory, DiplomaticRelationFactory - -# https://stackoverflow.com/a/815160/ +from .factories import (PoliticalEntityFactory, TerritoryFactory, + DiplomaticRelationFactory) def memoize(function): + """General-purpose memoization decorator. + + From : https://stackoverflow.com/a/815160/ + """ memo = {} def wrapper(*args): @@ -30,8 +32,9 @@ def wrapper(*args): @memoize -def getUserToken(client_id=settings.AUTH0_CLIENT_ID, +def getUserToken(client_id=settings.AUTH0_CLIENT_ID, # noqa client_secret=settings.AUTH0_CLIENT_SECRET): + """Autheticate for tests.""" url = "https://" + settings.AUTH0_DOMAIN + "/oauth/token" headers = {"content-type": "application/json"} parameter = { @@ -50,10 +53,8 @@ def getUserToken(client_id=settings.AUTH0_CLIENT_ID, class ModelTest(TestCase): @classmethod - def setUpTestData(cls): - """ - Create basic model instances and test user - """ + def setUpTestData(cls): # noqa + """Create basic model instances and test user.""" cls.new_nation = PoliticalEntityFactory( name="Test Nation", url_id="test_nation", @@ -77,7 +78,7 @@ def setUpTestData(cls): entity=cls.new_nation, references=["https://en.wikipedia.org/wiki/Test"], geo=GEOSGeometry( - '{"type": "MultiPolygon","coordinates": [[[ [102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0] ]],[[ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ],[ [100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2] ]]]}' + '{"type": "MultiPolygon","coordinates": [[[ [102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0] ]],[[ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ],[ [100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2] ]]]}' # noqa ), ) cls.diprel = DiplomaticRelationFactory( @@ -90,9 +91,7 @@ def setUpTestData(cls): cls.diprel.child_parties.add(cls.child_nation) def test_model_can_create_politicalentity(self): - """ - Ensure that we can create politicalentities. - """ + """Ensure that we can create politicalentities.""" new_politicalentity = PoliticalEntity.objects.create( name="Test Nation2", url_id="test_nation2", @@ -106,8 +105,9 @@ def test_model_can_create_politicalentity(self): url_id="test_nation2").exists()) def test_model_can_create_territory(self): - """ - Ensure that we can create territories. Specifically checks if we can create [start_date+1,end_date-1] + """Ensure that we can create territories. + + Specifically checks if we can create [start_date+1,end_date-1]. """ politicalentity = PoliticalEntity.objects.get(url_id="test_nation") Territory.objects.create( @@ -116,7 +116,7 @@ def test_model_can_create_territory(self): entity=politicalentity, references=["https://en.wikipedia.org/wiki/Test"], geo=GEOSGeometry( - '{"type": "MultiPolygon","coordinates": [[[ [102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0] ]],[[ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ],[ [100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2] ]]]}' + '{"type": "MultiPolygon","coordinates": [[[ [102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0] ]],[[ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ],[ [100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2] ]]]}' # noqa ), ) self.assertTrue( @@ -131,7 +131,7 @@ def test_model_can_create_territory(self): entity=politicalentity, references=["https://en.wikipedia.org/wiki/Test"], geo=GEOSGeometry( - '{"type": "MultiPolygon","coordinates": [[[ [102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0] ]],[[ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ],[ [100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2] ]]]}' + '{"type": "MultiPolygon","coordinates": [[[ [102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0] ]],[[ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ],[ [100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2] ]]]}' # noqa ) ) self.assertTrue( @@ -141,9 +141,7 @@ def test_model_can_create_territory(self): end_date="0006-12-31").exists()) def test_model_can_not_create_territory(self): - """ - Ensure that date checks work. - """ + """Ensure that date checks work.""" new_politicalentity = PoliticalEntity.objects.get(url_id="test_nation") with self.assertRaises(ValidationError): Territory.objects.create( @@ -152,7 +150,7 @@ def test_model_can_not_create_territory(self): entity=new_politicalentity, references=["https://en.wikipedia.org/wiki/Test"], geo=GEOSGeometry( - '{"type": "MultiPolygon","coordinates": [[[ [102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0] ]],[[ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ],[ [100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2] ]]]}' + '{"type": "MultiPolygon","coordinates": [[[ [102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0] ]],[[ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ],[ [100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2] ]]]}' # noqa ) ) with self.assertRaises(ValidationError): @@ -162,7 +160,7 @@ def test_model_can_not_create_territory(self): entity=new_politicalentity, references=["https://en.wikipedia.org/wiki/Test"], geo=GEOSGeometry( - '{"type": "MultiPolygon","coordinates": [[[ [102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0] ]],[[ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ],[ [100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2] ]]]}' + '{"type": "MultiPolygon","coordinates": [[[ [102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0] ]],[[ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ],[ [100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2] ]]]}' # noqa ) ) with self.assertRaises(ValidationError): @@ -172,7 +170,7 @@ def test_model_can_not_create_territory(self): entity=new_politicalentity, references=["https://en.wikipedia.org/wiki/Test"], geo=GEOSGeometry( - '{"type": "MultiPolygon","coordinates": [[[ [102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0] ]],[[ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ],[ [100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2] ]]]}' + '{"type": "MultiPolygon","coordinates": [[[ [102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0] ]],[[ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ],[ [100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2] ]]]}' # noqa ) ) with self.assertRaises(ValidationError): @@ -182,17 +180,15 @@ def test_model_can_not_create_territory(self): entity=new_politicalentity, references=["https://en.wikipedia.org/wiki/Test"], geo=GEOSGeometry( - '{"type": "MultiPolygon","coordinates": [[[ [102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0] ]],[[ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ],[ [100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2] ]]]}' + '{"type": "MultiPolygon","coordinates": [[[ [102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0] ]],[[ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ],[ [100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2] ]]]}' # noqa ) ) class APITest(APITestCase): @classmethod - def setUpTestData(cls): - """ - Create basic model instances - """ + def setUpTestData(cls): # noqa + """Create basic model instances.""" cls.new_nation = PoliticalEntityFactory( name="Test Nation", url_id="test_nation", @@ -215,7 +211,7 @@ def setUpTestData(cls): entity=cls.new_nation, references=["https://en.wikipedia.org/wiki/Test"], geo=GEOSGeometry( - '{"type": "MultiPolygon","coordinates": [[[ [102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0] ]],[[ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ],[ [100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2] ]]]}' + '{"type": "MultiPolygon","coordinates": [[[ [102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0] ]],[[ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ],[ [100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2] ]]]}' # noqa ), ) cls.territory2 = TerritoryFactory( @@ -224,7 +220,7 @@ def setUpTestData(cls): entity=cls.new_nation, references=["https://en.wikipedia.org/wiki/Test"], geo=GEOSGeometry( - '{"type": "MultiPolygon","coordinates": [[[ [102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0] ]],[[ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ]]]}' + '{"type": "MultiPolygon","coordinates": [[[ [102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0] ]],[[ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ]]]}' # noqa ), ) cls.diprel = DiplomaticRelationFactory( @@ -236,10 +232,8 @@ def setUpTestData(cls): cls.diprel.parent_parties.add(cls.new_nation) cls.diprel.child_parties.add(cls.child_nation) - def test_api_can_create_PoliticalEntity(self): - """ - Ensure we can create a new PoliticalEntity - """ + def test_api_can_create_PoliticalEntity(self): # noqa + """Ensure we can create a new PoliticalEntity.""" url = reverse("politicalentity-list") data = { "name": "Created Test Nation", @@ -258,7 +252,7 @@ def test_api_can_create_PoliticalEntity(self): pk=3).name, "Created Test Nation") - def test_api_can_create_territory_FC(self): + def test_api_can_create_territory_FC(self): # noqa """ Ensure we can create a new territory through a FeatureCollection @@ -269,7 +263,7 @@ def test_api_can_create_territory_FC(self): "end_date": "0009-01-01", "entity": self.new_nation.id, "references": ["https://en.wikipedia.org/wiki/Test"], - "geo": '{"type": "FeatureCollection","features": [{"type": "Feature","id": "id0","geometry": {"type": "Polygon","coordinates": [[[100,0],[101,0],[101,1],[100,1],[100,0]]]},"properties": {"prop0": "value0","prop1": "value1"}},{"type": "Feature","properties": {},"geometry": {"type": "Polygon","coordinates": [[[101.22802734375,-1.043643455908483],[102.601318359375,-2.2516174965491453],[102.864990234375,-0.36254640877525024],[101.22802734375,-1.043643455908483]]]}}]}', + "geo": '{"type": "FeatureCollection","features": [{"type": "Feature","id": "id0","geometry": {"type": "Polygon","coordinates": [[[100,0],[101,0],[101,1],[100,1],[100,0]]]},"properties": {"prop0": "value0","prop1": "value1"}},{"type": "Feature","properties": {},"geometry": {"type": "Polygon","coordinates": [[[101.22802734375,-1.043643455908483],[102.601318359375,-2.2516174965491453],[102.864990234375,-0.36254640877525024],[101.22802734375,-1.043643455908483]]]}}]}', # noqa } self.client.credentials(HTTP_AUTHORIZATION="Bearer " + getUserToken()) response = self.client.post(url, data, format="json") @@ -278,16 +272,14 @@ def test_api_can_create_territory_FC(self): self.assertEqual(Territory.objects.last().entity, self.new_nation) def test_api_can_create_territory(self): - """ - Ensure we can create a new territory - """ + """Ensure we can create a new territory.""" url = reverse("territory-list") data = { "start_date": "0006-01-01", "end_date": "0007-01-01", "entity": self.new_nation.id, "references": ["https://en.wikipedia.org/wiki/Test"], - "geo": '{"type": "MultiPolygon","coordinates": [[[ [102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0] ]],[[ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ],[ [100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2] ]]]}', + "geo": '{"type": "MultiPolygon","coordinates": [[[ [102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0] ]],[[ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ],[ [100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2] ]]]}', # noqa } self.client.credentials(HTTP_AUTHORIZATION="Bearer " + getUserToken()) response = self.client.post(url, data, format="json") @@ -295,17 +287,15 @@ def test_api_can_create_territory(self): self.assertEqual(Territory.objects.count(), 3) self.assertEqual(Territory.objects.last().entity, self.new_nation) - def test_api_can_update_PoliticalEntity(self): - """ - Ensure we can update individual PoliticalEntities - """ + def test_api_can_update_PoliticalEntity(self): # noqa + """Ensure we can update individual PoliticalEntities.""" url = reverse("politicalentity-detail", args=["test_nation"]) data = { "name": "Created Test Nation", "url_id": "created_test_nation", "color": "#ccffff", "references": ["https://en.wikipedia.org/wiki/Test"], - "geo": '{"type": "MultiPolygon","coordinates": [[[ [102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0] ]],[[ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ],[ [100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2] ]]]}', + "geo": '{"type": "MultiPolygon","coordinates": [[[ [102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0] ]],[[ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ],[ [100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2] ]]]}', # noqa } self.client.credentials(HTTP_AUTHORIZATION="Bearer " + getUserToken()) response = self.client.put(url, data, format="json") @@ -313,43 +303,35 @@ def test_api_can_update_PoliticalEntity(self): self.assertEqual(response.data["name"], "Created Test Nation") def test_api_can_update_territory(self): - """ - Ensure we can update individual territories - """ + """Ensure we can update individual territories.""" url = reverse("territory-detail", args=[self.territory.id]) data = { "start_date": "0010-01-01", "end_date": "0011-01-01", "entity": self.child_nation.id, - "geo": '{"type": "MultiPolygon","coordinates": [[[ [102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0] ]],[[ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ],[ [100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2] ]]]}', + "geo": '{"type": "MultiPolygon","coordinates": [[[ [102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0] ]],[[ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ],[ [100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2] ]]]}', # noqa } self.client.credentials(HTTP_AUTHORIZATION="Bearer " + getUserToken()) response = self.client.put(url, data, format="json") self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.data['entity'], self.child_nation.url_id) - def test_api_can_query_PoliticalEntities(self): - """ - Ensure we can query for all PoliticalEntities - """ + def test_api_can_query_PoliticalEntities(self): # noqa + """Ensure we can query for all PoliticalEntities.""" url = reverse("politicalentity-list") response = self.client.get(url, format="json") self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.data[0]["name"], "Test Nation") def test_api_can_query_territories(self): - """ - Ensure we can query for all territories - """ + """Ensure we can query for all territories.""" url = reverse("territory-list") response = self.client.get(url, format="json") self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.data[0]["entity"], "test_nation") def test_api_can_query_territory(self): - """ - Ensure we can query individual territories - """ + """Ensure we can query individual territories.""" url = reverse("territory-detail", args=[self.territory.id]) response = self.client.get(url, format="json") self.assertEqual(response.status_code, status.HTTP_200_OK) @@ -362,7 +344,8 @@ def test_api_can_query_territories_bounds(self): """ url = ( reverse("territory-list") + - "?bounds=((0.0, 0.0), (0.0, 150.0), (150.0, 150.0), (150.0, 0.0), (0.0, 0.0))") + "?bounds=((0.0, 0.0), (0.0, 150.0), (150.0, 150.0), (150.0, 0.0)" + + ", (0.0, 0.0))") response = self.client.get(url, format="json") self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.data[0]["entity"], "test_nation") @@ -370,19 +353,18 @@ def test_api_can_query_territories_bounds(self): def test_api_can_not_query_territories_bounds(self): """ Ensure querying for bounds in which the PoliticalEntity does not - lie in fails + lie in fails. """ url = ( reverse("territory-list") + - "?bounds=((0.0, 0.0), (0.0, 50.0), (50.0, 50.0), (50.0, 0.0), (0.0, 0.0))") + "?bounds=((0.0, 0.0), (0.0, 50.0), (50.0, 50.0), (50.0, 0.0)," + + " (0.0, 0.0))") response = self.client.get(url, format="json") self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertTrue(not response.data) def test_api_can_query_territories_date(self): - """ - Ensure we can query for territories with a date - """ + """Ensure we can query for territories with a date.""" url = reverse("territory-list") + "?date=0001-01-01" response = self.client.get(url, format="json") self.assertEqual(response.status_code, status.HTTP_200_OK) @@ -391,26 +373,22 @@ def test_api_can_query_territories_date(self): def test_api_can_not_query_territories_date(self): """ Ensure querying for territories with an earlier start - date fails + date fails. """ url = reverse("territory-list") + "?date=2020-01-01" response = self.client.get(url, format="json") self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertTrue(not response.data) - def test_api_can_query_PoliticalEntity(self): - """ - Ensure we can query individual PoliticalEntities - """ + def test_api_can_query_PoliticalEntity(self): # noqa + """Ensure we can query individual PoliticalEntities.""" url = reverse("politicalentity-detail", args=["test_nation"]) response = self.client.get(url, format="json") self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.data["name"], "Test Nation") def test_api_can_query_territories_exclude(self): - """ - Ensure we can exclude territories by id - """ + """.Ensure we can exclude territories by id.""" url = reverse("territory-list") + "?exclude_ids=" + \ str(self.territory.id) response = self.client.get(url, format="json") @@ -420,9 +398,7 @@ def test_api_can_query_territories_exclude(self): self.assertTrue(not response.data) def test_api_can_create_diprel(self): - """ - Ensure we can create a new DiplomaticRelation - """ + """Ensure we can create a new DiplomaticRelation.""" url = reverse("diplomaticrelation-list") data = { "start_date": "0001-01-01", @@ -439,9 +415,7 @@ def test_api_can_create_diprel(self): self.assertEqual(DiplomaticRelation.objects.last().diplo_type, "A") def test_api_can_update_diprel(self): - """ - Ensure we can update individual DipRels - """ + """Ensure we can update individual DipRels.""" url = reverse("diplomaticrelation-detail", args=[self.diprel.id]) data = { "start_date": "0006-01-01", @@ -457,18 +431,14 @@ def test_api_can_update_diprel(self): self.assertEqual(response.data["diplo_type"], "A") def test_api_can_query_diprels(self): - """ - Ensure we can query for all DipRels - """ + """Ensure we can query for all DipRels.""" url = reverse("diplomaticrelation-list") response = self.client.get(url, format="json") self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.data[0]["diplo_type"], "A") def test_api_can_query_diprel(self): - """ - Ensure we can query individual DipRels - """ + """Ensure we can query individual DipRels.""" url = reverse("diplomaticrelation-detail", args=[self.diprel.id]) response = self.client.get(url, format="json") self.assertEqual(response.status_code, status.HTTP_200_OK) diff --git a/project/api/user.py b/project/api/user.py index e0d7c7c..9eac202 100644 --- a/project/api/user.py +++ b/project/api/user.py @@ -2,6 +2,7 @@ def jwt_get_username_from_payload_handler(payload): + """Handle for JWT authetication in settings.py.""" username = payload.get('sub').replace('|', '.') authenticate(remote_user=username) return username diff --git a/project/api/views.py b/project/api/views.py index f995307..4bde72c 100644 --- a/project/api/views.py +++ b/project/api/views.py @@ -1,14 +1,13 @@ from rest_framework import viewsets, permissions from .models import PoliticalEntity, Territory, DiplomaticRelation -from .serializers import PoliticalEntitySerializer, TerritorySerializer, DiplomaticRelationSerializer +from .serializers import (PoliticalEntitySerializer, TerritorySerializer, + DiplomaticRelationSerializer) from .filters import TerritoryFilter class PoliticalEntityViewSet(viewsets.ModelViewSet): - """ - Viewset for the PoliticalEntity model - """ + """Viewset for the PoliticalEntity model.""" permission_classes = (permissions.IsAuthenticatedOrReadOnly,) queryset = PoliticalEntity.objects.all() serializer_class = PoliticalEntitySerializer @@ -18,9 +17,7 @@ class PoliticalEntityViewSet(viewsets.ModelViewSet): class TerritoryViewSet(viewsets.ModelViewSet): - """ - Viewset for the Territory model - """ + """Viewset for the Territory model.""" permission_classes = (permissions.IsAuthenticatedOrReadOnly,) serializer_class = TerritorySerializer filter_class = TerritoryFilter @@ -31,9 +28,7 @@ class TerritoryViewSet(viewsets.ModelViewSet): class DiplomaticRelationViewSet(viewsets.ModelViewSet): - """ - Viewset for the DiplomaticRelation model - """ + """Viewset for the DiplomaticRelation model.""" permission_classes = (permissions.IsAuthenticatedOrReadOnly,) queryset = DiplomaticRelation.objects.all() serializer_class = DiplomaticRelationSerializer diff --git a/project/interactivemap/settings.py b/project/interactivemap/settings.py index 195cd6a..48ef453 100644 --- a/project/interactivemap/settings.py +++ b/project/interactivemap/settings.py @@ -114,16 +114,20 @@ AUTH_PASSWORD_VALIDATORS = [ { - 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + 'NAME': ('django.contrib.auth.password_validation.UserAttribute' + 'SimilarityValidator'), }, { - 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + 'NAME': ('django.contrib.auth.password_validation.MinimumLength' + 'Validator'), }, { - 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + 'NAME': ('django.contrib.auth.password_validation.CommonPassword' + 'Validator'), }, { - 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + 'NAME': ('django.contrib.auth.password_validation.NumericPassword' + 'Validator'), }, ] @@ -183,7 +187,8 @@ # Add a line-break every 64 chars # https://stackoverflow.com/questions/2657693/insert-a-newline-character-every-64-characters-using-python body = re.sub("(.{64})", "\\1\n", jwks['keys'][0]['x5c'][0], 0, re.DOTALL) - cert = '-----BEGIN CERTIFICATE-----\n' + body + '\n-----END CERTIFICATE-----' + cert = ('-----BEGIN CERTIFICATE-----\n' + body + + '\n-----END CERTIFICATE-----') certificate = load_pem_x509_certificate( cert.encode('utf-8'), default_backend()) PUBLIC_KEY = certificate.public_key() diff --git a/project/manage.py b/project/manage.py index 65fd273..a463c3e 100755 --- a/project/manage.py +++ b/project/manage.py @@ -23,5 +23,5 @@ "Couldn't import Django. Are you sure it's installed and " "available on your PYTHONPATH environment variable? Did you " "forget to activate a virtual environment?" - ) from exc + ) from exc # noqa execute_from_command_line(sys.argv) From f2f63c5bf335e040b9d60c058682e2c6720d469d Mon Sep 17 00:00:00 2001 From: tokumaru Date: Sat, 13 Oct 2018 17:12:14 -0700 Subject: [PATCH 2/3] Track updated migrations. --- .../api/migrations/0005_auto_20181014_0009.py | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 project/api/migrations/0005_auto_20181014_0009.py diff --git a/project/api/migrations/0005_auto_20181014_0009.py b/project/api/migrations/0005_auto_20181014_0009.py new file mode 100644 index 0000000..b5713bf --- /dev/null +++ b/project/api/migrations/0005_auto_20181014_0009.py @@ -0,0 +1,28 @@ +# Generated by Django 2.1.2 on 2018-10-14 00:09 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('api', '0004_auto_20181011_0231'), + ] + + operations = [ + migrations.AlterField( + model_name='entity', + name='name', + field=models.TextField(help_text='Canonical name, which should not include any epithets and must be unique', max_length=100, unique=True), + ), + migrations.AlterField( + model_name='historicalentity', + name='name', + field=models.TextField(db_index=True, help_text='Canonical name, which should not include any epithets and must be unique', max_length=100), + ), + migrations.AlterField( + model_name='historicalpoliticalentity', + name='name', + field=models.TextField(db_index=True, help_text='Canonical name, which should not include any epithets and must be unique', max_length=100), + ), + ] From c03c208378b4f455e55310fc065c906a0604fb3c Mon Sep 17 00:00:00 2001 From: tokumaru Date: Sun, 21 Oct 2018 13:50:20 -0700 Subject: [PATCH 3/3] Apply changes to lint dwaxe suggested. --- project/api/filters.py | 4 ++-- project/api/models.py | 17 +++++++---------- project/api/permissions.py | 1 + project/api/serializers.py | 2 +- 4 files changed, 11 insertions(+), 13 deletions(-) diff --git a/project/api/filters.py b/project/api/filters.py index c75c990..940ad7b 100644 --- a/project/api/filters.py +++ b/project/api/filters.py @@ -14,12 +14,12 @@ class TerritoryFilter(FilterSet): ) def filter_bounds(self, queryset, field_name, value): - """Check the geometry.""" + """Filters geometries that intersect @bounds.""" geom = Polygon(make_tuple(value), srid=4326) return queryset.filter(geo__intersects=geom) def filter_date(self, queryset, field_name, value): - """Check the time range.""" + """Filters territories that exist during @Date.""" return queryset.filter(start_date__lte=value, end_date__gte=value) class Meta: diff --git a/project/api/models.py b/project/api/models.py index 4a20e23..c3b9852 100644 --- a/project/api/models.py +++ b/project/api/models.py @@ -13,8 +13,7 @@ class EntityManager(PolymorphicManager): """Manager for the Nation model to handle lookups by url_id.""" - def get_by_natural_key(self, url_id): - """Returns attributes by the given url_id.""" + def get_by_natural_key(self, url_id): # noqa return self.get(url_id=url_id) @@ -105,7 +104,8 @@ class Meta: history = HistoricalRecords() def clean(self, *args, **kwargs): - """Ensure that the input data is valid.""" + """Ensure that our geometry is a polygon and our dates do not intersect + with those of another Territory of the same Entity.""" if self.start_date > self.end_date: raise ValidationError("Start date cannot be later than end date") if ( @@ -114,7 +114,7 @@ def clean(self, *args, **kwargs): ): raise ValidationError( "Only Polygon and MultiPolygon objects are acceptable geometry" - "types.") + " types.") try: # This date check is inculsive. if Territory.objects.filter( @@ -131,8 +131,7 @@ def clean(self, *args, **kwargs): super(Territory, self).clean(*args, **kwargs) - def save(self, *args, **kwargs): - """Save the Territory data.""" + def save(self, *args, **kwargs): # noqa self.full_clean() super(Territory, self).save(*args, **kwargs) @@ -173,15 +172,13 @@ class DiplomaticRelation(models.Model): history = HistoricalRecords() - def clean(self, *args, **kwargs): - """Ensure that the input data is valid.""" + def clean(self, *args, **kwargs): # noqa if self.start_date > self.end_date: raise ValidationError("Start date cannot be later than end date") super(DiplomaticRelation, self).clean(*args, **kwargs) - def save(self, *args, **kwargs): - """Save the DiplomaticRelation data.""" + def save(self, *args, **kwargs): # noqa self.full_clean() super(DiplomaticRelation, self).save(*args, **kwargs) diff --git a/project/api/permissions.py b/project/api/permissions.py index 78eee4f..7d60760 100644 --- a/project/api/permissions.py +++ b/project/api/permissions.py @@ -26,6 +26,7 @@ def has_permission(self, request, view): def has_object_permission(self, request, view, obj): """Allow all users to view specific user information.""" + # TODO: Actually implement this. return True diff --git a/project/api/serializers.py b/project/api/serializers.py index b99a89c..80fb4d2 100644 --- a/project/api/serializers.py +++ b/project/api/serializers.py @@ -32,7 +32,7 @@ class TerritorySerializer(serializers.ModelSerializer): geo = GeoField(read_only=True) def to_internal_value(self, data): - """Converts data to GeoJSON.""" + """Return a dictionary of territory data.""" ret = {} # Update ret to include passed in data