From 140180b6b3f7551b425fd0d5bd9793d688d19a3a Mon Sep 17 00:00:00 2001 From: Vasilis Tsiligiannis Date: Sat, 27 Apr 2019 12:04:49 +0300 Subject: [PATCH] Reformat code with 'yapf', check format using 'tox' Use configration based on Django coding style guidelines Signed-off-by: Vasilis Tsiligiannis --- .yapfignore | 2 + auth0login/auth0backend.py | 14 ++-- db/__init__.py | 1 - db/api/filters.py | 13 ++-- db/api/serializers.py | 17 ++-- db/api/tests.py | 13 ++-- db/api/urls.py | 1 - db/api/views.py | 4 +- db/base/admin.py | 75 ++++++++++++------ db/base/helpers.py | 9 ++- db/base/management/commands/decode_data.py | 9 +-- .../management/commands/delete_satellite.py | 4 +- db/base/management/commands/fetch_data.py | 23 ++++-- .../management/commands/fetch_satellites.py | 4 +- db/base/models.py | 77 ++++++++++--------- db/base/tasks.py | 24 +++--- db/base/tests.py | 14 ++-- db/base/urls.py | 39 ++++++---- db/base/utils.py | 73 ++++++++++-------- db/base/views.py | 63 ++++++++------- db/celery.py | 11 ++- db/settings.py | 69 ++++++----------- db/urls.py | 7 +- db/wsgi.py | 1 - setup.cfg | 5 ++ tox.ini | 10 +++ 26 files changed, 321 insertions(+), 261 deletions(-) create mode 100644 .yapfignore diff --git a/.yapfignore b/.yapfignore new file mode 100644 index 0000000..e3b6bee --- /dev/null +++ b/.yapfignore @@ -0,0 +1,2 @@ +db/_version.py +db/base/migrations diff --git a/auth0login/auth0backend.py b/auth0login/auth0backend.py index 72a217e..590dbd1 100644 --- a/auth0login/auth0backend.py +++ b/auth0login/auth0backend.py @@ -7,9 +7,7 @@ class Auth0(BaseOAuth2): name = 'auth0' SCOPE_SEPARATOR = ' ' ACCESS_TOKEN_METHOD = 'POST' - EXTRA_DATA = [ - ('email', 'email') - ] + EXTRA_DATA = [('email', 'email')] def authorization_url(self): """Return the authorization endpoint.""" @@ -29,7 +27,9 @@ class Auth0(BaseOAuth2): resp = requests.get(url, headers=headers) userinfo = resp.json() - return {'username': userinfo['nickname'], - 'email': userinfo['email'], - # 'first_name': userinfo['name'], - 'user_id': userinfo['sub']} + return { + 'username': userinfo['nickname'], + 'email': userinfo['email'], + # 'first_name': userinfo['name'], + 'user_id': userinfo['sub'] + } diff --git a/db/__init__.py b/db/__init__.py index 325e20f..f0fa144 100644 --- a/db/__init__.py +++ b/db/__init__.py @@ -2,7 +2,6 @@ from __future__ import absolute_import from .celery import app as celery_app # noqa - __all__ = ['celery_app'] from ._version import get_versions diff --git a/db/api/filters.py b/db/api/filters.py index 857be75..34220ac 100644 --- a/db/api/filters.py +++ b/db/api/filters.py @@ -6,9 +6,7 @@ from db.base.models import Transmitter, DemodData, Satellite class TransmitterViewFilter(FilterSet): - alive = filters.BooleanFilter(field_name='status', - label='Alive', - method='filter_status') + alive = filters.BooleanFilter(field_name='status', label='Alive', method='filter_status') def filter_status(self, queryset, name, value): if value: @@ -23,9 +21,7 @@ class TransmitterViewFilter(FilterSet): class SatelliteViewFilter(FilterSet): ''' filter on decayed field ''' - in_orbit = filters.BooleanFilter(field_name='decayed', - label='In orbit', - lookup_expr='isnull') + in_orbit = filters.BooleanFilter(field_name='decayed', label='In orbit', lookup_expr='isnull') class Meta: model = Satellite @@ -33,8 +29,9 @@ class SatelliteViewFilter(FilterSet): class TelemetryViewFilter(FilterSet): - satellite = django_filters.NumberFilter(field_name='satellite__norad_cat_id', - lookup_expr='exact') + satellite = django_filters.NumberFilter( + field_name='satellite__norad_cat_id', lookup_expr='exact' + ) class Meta: model = DemodData diff --git a/db/api/serializers.py b/db/api/serializers.py index 643ef2a..05d80d9 100644 --- a/db/api/serializers.py +++ b/db/api/serializers.py @@ -24,9 +24,11 @@ class TransmitterSerializer(serializers.ModelSerializer): class Meta: model = Transmitter - fields = ('uuid', 'description', 'alive', 'type', 'uplink_low', 'uplink_high', - 'uplink_drift', 'downlink_low', 'downlink_high', 'downlink_drift', 'mode_id', - 'mode', 'invert', 'baud', 'norad_cat_id', 'status', 'updated', 'citation') + fields = ( + 'uuid', 'description', 'alive', 'type', 'uplink_low', 'uplink_high', 'uplink_drift', + 'downlink_low', 'downlink_high', 'downlink_drift', 'mode_id', 'mode', 'invert', 'baud', + 'norad_cat_id', 'status', 'updated', 'citation' + ) # Keeping alive field for compatibility issues def get_alive(self, obj): @@ -57,8 +59,10 @@ class TelemetrySerializer(serializers.ModelSerializer): class Meta: model = DemodData - fields = ('norad_cat_id', 'transmitter', 'app_source', 'schema', - 'decoded', 'frame', 'observer', 'timestamp') + fields = ( + 'norad_cat_id', 'transmitter', 'app_source', 'schema', 'decoded', 'frame', 'observer', + 'timestamp' + ) def get_norad_cat_id(self, obj): return obj.satellite.norad_cat_id @@ -85,5 +89,4 @@ class TelemetrySerializer(serializers.ModelSerializer): class SidsSerializer(serializers.ModelSerializer): class Meta: model = DemodData - fields = ('satellite', 'payload_frame', 'station', 'lat', 'lng', - 'timestamp', 'app_source') + fields = ('satellite', 'payload_frame', 'station', 'lat', 'lng', 'timestamp', 'app_source') diff --git a/db/api/tests.py b/db/api/tests.py index 746f5bd..67a2c40 100644 --- a/db/api/tests.py +++ b/db/api/tests.py @@ -22,8 +22,7 @@ class ModeViewApiTest(TestCase): self.assertEqual(response.status_code, status.HTTP_200_OK) def test_retrieve(self): - response = self.client.get('/api/modes/{0}/'.format(self.mode.id), - format='json') + response = self.client.get('/api/modes/{0}/'.format(self.mode.id), format='json') self.assertContains(response, self.mode.name) @@ -43,8 +42,9 @@ class SatelliteViewApiTest(TestCase): self.assertEqual(response.status_code, status.HTTP_200_OK) def test_retrieve(self): - response = self.client.get('/api/satellites/{0}/'.format(self.satellite.norad_cat_id), - format='json') + response = self.client.get( + '/api/satellites/{0}/'.format(self.satellite.norad_cat_id), format='json' + ) self.assertContains(response, self.satellite.name) @@ -65,8 +65,9 @@ class TransmitterViewApiTest(TestCase): self.assertEqual(response.status_code, status.HTTP_200_OK) def test_retrieve(self): - response = self.client.get('/api/transmitters/{0}/'.format(self.transmitter.uuid), - format='json') + response = self.client.get( + '/api/transmitters/{0}/'.format(self.transmitter.uuid), format='json' + ) self.assertContains(response, self.transmitter.description) diff --git a/db/api/urls.py b/db/api/urls.py index c8a160a..623df64 100644 --- a/db/api/urls.py +++ b/db/api/urls.py @@ -2,7 +2,6 @@ from rest_framework import routers from db.api import views - router = routers.DefaultRouter() router.register(r'modes', views.ModeView) diff --git a/db/api/views.py b/db/api/views.py index 6a57401..2138c3f 100644 --- a/db/api/views.py +++ b/db/api/views.py @@ -29,8 +29,8 @@ class TransmitterView(viewsets.ReadOnlyModelViewSet): lookup_field = 'uuid' -class TelemetryView(mixins.ListModelMixin, mixins.RetrieveModelMixin, - mixins.CreateModelMixin, viewsets.GenericViewSet): +class TelemetryView(mixins.ListModelMixin, mixins.RetrieveModelMixin, mixins.CreateModelMixin, + viewsets.GenericViewSet): queryset = DemodData.objects.all() serializer_class = serializers.TelemetrySerializer filter_class = filters.TelemetryViewFilter diff --git a/db/base/admin.py b/db/base/admin.py index 3d6d3a6..fec185b 100644 --- a/db/base/admin.py +++ b/db/base/admin.py @@ -8,17 +8,17 @@ from django.urls import reverse from django.http import HttpResponseRedirect from django.shortcuts import redirect -from db.base.models import (Mode, Satellite, TransmitterEntry, TransmitterSuggestion, - Transmitter, DemodData, Telemetry) +from db.base.models import ( + Mode, Satellite, TransmitterEntry, TransmitterSuggestion, Transmitter, DemodData, Telemetry +) from db.base.tasks import check_celery, reset_decoded_data, decode_all_data - logger = logging.getLogger('db') @admin.register(Mode) class ModeAdmin(admin.ModelAdmin): - list_display = ('name',) + list_display = ('name', ) @admin.register(Satellite) @@ -31,10 +31,12 @@ class SatelliteAdmin(admin.ModelAdmin): urls = super(SatelliteAdmin, self).get_urls() my_urls = [ url(r'^check_celery/$', self.check_celery, name='check_celery'), - url(r'^reset_data/(?P[0-9]+)/$', self.reset_data, - name='reset_data'), - url(r'^decode_all_data/(?P[0-9]+)/$', self.decode_all_data, - name='decode_all_data'), + url(r'^reset_data/(?P[0-9]+)/$', self.reset_data, name='reset_data'), + url( + r'^decode_all_data/(?P[0-9]+)/$', + self.decode_all_data, + name='decode_all_data' + ), ] return my_urls + urls @@ -72,25 +74,41 @@ class SatelliteAdmin(admin.ModelAdmin): @admin.register(TransmitterEntry) class TransmitterEntryAdmin(admin.ModelAdmin): - list_display = ('uuid', 'description', 'satellite', 'type', 'mode', 'baud', 'downlink_low', - 'downlink_high', 'downlink_drift', 'uplink_low', 'uplink_high', 'uplink_drift', - 'reviewed', 'approved', 'status', 'created', 'citation', 'user') + list_display = ( + 'uuid', 'description', 'satellite', 'type', 'mode', 'baud', 'downlink_low', + 'downlink_high', 'downlink_drift', 'uplink_low', 'uplink_high', 'uplink_drift', 'reviewed', + 'approved', 'status', 'created', 'citation', 'user' + ) search_fields = ('satellite__id', 'uuid', 'satellite__name', 'satellite__norad_cat_id') - list_filter = ('reviewed', 'approved', 'type', 'status', 'mode', 'baud',) + list_filter = ( + 'reviewed', + 'approved', + 'type', + 'status', + 'mode', + 'baud', + ) readonly_fields = ('uuid', 'satellite') @admin.register(TransmitterSuggestion) class TransmitterSuggestionAdmin(admin.ModelAdmin): - list_display = ('uuid', 'description', 'satellite', 'type', 'mode', 'baud', 'downlink_low', - 'downlink_high', 'downlink_drift', 'uplink_low', 'uplink_high', 'uplink_drift', - 'status', 'created', 'citation', 'user') + list_display = ( + 'uuid', 'description', 'satellite', 'type', 'mode', 'baud', 'downlink_low', + 'downlink_high', 'downlink_drift', 'uplink_low', 'uplink_high', 'uplink_drift', 'status', + 'created', 'citation', 'user' + ) search_fields = ('satellite__id', 'uuid', 'satellite__name', 'satellite__norad_cat_id') - list_filter = ('type', 'mode', 'baud',) - readonly_fields = ('uuid', 'description', 'status', 'type', 'uplink_low', 'uplink_high', - 'uplink_drift', 'downlink_low', 'downlink_high', 'downlink_drift', 'mode', - 'invert', 'baud', 'satellite', 'reviewed', 'approved', 'created', - 'citation', 'user') + list_filter = ( + 'type', + 'mode', + 'baud', + ) + readonly_fields = ( + 'uuid', 'description', 'status', 'type', 'uplink_low', 'uplink_high', 'uplink_drift', + 'downlink_low', 'downlink_high', 'downlink_drift', 'mode', 'invert', 'baud', 'satellite', + 'reviewed', 'approved', 'created', 'citation', 'user' + ) actions = ['approve_suggestion', 'reject_suggestion'] def get_actions(self, request): @@ -115,6 +133,7 @@ class TransmitterSuggestionAdmin(admin.ModelAdmin): self.message_user(request, "Transmitter suggestion was successfully approved") else: self.message_user(request, "Transmitter suggestions were successfully approved") + approve_suggestion.short_description = 'Approve selected transmitter suggestions' def reject_suggestion(self, request, queryset): @@ -132,16 +151,24 @@ class TransmitterSuggestionAdmin(admin.ModelAdmin): self.message_user(request, "Transmitter suggestion was successfully rejected") else: self.message_user(request, "Transmitter suggestions were successfully rejected") + reject_suggestion.short_description = 'Reject selected transmitter suggestions' @admin.register(Transmitter) class TransmitterAdmin(admin.ModelAdmin): - list_display = ('uuid', 'description', 'satellite', 'type', 'mode', 'baud', 'downlink_low', - 'downlink_high', 'downlink_drift', 'uplink_low', 'uplink_high', 'uplink_drift', - 'status', 'created', 'citation', 'user') + list_display = ( + 'uuid', 'description', 'satellite', 'type', 'mode', 'baud', 'downlink_low', + 'downlink_high', 'downlink_drift', 'uplink_low', 'uplink_high', 'uplink_drift', 'status', + 'created', 'citation', 'user' + ) search_fields = ('satellite__id', 'uuid', 'satellite__name', 'satellite__norad_cat_id') - list_filter = ('type', 'status', 'mode', 'baud',) + list_filter = ( + 'type', + 'status', + 'mode', + 'baud', + ) readonly_fields = ('uuid', 'satellite') diff --git a/db/base/helpers.py b/db/base/helpers.py index 82c7446..ff1889f 100644 --- a/db/base/helpers.py +++ b/db/base/helpers.py @@ -2,7 +2,6 @@ from rest_framework.authtoken.models import Token from django.core.cache import cache - UPPER = 'ABCDEFGHIJKLMNOPQRSTUVWX' LOWER = 'abcdefghijklmnopqrstuvwx' @@ -28,8 +27,10 @@ def gridsquare(lat, lng): grid_lat_subsq = LOWER[int(adj_lat_remainder / 2.5)] grid_lon_subsq = LOWER[int(adj_lon_remainder / 5)] - qth = '{}'.format(grid_lon_sq + grid_lat_sq + grid_lon_field + - grid_lat_field + grid_lon_subsq + grid_lat_subsq) + qth = '{}'.format( + grid_lon_sq + grid_lat_sq + grid_lon_field + grid_lat_field + grid_lon_subsq + + grid_lat_subsq + ) return qth @@ -63,5 +64,7 @@ def cache_for(time): result = fn(*args, **kwargs) cache.set(key, result, time) return result + return wrapper + return decorator diff --git a/db/base/management/commands/decode_data.py b/db/base/management/commands/decode_data.py index f7c620a..bcdda5c 100644 --- a/db/base/management/commands/decode_data.py +++ b/db/base/management/commands/decode_data.py @@ -8,9 +8,7 @@ class Command(BaseCommand): def add_arguments(self, parser): # Positional arguments - parser.add_argument('satellite_identifiers', - nargs='+', - metavar='') + parser.add_argument('satellite_identifiers', nargs='+', metavar='') def handle(self, *args, **options): for item in options['satellite_identifiers']: @@ -29,8 +27,9 @@ class Command(BaseCommand): frame = fp.read() try: - payload_decoded = decoder.decode_payload(frame, obj.timestamp, - obj.data_id) + payload_decoded = decoder.decode_payload( + frame, obj.timestamp, obj.data_id + ) except ValueError: obj.payload_decoded = '' obj.payload_telemetry = None diff --git a/db/base/management/commands/delete_satellite.py b/db/base/management/commands/delete_satellite.py index c22543b..b493805 100644 --- a/db/base/management/commands/delete_satellite.py +++ b/db/base/management/commands/delete_satellite.py @@ -8,9 +8,7 @@ class Command(BaseCommand): def add_arguments(self, parser): # Positional arguments - parser.add_argument('norad_ids', - nargs='+', - metavar='') + parser.add_argument('norad_ids', nargs='+', metavar='') def handle(self, *args, **options): for norad_id in options['norad_ids']: diff --git a/db/base/management/commands/fetch_data.py b/db/base/management/commands/fetch_data.py index 32701e2..e23dae3 100644 --- a/db/base/management/commands/fetch_data.py +++ b/db/base/management/commands/fetch_data.py @@ -34,7 +34,8 @@ class Command(BaseCommand): continue try: transmitter = TransmitterEntry.objects.get( - uuid=obj['transmitter'], created=obj['transmitter_created']) + uuid=obj['transmitter'], created=obj['transmitter_created'] + ) except TransmitterEntry.DoesNotExist: transmitter = None @@ -42,12 +43,20 @@ class Command(BaseCommand): for demoddata in obj['demoddata']: payload_url = demoddata['payload_demod'] - timestamp = datetime.strptime(payload_url.split('/')[-1].split('_')[0], - '%Y%m%dT%H%M%SZ').replace(tzinfo=timezone('UTC')) + timestamp = datetime.strptime( + payload_url.split('/')[-1].split('_')[0], '%Y%m%dT%H%M%SZ' + ).replace(tzinfo=timezone('UTC')) frame = str(requests.get(payload_url).json()) payload_frame = ContentFile(frame, name='network') - DemodData.objects.create(satellite=satellite, transmitter=transmitter, - data_id=data_id, payload_frame=payload_frame, - timestamp=timestamp, source='network', - station=station, lat=lat, lng=lng) + DemodData.objects.create( + satellite=satellite, + transmitter=transmitter, + data_id=data_id, + payload_frame=payload_frame, + timestamp=timestamp, + source='network', + station=station, + lat=lat, + lng=lng + ) diff --git a/db/base/management/commands/fetch_satellites.py b/db/base/management/commands/fetch_satellites.py index e41a1f4..bf497b7 100644 --- a/db/base/management/commands/fetch_satellites.py +++ b/db/base/management/commands/fetch_satellites.py @@ -8,9 +8,7 @@ class Command(BaseCommand): def add_arguments(self, parser): # Positional arguments - parser.add_argument('norad_ids', - nargs='+', - metavar='') + parser.add_argument('norad_ids', nargs='+', metavar='') def handle(self, *args, **options): for norad_id in options['norad_ids']: diff --git a/db/base/models.py b/db/base/models.py index db5658e..bc60cb1 100644 --- a/db/base/models.py +++ b/db/base/models.py @@ -61,13 +61,13 @@ class Satellite(models.Model): name = models.CharField(max_length=45) names = models.TextField(blank=True) description = models.TextField(blank=True) - image = models.ImageField(upload_to='satellites', blank=True, - help_text='Ideally: 250x250') + image = models.ImageField(upload_to='satellites', blank=True, help_text='Ideally: 250x250') tle1 = models.CharField(max_length=200, blank=True) tle2 = models.CharField(max_length=200, blank=True) tle_source = models.CharField(max_length=300, blank=True) - status = models.CharField(choices=zip(SATELLITE_STATUS, SATELLITE_STATUS), - max_length=10, default='alive') + status = models.CharField( + choices=zip(SATELLITE_STATUS, SATELLITE_STATUS), max_length=10, default='alive' + ) decayed = models.DateTimeField(null=True, blank=True) class Meta: @@ -109,23 +109,26 @@ class TransmitterEntry(models.Model): """Model for satellite transmitters.""" uuid = ShortUUIDField(db_index=True) description = models.TextField() - status = models.CharField(choices=zip(TRANSMITTER_STATUS, TRANSMITTER_STATUS), - max_length=8, default='active') - type = models.CharField(choices=zip(TRANSMITTER_TYPE, TRANSMITTER_TYPE), - max_length=11, default='Transmitter') + status = models.CharField( + choices=zip(TRANSMITTER_STATUS, TRANSMITTER_STATUS), max_length=8, default='active' + ) + type = models.CharField( + choices=zip(TRANSMITTER_TYPE, TRANSMITTER_TYPE), max_length=11, default='Transmitter' + ) uplink_low = models.BigIntegerField(blank=True, null=True) uplink_high = models.BigIntegerField(blank=True, null=True) uplink_drift = models.IntegerField(blank=True, null=True) downlink_low = models.BigIntegerField(blank=True, null=True) downlink_high = models.BigIntegerField(blank=True, null=True) downlink_drift = models.IntegerField(blank=True, null=True) - mode = models.ForeignKey(Mode, blank=True, null=True, on_delete=models.SET_NULL, - related_name='transmitter_entries') + mode = models.ForeignKey( + Mode, blank=True, null=True, on_delete=models.SET_NULL, related_name='transmitter_entries' + ) invert = models.BooleanField(default=False) baud = models.FloatField(validators=[MinValueValidator(0)], blank=True, null=True) - satellite = models.ForeignKey(Satellite, null=True, - related_name='transmitter_entries', - on_delete=models.SET_NULL) + satellite = models.ForeignKey( + Satellite, null=True, related_name='transmitter_entries', on_delete=models.SET_NULL + ) reviewed = models.BooleanField(default=False) approved = models.BooleanField(default=False) created = models.DateTimeField(default=now) @@ -154,18 +157,17 @@ class TransmitterSuggestion(TransmitterEntry): class Meta: proxy = True - permissions = (('approve', 'Can approve/reject transmitter suggestions'),) + permissions = (('approve', 'Can approve/reject transmitter suggestions'), ) class TransmitterManager(models.Manager): def get_queryset(self): subquery = TransmitterEntry.objects.filter( reviewed=True, approved=True - ).filter( - uuid=OuterRef('uuid') - ).order_by('-created') + ).filter(uuid=OuterRef('uuid')).order_by('-created') return super(TransmitterManager, self).get_queryset().filter( - reviewed=True, approved=True).filter(created=Subquery(subquery.values('created')[:1])) + reviewed=True, approved=True + ).filter(created=Subquery(subquery.values('created')[:1])) class Transmitter(TransmitterEntry): @@ -177,9 +179,9 @@ class Transmitter(TransmitterEntry): class Telemetry(models.Model): """Model for satellite telemtry decoders.""" - satellite = models.ForeignKey(Satellite, null=True, - related_name='telemetries', - on_delete=models.SET_NULL) + satellite = models.ForeignKey( + Satellite, null=True, related_name='telemetries', on_delete=models.SET_NULL + ) name = models.CharField(max_length=45) schema = models.TextField(blank=True) decoder = models.CharField(max_length=20, blank=True) @@ -194,24 +196,27 @@ class Telemetry(models.Model): class DemodData(models.Model): """Model for satellite for observation data.""" - satellite = models.ForeignKey(Satellite, null=True, - related_name='telemetry_data', - on_delete=models.SET_NULL) - transmitter = models.ForeignKey(TransmitterEntry, null=True, blank=True, - on_delete=models.SET_NULL) - app_source = models.CharField(choices=zip(DATA_SOURCES, DATA_SOURCES), - max_length=7, default='sids') + satellite = models.ForeignKey( + Satellite, null=True, related_name='telemetry_data', on_delete=models.SET_NULL + ) + transmitter = models.ForeignKey( + TransmitterEntry, null=True, blank=True, on_delete=models.SET_NULL + ) + app_source = models.CharField( + choices=zip(DATA_SOURCES, DATA_SOURCES), max_length=7, default='sids' + ) data_id = models.PositiveIntegerField(blank=True, null=True) payload_frame = models.FileField(upload_to=_name_payload_frame, blank=True, null=True) payload_decoded = models.TextField(blank=True) - payload_telemetry = models.ForeignKey(Telemetry, null=True, blank=True, - on_delete=models.SET_NULL) + payload_telemetry = models.ForeignKey( + Telemetry, null=True, blank=True, on_delete=models.SET_NULL + ) station = models.CharField(max_length=45, default='Unknown') observer = models.CharField(max_length=60, blank=True) - lat = models.FloatField(validators=[MaxValueValidator(90), MinValueValidator(-90)], - default=0) - lng = models.FloatField(validators=[MaxValueValidator(180), MinValueValidator(-180)], - default=0) + lat = models.FloatField(validators=[MaxValueValidator(90), MinValueValidator(-90)], default=0) + lng = models.FloatField( + validators=[MaxValueValidator(180), MinValueValidator(-180)], default=0 + ) is_decoded = models.BooleanField(default=False, db_index=True) timestamp = models.DateTimeField(null=True) @@ -233,9 +238,7 @@ class DemodData(models.Model): return fp.read() except IOError as err: logger.error( - err, - exc_info=True, - extra={ + err, exc_info=True, extra={ 'payload frame path': self.payload_frame.path, } ) diff --git a/db/base/tasks.py b/db/base/tasks.py index 93a9800..bdb3843 100644 --- a/db/base/tasks.py +++ b/db/base/tasks.py @@ -98,9 +98,7 @@ def update_all_tle(): satellite.tle2 = tle[2] satellite.save() - print('Updated TLE for {}: {} from {}'.format(norad_id, - satellite.name, - source)) + print('Updated TLE for {}: {} from {}'.format(norad_id, satellite.name, source)) for norad_id in sorted(missing_norad_ids): satellite = satellites.get(norad_cat_id=norad_id) @@ -123,8 +121,7 @@ def export_frames(norad, email, uid, period=None): q = now - timedelta(days=30) suffix = 'month' q = make_aware(q) - frames = DemodData.objects.filter(satellite__norad_cat_id=norad, - timestamp__gte=q) + frames = DemodData.objects.filter(satellite__norad_cat_id=norad, timestamp__gte=q) else: frames = DemodData.objects.filter(satellite__norad_cat_id=norad) suffix = 'all' @@ -142,8 +139,7 @@ def export_frames(norad, email, uid, period=None): subject = '[satnogs] Your request for exported frames is ready!' template = 'emails/exported_frames.txt' data = { - 'url': '{0}{1}download/{2}'.format(site.domain, - settings.MEDIA_URL, filename), + 'url': '{0}{1}download/{2}'.format(site.domain, settings.MEDIA_URL, filename), 'norad': norad } message = render_to_string(template, {'data': data}) @@ -169,11 +165,15 @@ def reset_decoded_data(norad): frame.is_decoded = False frame.save() if settings.USE_INFLUX: - client = InfluxDBClient(settings.INFLUX_HOST, settings.INFLUX_PORT, - settings.INFLUX_USER, settings.INFLUX_PASS, - settings.INFLUX_DB, ssl=settings.INFLUX_SSL) - client.query('DROP MEASUREMENT "{0}"' - .format(norad)) + client = InfluxDBClient( + settings.INFLUX_HOST, + settings.INFLUX_PORT, + settings.INFLUX_USER, + settings.INFLUX_PASS, + settings.INFLUX_DB, + ssl=settings.INFLUX_SSL + ) + client.query('DROP MEASUREMENT "{0}"'.format(norad)) # decode data for a satellite, and a given time frame (if provided). If not diff --git a/db/base/tests.py b/db/base/tests.py index 3133b68..c5f2f6c 100644 --- a/db/base/tests.py +++ b/db/base/tests.py @@ -8,9 +8,9 @@ from django.contrib.auth.models import User from django.test import TestCase from django.utils.timezone import now -from db.base.models import (DATA_SOURCES, Mode, Satellite, Transmitter, TransmitterSuggestion, - Telemetry, DemodData) - +from db.base.models import ( + DATA_SOURCES, Mode, Satellite, Transmitter, TransmitterSuggestion, Telemetry, DemodData +) DATA_SOURCE_IDS = [c[0] for c in DATA_SOURCES] @@ -26,8 +26,9 @@ def generate_payload(): def generate_payload_name(): - filename = datetime.strftime(fuzzy.FuzzyDateTime(now() - timedelta(days=10), now()).fuzz(), - '%Y%m%dT%H%M%SZ') + filename = datetime.strftime( + fuzzy.FuzzyDateTime(now() - timedelta(days=10), now()).fuzz(), '%Y%m%dT%H%M%SZ' + ) return filename @@ -139,6 +140,7 @@ class HomeViewTest(TestCase): """ Simple test to make sure the home page is working """ + def test_home_page(self): response = self.client.get('/') self.assertContains(response, 'SatNOGS DB is, and will always be, an open database.') @@ -165,6 +167,7 @@ class AboutViewTest(TestCase): """ Test to make sure the about page is working """ + def test_about_page(self): response = self.client.get('/about/') self.assertContains(response, 'SatNOGS DB is an effort to create an hollistic') @@ -175,6 +178,7 @@ class FaqViewTest(TestCase): """ Test to make sure the faq page is working """ + def test_faq_page(self): response = self.client.get('/faq/') self.assertContains(response, 'How do I suggest a new transmitter?') diff --git a/db/base/urls.py b/db/base/urls.py index 7a7d3b6..ce77aa1 100644 --- a/db/base/urls.py +++ b/db/base/urls.py @@ -2,19 +2,26 @@ from django.conf.urls import url from db.base import views - -base_urlpatterns = ([ - url(r'^$', views.home, name='home'), - url(r'^about/$', views.about, name='about'), - url(r'^faq/$', views.faq, name='faq'), - url(r'^satellite/(?P[0-9]+)/$', views.satellite, name='satellite'), - url(r'^frames/(?P[0-9]+)/$', views.request_export, - name='request_export_all'), - url(r'^frames/(?P[0-9]+)/(?P[0-9]+)/$', views.request_export, - name='request_export'), - url(r'^transmitter_suggestion/$', views.transmitter_suggestion, name='transmitter_suggestion'), - url(r'^statistics/$', views.statistics, name='statistics'), - url(r'^stats/$', views.stats, name='stats'), - url(r'^users/edit/$', views.users_edit, name='users_edit'), - url(r'^robots\.txt$', views.robots, name='robots'), -]) +base_urlpatterns = ( + [ + url(r'^$', views.home, name='home'), + url(r'^about/$', views.about, name='about'), + url(r'^faq/$', views.faq, name='faq'), + url(r'^satellite/(?P[0-9]+)/$', views.satellite, name='satellite'), + url(r'^frames/(?P[0-9]+)/$', views.request_export, name='request_export_all'), + url( + r'^frames/(?P[0-9]+)/(?P[0-9]+)/$', + views.request_export, + name='request_export' + ), + url( + r'^transmitter_suggestion/$', + views.transmitter_suggestion, + name='transmitter_suggestion' + ), + url(r'^statistics/$', views.statistics, name='statistics'), + url(r'^stats/$', views.stats, name='stats'), + url(r'^users/edit/$', views.users_edit, name='users_edit'), + url(r'^robots\.txt$', views.robots, name='robots'), + ] +) diff --git a/db/base/utils.py b/db/base/utils.py index 91d9b48..9e61337 100644 --- a/db/base/utils.py +++ b/db/base/utils.py @@ -25,9 +25,9 @@ def calculate_statistics(): alive_transmitters = transmitters.filter(status='active').count() if alive_transmitters > 0 and total_transmitters > 0: try: - alive_transmitters_percentage = '{0}%'.format(round((float(alive_transmitters) / - float(total_transmitters)) * - 100, 2)) + alive_transmitters_percentage = '{0}%'.format( + round((float(alive_transmitters) / float(total_transmitters)) * 100, 2) + ) except ZeroDivisionError as error: logger.error(error, exc_info=True) alive_transmitters_percentage = '0%' @@ -56,56 +56,63 @@ def calculate_statistics(): band_data.append(filtered) # 30.000.000 ~ 300.000.000 - VHF - filtered = transmitters.filter(downlink_low__gte=30000000, - downlink_low__lt=300000000).count() + filtered = transmitters.filter(downlink_low__gte=30000000, downlink_low__lt=300000000).count() band_label.append('VHF') band_data.append(filtered) # 300.000.000 ~ 1.000.000.000 - UHF - filtered = transmitters.filter(downlink_low__gte=300000000, - downlink_low__lt=1000000000).count() + filtered = transmitters.filter( + downlink_low__gte=300000000, downlink_low__lt=1000000000 + ).count() band_label.append('UHF') band_data.append(filtered) # 1G ~ 2G - L - filtered = transmitters.filter(downlink_low__gte=1000000000, - downlink_low__lt=2000000000).count() + filtered = transmitters.filter( + downlink_low__gte=1000000000, downlink_low__lt=2000000000 + ).count() band_label.append('L') band_data.append(filtered) # 2G ~ 4G - S - filtered = transmitters.filter(downlink_low__gte=2000000000, - downlink_low__lt=4000000000).count() + filtered = transmitters.filter( + downlink_low__gte=2000000000, downlink_low__lt=4000000000 + ).count() band_label.append('S') band_data.append(filtered) # 4G ~ 8G - C - filtered = transmitters.filter(downlink_low__gte=4000000000, - downlink_low__lt=8000000000).count() + filtered = transmitters.filter( + downlink_low__gte=4000000000, downlink_low__lt=8000000000 + ).count() band_label.append('C') band_data.append(filtered) # 8G ~ 12G - X - filtered = transmitters.filter(downlink_low__gte=8000000000, - downlink_low__lt=12000000000).count() + filtered = transmitters.filter( + downlink_low__gte=8000000000, downlink_low__lt=12000000000 + ).count() band_label.append('X') band_data.append(filtered) # 12G ~ 18G - Ku - filtered = transmitters.filter(downlink_low__gte=12000000000, - downlink_low__lt=18000000000).count() + filtered = transmitters.filter( + downlink_low__gte=12000000000, downlink_low__lt=18000000000 + ).count() band_label.append('Ku') band_data.append(filtered) # 18G ~ 27G - K - filtered = transmitters.filter(downlink_low__gte=18000000000, - downlink_low__lt=27000000000).count() + filtered = transmitters.filter( + downlink_low__gte=18000000000, downlink_low__lt=27000000000 + ).count() band_label.append('K') band_data.append(filtered) # 27G ~ 40G - Ka - filtered = transmitters.filter(downlink_low__gte=27000000000, - downlink_low__lt=40000000000).count() + filtered = transmitters.filter( + downlink_low__gte=27000000000, downlink_low__lt=40000000000 + ).count() band_label.append('Ka') band_data.append(filtered) @@ -147,9 +154,14 @@ def create_point(fields, satellite, telemetry, demoddata): def write_influx(json_obj): """Take a json object and send to influxdb.""" - client = InfluxDBClient(settings.INFLUX_HOST, settings.INFLUX_PORT, - settings.INFLUX_USER, settings.INFLUX_PASS, - settings.INFLUX_DB, ssl=settings.INFLUX_SSL) + client = InfluxDBClient( + settings.INFLUX_HOST, + settings.INFLUX_PORT, + settings.INFLUX_USER, + settings.INFLUX_PASS, + settings.INFLUX_DB, + ssl=settings.INFLUX_SSL + ) client.write_points(json_obj) @@ -174,8 +186,7 @@ def decode_data(norad, period=None): # iterate over Telemetry decoders for tlmdecoder in telemetry_decoders: try: - decoder_class = getattr(decoder, - tlmdecoder.decoder.capitalize()) + decoder_class = getattr(decoder, tlmdecoder.decoder.capitalize()) except AttributeError: continue try: @@ -189,8 +200,9 @@ def decode_data(norad, period=None): if settings.USE_INFLUX: try: frame = decoder_class.from_bytes(bindata) - json_obj = create_point(decoder.get_fields(frame), sat, - tlmdecoder, obj) + json_obj = create_point( + decoder.get_fields(frame), sat, tlmdecoder, obj + ) write_influx(json_obj) obj.payload_decoded = 'influxdb' obj.is_decoded = True @@ -209,8 +221,9 @@ def decode_data(norad, period=None): obj.save() continue else: - json_obj = create_point(decoder.get_fields(frame), sat, - tlmdecoder, obj) + json_obj = create_point( + decoder.get_fields(frame), sat, tlmdecoder, obj + ) obj.payload_decoded = json_obj obj.is_decoded = True obj.save() diff --git a/db/base/views.py b/db/base/views.py index f97048c..24e4fd1 100644 --- a/db/base/views.py +++ b/db/base/views.py @@ -20,7 +20,6 @@ from db.base.tasks import export_frames from db.base.utils import cache_statistics from _mysql_exceptions import OperationalError - logger = logging.getLogger('db') @@ -36,10 +35,14 @@ def home(request): statistics = cache.get('stats_transmitters') except OperationalError: pass - return render(request, 'base/home.html', {'satellites': satellites, - 'statistics': statistics, - 'contributors': contributors, - 'transmitter_suggestions': transmitter_suggestions}) + return render( + request, 'base/home.html', { + 'satellites': satellites, + 'statistics': statistics, + 'contributors': contributors, + 'transmitter_suggestions': transmitter_suggestions + } + ) def custom_404(request): @@ -54,8 +57,7 @@ def custom_500(request): def robots(request): data = render(request, 'robots.txt', {'environment': settings.ENVIRONMENT}) - response = HttpResponse(data, - content_type='text/plain; charset=utf-8') + response = HttpResponse(data, content_type='text/plain; charset=utf-8') return response @@ -83,23 +85,28 @@ def satellite(request, norad): except Exception: latest_frame = '' - return render(request, 'base/satellite.html', - {'satellite': satellite, - 'transmitter_suggestions': transmitter_suggestions, - 'modes': modes, - 'types': types, - 'statuses': statuses, - 'latest_frame': latest_frame, - 'sats_cache': sats_cache, - 'mapbox_token': settings.MAPBOX_TOKEN}) + return render( + request, 'base/satellite.html', { + 'satellite': satellite, + 'transmitter_suggestions': transmitter_suggestions, + 'modes': modes, + 'types': types, + 'statuses': statuses, + 'latest_frame': latest_frame, + 'sats_cache': sats_cache, + 'mapbox_token': settings.MAPBOX_TOKEN + } + ) @login_required def request_export(request, norad, period=None): """View to request frames export download.""" export_frames.delay(norad, request.user.email, request.user.pk, period) - messages.success(request, ('Your download request was received. ' - 'You will get an email when it\'s ready')) + messages.success( + request, ('Your download request was received. ' + 'You will get an email when it\'s ready') + ) return redirect(reverse('satellite', kwargs={'norad': norad})) @@ -121,8 +128,9 @@ def transmitter_suggestion(request): # Notify admins admins = User.objects.filter(is_superuser=True) site = get_current_site(request) - subject = '[{0}] A new suggestion for {1} was submitted'.format(site.name, - transmitter.satellite.name) + subject = '[{0}] A new suggestion for {1} was submitted'.format( + site.name, transmitter.satellite.name + ) template = 'emails/new_transmitter_suggestion.txt' saturl = '{0}{1}'.format( site.domain, @@ -139,13 +147,13 @@ def transmitter_suggestion(request): try: user.email_user(subject, message, from_email=settings.DEFAULT_FROM_EMAIL) except Exception: - logger.error( - 'Could not send email to user', - exc_info=True - ) + logger.error('Could not send email to user', exc_info=True) - messages.success(request, ('Your transmitter suggestion was stored successfully. ' - 'Thanks for contibuting!')) + messages.success( + request, + ('Your transmitter suggestion was stored successfully. ' + 'Thanks for contibuting!') + ) return redirect(reverse('satellite', kwargs={'norad': transmitter.satellite.norad_cat_id})) else: logger.error( @@ -179,8 +187,7 @@ def stats(request): cache_statistics() except OperationalError: pass - return render(request, 'base/stats.html', {'satellites': satellites, - 'observers': observers}) + return render(request, 'base/stats.html', {'satellites': satellites, 'observers': observers}) def statistics(request): diff --git a/db/celery.py b/db/celery.py index f51a500..44e4142 100644 --- a/db/celery.py +++ b/db/celery.py @@ -22,11 +22,10 @@ app.autodiscover_tasks(lambda: settings.INSTALLED_APPS) def setup_periodic_tasks(sender, **kwargs): from db.base.tasks import update_all_tle, background_cache_statistics, decode_recent_data - sender.add_periodic_task(RUN_DAILY, update_all_tle.s(), - name='update-all-tle') + sender.add_periodic_task(RUN_DAILY, update_all_tle.s(), name='update-all-tle') - sender.add_periodic_task(RUN_HOURLY, background_cache_statistics.s(), - name='background-cache-statistics') + sender.add_periodic_task( + RUN_HOURLY, background_cache_statistics.s(), name='background-cache-statistics' + ) - sender.add_periodic_task(RUN_EVERY_15, decode_recent_data.s(), - name='decode-recent-data') + sender.add_periodic_task(RUN_EVERY_15, decode_recent_data.s(), name='decode-recent-data') diff --git a/db/settings.py b/db/settings.py index 974dfbc..88f212c 100644 --- a/db/settings.py +++ b/db/settings.py @@ -4,7 +4,6 @@ from unipath import Path import sentry_sdk from sentry_sdk.integrations.django import DjangoIntegration - ROOT = Path(__file__).parent ENVIRONMENT = config('ENVIRONMENT', default='dev') @@ -39,8 +38,8 @@ LOCAL_APPS = ( ) if AUTH0: - THIRD_PARTY_APPS += ('social_django',) - LOCAL_APPS += ('auth0login',) + THIRD_PARTY_APPS += ('social_django', ) + LOCAL_APPS += ('auth0login', ) INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS @@ -67,22 +66,19 @@ EMAIL_USE_TLS = config('EMAIL_USE_TLS', default=False, cast=bool) EMAIL_HOST_USER = config('EMAIL_HOST_USER', default='') EMAIL_HOST_PASSWORD = config('EMAIL_HOST_PASSWORD', default='') DEFAULT_FROM_EMAIL = config('DEFAULT_FROM_EMAIL', default='noreply@satnogs.org') -ADMINS = [ - ('SatNOGS Admins', DEFAULT_FROM_EMAIL) -] +ADMINS = [('SatNOGS Admins', DEFAULT_FROM_EMAIL)] MANAGERS = ADMINS SERVER_EMAIL = DEFAULT_FROM_EMAIL # Cache CACHES = { 'default': { - 'BACKEND': config('CACHE_BACKEND', - default='django.core.cache.backends.locmem.LocMemCache'), + 'BACKEND': + config('CACHE_BACKEND', default='django.core.cache.backends.locmem.LocMemCache'), 'LOCATION': config('CACHE_LOCATION', default='unique-location'), 'OPTIONS': { 'MAX_ENTRIES': 5000, - 'CLIENT_CLASS': config('CACHE_CLIENT_CLASS', - default=''), + 'CLIENT_CLASS': config('CACHE_CLIENT_CLASS', default=''), }, 'KEY_PREFIX': 'db-{0}'.format(ENVIRONMENT), } @@ -113,21 +109,19 @@ TEMPLATES = [ 'django.template.context_processors.tz', 'django.contrib.messages.context_processors.messages', 'django.template.context_processors.request', - 'db.base.context_processors.analytics', - 'db.base.context_processors.stage_notice', - 'db.base.context_processors.auth_block', - 'db.base.context_processors.logout_block', - 'db.base.context_processors.version', - 'db.base.context_processors.decoders_version' + 'db.base.context_processors.analytics', 'db.base.context_processors.stage_notice', + 'db.base.context_processors.auth_block', 'db.base.context_processors.logout_block', + 'db.base.context_processors.version', 'db.base.context_processors.decoders_version' ], 'loaders': [ - ('django.template.loaders.cached.Loader', [ - 'django.template.loaders.filesystem.Loader', - 'django.template.loaders.app_directories.Loader', - ]), + ( + 'django.template.loaders.cached.Loader', [ + 'django.template.loaders.filesystem.Loader', + 'django.template.loaders.app_directories.Loader', + ] + ), ], }, - }, ] @@ -150,8 +144,7 @@ COMPRESS_ENABLED = config('COMPRESS_ENABLED', default=False, cast=bool) COMPRESS_OFFLINE = config('COMPRESS_OFFLINE', default=False, cast=bool) COMPRESS_CACHE_BACKEND = config('COMPRESS_CACHE_BACKEND', default='default') COMPRESS_CSS_FILTERS = [ - 'compressor.filters.css_default.CssAbsoluteFilter', - 'compressor.filters.cssmin.rCSSMinFilter' + 'compressor.filters.css_default.CssAbsoluteFilter', 'compressor.filters.cssmin.rCSSMinFilter' ] # App conf @@ -159,11 +152,9 @@ ROOT_URLCONF = 'db.urls' WSGI_APPLICATION = 'db.wsgi.application' # Auth -AUTHENTICATION_BACKENDS = ( - 'django.contrib.auth.backends.ModelBackend', -) +AUTHENTICATION_BACKENDS = ('django.contrib.auth.backends.ModelBackend', ) if AUTH0: - AUTHENTICATION_BACKENDS += ('auth0login.auth0backend.Auth0',) + AUTHENTICATION_BACKENDS += ('auth0login.auth0backend.Auth0', ) ACCOUNT_AUTHENTICATION_METHOD = 'username' ACCOUNT_EMAIL_REQUIRED = True @@ -220,10 +211,7 @@ LOGGING = { # Sentry SENTRY_ENABLED = config('SENTRY_ENABLED', default=False, cast=bool) if SENTRY_ENABLED: - sentry_sdk.init( - dsn=config('SENTRY_DSN', default=''), - integrations=[DjangoIntegration()] - ) + sentry_sdk.init(dsn=config('SENTRY_DSN', default=''), integrations=[DjangoIntegration()]) # Celery CELERY_ENABLE_UTC = USE_TZ @@ -245,15 +233,10 @@ REDIS_CONNECT_RETRY = True # API REST_FRAMEWORK = { - 'DEFAULT_PERMISSION_CLASSES': ( - 'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly', - ), - 'DEFAULT_AUTHENTICATION_CLASSES': ( - 'rest_framework.authentication.TokenAuthentication', - ), - 'DEFAULT_FILTER_BACKENDS': ( - 'django_filters.rest_framework.DjangoFilterBackend', - ) + 'DEFAULT_PERMISSION_CLASSES': + ('rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly', ), + 'DEFAULT_AUTHENTICATION_CLASSES': ('rest_framework.authentication.TokenAuthentication', ), + 'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend', ) } # Security @@ -276,9 +259,7 @@ CSP_IMG_SRC = ( 'data:', 'blob:', ) -CSP_CHILD_SRC = ( - 'blob:', -) +CSP_CHILD_SRC = ('blob:', ) SECURE_HSTS_INCLUDE_SUBDOMAINS = True SECURE_CONTENT_TYPE_NOSNIFF = True SECURE_BROWSER_XSS_FILTER = True @@ -306,7 +287,7 @@ INFLUX_DB = config('INFLUX_DB', default='db') INFLUX_SSL = config('INFLUX_SSL', default=False, cast=bool) if AUTH0: - SOCIAL_AUTH_TRAILING_SLASH = False # Remove end slash from routes + SOCIAL_AUTH_TRAILING_SLASH = False # Remove end slash from routes SOCIAL_AUTH_AUTH0_DOMAIN = config('SOCIAL_AUTH_AUTH0_DOMAIN', default='YOUR_AUTH0_DOMAIN') SOCIAL_AUTH_AUTH0_KEY = config('SOCIAL_AUTH_AUTH0_KEY', default='YOUR_CLIENT_ID') SOCIAL_AUTH_AUTH0_SECRET = config('SOCIAL_AUTH_AUTH0_SECRET', default='YOUR_CLIENT_SECRET') diff --git a/db/urls.py b/db/urls.py index d7a9f81..84097c0 100644 --- a/db/urls.py +++ b/db/urls.py @@ -27,12 +27,9 @@ urlpatterns = [ # Auth0 if settings.AUTH0: - urlpatterns += [ - url(r'^', include('auth0login.urls')) - ] + urlpatterns += [url(r'^', include('auth0login.urls'))] if settings.DEBUG: urlpatterns += [ - url(r'^media/(?P.*)$', serve, - {'document_root': settings.MEDIA_ROOT}), + url(r'^media/(?P.*)$', serve, {'document_root': settings.MEDIA_ROOT}), ] diff --git a/db/wsgi.py b/db/wsgi.py index a7cb1c7..19f6220 100644 --- a/db/wsgi.py +++ b/db/wsgi.py @@ -2,7 +2,6 @@ import os from django.core.wsgi import get_wsgi_application - os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'db.settings') application = get_wsgi_application() diff --git a/setup.cfg b/setup.cfg index d6b340b..ea99bac 100644 --- a/setup.cfg +++ b/setup.cfg @@ -83,6 +83,11 @@ max-line-length = 99 ignore = F403,W504 exclude = db/_version.py,versioneer.py,*/migrations,docs +[yapf] +column_limit = 99 +split_before_first_argument = True +dedent_closing_brackets = True + [tool:pytest] addopts = -v --cov --cov-report=term-missing python_files = tests.py diff --git a/tox.ini b/tox.ini index 0db1ba2..b5487cf 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,7 @@ [tox] envlist = flake8 + yapf pytest py27 py36 @@ -14,6 +15,15 @@ commands = flake8 \ db \ auth0login +[testenv:yapf] +deps = + yapf +skip_install = True +commands = yapf -d -r \ + setup.py \ + db \ + auth0login + [testenv:deps] install_command = python -m pip install --no-deps {opts} {packages} recreate = True