Format all python files using the formatter

Run `git ls-files '*.py' | xargs black`

Issue: HIC-161
Change-Id: I1619e6296bc4036504c5bb73128f769a1b7b688d
diff --git a/crashreport_stats/admin.py b/crashreport_stats/admin.py
index 3c1939b..db5b576 100644
--- a/crashreport_stats/admin.py
+++ b/crashreport_stats/admin.py
@@ -4,7 +4,7 @@
     Version,
     VersionDaily,
     RadioVersion,
-    RadioVersionDaily
+    RadioVersionDaily,
 )
 
 
@@ -15,4 +15,5 @@
 @admin.register(VersionDaily, RadioVersionDaily)
 class DailyVersionStatsAdmin(admin.ModelAdmin):
     """Admin for daily version stats."""
-    list_display = ('version', 'date')
+
+    list_display = ("version", "date")
diff --git a/crashreport_stats/apps.py b/crashreport_stats/apps.py
index 4b0fb94..07dd518 100644
--- a/crashreport_stats/apps.py
+++ b/crashreport_stats/apps.py
@@ -1,4 +1,5 @@
 from django.apps import AppConfig
 
+
 class CrashreportStatsConfig(AppConfig):
-    name = 'crashreport_stats'
+    name = "crashreport_stats"
diff --git a/crashreport_stats/management/commands/stats.py b/crashreport_stats/management/commands/stats.py
index 5ac2dea..c30c2e0 100644
--- a/crashreport_stats/management/commands/stats.py
+++ b/crashreport_stats/management/commands/stats.py
@@ -12,9 +12,11 @@
 import pytz
 
 from crashreport_stats.models import (
-    RadioVersion, RadioVersionDaily,
+    RadioVersion,
+    RadioVersionDaily,
     StatsMetadata,
-    Version, VersionDaily,
+    Version,
+    VersionDaily,
 )
 from crashreports.models import Crashreport, HeartBeat
 
@@ -23,7 +25,7 @@
 # Classes in this file inherit from each other and are not method containers.
 
 
-class _ReportCounterFilter():
+class _ReportCounterFilter:
     """Filter reports matching a report counter requirements.
 
     Attributes:
@@ -68,7 +70,8 @@
     def __init__(self):
         """Initialise the filter."""
         super(HeartBeatCounterFilter, self).__init__(
-            model=HeartBeat, name='heartbeats', field_name='heartbeats')
+            model=HeartBeat, name="heartbeats", field_name="heartbeats"
+        )
 
 
 class CrashreportCounterFilter(_ReportCounterFilter):
@@ -87,8 +90,12 @@
     """
 
     def __init__(
-            self, name, field_name, include_boot_reasons=None,
-            exclude_boot_reasons=None):
+        self,
+        name,
+        field_name,
+        include_boot_reasons=None,
+        exclude_boot_reasons=None,
+    ):
         """Initialise the filter.
 
         One or both of `include_boot_reasons` and `exclude_boot_reasons` must
@@ -113,11 +120,13 @@
         """
         if not include_boot_reasons and not exclude_boot_reasons:
             raise ValueError(
-                'One or both of `include_boot_reasons` and '
-                '`exclude_boot_reasons` must be specified.')
+                "One or both of `include_boot_reasons` and "
+                "`exclude_boot_reasons` must be specified."
+            )
 
         super(CrashreportCounterFilter, self).__init__(
-            model=Crashreport, name=name, field_name=field_name)
+            model=Crashreport, name=name, field_name=field_name
+        )
 
         # Cache the boot reasons inclusive filter
         self.include_boot_reasons = include_boot_reasons
@@ -163,7 +172,7 @@
         return query_objects
 
 
-class _StatsModelsEngine():
+class _StatsModelsEngine:
     """Stats models engine.
 
     An engine to update general stats (_VersionStats) and their daily
@@ -232,11 +241,12 @@
 
         """
         return (
-            query_objects
-            .annotate(_report_day=TruncDate('date'))
-            .values(self.version_field_name, '_report_day')
+            query_objects.annotate(_report_day=TruncDate("date")).values(
+                self.version_field_name, "_report_day"
+            )
             # FIXME Agressively drop duplicates
-            .annotate(count=Count('date', distinct=True)))
+            .annotate(count=Count("date", distinct=True))
+        )
 
     def delete_stats(self):
         """Delete the general and daily stats instances.
@@ -277,13 +287,15 @@
 
         """
         counts_per_model = {
-            self.stats_model: {'created': 0, 'updated': 0},
-            self.daily_stats_model: {'created': 0, 'updated': 0}}
+            self.stats_model: {"created": 0, "updated": 0},
+            self.daily_stats_model: {"created": 0, "updated": 0},
+        }
 
         query_objects = self._valid_objects(report_counter.model.objects.all())
         # Only include reports from the interesting period of time
         query_objects = self._objects_within_period(
-            query_objects, up_to, starting_from)
+            query_objects, up_to, starting_from
+        )
         # Apply the report counter requirements
         query_objects = report_counter.filter(query_objects)
         # Chain our own filters
@@ -292,17 +304,22 @@
         # Explicitly use the iterator() method to avoid caching as we will
         # not re-use the QuerySet
         for query_object in query_objects.iterator():
-            report_day = query_object['_report_day']
+            report_day = query_object["_report_day"]
             # Use a dict to be able to dereference the field name
-            stats, created = self.stats_model.objects.get_or_create(**{
-                self.version_field_name: query_object[self.version_field_name],
-                'defaults': {
-                    'first_seen_on': report_day,
-                    'released_on': report_day,
+            stats, created = self.stats_model.objects.get_or_create(
+                **{
+                    self.version_field_name: query_object[
+                        self.version_field_name
+                    ],
+                    "defaults": {
+                        "first_seen_on": report_day,
+                        "released_on": report_day,
+                    },
                 }
-            })
-            counts_per_model[self.stats_model][(
-                'created' if created else 'updated')] += 1
+            )
+            counts_per_model[self.stats_model][
+                ("created" if created else "updated")
+            ] += 1
 
             # Reports are coming in an unordered manner, a late report can
             # be older (device time wise). Make sure that the current reports
@@ -315,18 +332,23 @@
                     stats.released_on = report_day
                 stats.first_seen_on = report_day
 
-            daily_stats, created = (
-                self.daily_stats_model.objects.get_or_create(
-                    version=stats, date=report_day))
-            counts_per_model[self.daily_stats_model][(
-                'created' if created else 'updated')] += 1
+            daily_stats, created = self.daily_stats_model.objects.get_or_create(
+                version=stats, date=report_day
+            )
+            counts_per_model[self.daily_stats_model][
+                ("created" if created else "updated")
+            ] += 1
 
             setattr(
-                stats, report_counter.field_name,
-                F(report_counter.field_name) + query_object['count'])
+                stats,
+                report_counter.field_name,
+                F(report_counter.field_name) + query_object["count"],
+            )
             setattr(
-                daily_stats, report_counter.field_name,
-                F(report_counter.field_name) + query_object['count'])
+                daily_stats,
+                report_counter.field_name,
+                F(report_counter.field_name) + query_object["count"],
+            )
 
             stats.save()
             daily_stats.save()
@@ -344,8 +366,10 @@
     def __init__(self):
         """Initialise the engine."""
         super(VersionStatsEngine, self).__init__(
-            stats_model=Version, daily_stats_model=VersionDaily,
-            version_field_name='build_fingerprint')
+            stats_model=Version,
+            daily_stats_model=VersionDaily,
+            version_field_name="build_fingerprint",
+        )
 
 
 class RadioVersionStatsEngine(_StatsModelsEngine):
@@ -358,8 +382,10 @@
     def __init__(self):
         """Initialise the engine."""
         super(RadioVersionStatsEngine, self).__init__(
-            stats_model=RadioVersion, daily_stats_model=RadioVersionDaily,
-            version_field_name='radio_version')
+            stats_model=RadioVersion,
+            daily_stats_model=RadioVersionDaily,
+            version_field_name="radio_version",
+        )
 
     def _valid_objects(self, query_objects):
         # For legacy reasons, the version field might be null
@@ -369,43 +395,46 @@
 class Command(BaseCommand):
     """Management command to compute Hiccup statistics."""
 
-    _STATS_MODELS_ENGINES = [
-        VersionStatsEngine(),
-        RadioVersionStatsEngine(),
-    ]
+    _STATS_MODELS_ENGINES = [VersionStatsEngine(), RadioVersionStatsEngine()]
 
     # All the report counters that are listed in the stats models
     _REPORT_COUNTER_FILTERS = [
         HeartBeatCounterFilter(),
         CrashreportCounterFilter(
-            name='crashes', field_name='prob_crashes',
-            include_boot_reasons=Crashreport.CRASH_BOOT_REASONS),
+            name="crashes",
+            field_name="prob_crashes",
+            include_boot_reasons=Crashreport.CRASH_BOOT_REASONS,
+        ),
         CrashreportCounterFilter(
-            name='smpl', field_name='smpl',
-            include_boot_reasons=Crashreport.SMPL_BOOT_REASONS),
+            name="smpl",
+            field_name="smpl",
+            include_boot_reasons=Crashreport.SMPL_BOOT_REASONS,
+        ),
         CrashreportCounterFilter(
-            name='other', field_name='other',
+            name="other",
+            field_name="other",
             exclude_boot_reasons=(
-                Crashreport.SMPL_BOOT_REASONS
-                + Crashreport.CRASH_BOOT_REASONS)),
+                Crashreport.SMPL_BOOT_REASONS + Crashreport.CRASH_BOOT_REASONS
+            ),
+        ),
     ]
 
     help = __doc__
 
     def add_arguments(self, parser):
         """Add custom arguments to the command."""
-        parser.add_argument('action', choices=['reset', 'update'])
+        parser.add_argument("action", choices=["reset", "update"])
 
     def handle(self, *args, **options):
         """Carry out the command executive logic."""
         # pylint: disable=attribute-defined-outside-init
         # self.debug is only ever read through calls of handle().
-        self.debug = int(options['verbosity']) >= 2
+        self.debug = int(options["verbosity"]) >= 2
 
-        if options['action'] == 'reset':
+        if options["action"] == "reset":
             self.delete_all_stats()
             self.update_all_stats()
-        elif options['action'] == 'update':
+        elif options["action"] == "update":
             self.update_all_stats()
 
     def _success(self, msg, *args, **kwargs):
@@ -423,22 +452,21 @@
                     if not counts_per_model:
                         counts_per_model = {
                             engine.stats_model._meta.label: 0,
-                            engine.daily_stats_model._meta.label: 0}
+                            engine.daily_stats_model._meta.label: 0,
+                        }
                     for model, count in counts_per_model.items():
-                        name = model.split('.')[-1]
-                        self._success(
-                            '{} {} deleted'.format(count, name))
+                        name = model.split(".")[-1]
+                        self._success("{} {} deleted".format(count, name))
 
             # Reset the metadata
             count, _ = StatsMetadata.objects.all().delete()
             if self.debug:
-                self._success(
-                    '{} StatsMetadata deleted'.format(count))
+                self._success("{} StatsMetadata deleted".format(count))
 
     def update_all_stats(self):
         """Update the statistics from all stats models."""
         try:
-            previous_update = StatsMetadata.objects.latest('updated_at')
+            previous_update = StatsMetadata.objects.latest("updated_at")
             starting_from = previous_update.updated_at
         except StatsMetadata.DoesNotExist:
             starting_from = None
@@ -450,13 +478,14 @@
             with transaction.atomic():
                 for filter_ in self._REPORT_COUNTER_FILTERS:
                     counts_per_model = engine.update_stats(
-                        filter_, up_to, starting_from)
+                        filter_, up_to, starting_from
+                    )
                     if self.debug:
                         for model, counts in counts_per_model.items():
                             for action, count in counts.items():
-                                msg = '{} {} {} for counter {}'.format(
-                                    count, model.__name__, action,
-                                    filter_.name)
+                                msg = "{} {} {} for counter {}".format(
+                                    count, model.__name__, action, filter_.name
+                                )
                                 self._success(msg)
 
         StatsMetadata(updated_at=up_to).save()
diff --git a/crashreport_stats/migrations/0001_initial.py b/crashreport_stats/migrations/0001_initial.py
index b87395e..2ff76d4 100644
--- a/crashreport_stats/migrations/0001_initial.py
+++ b/crashreport_stats/migrations/0001_initial.py
@@ -8,39 +8,65 @@
 from django.db import connection
 from datetime import date, timedelta
 
+
 class Migration(migrations.Migration):
 
     initial = True
 
-    dependencies = [
-    ]
+    dependencies = []
 
     operations = [
         migrations.CreateModel(
-            name='Version',
+            name="Version",
             fields=[
-                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
-                ('build_fingerprint', models.CharField(max_length=200, unique=True)),
-                ('is_official_release', models.BooleanField(default=False)),
-                ('is_beta_release', models.BooleanField(default=False)),
-                ('first_seen_on', models.DateField()),
-                ('released_on', models.DateField()),
-                ('heartbeats', models.IntegerField()),
-                ('prob_crashes', models.IntegerField()),
-                ('smpl', models.IntegerField()),
-                ('other', models.IntegerField()),
+                (
+                    "id",
+                    models.AutoField(
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        verbose_name="ID",
+                    ),
+                ),
+                (
+                    "build_fingerprint",
+                    models.CharField(max_length=200, unique=True),
+                ),
+                ("is_official_release", models.BooleanField(default=False)),
+                ("is_beta_release", models.BooleanField(default=False)),
+                ("first_seen_on", models.DateField()),
+                ("released_on", models.DateField()),
+                ("heartbeats", models.IntegerField()),
+                ("prob_crashes", models.IntegerField()),
+                ("smpl", models.IntegerField()),
+                ("other", models.IntegerField()),
             ],
         ),
         migrations.CreateModel(
-            name='VersionDaily',
+            name="VersionDaily",
             fields=[
-                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
-                ('date', models.DateField()),
-                ('heartbeats', models.IntegerField()),
-                ('prob_crashes', models.IntegerField()),
-                ('smpl', models.IntegerField()),
-                ('other', models.IntegerField()),
-                ('version', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='daily_stats', to='crashreport_stats.Version')),
+                (
+                    "id",
+                    models.AutoField(
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        verbose_name="ID",
+                    ),
+                ),
+                ("date", models.DateField()),
+                ("heartbeats", models.IntegerField()),
+                ("prob_crashes", models.IntegerField()),
+                ("smpl", models.IntegerField()),
+                ("other", models.IntegerField()),
+                (
+                    "version",
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.CASCADE,
+                        related_name="daily_stats",
+                        to="crashreport_stats.Version",
+                    ),
+                ),
             ],
         ),
     ]
diff --git a/crashreport_stats/migrations/0002_version_and_versiondaily_with_defaults.py b/crashreport_stats/migrations/0002_version_and_versiondaily_with_defaults.py
index 0a58758..29da259 100644
--- a/crashreport_stats/migrations/0002_version_and_versiondaily_with_defaults.py
+++ b/crashreport_stats/migrations/0002_version_and_versiondaily_with_defaults.py
@@ -9,64 +9,62 @@
 
 class Migration(migrations.Migration):
 
-    dependencies = [
-        ('crashreport_stats', '0001_initial'),
-    ]
+    dependencies = [("crashreport_stats", "0001_initial")]
 
     operations = [
         migrations.AlterField(
-            model_name='version',
-            name='first_seen_on',
+            model_name="version",
+            name="first_seen_on",
             field=models.DateField(auto_now_add=True),
         ),
         migrations.AlterField(
-            model_name='version',
-            name='heartbeats',
+            model_name="version",
+            name="heartbeats",
             field=models.IntegerField(default=0),
         ),
         migrations.AlterField(
-            model_name='version',
-            name='other',
+            model_name="version",
+            name="other",
             field=models.IntegerField(default=0),
         ),
         migrations.AlterField(
-            model_name='version',
-            name='prob_crashes',
+            model_name="version",
+            name="prob_crashes",
             field=models.IntegerField(default=0),
         ),
         migrations.AlterField(
-            model_name='version',
-            name='released_on',
+            model_name="version",
+            name="released_on",
             field=models.DateField(auto_now_add=True),
         ),
         migrations.AlterField(
-            model_name='version',
-            name='smpl',
+            model_name="version",
+            name="smpl",
             field=models.IntegerField(default=0),
         ),
         migrations.AlterField(
-            model_name='versiondaily',
-            name='date',
+            model_name="versiondaily",
+            name="date",
             field=models.DateField(auto_now_add=True),
         ),
         migrations.AlterField(
-            model_name='versiondaily',
-            name='heartbeats',
+            model_name="versiondaily",
+            name="heartbeats",
             field=models.IntegerField(default=0),
         ),
         migrations.AlterField(
-            model_name='versiondaily',
-            name='other',
+            model_name="versiondaily",
+            name="other",
             field=models.IntegerField(default=0),
         ),
         migrations.AlterField(
-            model_name='versiondaily',
-            name='prob_crashes',
+            model_name="versiondaily",
+            name="prob_crashes",
             field=models.IntegerField(default=0),
         ),
         migrations.AlterField(
-            model_name='versiondaily',
-            name='smpl',
+            model_name="versiondaily",
+            name="smpl",
             field=models.IntegerField(default=0),
         ),
     ]
diff --git a/crashreport_stats/migrations/0003_radioversion_radioversiondaily.py b/crashreport_stats/migrations/0003_radioversion_radioversiondaily.py
index 3ce431a..e3e8261 100644
--- a/crashreport_stats/migrations/0003_radioversion_radioversiondaily.py
+++ b/crashreport_stats/migrations/0003_radioversion_radioversiondaily.py
@@ -10,41 +10,63 @@
 class Migration(migrations.Migration):
 
     dependencies = [
-        ('crashreport_stats', '0002_version_and_versiondaily_with_defaults'),
+        ("crashreport_stats", "0002_version_and_versiondaily_with_defaults")
     ]
 
     operations = [
         migrations.CreateModel(
-            name='RadioVersion',
+            name="RadioVersion",
             fields=[
-                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
-                ('is_official_release', models.BooleanField(default=False)),
-                ('is_beta_release', models.BooleanField(default=False)),
-                ('first_seen_on', models.DateField(auto_now_add=True)),
-                ('released_on', models.DateField(auto_now_add=True)),
-                ('heartbeats', models.IntegerField(default=0)),
-                ('prob_crashes', models.IntegerField(default=0)),
-                ('smpl', models.IntegerField(default=0)),
-                ('other', models.IntegerField(default=0)),
-                ('radio_version', models.CharField(max_length=200, unique=True)),
+                (
+                    "id",
+                    models.AutoField(
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        verbose_name="ID",
+                    ),
+                ),
+                ("is_official_release", models.BooleanField(default=False)),
+                ("is_beta_release", models.BooleanField(default=False)),
+                ("first_seen_on", models.DateField(auto_now_add=True)),
+                ("released_on", models.DateField(auto_now_add=True)),
+                ("heartbeats", models.IntegerField(default=0)),
+                ("prob_crashes", models.IntegerField(default=0)),
+                ("smpl", models.IntegerField(default=0)),
+                ("other", models.IntegerField(default=0)),
+                (
+                    "radio_version",
+                    models.CharField(max_length=200, unique=True),
+                ),
             ],
-            options={
-                'abstract': False,
-            },
+            options={"abstract": False},
         ),
         migrations.CreateModel(
-            name='RadioVersionDaily',
+            name="RadioVersionDaily",
             fields=[
-                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
-                ('date', models.DateField(auto_now_add=True)),
-                ('heartbeats', models.IntegerField(default=0)),
-                ('prob_crashes', models.IntegerField(default=0)),
-                ('smpl', models.IntegerField(default=0)),
-                ('other', models.IntegerField(default=0)),
-                ('version', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='daily_stats', to='crashreport_stats.RadioVersion')),
+                (
+                    "id",
+                    models.AutoField(
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        verbose_name="ID",
+                    ),
+                ),
+                ("date", models.DateField(auto_now_add=True)),
+                ("heartbeats", models.IntegerField(default=0)),
+                ("prob_crashes", models.IntegerField(default=0)),
+                ("smpl", models.IntegerField(default=0)),
+                ("other", models.IntegerField(default=0)),
+                (
+                    "version",
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.CASCADE,
+                        related_name="daily_stats",
+                        to="crashreport_stats.RadioVersion",
+                    ),
+                ),
             ],
-            options={
-                'abstract': False,
-            },
+            options={"abstract": False},
         ),
     ]
diff --git a/crashreport_stats/migrations/0004_statsmedata_and_no_broken_default_dates.py b/crashreport_stats/migrations/0004_statsmedata_and_no_broken_default_dates.py
index bf0ff94..7cbd433 100644
--- a/crashreport_stats/migrations/0004_statsmedata_and_no_broken_default_dates.py
+++ b/crashreport_stats/migrations/0004_statsmedata_and_no_broken_default_dates.py
@@ -8,48 +8,47 @@
     """Introduce the StatsMetadata model and remove broken default dates."""
 
     dependencies = [
-        ('crashreport_stats', '0003_radioversion_radioversiondaily'),
+        ("crashreport_stats", "0003_radioversion_radioversiondaily")
     ]
 
     operations = [
         migrations.CreateModel(
-            name='StatsMetadata',
+            name="StatsMetadata",
             fields=[
                 (
-                    'id', models.AutoField(
-                        auto_created=True, primary_key=True,
-                        serialize=False, verbose_name='ID')),
-                ('updated_at', models.DateTimeField(default=None)),
+                    "id",
+                    models.AutoField(
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        verbose_name="ID",
+                    ),
+                ),
+                ("updated_at", models.DateTimeField(default=None)),
             ],
         ),
         migrations.AlterField(
-            model_name='radioversiondaily',
-            name='date',
+            model_name="radioversiondaily",
+            name="date",
             field=models.DateField(),
         ),
         migrations.AlterField(
-            model_name='versiondaily',
-            name='date',
+            model_name="versiondaily", name="date", field=models.DateField()
+        ),
+        migrations.AlterField(
+            model_name="radioversion",
+            name="first_seen_on",
             field=models.DateField(),
         ),
         migrations.AlterField(
-            model_name='radioversion',
-            name='first_seen_on',
+            model_name="radioversion",
+            name="released_on",
             field=models.DateField(),
         ),
         migrations.AlterField(
-            model_name='radioversion',
-            name='released_on',
-            field=models.DateField(),
+            model_name="version", name="first_seen_on", field=models.DateField()
         ),
         migrations.AlterField(
-            model_name='version',
-            name='first_seen_on',
-            field=models.DateField(),
-        ),
-        migrations.AlterField(
-            model_name='version',
-            name='released_on',
-            field=models.DateField(),
+            model_name="version", name="released_on", field=models.DateField()
         ),
     ]
diff --git a/crashreport_stats/migrations/0005_remove_manual_default_value.py b/crashreport_stats/migrations/0005_remove_manual_default_value.py
index 3c508ed..ebc9db5 100644
--- a/crashreport_stats/migrations/0005_remove_manual_default_value.py
+++ b/crashreport_stats/migrations/0005_remove_manual_default_value.py
@@ -10,13 +10,13 @@
     """Remove default None value which was added manually."""
 
     dependencies = [
-        ('crashreport_stats', '0004_statsmedata_and_no_broken_default_dates'),
+        ("crashreport_stats", "0004_statsmedata_and_no_broken_default_dates")
     ]
 
     operations = [
         migrations.AlterField(
-            model_name='statsmetadata',
-            name='updated_at',
+            model_name="statsmetadata",
+            name="updated_at",
             field=models.DateTimeField(),
-        ),
+        )
     ]
diff --git a/crashreport_stats/models.py b/crashreport_stats/models.py
index 16ccb51..e4bb683 100644
--- a/crashreport_stats/models.py
+++ b/crashreport_stats/models.py
@@ -96,8 +96,11 @@
     """
 
     version = models.ForeignKey(
-        Version, db_index=True, related_name='daily_stats',
-        on_delete=models.CASCADE)
+        Version,
+        db_index=True,
+        related_name="daily_stats",
+        on_delete=models.CASCADE,
+    )
 
 
 class RadioVersion(_VersionStats):
@@ -125,8 +128,11 @@
     """
 
     version = models.ForeignKey(
-        RadioVersion, db_index=True, related_name='daily_stats',
-        on_delete=models.CASCADE)
+        RadioVersion,
+        db_index=True,
+        related_name="daily_stats",
+        on_delete=models.CASCADE,
+    )
 
 
 class StatsMetadata(models.Model):
diff --git a/crashreport_stats/raw_querys.py b/crashreport_stats/raw_querys.py
index 5b1878b..a71a346 100644
--- a/crashreport_stats/raw_querys.py
+++ b/crashreport_stats/raw_querys.py
@@ -1,34 +1,51 @@
 from django.conf import settings
 
+
 class FormatDict(dict):
     def __missing__(self, key):
         return "{" + key + "}"
 
+
 def fill_in_build_fingerprints(query, build_fingerprints):
-    all_fingerprints_query = 'select distinct build_fingerprint from crashreports_crashreport'
-    if len(build_fingerprints) > 0 :
+    all_fingerprints_query = (
+        "select distinct build_fingerprint from crashreports_crashreport"
+    )
+    if len(build_fingerprints) > 0:
         return query.format(
-                FormatDict(fingerprint_placeholers=
-                    ','.join(["%s"] * len(build_fingerprints))))
+            FormatDict(
+                fingerprint_placeholers=",".join(
+                    ["%s"] * len(build_fingerprints)
+                )
+            )
+        )
     else:
-        return query.format(FormatDict(fingerprint_placeholers = all_fingerprints_query))
+        return query.format(
+            FormatDict(fingerprint_placeholers=all_fingerprints_query)
+        )
 
 
 def execute_device_update_history_query(cursor, params):
-    if settings.DATABASES['default']['ENGINE'] == 'django.db.backends.postgresql_psycopg2':
+    if (
+        settings.DATABASES["default"]["ENGINE"]
+        == "django.db.backends.postgresql_psycopg2"
+    ):
         return psql_execute_device_update_history_query(cursor, params)
     else:
         return sqlite_execute_device_update_history_query(cursor, params)
 
 
 def execute_device_report_history(cursor, params):
-    if settings.DATABASES['default']['ENGINE'] == 'django.db.backends.postgresql_psycopg2':
+    if (
+        settings.DATABASES["default"]["ENGINE"]
+        == "django.db.backends.postgresql_psycopg2"
+    ):
         return psql_execute_device_report_history(cursor, params)
     else:
         return sqlite_execute_device_report_history(cursor, params)
 
+
 def sqlite_execute_device_update_history_query(cursor, params):
-    query = '''
+    query = """
     SELECT
         min(crashreports_heartbeat.date) as update_date,
         build_fingerprint,
@@ -54,14 +71,14 @@
     where
         crashreports_device.uuid=%s
         group by build_fingerprint;
-    '''
-    uuid = params.get('uuid', '18f530d7-e9c3-4dcf-adba-3dddcd7d3155')
+    """
+    uuid = params.get("uuid", "18f530d7-e9c3-4dcf-adba-3dddcd7d3155")
     param_array = [uuid]
     cursor.execute(query, param_array)
 
 
 def psql_execute_device_update_history_query(cursor, params):
-    query = '''
+    query = """
     SELECT
         min(crashreports_heartbeat.date) as update_date,
         build_fingerprint,
@@ -88,14 +105,14 @@
     where
         crashreports_device.uuid=%s
         group by build_fingerprint;
-    '''
-    uuid = params.get('uuid', '18f530d7-e9c3-4dcf-adba-3dddcd7d3155')
+    """
+    uuid = params.get("uuid", "18f530d7-e9c3-4dcf-adba-3dddcd7d3155")
     param_array = [uuid]
     cursor.execute(query, param_array)
 
 
 def sqlite_execute_device_report_history(cursor, params):
-    query = '''
+    query = """
     SELECT
       strftime("%%Y-%%m-%%d",crashreports_heartbeat.date) as date,
       count(crashreports_heartbeat.id) as heartbeats,
@@ -126,14 +143,14 @@
     where
       crashreports_device.uuid = %s
     group by date;
-    '''
-    uuid = params.get('uuid', '18f530d7-e9c3-4dcf-adba-3dddcd7d3155')
+    """
+    uuid = params.get("uuid", "18f530d7-e9c3-4dcf-adba-3dddcd7d3155")
     param_array = [uuid]
     cursor.execute(query, param_array)
 
 
 def psql_execute_device_report_history(cursor, params):
-    query = '''
+    query = """
     SELECT
       crashreports_heartbeat.date::date as date,
       count(crashreports_heartbeat.id) as heartbeats,
@@ -145,7 +162,7 @@
     left join crashreports_crashreport on crashreports_device.id = crashreports_crashreport.device_id and  crashreports_heartbeat.date::date = crashreports_crashreport.date::date
     where
       crashreports_device.uuid = %s group by crashreports_heartbeat.date, crashreports_device.id;
-    '''
-    uuid = params.get('uuid', '18f530d7-e9c3-4dcf-adba-3dddcd7d3155')
+    """
+    uuid = params.get("uuid", "18f530d7-e9c3-4dcf-adba-3dddcd7d3155")
     param_array = [uuid]
     cursor.execute(query, param_array)
diff --git a/crashreport_stats/rest_endpoints.py b/crashreport_stats/rest_endpoints.py
index 7da1a5f..5db2e36 100644
--- a/crashreport_stats/rest_endpoints.py
+++ b/crashreport_stats/rest_endpoints.py
@@ -12,18 +12,23 @@
 from django.db.models.expressions import F
 
 from django_filters.rest_framework import (
-    DjangoFilterBackend, DateFilter,
-    FilterSet, CharFilter, BooleanFilter
+    DjangoFilterBackend,
+    DateFilter,
+    FilterSet,
+    CharFilter,
+    BooleanFilter,
 )
 
 from crashreport_stats.models import (
-    Version, VersionDaily, RadioVersion, RadioVersionDaily
+    Version,
+    VersionDaily,
+    RadioVersion,
+    RadioVersionDaily,
 )
-from crashreports.models import (
-    Device, Crashreport, HeartBeat, LogFile
-)
+from crashreports.models import Device, Crashreport, HeartBeat, LogFile
 from crashreports.permissions import (
-    HasRightsOrIsDeviceOwnerDeviceCreation, HasStatsAccess
+    HasRightsOrIsDeviceOwnerDeviceCreation,
+    HasStatsAccess,
 )
 from . import raw_querys
 
@@ -32,15 +37,14 @@
     """Return all rows from a cursor as a dict."""
     desc = cursor.description
     return [
-        dict(zip([col[0] for col in desc], row))
-        for row in cursor.fetchall()
+        dict(zip([col[0] for col in desc], row)) for row in cursor.fetchall()
     ]
 
 
 class DeviceUpdateHistory(APIView):
     """View the update history of a specific device."""
 
-    permission_classes = (HasRightsOrIsDeviceOwnerDeviceCreation, )
+    permission_classes = (HasRightsOrIsDeviceOwnerDeviceCreation,)
 
     def get(self, request, uuid, format=None):
         """Get the update history of a device.
@@ -54,11 +58,7 @@
 
         """
         cursor = connection.cursor()
-        raw_querys.execute_device_update_history_query(
-            cursor,
-            {
-                'uuid': uuid
-            })
+        raw_querys.execute_device_update_history_query(cursor, {"uuid": uuid})
         res = dictfetchall(cursor)
         return Response(res)
 
@@ -66,7 +66,7 @@
 class DeviceReportHistory(APIView):
     """View the report history of a specific device."""
 
-    permission_classes = (HasRightsOrIsDeviceOwnerDeviceCreation, )
+    permission_classes = (HasRightsOrIsDeviceOwnerDeviceCreation,)
 
     def get(self, request, uuid, format=None):
         """Get the report history of a device.
@@ -80,11 +80,7 @@
 
         """
         cursor = connection.cursor()
-        raw_querys.execute_device_report_history(
-            cursor,
-            {
-                'uuid': uuid
-            })
+        raw_querys.execute_device_report_history(cursor, {"uuid": uuid})
         res = dictfetchall(cursor)
         return Response(res)
 
@@ -94,7 +90,7 @@
 
     permission_classes = (HasStatsAccess,)
 
-    def get(self, request, format=None, ):
+    def get(self, request, format=None):
         """Get the number of devices, crashreports and heartbeats.
 
         Args:
@@ -107,19 +103,21 @@
         num_devices = Device.objects.count()
         num_crashreports = Crashreport.objects.count()
         num_heartbeats = HeartBeat.objects.count()
-        return Response({
-            'devices': num_devices,
-            'crashreports': num_crashreports,
-            'heartbeats': num_heartbeats
-        })
+        return Response(
+            {
+                "devices": num_devices,
+                "crashreports": num_crashreports,
+                "heartbeats": num_heartbeats,
+            }
+        )
 
 
 class DeviceStat(APIView):
     """View an overview of the statistics of a device."""
 
-    permission_classes = (HasRightsOrIsDeviceOwnerDeviceCreation, )
+    permission_classes = (HasRightsOrIsDeviceOwnerDeviceCreation,)
 
-    def get(self, request, uuid, format=None, ):
+    def get(self, request, uuid, format=None):
         """Get some general statistics for a device.
 
         Args:
@@ -131,32 +129,42 @@
 
         """
         device = Device.objects.filter(uuid=uuid)
-        last_active = HeartBeat.objects.filter(device=device).order_by(
-            '-date')[0].date
+        last_active = (
+            HeartBeat.objects.filter(device=device).order_by("-date")[0].date
+        )
         heartbeats = HeartBeat.objects.filter(device=device).count()
-        crashreports = Crashreport.objects.filter(device=device).filter(
-            boot_reason__in=Crashreport.CRASH_BOOT_REASONS).count()
-        crashes_per_day = crashreports*1.0/heartbeats if heartbeats > 0 else 0
-        smpls = Crashreport.objects.filter(device=device).filter(
-            boot_reason__in=Crashreport.SMPL_BOOT_REASONS).count()
-        smpl_per_day = smpls*1.0/heartbeats if heartbeats > 0 else 0
+        crashreports = (
+            Crashreport.objects.filter(device=device)
+            .filter(boot_reason__in=Crashreport.CRASH_BOOT_REASONS)
+            .count()
+        )
+        crashes_per_day = (
+            crashreports * 1.0 / heartbeats if heartbeats > 0 else 0
+        )
+        smpls = (
+            Crashreport.objects.filter(device=device)
+            .filter(boot_reason__in=Crashreport.SMPL_BOOT_REASONS)
+            .count()
+        )
+        smpl_per_day = smpls * 1.0 / heartbeats if heartbeats > 0 else 0
         return Response(
             {
-                'uuid': uuid,
-                'last_active': last_active,
-                'heartbeats': heartbeats,
-                'crashreports': crashreports,
-                'crashes_per_day': crashes_per_day,
-                'smpls': smpls,
-                'smpl_per_day': smpl_per_day,
-                'board_date': device[0].board_date,
-            })
+                "uuid": uuid,
+                "last_active": last_active,
+                "heartbeats": heartbeats,
+                "crashreports": crashreports,
+                "crashes_per_day": crashes_per_day,
+                "smpls": smpls,
+                "smpl_per_day": smpl_per_day,
+                "board_date": device[0].board_date,
+            }
+        )
 
 
 class LogFileDownload(APIView):
     """View for downloading log files."""
 
-    permission_classes = (HasRightsOrIsDeviceOwnerDeviceCreation, )
+    permission_classes = (HasRightsOrIsDeviceOwnerDeviceCreation,)
 
     def get(self, request, id_logfile, format=None):
         """Get a logfile.
@@ -182,12 +190,12 @@
 
 
 class _VersionStatsFilter(FilterSet):
-    first_seen_before = DateFilter(field_name="first_seen_on",
-                                   lookup_expr='lte')
-    first_seen_after = DateFilter(field_name="first_seen_on",
-                                  lookup_expr='gte')
-    released_before = DateFilter(field_name="released_on", lookup_expr='lte')
-    released_after = DateFilter(field_name="released_on", lookup_expr='gte')
+    first_seen_before = DateFilter(
+        field_name="first_seen_on", lookup_expr="lte"
+    )
+    first_seen_after = DateFilter(field_name="first_seen_on", lookup_expr="gte")
+    released_before = DateFilter(field_name="released_on", lookup_expr="lte")
+    released_after = DateFilter(field_name="released_on", lookup_expr="gte")
 
 
 class _VersionStatsSerializer(serializers.ModelSerializer):
@@ -200,8 +208,8 @@
 
 
 class _DailyVersionStatsFilter(FilterSet):
-    date_start = DateFilter(field_name="date", lookup_expr='gte')
-    date_end = DateFilter(field_name="date", lookup_expr='lte')
+    date_start = DateFilter(field_name="date", lookup_expr="gte")
+    date_end = DateFilter(field_name="date", lookup_expr="lte")
 
 
 class _DailyVersionStatsSerializer(serializers.ModelSerializer):
@@ -218,7 +226,7 @@
 
     class Meta:  # noqa: D106
         model = Version
-        fields = '__all__'
+        fields = "__all__"
 
 
 class VersionFilter(_VersionStatsFilter):
@@ -226,13 +234,13 @@
 
     class Meta:  # noqa: D106
         model = Version
-        fields = '__all__'
+        fields = "__all__"
 
 
 class VersionListView(_VersionStatsListView):
     """View for listing versions."""
 
-    queryset = Version.objects.all().order_by('-heartbeats')
+    queryset = Version.objects.all().order_by("-heartbeats")
     filter_class = VersionFilter
     serializer_class = VersionSerializer
 
@@ -246,7 +254,7 @@
 
     class Meta:  # noqa: D106
         model = VersionDaily
-        fields = '__all__'
+        fields = "__all__"
 
 
 class VersionDailySerializer(_DailyVersionStatsSerializer):
@@ -256,24 +264,24 @@
 
     class Meta:  # noqa: D106
         model = VersionDaily
-        fields = '__all__'
+        fields = "__all__"
 
 
 class VersionDailyListView(_DailyVersionStatsListView):
     """View for listing VersionDaily instances."""
 
     queryset = (
-        VersionDaily
-        .objects
-        .annotate(build_fingerprint=F('version__build_fingerprint'))
+        VersionDaily.objects.annotate(
+            build_fingerprint=F("version__build_fingerprint")
+        )
         .all()
-        .order_by('date')
+        .order_by("date")
     )
     filter_class = VersionDailyFilter
     filter_fields = (
-        'version__build_fingerprint',
-        'version__is_official_release',
-        'version__is_beta_release',
+        "version__build_fingerprint",
+        "version__is_official_release",
+        "version__is_beta_release",
     )
     serializer_class = VersionDailySerializer
 
@@ -283,7 +291,7 @@
 
     class Meta:  # noqa: D106
         model = RadioVersion
-        fields = '__all__'
+        fields = "__all__"
 
 
 class RadioVersionFilter(_VersionStatsFilter):
@@ -291,13 +299,13 @@
 
     class Meta:  # noqa: D106
         model = RadioVersion
-        fields = '__all__'
+        fields = "__all__"
 
 
 class RadioVersionListView(_VersionStatsListView):
     """View for listing RadioVersion instances."""
 
-    queryset = RadioVersion.objects.all().order_by('-heartbeats')
+    queryset = RadioVersion.objects.all().order_by("-heartbeats")
     serializer_class = RadioVersionSerializer
     filter_class = RadioVersionFilter
 
@@ -311,7 +319,7 @@
 
     class Meta:  # noqa: D106
         model = RadioVersionDaily
-        fields = '__all__'
+        fields = "__all__"
 
 
 class RadioVersionDailySerializer(_DailyVersionStatsSerializer):
@@ -321,7 +329,7 @@
 
     class Meta:  # noqa: D106
         model = RadioVersionDaily
-        fields = '__all__'
+        fields = "__all__"
 
 
 class RadioVersionDailyListView(_DailyVersionStatsListView):
@@ -329,14 +337,15 @@
 
     queryset = (
         RadioVersionDaily.objects.annotate(
-            radio_version=F('version__radio_version'))
+            radio_version=F("version__radio_version")
+        )
         .all()
-        .order_by('date')
+        .order_by("date")
     )
     filter_class = RadioVersionDailyFilter
     filter_fields = (
-        'version__radio_version',
-        'version__is_official_release',
-        'version__is_beta_release',
+        "version__radio_version",
+        "version__is_official_release",
+        "version__is_beta_release",
     )
     serializer_class = RadioVersionDailySerializer
diff --git a/crashreport_stats/templatetags/crashreport_stats_tags.py b/crashreport_stats/templatetags/crashreport_stats_tags.py
index 235175d..22f475d 100644
--- a/crashreport_stats/templatetags/crashreport_stats_tags.py
+++ b/crashreport_stats/templatetags/crashreport_stats_tags.py
@@ -3,67 +3,118 @@
 
 register = template.Library()
 
-@register.simple_tag
-def device_overview(title = "General Information", uuid='e1c0cc95-ab8d-461a-a768-cb8d9d7adb04'):
-    t = template.loader.get_template('crashreport_stats/tags/device_overview.html')
-    return t.render({
-        'uuid': uuid,
-        "title": title,
-        "element_name": "device_overview"})
 
 @register.simple_tag
-def device_crashreport_table(title = "Crashreports", uuid='e1c0cc95-ab8d-461a-a768-cb8d9d7adb04'):
-    t = template.loader.get_template('crashreport_stats/tags/device_crashreport_table.html')
-    return t.render({
-        'uuid': uuid,
-        "title": title,
-        "element_name": "device_crashreport_table"})
-
-@register.simple_tag
-def device_update_history(title = "Update History", uuid='e1c0cc95-ab8d-461a-a768-cb8d9d7adb04'):
-    t = template.loader.get_template('crashreport_stats/tags/device_update_history.html')
-    return t.render({
-        'uuid': uuid,
-        "title": title,
-        "element_name": "device_update_statistic"})
-
-@register.simple_tag
-def device_report_history(title = "Report History", uuid='e1c0cc95-ab8d-461a-a768-cb8d9d7adb04'):
-    t = template.loader.get_template('crashreport_stats/tags/device_report_history.html')
-    return t.render({
-        'uuid': uuid,
-        "title": title,
-        "element_name": "device_report_history"})
+def device_overview(
+    title="General Information", uuid="e1c0cc95-ab8d-461a-a768-cb8d9d7adb04"
+):
+    t = template.loader.get_template(
+        "crashreport_stats/tags/device_overview.html"
+    )
+    return t.render(
+        {"uuid": uuid, "title": title, "element_name": "device_overview"}
+    )
 
 
 @register.simple_tag
-def versions_table(title = "FP2 OS Versions",  is_official_release="1"):
-    t = template.loader.get_template('crashreport_stats/tags/versions_table.html')
-    return t.render({
-        "title": title,
-        "is_official_release":is_official_release,
-        "element_name": "versions_overview_table"})
+def device_crashreport_table(
+    title="Crashreports", uuid="e1c0cc95-ab8d-461a-a768-cb8d9d7adb04"
+):
+    t = template.loader.get_template(
+        "crashreport_stats/tags/device_crashreport_table.html"
+    )
+    return t.render(
+        {
+            "uuid": uuid,
+            "title": title,
+            "element_name": "device_crashreport_table",
+        }
+    )
+
 
 @register.simple_tag
-def versions_pie_chart(title = "FP2 Version Distribution", is_official_release="1"):
-    t = template.loader.get_template('crashreport_stats/tags/versions_pie_chart.html')
-    return t.render({
-        "title": title,
-        "is_official_release":is_official_release,
-        "element_name": "versions_overview_pie_chart"})
+def device_update_history(
+    title="Update History", uuid="e1c0cc95-ab8d-461a-a768-cb8d9d7adb04"
+):
+    t = template.loader.get_template(
+        "crashreport_stats/tags/device_update_history.html"
+    )
+    return t.render(
+        {
+            "uuid": uuid,
+            "title": title,
+            "element_name": "device_update_statistic",
+        }
+    )
+
 
 @register.simple_tag
-def versions_area_chart(title = "FP2 Version Distribution",  is_official_release="1"):
-    t = template.loader.get_template('crashreport_stats/tags/versions_area_chart.html')
-    return t.render({
-        "title": title,
-        "is_official_release":is_official_release,
-        "element_name": "versions_overview_area_chart"})
+def device_report_history(
+    title="Report History", uuid="e1c0cc95-ab8d-461a-a768-cb8d9d7adb04"
+):
+    t = template.loader.get_template(
+        "crashreport_stats/tags/device_report_history.html"
+    )
+    return t.render(
+        {"uuid": uuid, "title": title, "element_name": "device_report_history"}
+    )
+
 
 @register.simple_tag
-def versions_bar_chart(title = "Version Stability", is_official_release="1"):
-    t = template.loader.get_template('crashreport_stats/tags/versions_bar_chart.html')
-    return t.render({
-        "title": title,
-        "is_official_release":is_official_release,
-        "element_name": "versions_overview_bar_chart"})
+def versions_table(title="FP2 OS Versions", is_official_release="1"):
+    t = template.loader.get_template(
+        "crashreport_stats/tags/versions_table.html"
+    )
+    return t.render(
+        {
+            "title": title,
+            "is_official_release": is_official_release,
+            "element_name": "versions_overview_table",
+        }
+    )
+
+
+@register.simple_tag
+def versions_pie_chart(
+    title="FP2 Version Distribution", is_official_release="1"
+):
+    t = template.loader.get_template(
+        "crashreport_stats/tags/versions_pie_chart.html"
+    )
+    return t.render(
+        {
+            "title": title,
+            "is_official_release": is_official_release,
+            "element_name": "versions_overview_pie_chart",
+        }
+    )
+
+
+@register.simple_tag
+def versions_area_chart(
+    title="FP2 Version Distribution", is_official_release="1"
+):
+    t = template.loader.get_template(
+        "crashreport_stats/tags/versions_area_chart.html"
+    )
+    return t.render(
+        {
+            "title": title,
+            "is_official_release": is_official_release,
+            "element_name": "versions_overview_area_chart",
+        }
+    )
+
+
+@register.simple_tag
+def versions_bar_chart(title="Version Stability", is_official_release="1"):
+    t = template.loader.get_template(
+        "crashreport_stats/tags/versions_bar_chart.html"
+    )
+    return t.render(
+        {
+            "title": title,
+            "is_official_release": is_official_release,
+            "element_name": "versions_overview_bar_chart",
+        }
+    )
diff --git a/crashreport_stats/tests.py b/crashreport_stats/tests.py
index e852700..68f8e82 100644
--- a/crashreport_stats/tests.py
+++ b/crashreport_stats/tests.py
@@ -12,84 +12,91 @@
 from rest_framework.test import APITestCase, APIClient
 
 from crashreport_stats.models import (
-    Version, VersionDaily, RadioVersion, RadioVersionDaily, StatsMetadata
+    Version,
+    VersionDaily,
+    RadioVersion,
+    RadioVersionDaily,
+    StatsMetadata,
 )
 
 from crashreports.models import User, Device, Crashreport, HeartBeat
 
 
-class Dummy():
+class Dummy:
     """Class for creating dummy instances for testing."""
 
     # Valid unique entries
-    BUILD_FINGERPRINTS = [(
-        'Fairphone/FP2/FP2:5.1/FP2/r4275.1_FP2_gms76_1.13.0:user/release-keys'
-    ), (
-        'Fairphone/FP2/FP2:5.1.1/FP2-gms75.1.13.0/FP2-gms75.1.13.0'
-        ':user/release-keys'
-    ), (
-        'Fairphone/FP2/FP2:6.0.1/FP2-gms-18.04.1/FP2-gms-18.04.1'
-        ':user/release-keys'
-    ), (
-        'Fairphone/FP2/FP2:7.1.2/18.07.2/gms-7480c31d'
-        ':user/release-keys'
-    )]
-    RADIO_VERSIONS = ['4437.1-FP2-0-07', '4437.1-FP2-0-08',
-                      '4437.1-FP2-0-09', '4437.1-FP2-0-10']
+    BUILD_FINGERPRINTS = [
+        (
+            "Fairphone/FP2/FP2:5.1/FP2/r4275.1_FP2_gms76_1.13.0:user/release-keys"
+        ),
+        (
+            "Fairphone/FP2/FP2:5.1.1/FP2-gms75.1.13.0/FP2-gms75.1.13.0"
+            ":user/release-keys"
+        ),
+        (
+            "Fairphone/FP2/FP2:6.0.1/FP2-gms-18.04.1/FP2-gms-18.04.1"
+            ":user/release-keys"
+        ),
+        ("Fairphone/FP2/FP2:7.1.2/18.07.2/gms-7480c31d" ":user/release-keys"),
+    ]
+    RADIO_VERSIONS = [
+        "4437.1-FP2-0-07",
+        "4437.1-FP2-0-08",
+        "4437.1-FP2-0-09",
+        "4437.1-FP2-0-10",
+    ]
 
     DATES = [date(2018, 3, 19), date(2018, 3, 26), date(2018, 5, 1)]
 
     DEFAULT_DUMMY_VERSION_VALUES = {
-        'build_fingerprint': BUILD_FINGERPRINTS[0],
-        'first_seen_on': DATES[1],
-        'released_on': DATES[0]
+        "build_fingerprint": BUILD_FINGERPRINTS[0],
+        "first_seen_on": DATES[1],
+        "released_on": DATES[0],
     }
 
-    DEFAULT_DUMMY_VERSION_DAILY_VALUES = {
-        'date': DATES[1]
-    }
+    DEFAULT_DUMMY_VERSION_DAILY_VALUES = {"date": DATES[1]}
 
     DEFAULT_DUMMY_RADIO_VERSION_VALUES = {
-        'radio_version': RADIO_VERSIONS[0],
-        'first_seen_on': DATES[1],
-        'released_on': DATES[0]
+        "radio_version": RADIO_VERSIONS[0],
+        "first_seen_on": DATES[1],
+        "released_on": DATES[0],
     }
 
-    DEFAULT_DUMMY_RADIO_VERSION_DAILY_VALUES = {
-        'date': DATES[1]
-    }
+    DEFAULT_DUMMY_RADIO_VERSION_DAILY_VALUES = {"date": DATES[1]}
 
     DEFAULT_DUMMY_STATSMETADATA_VALUES = {
-        'updated_at': datetime(2018, 6, 15, 2, 12, 24, tzinfo=pytz.utc),
+        "updated_at": datetime(2018, 6, 15, 2, 12, 24, tzinfo=pytz.utc)
     }
 
     DEFAULT_DUMMY_DEVICE_VALUES = {
-        'board_date': datetime(2015, 12, 15, 1, 23, 45, tzinfo=pytz.utc),
-        'chipset': 'Qualcomm MSM8974PRO-AA',
-        'token': '64111c62d521fb4724454ca6dea27e18f93ef56e'
+        "board_date": datetime(2015, 12, 15, 1, 23, 45, tzinfo=pytz.utc),
+        "chipset": "Qualcomm MSM8974PRO-AA",
+        "token": "64111c62d521fb4724454ca6dea27e18f93ef56e",
     }
 
-    DEFAULT_DUMMY_USER_VALUES = {
-        'username': 'testuser'
-    }
+    DEFAULT_DUMMY_USER_VALUES = {"username": "testuser"}
 
     DEFAULT_DUMMY_HEARTBEAT_VALUES = {
-        'app_version': 10100,
-        'uptime': (
-            'up time: 16 days, 21:49:56, idle time: 5 days, 20:55:04, '
-            'sleep time: 10 days, 20:46:27'),
-        'build_fingerprint': BUILD_FINGERPRINTS[0],
-        'radio_version': RADIO_VERSIONS[0],
-        'date': datetime(2018, 3, 19, tzinfo=pytz.utc),
+        "app_version": 10100,
+        "uptime": (
+            "up time: 16 days, 21:49:56, idle time: 5 days, 20:55:04, "
+            "sleep time: 10 days, 20:46:27"
+        ),
+        "build_fingerprint": BUILD_FINGERPRINTS[0],
+        "radio_version": RADIO_VERSIONS[0],
+        "date": datetime(2018, 3, 19, tzinfo=pytz.utc),
     }
 
     DEFAULT_DUMMY_CRASHREPORT_VALUES = DEFAULT_DUMMY_HEARTBEAT_VALUES.copy()
-    DEFAULT_DUMMY_CRASHREPORT_VALUES.update({
-        'is_fake_report': 0,
-        'boot_reason': Crashreport.BOOT_REASON_UNKOWN,
-        'power_on_reason': 'it was powered on',
-        'power_off_reason': 'something happened and it went off',
-    })
+    DEFAULT_DUMMY_CRASHREPORT_VALUES.update(
+        {
+            "is_fake_report": 0,
+            "boot_reason": Crashreport.BOOT_REASON_UNKOWN,
+            "power_on_reason": "it was powered on",
+            "power_off_reason": "something happened and it went off",
+        }
+    )
 
     @staticmethod
     def update_copy(original, update):
@@ -110,8 +117,9 @@
         Returns: The created user instance.
 
         """
-        entity = User(**Dummy.update_copy(
-            Dummy.DEFAULT_DUMMY_USER_VALUES, kwargs))
+        entity = User(
+            **Dummy.update_copy(Dummy.DEFAULT_DUMMY_USER_VALUES, kwargs)
+        )
         entity.save()
         return entity
 
@@ -128,8 +136,10 @@
         Returns: The created device instance.
 
         """
-        entity = Device(user=user, **Dummy.update_copy(
-            Dummy.DEFAULT_DUMMY_DEVICE_VALUES, kwargs))
+        entity = Device(
+            user=user,
+            **Dummy.update_copy(Dummy.DEFAULT_DUMMY_DEVICE_VALUES, kwargs)
+        )
         entity.save()
         return entity
 
@@ -148,15 +158,25 @@
 
         """
         if report_type == HeartBeat:
-            entity = HeartBeat(device=device, **Dummy.update_copy(
-                Dummy.DEFAULT_DUMMY_HEARTBEAT_VALUES, kwargs))
+            entity = HeartBeat(
+                device=device,
+                **Dummy.update_copy(
+                    Dummy.DEFAULT_DUMMY_HEARTBEAT_VALUES, kwargs
+                )
+            )
         elif report_type == Crashreport:
-            entity = Crashreport(device=device, **Dummy.update_copy(
-                Dummy.DEFAULT_DUMMY_CRASHREPORT_VALUES, kwargs))
+            entity = Crashreport(
+                device=device,
+                **Dummy.update_copy(
+                    Dummy.DEFAULT_DUMMY_CRASHREPORT_VALUES, kwargs
+                )
+            )
         else:
             raise RuntimeError(
-                'No dummy report instance can be created for {}'.format(
-                    report_type.__name__))
+                "No dummy report instance can be created for {}".format(
+                    report_type.__name__
+                )
+            )
         entity.save()
         return entity
 
@@ -172,8 +192,9 @@
         Returns: The created version instance.
 
         """
-        entity = Version(**Dummy.update_copy(
-            Dummy.DEFAULT_DUMMY_VERSION_VALUES, kwargs))
+        entity = Version(
+            **Dummy.update_copy(Dummy.DEFAULT_DUMMY_VERSION_VALUES, kwargs)
+        )
         entity.save()
         return entity
 
@@ -189,8 +210,11 @@
         Returns: The created radio version instance.
 
         """
-        entity = RadioVersion(**Dummy.update_copy(
-            Dummy.DEFAULT_DUMMY_RADIO_VERSION_VALUES, kwargs))
+        entity = RadioVersion(
+            **Dummy.update_copy(
+                Dummy.DEFAULT_DUMMY_RADIO_VERSION_VALUES, kwargs
+            )
+        )
         entity.save()
         return entity
 
@@ -206,8 +230,12 @@
         Returns: The created daily version instance.
 
         """
-        entity = VersionDaily(version=version, **Dummy.update_copy(
-            Dummy.DEFAULT_DUMMY_VERSION_DAILY_VALUES, kwargs))
+        entity = VersionDaily(
+            version=version,
+            **Dummy.update_copy(
+                Dummy.DEFAULT_DUMMY_VERSION_DAILY_VALUES, kwargs
+            )
+        )
         entity.save()
         return entity
 
@@ -223,8 +251,12 @@
         Returns: The created daily radio version instance.
 
         """
-        entity = RadioVersionDaily(version=version, **Dummy.update_copy(
-            Dummy.DEFAULT_DUMMY_RADIO_VERSION_DAILY_VALUES, kwargs))
+        entity = RadioVersionDaily(
+            version=version,
+            **Dummy.update_copy(
+                Dummy.DEFAULT_DUMMY_RADIO_VERSION_DAILY_VALUES, kwargs
+            )
+        )
         entity.save()
         return entity
 
@@ -240,8 +272,11 @@
         Returns: The created stats metadata instance.
 
         """
-        entity = StatsMetadata(**Dummy.update_copy(
-            Dummy.DEFAULT_DUMMY_STATSMETADATA_VALUES, kwargs))
+        entity = StatsMetadata(
+            **Dummy.update_copy(
+                Dummy.DEFAULT_DUMMY_STATSMETADATA_VALUES, kwargs
+            )
+        )
         entity.save()
         return entity
 
@@ -251,11 +286,11 @@
 
     # The attribute name characterising the unicity of a stats entry (the
     # named identifier)
-    unique_entry_name = 'build_fingerprint'
+    unique_entry_name = "build_fingerprint"
     # The collection of unique entries to post
     unique_entries = Dummy.BUILD_FINGERPRINTS
     # The URL to retrieve the stats entries from
-    endpoint_url = reverse('hiccup_stats_api_v1_versions')
+    endpoint_url = reverse("hiccup_stats_api_v1_versions")
 
     @classmethod
     def setUpTestData(cls):  # noqa: N802
@@ -265,7 +300,8 @@
         server is stored in self.admin.
         """
         admin_user = User.objects.create_superuser(
-            'somebody', 'somebody@example.com', 'thepassword')
+            "somebody", "somebody@example.com", "thepassword"
+        )
         cls.admin = APIClient()
         cls.admin.force_authenticate(admin_user)
 
@@ -274,14 +310,14 @@
         return Dummy.create_dummy_version(**kwargs)
 
     def _get_with_params(self, url, params):
-        return self.admin.get('{}?{}'.format(url, urlencode(params)))
+        return self.admin.get("{}?{}".format(url, urlencode(params)))
 
     def _assert_result_length_is(self, response, count):
         self.assertEqual(response.status_code, status.HTTP_200_OK)
-        self.assertIn('results', response.data)
-        self.assertIn('count', response.data)
-        self.assertEqual(response.data['count'], count)
-        self.assertEqual(len(response.data['results']), count)
+        self.assertIn("results", response.data)
+        self.assertIn("count", response.data)
+        self.assertEqual(response.data["count"], count)
+        self.assertEqual(len(response.data["results"]), count)
 
     def _assert_device_owner_has_no_get_access(self, entries_url):
         # Create a user and device
@@ -290,7 +326,7 @@
 
         # Create authenticated client
         user = APIClient()
-        user.credentials(HTTP_AUTHORIZATION='Token ' + device.token)
+        user.credentials(HTTP_AUTHORIZATION="Token " + device.token)
 
         # Try getting entries using the client
         response = user.get(entries_url)
@@ -302,8 +338,10 @@
 
         # Expect only the single matching result to be returned
         self._assert_result_length_is(response, 1)
-        self.assertEqual(response.data['results'][0][self.unique_entry_name],
-                         getattr(expected_result, self.unique_entry_name))
+        self.assertEqual(
+            response.data["results"][0][self.unique_entry_name],
+            getattr(expected_result, self.unique_entry_name),
+        )
 
 
 class VersionTestCase(_VersionTestCase):
@@ -311,9 +349,7 @@
 
     def _create_version_entities(self):
         versions = [
-            self._create_dummy_version(
-                **{self.unique_entry_name: unique_entry}
-            )
+            self._create_dummy_version(**{self.unique_entry_name: unique_entry})
             for unique_entry in self.unique_entries
         ]
         return versions
@@ -348,11 +384,11 @@
 
         # List entities with filter
         filter_params = {
-            self.unique_entry_name: getattr(versions[0],
-                                            self.unique_entry_name)
+            self.unique_entry_name: getattr(versions[0], self.unique_entry_name)
         }
-        self._assert_filter_result_matches(filter_params,
-                                           expected_result=versions[0])
+        self._assert_filter_result_matches(
+            filter_params, expected_result=versions[0]
+        )
 
     def test_filter_versions_by_release_type(self):
         """Test filtering versions by release type."""
@@ -361,11 +397,15 @@
         i = 0
         for is_official_release in True, False:
             for is_beta_release in True, False:
-                versions.append(self._create_dummy_version(**{
-                    'is_official_release': is_official_release,
-                    'is_beta_release': is_beta_release,
-                    self.unique_entry_name: self.unique_entries[i]
-                }))
+                versions.append(
+                    self._create_dummy_version(
+                        **{
+                            "is_official_release": is_official_release,
+                            "is_beta_release": is_beta_release,
+                            self.unique_entry_name: self.unique_entries[i],
+                        }
+                    )
+                )
                 i += 1
 
         # # Listing all entities should return the correct result length
@@ -375,11 +415,12 @@
         # List each of the entities with the matching filter params
         for version in versions:
             filter_params = {
-                'is_official_release': version.is_official_release,
-                'is_beta_release': version.is_beta_release
+                "is_official_release": version.is_official_release,
+                "is_beta_release": version.is_beta_release,
             }
-            self._assert_filter_result_matches(filter_params,
-                                               expected_result=version)
+            self._assert_filter_result_matches(
+                filter_params, expected_result=version
+            )
 
     def test_filter_versions_by_first_seen_date(self):
         """Test filtering versions by first seen date."""
@@ -394,18 +435,19 @@
         self._assert_result_length_is(response, len(versions))
 
         # Expect the single matching result to be returned
-        filter_params = {'first_seen_after': Dummy.DATES[2]}
-        self._assert_filter_result_matches(filter_params,
-                                           expected_result=versions[0])
+        filter_params = {"first_seen_after": Dummy.DATES[2]}
+        self._assert_filter_result_matches(
+            filter_params, expected_result=versions[0]
+        )
 
 
 # pylint: disable=too-many-ancestors
 class RadioVersionTestCase(VersionTestCase):
     """Test the RadioVersion REST endpoint."""
 
-    unique_entry_name = 'radio_version'
+    unique_entry_name = "radio_version"
     unique_entries = Dummy.RADIO_VERSIONS
-    endpoint_url = reverse('hiccup_stats_api_v1_radio_versions')
+    endpoint_url = reverse("hiccup_stats_api_v1_radio_versions")
 
     @staticmethod
     def _create_dummy_version(**kwargs):
@@ -415,7 +457,7 @@
 class VersionDailyTestCase(_VersionTestCase):
     """Test the VersionDaily REST endpoint."""
 
-    endpoint_url = reverse('hiccup_stats_api_v1_version_daily')
+    endpoint_url = reverse("hiccup_stats_api_v1_version_daily")
 
     @staticmethod
     def _create_dummy_daily_version(version, **kwargs):
@@ -423,9 +465,7 @@
 
     def _create_version_entities(self):
         versions = [
-            self._create_dummy_version(
-                **{self.unique_entry_name: unique_entry}
-            )
+            self._create_dummy_version(**{self.unique_entry_name: unique_entry})
             for unique_entry in self.unique_entries
         ]
         versions_daily = [
@@ -464,12 +504,13 @@
         self._assert_result_length_is(response, len(versions))
 
         # List entities with filter
-        param_name = 'version__' + self.unique_entry_name
+        param_name = "version__" + self.unique_entry_name
         filter_params = {
             param_name: getattr(versions[0].version, self.unique_entry_name)
         }
-        self._assert_filter_result_matches(filter_params,
-                                           expected_result=versions[0].version)
+        self._assert_filter_result_matches(
+            filter_params, expected_result=versions[0].version
+        )
 
     def test_filter_daily_versions_by_date(self):
         """Test filtering daily versions by date."""
@@ -485,22 +526,26 @@
         self._assert_result_length_is(response, len(versions))
 
         # Expect the single matching result to be returned
-        filter_params = {'date': versions[0].date}
-        self._assert_filter_result_matches(filter_params,
-                                           expected_result=versions[0].version)
+        filter_params = {"date": versions[0].date}
+        self._assert_filter_result_matches(
+            filter_params, expected_result=versions[0].version
+        )
 
 
 class RadioVersionDailyTestCase(VersionDailyTestCase):
     """Test the RadioVersionDaily REST endpoint."""
 
-    unique_entry_name = 'radio_version'
+    unique_entry_name = "radio_version"
     unique_entries = Dummy.RADIO_VERSIONS
-    endpoint_url = reverse('hiccup_stats_api_v1_radio_version_daily')
+    endpoint_url = reverse("hiccup_stats_api_v1_radio_version_daily")
 
     @staticmethod
     def _create_dummy_version(**kwargs):
-        entity = RadioVersion(**Dummy.update_copy(
-            Dummy.DEFAULT_DUMMY_RADIO_VERSION_VALUES, kwargs))
+        entity = RadioVersion(
+            **Dummy.update_copy(
+                Dummy.DEFAULT_DUMMY_RADIO_VERSION_VALUES, kwargs
+            )
+        )
         entity.save()
         return entity
 
@@ -523,20 +568,21 @@
     version_class = Version
     # The attribute name characterising the unicity of a stats entry (the
     # named identifier)
-    unique_entry_name = 'build_fingerprint'
+    unique_entry_name = "build_fingerprint"
     # The collection of unique entries to post
     unique_entries = Dummy.BUILD_FINGERPRINTS
 
-    def _create_reports(self, report_type, unique_entry_name, device,
-                        number, **kwargs):
+    def _create_reports(
+        self, report_type, unique_entry_name, device, number, **kwargs
+    ):
         # Create reports with distinct timestamps
         now = datetime.now(pytz.utc)
         for i in range(number):
             report_date = now - timedelta(milliseconds=i)
             report_attributes = {
                 self.unique_entry_name: unique_entry_name,
-                'device': device,
-                'date': report_date
+                "device": device,
+                "date": report_date,
             }
             report_attributes.update(**kwargs)
             Dummy.create_dummy_report(report_type, **report_attributes)
@@ -551,11 +597,14 @@
         get_params = {
             self.unique_entry_name: getattr(heartbeat, self.unique_entry_name)
         }
-        self.assertRaises(self.version_class.DoesNotExist,
-                          self.version_class.objects.get, **get_params)
+        self.assertRaises(
+            self.version_class.DoesNotExist,
+            self.version_class.objects.get,
+            **get_params
+        )
 
         # Run the command to update the database
-        call_command('stats', 'update')
+        call_command("stats", "update")
 
         # Assume that a corresponding Version instance has been created
         version = self.version_class.objects.get(**get_params)
@@ -568,7 +617,7 @@
         report = Dummy.create_dummy_report(report_type, device=device)
 
         # Run the command to update the database
-        call_command('stats', 'update')
+        call_command("stats", "update")
 
         get_params = {
             self.unique_entry_name: getattr(report, self.unique_entry_name)
@@ -579,11 +628,12 @@
 
         # Create a new report from an earlier point in time
         report_time_2 = report.date - timedelta(weeks=1)
-        Dummy.create_dummy_report(report_type, device=device,
-                                  date=report_time_2)
+        Dummy.create_dummy_report(
+            report_type, device=device, date=report_time_2
+        )
 
         # Run the command to update the database
-        call_command('stats', 'update')
+        call_command("stats", "update")
 
         # Get the same version object from before
         version = self.version_class.objects.get(**get_params)
@@ -608,34 +658,37 @@
             self._create_reports(HeartBeat, unique_entry, device, 10)
 
         # Run the command to update the database
-        call_command('stats', 'update')
+        call_command("stats", "update")
 
         # Check whether the correct amount of distinct versions have been
         # created
         versions = self.version_class.objects.all()
         for version in versions:
-            self.assertIn(getattr(version, self.unique_entry_name),
-                          self.unique_entries)
+            self.assertIn(
+                getattr(version, self.unique_entry_name), self.unique_entries
+            )
         self.assertEqual(len(versions), len(self.unique_entries))
 
-    def _assert_counter_distribution_is_correct(self, report_type, numbers,
-                                                counter_attribute_name,
-                                                **kwargs):
+    def _assert_counter_distribution_is_correct(
+        self, report_type, numbers, counter_attribute_name, **kwargs
+    ):
         """Validate a counter distribution in the database."""
         if len(numbers) != len(self.unique_entries):
-            raise ValueError('The length of the numbers list must match the '
-                             'length of self.unique_entries in the test class'
-                             '({} != {})'.format(len(numbers),
-                                                 len(self.unique_entries)))
+            raise ValueError(
+                "The length of the numbers list must match the "
+                "length of self.unique_entries in the test class"
+                "({} != {})".format(len(numbers), len(self.unique_entries))
+            )
         # Create some reports
         user = Dummy.create_dummy_user()
         device = Dummy.create_dummy_device(user=user)
         for unique_entry, num in zip(self.unique_entries, numbers):
-            self._create_reports(report_type, unique_entry, device, num,
-                                 **kwargs)
+            self._create_reports(
+                report_type, unique_entry, device, num, **kwargs
+            )
 
         # Run the command to update the database
-        call_command('stats', 'update')
+        call_command("stats", "update")
 
         # Check whether the numbers of reports match
         for version in self.version_class.objects.all():
@@ -646,50 +699,52 @@
     def test_heartbeats_counter(self):
         """Test the calculation of the heartbeats counter."""
         numbers = [10, 7, 8, 5]
-        counter_attribute_name = 'heartbeats'
-        self._assert_counter_distribution_is_correct(HeartBeat, numbers,
-                                                     counter_attribute_name)
+        counter_attribute_name = "heartbeats"
+        self._assert_counter_distribution_is_correct(
+            HeartBeat, numbers, counter_attribute_name
+        )
 
     def test_crash_reports_counter(self):
         """Test the calculation of the crashreports counter."""
         numbers = [2, 5, 0, 3]
-        counter_attribute_name = 'prob_crashes'
-        boot_reason_param = {'boot_reason': Crashreport.BOOT_REASON_UNKOWN}
-        self._assert_counter_distribution_is_correct(Crashreport, numbers,
-                                                     counter_attribute_name,
-                                                     **boot_reason_param)
+        counter_attribute_name = "prob_crashes"
+        boot_reason_param = {"boot_reason": Crashreport.BOOT_REASON_UNKOWN}
+        self._assert_counter_distribution_is_correct(
+            Crashreport, numbers, counter_attribute_name, **boot_reason_param
+        )
 
     def test_smpl_reports_counter(self):
         """Test the calculation of the smpl reports counter."""
         numbers = [1, 3, 4, 0]
-        counter_attribute_name = 'smpl'
-        boot_reason_param = {'boot_reason': Crashreport.BOOT_REASON_RTC_ALARM}
-        self._assert_counter_distribution_is_correct(Crashreport, numbers,
-                                                     counter_attribute_name,
-                                                     **boot_reason_param)
+        counter_attribute_name = "smpl"
+        boot_reason_param = {"boot_reason": Crashreport.BOOT_REASON_RTC_ALARM}
+        self._assert_counter_distribution_is_correct(
+            Crashreport, numbers, counter_attribute_name, **boot_reason_param
+        )
 
     def test_other_reports_counter(self):
         """Test the calculation of the other reports counter."""
         numbers = [0, 2, 1, 2]
-        counter_attribute_name = 'other'
-        boot_reason_param = {'boot_reason': "random boot reason"}
-        self._assert_counter_distribution_is_correct(Crashreport, numbers,
-                                                     counter_attribute_name,
-                                                     **boot_reason_param)
+        counter_attribute_name = "other"
+        boot_reason_param = {"boot_reason": "random boot reason"}
+        self._assert_counter_distribution_is_correct(
+            Crashreport, numbers, counter_attribute_name, **boot_reason_param
+        )
 
-    def _assert_duplicates_are_ignored(self, report_type, device,
-                                       counter_attribute_name, **kwargs):
+    def _assert_duplicates_are_ignored(
+        self, report_type, device, counter_attribute_name, **kwargs
+    ):
         """Validate that reports with duplicate timestamps are ignored."""
         # Create a report
-        report = Dummy.create_dummy_report(report_type, device=device,
-                                           **kwargs)
+        report = Dummy.create_dummy_report(report_type, device=device, **kwargs)
 
         # Create a second report with the same timestamp
-        Dummy.create_dummy_report(report_type, device=device,
-                                  date=report.date, **kwargs)
+        Dummy.create_dummy_report(
+            report_type, device=device, date=report.date, **kwargs
+        )
 
         # Run the command to update the database
-        call_command('stats', 'update')
+        call_command("stats", "update")
 
         # Get the corresponding version instance from the database
         get_params = {
@@ -703,41 +758,46 @@
 
     def test_heartbeat_duplicates_are_ignored(self):
         """Validate that heartbeat duplicates are ignored."""
-        counter_attribute_name = 'heartbeats'
+        counter_attribute_name = "heartbeats"
         device = Dummy.create_dummy_device(user=Dummy.create_dummy_user())
-        self._assert_duplicates_are_ignored(HeartBeat, device,
-                                            counter_attribute_name)
+        self._assert_duplicates_are_ignored(
+            HeartBeat, device, counter_attribute_name
+        )
 
     def test_crash_report_duplicates_are_ignored(self):
         """Validate that crash report duplicates are ignored."""
-        counter_attribute_name = 'prob_crashes'
+        counter_attribute_name = "prob_crashes"
         device = Dummy.create_dummy_device(user=Dummy.create_dummy_user())
         for i, boot_reason in enumerate(Crashreport.CRASH_BOOT_REASONS):
-            params = {'boot_reason': boot_reason,
-                      self.unique_entry_name: self.unique_entries[i]}
-            self._assert_duplicates_are_ignored(Crashreport, device,
-                                                counter_attribute_name,
-                                                **params)
+            params = {
+                "boot_reason": boot_reason,
+                self.unique_entry_name: self.unique_entries[i],
+            }
+            self._assert_duplicates_are_ignored(
+                Crashreport, device, counter_attribute_name, **params
+            )
 
     def test_smpl_report_duplicates_are_ignored(self):
         """Validate that smpl report duplicates are ignored."""
-        counter_attribute_name = 'smpl'
+        counter_attribute_name = "smpl"
         device = Dummy.create_dummy_device(user=Dummy.create_dummy_user())
         for i, boot_reason in enumerate(Crashreport.SMPL_BOOT_REASONS):
-            params = {'boot_reason': boot_reason,
-                      self.unique_entry_name: self.unique_entries[i]}
-            self._assert_duplicates_are_ignored(Crashreport, device,
-                                                counter_attribute_name,
-                                                **params)
+            params = {
+                "boot_reason": boot_reason,
+                self.unique_entry_name: self.unique_entries[i],
+            }
+            self._assert_duplicates_are_ignored(
+                Crashreport, device, counter_attribute_name, **params
+            )
 
     def test_other_report_duplicates_are_ignored(self):
         """Validate that other report duplicates are ignored."""
-        counter_attribute_name = 'other'
-        params = {'boot_reason': 'random boot reason'}
+        counter_attribute_name = "other"
+        params = {"boot_reason": "random boot reason"}
         device = Dummy.create_dummy_device(user=Dummy.create_dummy_user())
-        self._assert_duplicates_are_ignored(Crashreport, device,
-                                            counter_attribute_name,
-                                            **params)
+        self._assert_duplicates_are_ignored(
+            Crashreport, device, counter_attribute_name, **params
+        )
 
 
 # pylint: disable=too-many-ancestors
@@ -745,7 +805,7 @@
     """Test the generation of RadioVersion stats with the stats command."""
 
     version_class = RadioVersion
-    unique_entry_name = 'radio_version'
+    unique_entry_name = "radio_version"
     unique_entries = Dummy.RADIO_VERSIONS
 
 
@@ -753,17 +813,14 @@
     """Test the reset and update commands debug output."""
 
     # Additional positional arguments to pass to the commands
-    _CMD_ARGS = [
-        '--no-color',
-        '-v 2',
-    ]
+    _CMD_ARGS = ["--no-color", "-v 2"]
 
     # The stats models
     _STATS_MODELS = [Version, VersionDaily, RadioVersion, RadioVersionDaily]
     # The models that will generate an output
     _ALL_MODELS = _STATS_MODELS + [StatsMetadata]
-    _COUNTER_NAMES = ['heartbeats', 'crashes', 'smpl', 'other']
-    _COUNTER_ACTIONS = ['created', 'updated']
+    _COUNTER_NAMES = ["heartbeats", "crashes", "smpl", "other"]
+    _COUNTER_ACTIONS = ["created", "updated"]
 
     def _assert_command_output_matches(self, command, number, facts, models):
         """Validate the debug output of a command.
@@ -772,38 +829,42 @@
         the parameters.
         """
         buffer = StringIO()
-        call_command('stats', command, *self._CMD_ARGS, stdout=buffer)
+        call_command("stats", command, *self._CMD_ARGS, stdout=buffer)
         output = buffer.getvalue().splitlines()
 
-        expected_output = '{number} {model} {fact}'
+        expected_output = "{number} {model} {fact}"
         for model in models:
             for fact in facts:
                 self.assertIn(
-                    expected_output.format(number=number,
-                                           model=model.__name__,
-                                           fact=fact),
-                    output)
+                    expected_output.format(
+                        number=number, model=model.__name__, fact=fact
+                    ),
+                    output,
+                )
 
     def test_reset_command_on_empty_db(self):
         """Test the reset command on an empty database.
 
         The reset command should yield nothing on an empty database.
         """
-        self._assert_command_output_matches('reset', 0, ['deleted'],
-                                            self._ALL_MODELS)
+        self._assert_command_output_matches(
+            "reset", 0, ["deleted"], self._ALL_MODELS
+        )
 
     def test_update_command_on_empty_db(self):
         """Test the update command on an empty database.
 
         The update command should yield nothing on an empty database.
         """
-        pattern = '{action} for counter {counter}'
+        pattern = "{action} for counter {counter}"
         facts = [
             pattern.format(action=counter_action, counter=counter_name)
             for counter_action in self._COUNTER_ACTIONS
-            for counter_name in self._COUNTER_NAMES]
-        self._assert_command_output_matches('update', 0, facts,
-                                            self._STATS_MODELS)
+            for counter_name in self._COUNTER_NAMES
+        ]
+        self._assert_command_output_matches(
+            "update", 0, facts, self._STATS_MODELS
+        )
 
     def test_reset_command_deletion_of_instances(self):
         """Test the deletion of stats model instances with the reset command.
@@ -820,5 +881,6 @@
         Dummy.create_dummy_stats_metadata()
 
         # We expect that the model instances get deleted
-        self._assert_command_output_matches('reset', 1, ['deleted'],
-                                            self._ALL_MODELS)
+        self._assert_command_output_matches(
+            "reset", 1, ["deleted"], self._ALL_MODELS
+        )
diff --git a/crashreport_stats/urls.py b/crashreport_stats/urls.py
index 54c70db..cedbd73 100644
--- a/crashreport_stats/urls.py
+++ b/crashreport_stats/urls.py
@@ -4,46 +4,57 @@
 
 
 urlpatterns = [
-    url(r'^device/$',
-        views.device_stats,
-        name='hiccup_stats_device'),
-    url(r'^$',
-        views.home,
-        name='device'),
-    url(r'^versions/$',
-        views.versions_overview,
-        name='hiccup_stats_versions'),
-    url(r'^versions/all/$',
+    url(r"^device/$", views.device_stats, name="hiccup_stats_device"),
+    url(r"^$", views.home, name="device"),
+    url(r"^versions/$", views.versions_overview, name="hiccup_stats_versions"),
+    url(
+        r"^versions/all/$",
         views.versions_all_overview,
-        name='hiccup_stats_versions_all'),
-    url(r'^api/v1/device_overview/(?P<uuid>[a-f0-9-]+)/$',
+        name="hiccup_stats_versions_all",
+    ),
+    url(
+        r"^api/v1/device_overview/(?P<uuid>[a-f0-9-]+)/$",
         rest_endpoints.DeviceStat.as_view(),
-        name='hiccup_stats_api_v1_device_overview'),
-    url(r'^api/v1/status/$',
+        name="hiccup_stats_api_v1_device_overview",
+    ),
+    url(
+        r"^api/v1/status/$",
         rest_endpoints.Status.as_view(),
-        name='hiccup_stats_api_v1_status'),
-    url(r'^api/v1/device_update_history/(?P<uuid>[a-f0-9-]+)/$',
+        name="hiccup_stats_api_v1_status",
+    ),
+    url(
+        r"^api/v1/device_update_history/(?P<uuid>[a-f0-9-]+)/$",
         rest_endpoints.DeviceUpdateHistory.as_view(),
-        name='hiccup_stats_api_v1_device_update_history'),
-    url(r'^api/v1/device_report_history/(?P<uuid>[a-f0-9-]+)/$',
+        name="hiccup_stats_api_v1_device_update_history",
+    ),
+    url(
+        r"^api/v1/device_report_history/(?P<uuid>[a-f0-9-]+)/$",
         rest_endpoints.DeviceReportHistory.as_view(),
-        name='hiccup_stats_api_v1_device_report_history'),
-
-    url(r'^api/v1/logfile_download/(?P<id>[0-9]+)/$',
+        name="hiccup_stats_api_v1_device_report_history",
+    ),
+    url(
+        r"^api/v1/logfile_download/(?P<id>[0-9]+)/$",
         rest_endpoints.LogFileDownload.as_view(),
-        name='hiccup_stats_api_v1_logfile_download'),
-
-    url(r'^api/v1/versions/$',
+        name="hiccup_stats_api_v1_logfile_download",
+    ),
+    url(
+        r"^api/v1/versions/$",
         rest_endpoints.VersionListView.as_view(),
-        name='hiccup_stats_api_v1_versions'),
-    url(r'^api/v1/version_daily/$',
+        name="hiccup_stats_api_v1_versions",
+    ),
+    url(
+        r"^api/v1/version_daily/$",
         rest_endpoints.VersionDailyListView.as_view(),
-        name='hiccup_stats_api_v1_version_daily'),
-
-    url(r'^api/v1/radio_versions/$',
+        name="hiccup_stats_api_v1_version_daily",
+    ),
+    url(
+        r"^api/v1/radio_versions/$",
         rest_endpoints.RadioVersionListView.as_view(),
-        name='hiccup_stats_api_v1_radio_versions'),
-    url(r'^api/v1/radio_version_daily/$',
+        name="hiccup_stats_api_v1_radio_versions",
+    ),
+    url(
+        r"^api/v1/radio_version_daily/$",
         rest_endpoints.RadioVersionDailyListView.as_view(),
-        name='hiccup_stats_api_v1_radio_version_daily'),
+        name="hiccup_stats_api_v1_radio_version_daily",
+    ),
 ]
diff --git a/crashreport_stats/util.py b/crashreport_stats/util.py
index 316ab53..a2111f7 100644
--- a/crashreport_stats/util.py
+++ b/crashreport_stats/util.py
@@ -8,18 +8,19 @@
 
 from django.db import transaction
 
+
 def dictfetchall(cursor):
     "Returns all rows from a cursor as a dict"
     desc = cursor.description
     return [
-        dict(zip([col[0] for col in desc], row))
-        for row in cursor.fetchall()
+        dict(zip([col[0] for col in desc], row)) for row in cursor.fetchall()
     ]
 
+
 @transaction.atomic
 def fill_version_data():
     myModels.Version.objects.all().delete()
-    query = '''
+    query = """
         SELECT fingerprint as build_fingerprint,
         ( select count(id) from crashreports_crashreport where boot_reason in ("RTC alarm")  and crashreports_crashreport.build_fingerprint = fingerprint) as SMPL,
         ( select count(id) from crashreports_crashreport where boot_reason in ("UNKNOWN", "keyboard power on")  and crashreports_crashreport.build_fingerprint = fingerprint) as prob_crashes,
@@ -27,54 +28,61 @@
         ( select count(id) from crashreports_heartbeat where  crashreports_heartbeat.build_fingerprint = fingerprint) as heartbeats,
         ( select min(crashreports_heartbeat.created_at) from crashreports_heartbeat where  crashreports_heartbeat.build_fingerprint = fingerprint) as first_seen
         from  (select distinct(build_fingerprint) as fingerprint
-        from crashreports_heartbeat) group by fingerprint order by heartbeats;'''
+        from crashreports_heartbeat) group by fingerprint order by heartbeats;"""
     cursor = connection.cursor()
-    cursor.execute(query,[])
+    cursor.execute(query, [])
     desc = cursor.description
     for row in cursor.fetchall():
         i = dict(zip([col[0] for col in desc], row))
         version = myModels.Version(
-            build_fingerprint = i['build_fingerprint'],
-            first_seen_on = i['first_seen'].split()[0],
-            released_on = i['first_seen'].split()[0],
-            heartbeats= i['heartbeats'],
-            prob_crashes = i['prob_crashes'],
-            smpl = i['SMPL'],
-            other = i['other']
+            build_fingerprint=i["build_fingerprint"],
+            first_seen_on=i["first_seen"].split()[0],
+            released_on=i["first_seen"].split()[0],
+            heartbeats=i["heartbeats"],
+            prob_crashes=i["prob_crashes"],
+            smpl=i["SMPL"],
+            other=i["other"],
         )
         version.save()
 
+
 @transaction.atomic
 def fill_version_daily_data():
     myModels.VersionDaily.objects.all().delete()
-    query = '''
+    query = """
         SELECT build_fingerprint, count(id) as heartbeats,
         strftime("%%Y-%%m-%%d",crashreports_heartbeat.date) as date,
         ( select count(id) from crashreports_crashreport where boot_reason in ("RTC alarm")  and crashreports_crashreport.build_fingerprint = crashreports_heartbeat.build_fingerprint and  crashreports_crashreport.date >= %s and  crashreports_crashreport.date < %s) as SMPL,
         ( select count(id) from crashreports_crashreport where boot_reason in ("UNKNOWN", "keyboard power on")  and crashreports_crashreport.build_fingerprint =  crashreports_heartbeat.build_fingerprint and crashreports_crashreport.date >= %s and  crashreports_crashreport.date < %s) as prob_crashes,
         ( select count(id) from crashreports_crashreport where boot_reason not in ("RTC alarm", "UNKNOWN", "keyboard power on")  and crashreports_crashreport.build_fingerprint =  crashreports_heartbeat.build_fingerprint and crashreports_crashreport.date >= %s and  crashreports_crashreport.date < %s) as other
          from crashreports_heartbeat where  crashreports_heartbeat.date >= %s and  crashreports_heartbeat.date < %s
-         group by build_fingerprint'''
+         group by build_fingerprint"""
     start = date(2016, 8, 1)
-    end   = date.today() + timedelta(days=5)
+    end = date.today() + timedelta(days=5)
     delta = end - start
     for d in range(delta.days + 1):
         day = start + timedelta(days=d)
         print("Getting Stats for " + str(day))
         cursor = connection.cursor()
-        cursor.execute(query,[str(day), str(day+timedelta(days=1))]*4)
+        cursor.execute(query, [str(day), str(day + timedelta(days=1))] * 4)
         desc = cursor.description
         for row in cursor.fetchall():
             i = dict(zip([col[0] for col in desc], row))
             try:
                 version_daily = myModels.VersionDaily(
-                    version = myModels.Version.objects.get(build_fingerprint=i['build_fingerprint']),
-                    heartbeats= i['heartbeats'],
+                    version=myModels.Version.objects.get(
+                        build_fingerprint=i["build_fingerprint"]
+                    ),
+                    heartbeats=i["heartbeats"],
                     date=day,
-                    prob_crashes = i['prob_crashes'],
-                    smpl = i['SMPL'],
-                    other = i['other']
+                    prob_crashes=i["prob_crashes"],
+                    smpl=i["SMPL"],
+                    other=i["other"],
                 )
             except:
-                print("Skipping entry for {} {}".format(i['build_fingerprint'],day))
+                print(
+                    "Skipping entry for {} {}".format(
+                        i["build_fingerprint"], day
+                    )
+                )
             version_daily.save()
diff --git a/crashreport_stats/views.py b/crashreport_stats/views.py
index 9ec7dc6..54a67e7 100644
--- a/crashreport_stats/views.py
+++ b/crashreport_stats/views.py
@@ -1,5 +1,5 @@
 from crashreports.models import *
-from django.http import HttpResponse,Http404,HttpResponseRedirect
+from django.http import HttpResponse, Http404, HttpResponseRedirect
 from django.shortcuts import render
 from django.shortcuts import render_to_response
 from django.template import loader
@@ -11,53 +11,62 @@
 from django.contrib import messages
 from django.urls import reverse
 
+
 def is_fairphone_staff(user):
-    return user.groups.filter(name='FairphoneSoftwareTeam').exists()
+    return user.groups.filter(name="FairphoneSoftwareTeam").exists()
 
 
 class DeviceUUIDForm(forms.Form):
-    uuid = forms.CharField(label='Device UUID:', max_length=100)
+    uuid = forms.CharField(label="Device UUID:", max_length=100)
+
 
 @user_passes_test(is_fairphone_staff)
 def device_stats(request):
-    template = loader.get_template('crashreport_stats/device.html')
-    uuid = request.GET.get('uuid', "NO_UUID")
+    template = loader.get_template("crashreport_stats/device.html")
+    uuid = request.GET.get("uuid", "NO_UUID")
     if not Device.objects.filter(uuid=uuid).exists():
         raise Http404("Device doesn't exist.")
-    return HttpResponse(template.render({'uuid':uuid}, request))
+    return HttpResponse(template.render({"uuid": uuid}, request))
+
 
 @user_passes_test(is_fairphone_staff)
 def versions_all_overview(request):
-    template = loader.get_template('crashreport_stats/versions.html')
-    return HttpResponse(template.render({"is_official_release":"1"}, request))
+    template = loader.get_template("crashreport_stats/versions.html")
+    return HttpResponse(template.render({"is_official_release": "1"}, request))
+
 
 @user_passes_test(is_fairphone_staff)
 def versions_overview(request):
-    template = loader.get_template('crashreport_stats/versions.html')
-    return HttpResponse(template.render({"is_official_release":"2"}, request))
+    template = loader.get_template("crashreport_stats/versions.html")
+    return HttpResponse(template.render({"is_official_release": "2"}, request))
+
 
 @user_passes_test(is_fairphone_staff)
 def home(request):
     """ The home view allows to search for devices. """
     devices = None
-    if request.method == 'POST':
+    if request.method == "POST":
         # create a form instance and populate it with data from the request:
         form = DeviceUUIDForm(request.POST)
         if form.is_valid():
-            uuid = form.cleaned_data['uuid']
+            uuid = form.cleaned_data["uuid"]
             if not Device.objects.filter(uuid=uuid).exists():
                 devices = Device.objects.filter(uuid__startswith=uuid)
-                if len(devices)==1:
+                if len(devices) == 1:
                     return HttpResponseRedirect(
-                        reverse("hiccup_stats_device")+'?uuid='+devices[0].uuid)
-                elif len(devices)==0:
-                     messages.warning(request, "No devices found.")
+                        reverse("hiccup_stats_device")
+                        + "?uuid="
+                        + devices[0].uuid
+                    )
+                elif len(devices) == 0:
+                    messages.warning(request, "No devices found.")
             else:
                 return HttpResponseRedirect(
-                    reverse("hiccup_stats_device")+'?uuid='+uuid)
+                    reverse("hiccup_stats_device") + "?uuid=" + uuid
+                )
     else:
         form = DeviceUUIDForm()
-    template = loader.get_template('crashreport_stats/home.html')
-    return HttpResponse(template.render(
-        {'form':form, 'devices':devices}
-        , request))
+    template = loader.get_template("crashreport_stats/home.html")
+    return HttpResponse(
+        template.render({"form": form, "devices": devices}, request)
+    )
diff --git a/crashreports/admin.py b/crashreports/admin.py
index 7133070..97b32e0 100644
--- a/crashreports/admin.py
+++ b/crashreports/admin.py
@@ -8,15 +8,18 @@
 @admin.register(Crashreport)
 class CrashreportAdmin(admin.ModelAdmin):
     pass
-    
+
+
 @admin.register(HeartBeat)
 class CrashreportAdmin(admin.ModelAdmin):
     pass
 
+
 @admin.register(LogFile)
 class CrashreportAdmin(admin.ModelAdmin):
     pass
 
+
 @admin.register(Device)
 class CrashreportAdmin(admin.ModelAdmin):
     pass
diff --git a/crashreports/apps.py b/crashreports/apps.py
index d651203..dacae51 100644
--- a/crashreports/apps.py
+++ b/crashreports/apps.py
@@ -4,4 +4,4 @@
 
 
 class crashreportsConfig(AppConfig):
-    name = 'crashreports'
+    name = "crashreports"
diff --git a/crashreports/migrations/0001_initial.py b/crashreports/migrations/0001_initial.py
index effb757..4542b4b 100644
--- a/crashreports/migrations/0001_initial.py
+++ b/crashreports/migrations/0001_initial.py
@@ -16,75 +16,179 @@
 
     dependencies = [
         migrations.swappable_dependency(settings.AUTH_USER_MODEL),
-        ('taggit', '0002_auto_20150616_2121'),
+        ("taggit", "0002_auto_20150616_2121"),
     ]
 
     operations = [
         migrations.CreateModel(
-            name='Crashreport',
+            name="Crashreport",
             fields=[
-                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
-                ('is_fake_report', models.BooleanField(default=False)),
-                ('app_version', models.IntegerField()),
-                ('uptime', models.CharField(max_length=200)),
-                ('build_fingerprint', models.CharField(max_length=200)),
-                ('boot_reason', models.CharField(max_length=200)),
-                ('power_on_reason', models.CharField(max_length=200)),
-                ('power_off_reason', models.CharField(max_length=200)),
-                ('date', models.DateTimeField()),
-                ('device_local_id', models.PositiveIntegerField(blank=True)),
-                ('next_logfile_key', models.PositiveIntegerField(default=1)),
-                ('created_at', models.DateTimeField(auto_now_add=True)),
+                (
+                    "id",
+                    models.AutoField(
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        verbose_name="ID",
+                    ),
+                ),
+                ("is_fake_report", models.BooleanField(default=False)),
+                ("app_version", models.IntegerField()),
+                ("uptime", models.CharField(max_length=200)),
+                ("build_fingerprint", models.CharField(max_length=200)),
+                ("boot_reason", models.CharField(max_length=200)),
+                ("power_on_reason", models.CharField(max_length=200)),
+                ("power_off_reason", models.CharField(max_length=200)),
+                ("date", models.DateTimeField()),
+                ("device_local_id", models.PositiveIntegerField(blank=True)),
+                ("next_logfile_key", models.PositiveIntegerField(default=1)),
+                ("created_at", models.DateTimeField(auto_now_add=True)),
             ],
         ),
         migrations.CreateModel(
-            name='Device',
+            name="Device",
             fields=[
-                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
-                ('uuid', models.CharField(default=uuid.uuid4, editable=False, max_length=64, unique=True)),
-                ('imei', models.CharField(blank=True, max_length=32, null=True)),
-                ('board_date', models.DateTimeField(blank=True, null=True)),
-                ('chipset', models.CharField(blank=True, max_length=200, null=True)),
-                ('last_heartbeat', models.DateTimeField(blank=True, null=True)),
-                ('token', models.CharField(blank=True, max_length=200, null=True)),
-                ('next_per_crashreport_key', models.PositiveIntegerField(default=1)),
-                ('next_per_heartbeat_key', models.PositiveIntegerField(default=1)),
-                ('tags', taggit.managers.TaggableManager(blank=True, help_text='A comma-separated list of tags.', through='taggit.TaggedItem', to='taggit.Tag', verbose_name='Tags')),
-                ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='Hiccup_Device', to=settings.AUTH_USER_MODEL)),
+                (
+                    "id",
+                    models.AutoField(
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        verbose_name="ID",
+                    ),
+                ),
+                (
+                    "uuid",
+                    models.CharField(
+                        default=uuid.uuid4,
+                        editable=False,
+                        max_length=64,
+                        unique=True,
+                    ),
+                ),
+                (
+                    "imei",
+                    models.CharField(blank=True, max_length=32, null=True),
+                ),
+                ("board_date", models.DateTimeField(blank=True, null=True)),
+                (
+                    "chipset",
+                    models.CharField(blank=True, max_length=200, null=True),
+                ),
+                ("last_heartbeat", models.DateTimeField(blank=True, null=True)),
+                (
+                    "token",
+                    models.CharField(blank=True, max_length=200, null=True),
+                ),
+                (
+                    "next_per_crashreport_key",
+                    models.PositiveIntegerField(default=1),
+                ),
+                (
+                    "next_per_heartbeat_key",
+                    models.PositiveIntegerField(default=1),
+                ),
+                (
+                    "tags",
+                    taggit.managers.TaggableManager(
+                        blank=True,
+                        help_text="A comma-separated list of tags.",
+                        through="taggit.TaggedItem",
+                        to="taggit.Tag",
+                        verbose_name="Tags",
+                    ),
+                ),
+                (
+                    "user",
+                    models.OneToOneField(
+                        on_delete=django.db.models.deletion.CASCADE,
+                        related_name="Hiccup_Device",
+                        to=settings.AUTH_USER_MODEL,
+                    ),
+                ),
             ],
         ),
         migrations.CreateModel(
-            name='HeartBeat',
+            name="HeartBeat",
             fields=[
-                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
-                ('app_version', models.IntegerField()),
-                ('uptime', models.CharField(max_length=200)),
-                ('build_fingerprint', models.CharField(max_length=200)),
-                ('date', models.DateTimeField()),
-                ('device_local_id', models.PositiveIntegerField(blank=True)),
-                ('created_at', models.DateTimeField(auto_now_add=True)),
-                ('device', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='crashreports.Device')),
+                (
+                    "id",
+                    models.AutoField(
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        verbose_name="ID",
+                    ),
+                ),
+                ("app_version", models.IntegerField()),
+                ("uptime", models.CharField(max_length=200)),
+                ("build_fingerprint", models.CharField(max_length=200)),
+                ("date", models.DateTimeField()),
+                ("device_local_id", models.PositiveIntegerField(blank=True)),
+                ("created_at", models.DateTimeField(auto_now_add=True)),
+                (
+                    "device",
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.CASCADE,
+                        to="crashreports.Device",
+                    ),
+                ),
             ],
         ),
         migrations.CreateModel(
-            name='LogFile',
+            name="LogFile",
             fields=[
-                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
-                ('logfile_type', models.TextField(default='last_kmsg', max_length=36)),
-                ('logfile', models.FileField(max_length=500, upload_to=crashreports.models.crashreport_file_name)),
-                ('crashreport_local_id', models.PositiveIntegerField(blank=True)),
-                ('created_at', models.DateTimeField(auto_now_add=True)),
-                ('crashreport', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='crashreports.Crashreport')),
+                (
+                    "id",
+                    models.AutoField(
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        verbose_name="ID",
+                    ),
+                ),
+                (
+                    "logfile_type",
+                    models.TextField(default="last_kmsg", max_length=36),
+                ),
+                (
+                    "logfile",
+                    models.FileField(
+                        max_length=500,
+                        upload_to=crashreports.models.crashreport_file_name,
+                    ),
+                ),
+                (
+                    "crashreport_local_id",
+                    models.PositiveIntegerField(blank=True),
+                ),
+                ("created_at", models.DateTimeField(auto_now_add=True)),
+                (
+                    "crashreport",
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.CASCADE,
+                        to="crashreports.Crashreport",
+                    ),
+                ),
             ],
         ),
         migrations.AddField(
-            model_name='crashreport',
-            name='device',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='crashreports.Device'),
+            model_name="crashreport",
+            name="device",
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.CASCADE,
+                to="crashreports.Device",
+            ),
         ),
         migrations.AddField(
-            model_name='crashreport',
-            name='tags',
-            field=taggit.managers.TaggableManager(blank=True, help_text='A comma-separated list of tags.', through='taggit.TaggedItem', to='taggit.Tag', verbose_name='Tags'),
+            model_name="crashreport",
+            name="tags",
+            field=taggit.managers.TaggableManager(
+                blank=True,
+                help_text="A comma-separated list of tags.",
+                through="taggit.TaggedItem",
+                to="taggit.Tag",
+                verbose_name="Tags",
+            ),
         ),
     ]
diff --git a/crashreports/migrations/0002_auto_20170502_1155.py b/crashreports/migrations/0002_auto_20170502_1155.py
index 38ee8db..e6e520c 100644
--- a/crashreports/migrations/0002_auto_20170502_1155.py
+++ b/crashreports/migrations/0002_auto_20170502_1155.py
@@ -9,64 +9,80 @@
 
 class Migration(migrations.Migration):
 
-    dependencies = [
-        ('crashreports', '0001_initial'),
-    ]
+    dependencies = [("crashreports", "0001_initial")]
 
     operations = [
         migrations.AlterField(
-            model_name='crashreport',
-            name='boot_reason',
+            model_name="crashreport",
+            name="boot_reason",
             field=models.CharField(db_index=True, max_length=200),
         ),
         migrations.AlterField(
-            model_name='crashreport',
-            name='build_fingerprint',
+            model_name="crashreport",
+            name="build_fingerprint",
             field=models.CharField(db_index=True, max_length=200),
         ),
         migrations.AlterField(
-            model_name='crashreport',
-            name='date',
+            model_name="crashreport",
+            name="date",
             field=models.DateTimeField(db_index=True),
         ),
         migrations.AlterField(
-            model_name='crashreport',
-            name='device',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='crashreports', to='crashreports.Device'),
+            model_name="crashreport",
+            name="device",
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.CASCADE,
+                related_name="crashreports",
+                to="crashreports.Device",
+            ),
         ),
         migrations.AlterField(
-            model_name='crashreport',
-            name='power_off_reason',
+            model_name="crashreport",
+            name="power_off_reason",
             field=models.CharField(db_index=True, max_length=200),
         ),
         migrations.AlterField(
-            model_name='crashreport',
-            name='power_on_reason',
+            model_name="crashreport",
+            name="power_on_reason",
             field=models.CharField(db_index=True, max_length=200),
         ),
         migrations.AlterField(
-            model_name='device',
-            name='uuid',
-            field=models.CharField(db_index=True, default=uuid.uuid4, editable=False, max_length=64, unique=True),
+            model_name="device",
+            name="uuid",
+            field=models.CharField(
+                db_index=True,
+                default=uuid.uuid4,
+                editable=False,
+                max_length=64,
+                unique=True,
+            ),
         ),
         migrations.AlterField(
-            model_name='heartbeat',
-            name='build_fingerprint',
+            model_name="heartbeat",
+            name="build_fingerprint",
             field=models.CharField(db_index=True, max_length=200),
         ),
         migrations.AlterField(
-            model_name='heartbeat',
-            name='date',
+            model_name="heartbeat",
+            name="date",
             field=models.DateTimeField(db_index=True),
         ),
         migrations.AlterField(
-            model_name='heartbeat',
-            name='device',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='heartbeats', to='crashreports.Device'),
+            model_name="heartbeat",
+            name="device",
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.CASCADE,
+                related_name="heartbeats",
+                to="crashreports.Device",
+            ),
         ),
         migrations.AlterField(
-            model_name='logfile',
-            name='crashreport',
-            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='logfiles', to='crashreports.Crashreport'),
+            model_name="logfile",
+            name="crashreport",
+            field=models.ForeignKey(
+                on_delete=django.db.models.deletion.CASCADE,
+                related_name="logfiles",
+                to="crashreports.Crashreport",
+            ),
         ),
     ]
diff --git a/crashreports/migrations/0003_crashreport_and_heartbeat_with_radio_version.py b/crashreports/migrations/0003_crashreport_and_heartbeat_with_radio_version.py
index 564cc0e..403593e 100644
--- a/crashreports/migrations/0003_crashreport_and_heartbeat_with_radio_version.py
+++ b/crashreports/migrations/0003_crashreport_and_heartbeat_with_radio_version.py
@@ -8,19 +8,17 @@
 
 class Migration(migrations.Migration):
 
-    dependencies = [
-        ('crashreports', '0002_auto_20170502_1155'),
-    ]
+    dependencies = [("crashreports", "0002_auto_20170502_1155")]
 
     operations = [
         migrations.AddField(
-            model_name='crashreport',
-            name='radio_version',
+            model_name="crashreport",
+            name="radio_version",
             field=models.CharField(db_index=True, max_length=200, null=True),
         ),
         migrations.AddField(
-            model_name='heartbeat',
-            name='radio_version',
+            model_name="heartbeat",
+            name="radio_version",
             field=models.CharField(db_index=True, max_length=200, null=True),
         ),
     ]
diff --git a/crashreports/models.py b/crashreports/models.py
index 6bf6056..5120322 100644
--- a/crashreports/models.py
+++ b/crashreports/models.py
@@ -9,14 +9,23 @@
 
 
 class Device(models.Model):
-    def __str__( self ):
+    def __str__(self):
         return self.uuid
+
     # for every device there is a django user
-    uuid = models.CharField( db_index=True,max_length=64, unique=True,
-                            default=uuid.uuid4, editable=False)
+    uuid = models.CharField(
+        db_index=True,
+        max_length=64,
+        unique=True,
+        default=uuid.uuid4,
+        editable=False,
+    )
     user = models.OneToOneField(
-        User, related_name='Hiccup_Device', on_delete=models.CASCADE,
-        unique=True)
+        User,
+        related_name="Hiccup_Device",
+        on_delete=models.CASCADE,
+        unique=True,
+    )
     imei = models.CharField(max_length=32, null=True, blank=True)
     board_date = models.DateTimeField(null=True, blank=True)
     chipset = models.CharField(max_length=200, null=True, blank=True)
@@ -42,27 +51,30 @@
 
 
 def crashreport_file_name(instance, filename):
-    return '/'.join([
-        "crashreport_uploads",
-        instance.crashreport.device.uuid,
-        str(instance.crashreport.id),
-        str(instance.crashreport.date),
-        filename])
+    return "/".join(
+        [
+            "crashreport_uploads",
+            instance.crashreport.device.uuid,
+            str(instance.crashreport.id),
+            str(instance.crashreport.date),
+            filename,
+        ]
+    )
 
 
 class Crashreport(models.Model):
-    BOOT_REASON_UNKOWN = 'UNKNOWN'
-    BOOT_REASON_KEYBOARD_POWER_ON = 'keyboard power on'
-    BOOT_REASON_RTC_ALARM = 'RTC alarm'
-    CRASH_BOOT_REASONS = [
-        BOOT_REASON_UNKOWN,
-        BOOT_REASON_KEYBOARD_POWER_ON,
-    ]
-    SMPL_BOOT_REASONS = [
-        BOOT_REASON_RTC_ALARM,
-    ]
+    BOOT_REASON_UNKOWN = "UNKNOWN"
+    BOOT_REASON_KEYBOARD_POWER_ON = "keyboard power on"
+    BOOT_REASON_RTC_ALARM = "RTC alarm"
+    CRASH_BOOT_REASONS = [BOOT_REASON_UNKOWN, BOOT_REASON_KEYBOARD_POWER_ON]
+    SMPL_BOOT_REASONS = [BOOT_REASON_RTC_ALARM]
 
-    device = models.ForeignKey(Device, db_index=True, related_name='crashreports', on_delete=models.CASCADE)
+    device = models.ForeignKey(
+        Device,
+        db_index=True,
+        related_name="crashreports",
+        on_delete=models.CASCADE,
+    )
     is_fake_report = models.BooleanField(default=False)
     app_version = models.IntegerField()
     uptime = models.CharField(max_length=200)
@@ -92,12 +104,16 @@
     def _get_uuid(self):
         "Returns the person's full name."
         return self.device.uuid
+
     uuid = property(_get_uuid)
 
-#TODO remove logfile_type or make it meaningful
+
+# TODO remove logfile_type or make it meaningful
 class LogFile(models.Model):
     logfile_type = models.TextField(max_length=36, default="last_kmsg")
-    crashreport = models.ForeignKey(Crashreport,related_name='logfiles', on_delete=models.CASCADE)
+    crashreport = models.ForeignKey(
+        Crashreport, related_name="logfiles", on_delete=models.CASCADE
+    )
     logfile = models.FileField(upload_to=crashreport_file_name, max_length=500)
     crashreport_local_id = models.PositiveIntegerField(blank=True)
     created_at = models.DateTimeField(auto_now_add=True)
@@ -109,13 +125,15 @@
 
 
 class HeartBeat(models.Model):
-    device = models.ForeignKey(Device,
+    device = models.ForeignKey(
+        Device,
         db_index=True,
-        related_name='heartbeats',
-        on_delete=models.CASCADE)
+        related_name="heartbeats",
+        on_delete=models.CASCADE,
+    )
     app_version = models.IntegerField()
     uptime = models.CharField(max_length=200)
-    build_fingerprint = models.CharField( db_index=True, max_length=200)
+    build_fingerprint = models.CharField(db_index=True, max_length=200)
     radio_version = models.CharField(db_index=True, max_length=200, null=True)
     date = models.DateTimeField(db_index=True)
     device_local_id = models.PositiveIntegerField(blank=True)
@@ -129,4 +147,5 @@
     def _get_uuid(self):
         "Returns the person's full name."
         return self.device.uuid
+
     uuid = property(_get_uuid)
diff --git a/crashreports/permissions.py b/crashreports/permissions.py
index ff79149..c1efe79 100644
--- a/crashreports/permissions.py
+++ b/crashreports/permissions.py
@@ -7,42 +7,49 @@
         device = Device.objects.get(user=user)
     except:
         return False
-    if (uuid == device.uuid):
+    if uuid == device.uuid:
         return True
     return False
 
 
 def user_is_hiccup_staff(user):
-    if (user.groups.filter(name='FairphoneSoftwareTeam').exists()):
+    if user.groups.filter(name="FairphoneSoftwareTeam").exists():
         return True
     else:
-        return user.has_perms([
-            # Crashreports
-            'crashreports.add_crashreport', 'crashreports.change_crashreport',
-            'crashreports.del_crashreport',
-            # Heartbeats
-            'heartbeat.add_crashreport', 'heartbeat.change_crashreport',
-            'heartbeat.del_crashreport',
-            # Logfiles
-            'heartbeat.add_logfile', 'heartbeat.change_logfile',
-            'heartbeat.del_logfile',
-            ])
+        return user.has_perms(
+            [
+                # Crashreports
+                "crashreports.add_crashreport",
+                "crashreports.change_crashreport",
+                "crashreports.del_crashreport",
+                # Heartbeats
+                "heartbeat.add_crashreport",
+                "heartbeat.change_crashreport",
+                "heartbeat.del_crashreport",
+                # Logfiles
+                "heartbeat.add_logfile",
+                "heartbeat.change_logfile",
+                "heartbeat.del_logfile",
+            ]
+        )
+
 
 class HasStatsAccess(BasePermission):
     def has_permission(self, request, view):
         return user_is_hiccup_staff(request.user)
 
+
 class HasRightsOrIsDeviceOwnerDeviceCreation(BasePermission):
     def has_permission(self, request, view):
-        if (user_is_hiccup_staff(request.user)):
+        if user_is_hiccup_staff(request.user):
             return True
 
         # special case:
         # user is the owner of a device. in this case creations are allowed.
         # we have to check if the device with the supplied uuid indeed
         # belongs to the user
-        if request.method == 'POST':
-            if ('uuid' not in request.data):
+        if request.method == "POST":
+            if "uuid" not in request.data:
                 return False
             return user_owns_uuid(request.user, request.data["uuid"])
         return False
diff --git a/crashreports/rest_api_crashreports.py b/crashreports/rest_api_crashreports.py
index b6555fd..df99732 100644
--- a/crashreports/rest_api_crashreports.py
+++ b/crashreports/rest_api_crashreports.py
@@ -10,31 +10,32 @@
 class ListCreateView(generics.ListCreateAPIView):
     queryset = Crashreport.objects.all()
     paginate_by = 20
-    permission_classes = (HasRightsOrIsDeviceOwnerDeviceCreation, )
+    permission_classes = (HasRightsOrIsDeviceOwnerDeviceCreation,)
     serializer_class = CrashReportSerializer
-    filter_fields = ('device', 'build_fingerprint', 'radio_version')
+    filter_fields = ("device", "build_fingerprint", "radio_version")
 
     pass
 
     def dispatch(self, *args, **kwargs):
-        if 'uuid' in kwargs:
+        if "uuid" in kwargs:
             self.queryset = Crashreport.objects.filter(
-                device__uuid=kwargs['uuid'])
+                device__uuid=kwargs["uuid"]
+            )
         return generics.ListCreateAPIView.dispatch(self, *args, **kwargs)
 
     def perform_create(self, serializer):
         serializer.save()
         return Response(
-            {
-                'device_local_id': serializer.data['device_local_id']
-            },  status.HTTP_200_OK)
+            {"device_local_id": serializer.data["device_local_id"]},
+            status.HTTP_200_OK,
+        )
 
 
 class RetrieveUpdateDestroyView(generics.RetrieveUpdateDestroyAPIView):
     queryset = Crashreport.objects.all()
-    permission_classes = (HasRightsOrIsDeviceOwnerDeviceCreation, )
+    permission_classes = (HasRightsOrIsDeviceOwnerDeviceCreation,)
     serializer_class = CrashReportSerializer
-    multiple_lookup_fields = {'id', 'device__uuid', 'device_local_id'}
+    multiple_lookup_fields = {"id", "device__uuid", "device_local_id"}
 
     def get_object(self):
         queryset = self.get_queryset()
diff --git a/crashreports/rest_api_devices.py b/crashreports/rest_api_devices.py
index 17e0d77..96923b2 100644
--- a/crashreports/rest_api_devices.py
+++ b/crashreports/rest_api_devices.py
@@ -17,42 +17,64 @@
 from crashreports.response_descriptions import default_desc
 
 
-@method_decorator(name='get', decorator=swagger_auto_schema(
-    operation_description='List devices'))
-@method_decorator(name='post', decorator=swagger_auto_schema(
-    operation_description='Create a device',
-    responses=dict([default_desc(ValidationError)])))
+@method_decorator(
+    name="get",
+    decorator=swagger_auto_schema(operation_description="List devices"),
+)
+@method_decorator(
+    name="post",
+    decorator=swagger_auto_schema(
+        operation_description="Create a device",
+        responses=dict([default_desc(ValidationError)]),
+    ),
+)
 class ListCreateDevices(generics.ListCreateAPIView):
     """Endpoint for listing devices and creating new devices."""
 
     queryset = Device.objects.all()
     paginate_by = 20
-    permission_classes = (HasRightsOrIsDeviceOwnerDeviceCreation, )
+    permission_classes = (HasRightsOrIsDeviceOwnerDeviceCreation,)
     serializer_class = DeviceSerializer
-    filter_fields = ('uuid', 'board_date', 'chipset')
+    filter_fields = ("uuid", "board_date", "chipset")
 
 
-@method_decorator(name='get', decorator=swagger_auto_schema(
-    operation_description='Get a device',
-    responses=dict([default_desc(NotFound)])))
-@method_decorator(name='put', decorator=swagger_auto_schema(
-    operation_description='Update a device',
-    responses=dict([default_desc(NotFound), default_desc(ValidationError)])))
-@method_decorator(name='patch', decorator=swagger_auto_schema(
-    operation_description='Make a partial update for a device',
-    responses=dict([default_desc(NotFound), default_desc(ValidationError)])))
-@method_decorator(name='delete', decorator=swagger_auto_schema(
-    operation_description='Delete a device',
-    responses=dict([default_desc(NotFound)])))
+@method_decorator(
+    name="get",
+    decorator=swagger_auto_schema(
+        operation_description="Get a device",
+        responses=dict([default_desc(NotFound)]),
+    ),
+)
+@method_decorator(
+    name="put",
+    decorator=swagger_auto_schema(
+        operation_description="Update a device",
+        responses=dict([default_desc(NotFound), default_desc(ValidationError)]),
+    ),
+)
+@method_decorator(
+    name="patch",
+    decorator=swagger_auto_schema(
+        operation_description="Make a partial update for a device",
+        responses=dict([default_desc(NotFound), default_desc(ValidationError)]),
+    ),
+)
+@method_decorator(
+    name="delete",
+    decorator=swagger_auto_schema(
+        operation_description="Delete a device",
+        responses=dict([default_desc(NotFound)]),
+    ),
+)
 class RetrieveUpdateDestroyDevice(generics.RetrieveUpdateDestroyAPIView):
     """Endpoint for retrieving, updating, patching and deleting devices."""
 
     # pylint: disable=too-many-ancestors
 
     queryset = Device.objects.all()
-    permission_classes = (HasRightsOrIsDeviceOwnerDeviceCreation, )
+    permission_classes = (HasRightsOrIsDeviceOwnerDeviceCreation,)
     serializer_class = DeviceSerializer
-    lookup_field = 'uuid'
+    lookup_field = "uuid"
 
 
 class DeviceRegisterResponseSchema(DeviceSerializer):
@@ -60,19 +82,26 @@
 
     class Meta:  # noqa: D106
         model = Device
-        fields = ['uuid', 'token']
+        fields = ["uuid", "token"]
 
 
 @swagger_auto_schema(
-    method='post',
+    method="post",
     request_body=DeviceCreateSerializer,
-    responses=dict([
-        default_desc(ValidationError),
-        (status.HTTP_200_OK,
-         openapi.Response('The device has been successfully registered.',
-                          DeviceRegisterResponseSchema))
-    ]))
-@api_view(http_method_names=['POST'], )
+    responses=dict(
+        [
+            default_desc(ValidationError),
+            (
+                status.HTTP_200_OK,
+                openapi.Response(
+                    "The device has been successfully registered.",
+                    DeviceRegisterResponseSchema,
+                ),
+            ),
+        ]
+    ),
+)
+@api_view(http_method_names=["POST"])
 @permission_classes((AllowAny,))
 def register_device(request):
     """Register a new device.
@@ -84,13 +113,13 @@
     serializer = DeviceCreateSerializer(data=request.data)
     serializer.is_valid(raise_exception=True)
     device = Device()
-    user = User.objects.create_user("device_" + str(device.uuid), '', None)
-    permission = Permission.objects.get(name='Can add crashreport')
+    user = User.objects.create_user("device_" + str(device.uuid), "", None)
+    permission = Permission.objects.get(name="Can add crashreport")
     user.user_permissions.add(permission)
     user.save()
-    device.board_date = serializer.validated_data['board_date']
-    device.chipset = serializer.validated_data['chipset']
+    device.board_date = serializer.validated_data["board_date"]
+    device.chipset = serializer.validated_data["chipset"]
     device.user = user
     device.token = Token.objects.create(user=user).key
     device.save()
-    return Response({'uuid': device.uuid, 'token': device.token})
+    return Response({"uuid": device.uuid, "token": device.token})
diff --git a/crashreports/rest_api_heartbeats.py b/crashreports/rest_api_heartbeats.py
index 841dec8..f2e19db 100644
--- a/crashreports/rest_api_heartbeats.py
+++ b/crashreports/rest_api_heartbeats.py
@@ -11,23 +11,23 @@
 class ListCreateView(generics.ListCreateAPIView):
     queryset = HeartBeat.objects.all()
     paginate_by = 20
-    permission_classes = (HasRightsOrIsDeviceOwnerDeviceCreation, )
+    permission_classes = (HasRightsOrIsDeviceOwnerDeviceCreation,)
     serializer_class = HeartBeatSerializer
-    filter_fields = ('device', 'build_fingerprint', 'radio_version')
-
+    filter_fields = ("device", "build_fingerprint", "radio_version")
 
     def get(self, *args, **kwargs):
-        if 'uuid' in kwargs:
+        if "uuid" in kwargs:
             self.queryset = HeartBeat.objects.filter(
-                device__uuid=kwargs['uuid'])
+                device__uuid=kwargs["uuid"]
+            )
         return generics.ListCreateAPIView.get(self, *args, **kwargs)
 
 
 class RetrieveUpdateDestroyView(generics.RetrieveUpdateDestroyAPIView):
     queryset = HeartBeat.objects.all()
-    permission_classes = (HasRightsOrIsDeviceOwnerDeviceCreation, )
+    permission_classes = (HasRightsOrIsDeviceOwnerDeviceCreation,)
     serializer_class = HeartBeatSerializer
-    multiple_lookup_fields = {'id', 'device__uuid', 'device_local_id'}
+    multiple_lookup_fields = {"id", "device__uuid", "device_local_id"}
 
     def get_object(self):
         queryset = self.get_queryset()
diff --git a/crashreports/rest_api_logfiles.py b/crashreports/rest_api_logfiles.py
index 7e02dab..df3bbcb 100644
--- a/crashreports/rest_api_logfiles.py
+++ b/crashreports/rest_api_logfiles.py
@@ -21,28 +21,31 @@
 
 class ListCreateView(generics.ListAPIView):
     queryset = LogFile.objects.all()
-    permission_classes = (HasRightsOrIsDeviceOwnerDeviceCreation, )
+    permission_classes = (HasRightsOrIsDeviceOwnerDeviceCreation,)
     serializer_class = LogFileSerializer
 
 
 class RetrieveUpdateDestroyView(generics.RetrieveUpdateDestroyAPIView):
     queryset = LogFile.objects.all()
-    permission_classes = (HasRightsOrIsDeviceOwnerDeviceCreation, )
+    permission_classes = (HasRightsOrIsDeviceOwnerDeviceCreation,)
     serializer_class = LogFileSerializer
 
 
-@api_view(http_method_names=['POST'], )
-@parser_classes([FileUploadParser, ])
-@permission_classes([IsAuthenticated, ])
+@api_view(http_method_names=["POST"])
+@parser_classes([FileUploadParser])
+@permission_classes([IsAuthenticated])
 def logfile_put(request, uuid, device_local_id, filename):
     try:
-        crashreport = Crashreport.objects.get(device__uuid=uuid,
-                                              device_local_id=device_local_id)
+        crashreport = Crashreport.objects.get(
+            device__uuid=uuid, device_local_id=device_local_id
+        )
     except:
         raise NotFound(detail="Crashreport does not exist.")
 
-    if (not (user_owns_uuid(request.user, crashreport.device.uuid)
-             or user_is_hiccup_staff(request.user))):
+    if not (
+        user_owns_uuid(request.user, crashreport.device.uuid)
+        or user_is_hiccup_staff(request.user)
+    ):
         raise PermissionDenied(detail="Not allowed.")
     f = request.data["file"]
     logfile = LogFile(crashreport=crashreport, logfile=f)
diff --git a/crashreports/serializers.py b/crashreports/serializers.py
index 732e595..af71a70 100644
--- a/crashreports/serializers.py
+++ b/crashreports/serializers.py
@@ -5,9 +5,7 @@
 from rest_framework.exceptions import NotFound
 from rest_framework import permissions
 
-from crashreports.models import (
-    Crashreport, Device, HeartBeat, LogFile
-)
+from crashreports.models import Crashreport, Device, HeartBeat, LogFile
 from crashreports.permissions import user_is_hiccup_staff
 
 
@@ -23,7 +21,7 @@
         Given the *outgoing* object instance, return the primitive value
         that should be used for this field.
         """
-        if user_is_hiccup_staff(self.context['request'].user):
+        if user_is_hiccup_staff(self.context["request"].user):
             return super(PrivateField, self).get_attribute(instance)
         return -1
 
@@ -33,10 +31,8 @@
 
     permission_classes = (permissions.AllowAny,)
     logfiles = serializers.HyperlinkedRelatedField(
-        read_only=True,
-        many=True,
-        view_name='api_v1_logfiles_by_id',
-        )
+        read_only=True, many=True, view_name="api_v1_logfiles_by_id"
+    )
     uuid = serializers.CharField(max_length=64)
     id = PrivateField()
     device_local_id = serializers.IntegerField(required=False)
@@ -44,7 +40,7 @@
 
     class Meta:  # noqa: D106
         model = Crashreport
-        exclude = ('device',)
+        exclude = ("device",)
 
     def create(self, validated_data):
         """Create a crashreport.
@@ -56,10 +52,10 @@
 
         """
         try:
-            device = Device.objects.get(uuid=validated_data['uuid'])
+            device = Device.objects.get(uuid=validated_data["uuid"])
         except ObjectDoesNotExist:
             raise NotFound(detail="uuid does not exist")
-        validated_data.pop('uuid', None)
+        validated_data.pop("uuid", None)
         report = Crashreport(**validated_data)
         report.device = device
         report.save()
@@ -77,7 +73,7 @@
 
     class Meta:  # noqa: D106
         model = HeartBeat
-        exclude = ('device',)
+        exclude = ("device",)
 
     def create(self, validated_data):
         """Create a heartbeat report.
@@ -89,10 +85,10 @@
 
         """
         try:
-            device = Device.objects.get(uuid=validated_data['uuid'])
+            device = Device.objects.get(uuid=validated_data["uuid"])
         except ObjectDoesNotExist:
             raise NotFound(detail="uuid does not exist")
-        validated_data.pop('uuid', None)
+        validated_data.pop("uuid", None)
         heartbeat = HeartBeat(**validated_data)
         heartbeat.device = device
         heartbeat.save()
@@ -106,7 +102,7 @@
 
     class Meta:  # noqa: D106
         model = LogFile
-        fields = '__all__'
+        fields = "__all__"
 
 
 class DeviceSerializer(serializers.ModelSerializer):
@@ -118,7 +114,7 @@
 
     class Meta:  # noqa: D106
         model = Device
-        fields = '__all__'
+        fields = "__all__"
 
 
 class DeviceCreateSerializer(DeviceSerializer):
@@ -126,8 +122,8 @@
 
     class Meta:  # noqa: D106
         model = Device
-        fields = ('board_date', 'chipset')
+        fields = ("board_date", "chipset")
         extra_kwargs = {
-            'board_date': {'required': True},
-            'chipset': {'required': True},
+            "board_date": {"required": True},
+            "chipset": {"required": True},
         }
diff --git a/crashreports/tests.py b/crashreports/tests.py
index 2267a79..354b330 100644
--- a/crashreports/tests.py
+++ b/crashreports/tests.py
@@ -30,42 +30,47 @@
             crash_type: The invalid crash type.
         """
         super(InvalidCrashTypeError, self).__init__(
-            '{} is not a valid crash type'.format(crash_type))
+            "{} is not a valid crash type".format(crash_type)
+        )
 
 
-class Dummy():
+class Dummy:
     """Dummy values for devices, heartbeats and crashreports."""
 
     DEFAULT_DUMMY_DEVICE_REGISTER_VALUES = {
-        'board_date': '2015-12-15T01:23:45Z',
-        'chipset': 'Qualcomm MSM8974PRO-AA',
+        "board_date": "2015-12-15T01:23:45Z",
+        "chipset": "Qualcomm MSM8974PRO-AA",
     }
 
     DEFAULT_DUMMY_HEARTBEAT_VALUES = {
-        'uuid': None,
-        'app_version': 10100,
-        'uptime': (
-            'up time: 16 days, 21:49:56, idle time: 5 days, 20:55:04, '
-            'sleep time: 10 days, 20:46:27'),
-        'build_fingerprint': (
-            'Fairphone/FP2/FP2:6.0.1/FP2-gms-18.03.1/FP2-gms-18.03.1:user/'
-            'release-keys'),
-        'radio_version': '4437.1-FP2-0-08',
-        'date': '2018-03-19T09:58:30.386Z',
+        "uuid": None,
+        "app_version": 10100,
+        "uptime": (
+            "up time: 16 days, 21:49:56, idle time: 5 days, 20:55:04, "
+            "sleep time: 10 days, 20:46:27"
+        ),
+        "build_fingerprint": (
+            "Fairphone/FP2/FP2:6.0.1/FP2-gms-18.03.1/FP2-gms-18.03.1:user/"
+            "release-keys"
+        ),
+        "radio_version": "4437.1-FP2-0-08",
+        "date": "2018-03-19T09:58:30.386Z",
     }
 
     DEFAULT_DUMMY_CRASHREPORTS_VALUES = DEFAULT_DUMMY_HEARTBEAT_VALUES.copy()
-    DEFAULT_DUMMY_CRASHREPORTS_VALUES.update({
-        'is_fake_report': 0,
-        'boot_reason': 'why?',
-        'power_on_reason': 'it was powered on',
-        'power_off_reason': 'something happened and it went off',
-    })
+    DEFAULT_DUMMY_CRASHREPORTS_VALUES.update(
+        {
+            "is_fake_report": 0,
+            "boot_reason": "why?",
+            "power_on_reason": "it was powered on",
+            "power_off_reason": "something happened and it went off",
+        }
+    )
 
     CRASH_TYPE_TO_BOOT_REASON_MAP = {
-        'crash': Crashreport.BOOT_REASON_KEYBOARD_POWER_ON,
-        'smpl': Crashreport.BOOT_REASON_RTC_ALARM,
-        'other': 'whatever',
+        "crash": Crashreport.BOOT_REASON_KEYBOARD_POWER_ON,
+        "smpl": Crashreport.BOOT_REASON_RTC_ALARM,
+        "other": "whatever",
     }
 
     @staticmethod
@@ -83,7 +88,8 @@
         from `Dummy.DEFAULT_DUMMY_DEVICE_REGISTER_VALUES`.
         """
         return Dummy._update_copy(
-            Dummy.DEFAULT_DUMMY_DEVICE_REGISTER_VALUES, kwargs)
+            Dummy.DEFAULT_DUMMY_DEVICE_REGISTER_VALUES, kwargs
+        )
 
     @staticmethod
     def heartbeat_data(**kwargs):
@@ -108,12 +114,14 @@
                 keyword arguments already.
         """
         data = Dummy._update_copy(
-            Dummy.DEFAULT_DUMMY_CRASHREPORTS_VALUES, kwargs)
-        if report_type and 'boot_reason' not in kwargs:
+            Dummy.DEFAULT_DUMMY_CRASHREPORTS_VALUES, kwargs
+        )
+        if report_type and "boot_reason" not in kwargs:
             if report_type not in Dummy.CRASH_TYPE_TO_BOOT_REASON_MAP:
                 raise InvalidCrashTypeError(report_type)
-            data['boot_reason'] = Dummy.CRASH_TYPE_TO_BOOT_REASON_MAP.get(
-                report_type)
+            data["boot_reason"] = Dummy.CRASH_TYPE_TO_BOOT_REASON_MAP.get(
+                report_type
+            )
         return data
 
 
@@ -129,7 +137,8 @@
         server is stored in self.admin.
         """
         admin_user = User.objects.create_superuser(
-            'somebody', 'somebody@example.com', 'thepassword')
+            "somebody", "somebody@example.com", "thepassword"
+        )
         self.admin = APIClient()
         self.admin.force_authenticate(admin_user)
 
@@ -148,10 +157,10 @@
         response = self.client.post(reverse(self.REGISTER_DEVICE_URL), data)
         self.assertEqual(response.status_code, status.HTTP_200_OK)
 
-        uuid = response.data['uuid']
-        token = response.data['token']
+        uuid = response.data["uuid"]
+        token = response.data["token"]
         user = APIClient()
-        user.credentials(HTTP_AUTHORIZATION='Token ' + token)
+        user.credentials(HTTP_AUTHORIZATION="Token " + token)
 
         return uuid, user, token
 
@@ -161,8 +170,9 @@
 
     def test_register(self):
         """Test registration of devices."""
-        response = self.client.post(reverse(self.REGISTER_DEVICE_URL),
-                                    Dummy.device_register_data())
+        response = self.client.post(
+            reverse(self.REGISTER_DEVICE_URL), Dummy.device_register_data()
+        )
         self.assertTrue("token" in response.data)
         self.assertTrue("uuid" in response.data)
         self.assertEqual(response.status_code, status.HTTP_200_OK)
@@ -175,21 +185,21 @@
     def test_create_missing_board_date(self):
         """Test registration with missing board date."""
         data = Dummy.device_register_data()
-        data.pop('board_date')
+        data.pop("board_date")
         response = self.client.post(reverse(self.REGISTER_DEVICE_URL), data)
         self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
 
     def test_create_missing_chipset(self):
         """Test registration with missing chipset."""
         data = Dummy.device_register_data()
-        data.pop('chipset')
+        data.pop("chipset")
         response = self.client.post(reverse(self.REGISTER_DEVICE_URL), data)
         self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
 
     def test_create_invalid_board_date(self):
         """Test registration with invalid board date."""
         data = Dummy.device_register_data()
-        data['board_date'] = 'not_a_valid_date'
+        data["board_date"] = "not_a_valid_date"
         response = self.client.post(reverse(self.REGISTER_DEVICE_URL), data)
         self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
 
@@ -204,7 +214,7 @@
         data = Dummy.device_register_data()
         # In 2017, the Netherlands changed from CET to CEST on March,
         # 26 at 02:00
-        data['board_date'] = '2017-03-26 02:34:56'
+        data["board_date"] = "2017-03-26 02:34:56"
         response = self.client.post(reverse(self.REGISTER_DEVICE_URL), data)
         self.assertEqual(response.status_code, status.HTTP_200_OK)
 
@@ -219,7 +229,7 @@
         data = Dummy.device_register_data()
         # In 2017, the Netherlands changed from CEST to CET on October,
         # 29 at 03:00
-        data['board_date'] = '2017-10-29 02:34:56'
+        data["board_date"] = "2017-10-29 02:34:56"
         response = self.client.post(reverse(self.REGISTER_DEVICE_URL), data)
         self.assertEqual(response.status_code, status.HTTP_200_OK)
 
@@ -234,15 +244,14 @@
         """Test registration of 2 devices."""
         number_of_devices = 2
         uuids = [
-            str(self._register_device()[0])
-            for _ in range(number_of_devices)
+            str(self._register_device()[0]) for _ in range(number_of_devices)
         ]
 
         response = self.admin.get(reverse(self.LIST_CREATE_URL), {})
         self.assertEqual(response.status_code, status.HTTP_200_OK)
-        self.assertEqual(len(response.data['results']), number_of_devices)
-        for result in response.data['results']:
-            self.assertIn(result['uuid'], uuids)
+        self.assertEqual(len(response.data["results"]), number_of_devices)
+        for result in response.data["results"]:
+            self.assertIn(result["uuid"], uuids)
 
     def test_device_list_unauth(self):
         """Test listing devices without authentication."""
@@ -254,8 +263,8 @@
         uuid, _, token = self._register_device()
         response = self.admin.get(reverse(self.RETRIEVE_URL, args=[uuid]), {})
         self.assertEqual(response.status_code, status.HTTP_200_OK)
-        self.assertEqual(response.data['uuid'], str(uuid))
-        self.assertEqual(response.data['token'], token)
+        self.assertEqual(response.data["uuid"], str(uuid))
+        self.assertEqual(response.data["token"], token)
 
     def test_retrieve_device_unauth(self):
         """Test retrieval of devices without authentication."""
@@ -288,14 +297,15 @@
     def _post_multiple(self, client, data, count):
         return [
             client.post(reverse(self.LIST_CREATE_URL), data)
-            for _ in range(count)]
+            for _ in range(count)
+        ]
 
     def _retrieve_single(self, user):
         count = 5
         response = self._post_multiple(self.admin, self.data, count)
         self.assertEqual(len(response), count)
         self.assertEqual(response[0].status_code, status.HTTP_201_CREATED)
-        url = reverse(self.RETRIEVE_URL, args=[response[0].data['id']])
+        url = reverse(self.RETRIEVE_URL, args=[response[0].data["id"]])
         request = user.get(url)
         return request.status_code
 
@@ -304,8 +314,10 @@
         response = self._post_multiple(self.user, self.data, count)
         self.assertEqual(len(response), count)
         self.assertEqual(response[0].status_code, status.HTTP_201_CREATED)
-        url = reverse(self.RETRIEVE_BY_UUID_URL, args=[
-            self.uuid, response[0].data['device_local_id']])
+        url = reverse(
+            self.RETRIEVE_BY_UUID_URL,
+            args=[self.uuid, response[0].data["device_local_id"]],
+        )
         request = user.get(url)
         return request.status_code
 
@@ -318,36 +330,37 @@
     def test_create_no_auth(self):
         """Test creation without authentication."""
         noauth_client = APIClient()
-        response = noauth_client.post(
-            reverse(self.LIST_CREATE_URL), self.data)
+        response = noauth_client.post(reverse(self.LIST_CREATE_URL), self.data)
         self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
 
     def test_create_as_admin(self):
         """Test creation as admin."""
         response = self.admin.post(reverse(self.LIST_CREATE_URL), self.data)
         self.assertEqual(response.status_code, status.HTTP_201_CREATED)
-        self.assertTrue(response.data['id'] > 0)
+        self.assertTrue(response.data["id"] > 0)
 
     def test_create_as_admin_not_existing_device(self):
         """Test creation of heartbeat on non-existing device."""
         response = self.admin.post(
-            reverse(self.LIST_CREATE_URL), self._create_dummy_data())
+            reverse(self.LIST_CREATE_URL), self._create_dummy_data()
+        )
         self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
 
     def test_create_as_uuid_owner(self):
         """Test creation as owner."""
         response = self.user.post(
             reverse(self.LIST_CREATE_URL),
-            self._create_dummy_data(uuid=self.uuid))
+            self._create_dummy_data(uuid=self.uuid),
+        )
         self.assertEqual(response.status_code, status.HTTP_201_CREATED)
-        self.assertEqual(response.data['id'], -1)
+        self.assertEqual(response.data["id"], -1)
 
     def test_create_as_uuid_not_owner(self):
         """Test creation as non-owner."""
         uuid, _, _ = self._register_device()
         response = self.user.post(
-            reverse(self.LIST_CREATE_URL),
-            self._create_dummy_data(uuid=uuid))
+            reverse(self.LIST_CREATE_URL), self._create_dummy_data(uuid=uuid)
+        )
         self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
 
     def test_list(self):
@@ -356,42 +369,45 @@
         self._post_multiple(self.user, self.data, count)
         response = self.admin.get(reverse(self.LIST_CREATE_URL))
         self.assertEqual(response.status_code, status.HTTP_200_OK)
-        self.assertEqual(len(response.data['results']), count)
+        self.assertEqual(len(response.data["results"]), count)
 
     def test_retrieve_single_admin(self):
         """Test retrieval as admin."""
-        self.assertEqual(
-            self._retrieve_single(self.admin), status.HTTP_200_OK)
+        self.assertEqual(self._retrieve_single(self.admin), status.HTTP_200_OK)
 
     def test_retrieve_single_device_owner(self):
         """Test retrieval as device owner."""
         self.assertEqual(
-            self._retrieve_single(self.user), status.HTTP_403_FORBIDDEN)
+            self._retrieve_single(self.user), status.HTTP_403_FORBIDDEN
+        )
 
     def test_retrieve_single_noauth(self):
         """Test retrieval without authentication."""
         noauth_client = APIClient()
         self.assertEqual(
-            self._retrieve_single(noauth_client),
-            status.HTTP_401_UNAUTHORIZED)
+            self._retrieve_single(noauth_client), status.HTTP_401_UNAUTHORIZED
+        )
 
     def test_retrieve_single_by_device_admin(self):
         """Test retrieval by device as admin."""
         self.assertEqual(
-            self._retrieve_single_by_device(self.admin), status.HTTP_200_OK)
+            self._retrieve_single_by_device(self.admin), status.HTTP_200_OK
+        )
 
     def test_retrieve_single_by_device_device_owner(self):
         """Test retrieval by device as owner."""
         self.assertEqual(
             self._retrieve_single_by_device(self.user),
-            status.HTTP_403_FORBIDDEN)
+            status.HTTP_403_FORBIDDEN,
+        )
 
     def test_retrieve_single_by_device_noauth(self):
         """Test retrieval by device without authentication."""
         noauth_client = APIClient()
         self.assertEqual(
             self._retrieve_single_by_device(noauth_client),
-            status.HTTP_401_UNAUTHORIZED)
+            status.HTTP_401_UNAUTHORIZED,
+        )
 
     def test_list_by_uuid(self):
         """Test listing of devices by UUID."""
@@ -399,11 +415,12 @@
         uuid, _, _ = self._register_device()
         self._post_multiple(self.user, self.data, count)
         self._post_multiple(
-            self.admin, self._create_dummy_data(uuid=uuid), count)
+            self.admin, self._create_dummy_data(uuid=uuid), count
+        )
         url = reverse(self.LIST_CREATE_BY_UUID_URL, args=[self.uuid])
         response = self.admin.get(url)
         self.assertEqual(response.status_code, status.HTTP_200_OK)
-        self.assertEqual(len(response.data['results']), count)
+        self.assertEqual(len(response.data["results"]), count)
 
     def test_list_noauth(self):
         """Test listing of devices without authentication."""
@@ -423,14 +440,14 @@
     def test_no_radio_version(self):
         """Test creation and retrieval without radio version."""
         data = self._create_dummy_data(uuid=self.uuid)
-        data.pop('radio_version')
+        data.pop("radio_version")
         response = self.user.post(reverse(self.LIST_CREATE_URL), data)
         self.assertEqual(response.status_code, status.HTTP_201_CREATED)
         url = reverse(self.LIST_CREATE_BY_UUID_URL, args=[self.uuid])
         response = self.admin.get(url)
         self.assertEqual(response.status_code, status.HTTP_200_OK)
-        self.assertEqual(len(response.data['results']), 1)
-        self.assertIsNone(response.data['results'][0]['radio_version'])
+        self.assertEqual(len(response.data["results"]), 1)
+        self.assertIsNone(response.data["results"][0]["radio_version"])
 
     def test_radio_version_field(self):
         """Test retrieval of radio version field."""
@@ -439,9 +456,11 @@
         url = reverse(self.LIST_CREATE_BY_UUID_URL, args=[self.uuid])
         response = self.admin.get(url)
         self.assertEqual(response.status_code, status.HTTP_200_OK)
-        self.assertEqual(len(response.data['results']), 1)
-        self.assertEqual(response.data['results'][0]['radio_version'],
-                         self.data['radio_version'])
+        self.assertEqual(len(response.data["results"]), 1)
+        self.assertEqual(
+            response.data["results"][0]["radio_version"],
+            self.data["radio_version"],
+        )
 
     def test_send_non_existent_time(self):
         """Test sending of heartbeat with non existent time.
@@ -453,7 +472,7 @@
         data = self._create_dummy_data(uuid=self.uuid)
         # In 2017, the Netherlands changed from CET to CEST on March,
         # 26 at 02:00
-        data['date'] = '2017-03-26 02:34:56'
+        data["date"] = "2017-03-26 02:34:56"
         response = self.user.post(reverse(self.LIST_CREATE_URL), data)
         self.assertEqual(response.status_code, status.HTTP_201_CREATED)
 
@@ -467,7 +486,7 @@
         data = self._create_dummy_data(uuid=self.uuid)
         # In 2017, the Netherlands changed from CEST to CET on October,
         # 29 at 03:00
-        data['date'] = '2017-10-29 02:34:56'
+        data["date"] = "2017-10-29 02:34:56"
         response = self.user.post(reverse(self.LIST_CREATE_URL), data)
         self.assertEqual(response.status_code, status.HTTP_201_CREATED)
 
@@ -506,8 +525,8 @@
         data = Dummy.crashreport_data(uuid=uuid)
         response = user.post(reverse(self.LIST_CREATE_URL), data)
         self.assertEqual(status.HTTP_201_CREATED, response.status_code)
-        self.assertTrue('device_local_id' in response.data)
-        device_local_id = response.data['device_local_id']
+        self.assertTrue("device_local_id" in response.data)
+        device_local_id = response.data["device_local_id"]
 
         return device_local_id
 
@@ -516,13 +535,16 @@
         device_local_id = self._upload_crashreport(user, uuid)
 
         # Upload a logfile for the crashreport
-        logfile = tempfile.NamedTemporaryFile('w+', suffix=".log", delete=True)
+        logfile = tempfile.NamedTemporaryFile("w+", suffix=".log", delete=True)
         logfile.write(u"blihblahblub")
         response = user.post(
-            reverse(self.PUT_LOGFILE_URL, args=[
-                uuid, device_local_id, os.path.basename(logfile.name)
-            ]),
-            {'file': logfile}, format="multipart")
+            reverse(
+                self.PUT_LOGFILE_URL,
+                args=[uuid, device_local_id, os.path.basename(logfile.name)],
+            ),
+            {"file": logfile},
+            format="multipart",
+        )
         self.assertEqual(status.HTTP_201_CREATED, response.status_code)
 
     def test_logfile_upload_as_user(self):
diff --git a/crashreports/urls.py b/crashreports/urls.py
index d86c976..b876aaf 100644
--- a/crashreports/urls.py
+++ b/crashreports/urls.py
@@ -7,54 +7,80 @@
 
 urlpatterns = [
     # crashreports
-    url(r'^api/v1/crashreports/$',
+    url(
+        r"^api/v1/crashreports/$",
         rest_api_crashreports.ListCreateView.as_view(),
-        name='api_v1_crashreports'),
-    url(r'^api/v1/devices/(?P<uuid>[a-f0-9-]+)/crashreports/$',
+        name="api_v1_crashreports",
+    ),
+    url(
+        r"^api/v1/devices/(?P<uuid>[a-f0-9-]+)/crashreports/$",
         rest_api_crashreports.ListCreateView.as_view(),
-        name='api_v1_crashreports_by_uuid'),
-    url(r'^api/v1/crashreports/(?P<id>[0-9]+)/$',
+        name="api_v1_crashreports_by_uuid",
+    ),
+    url(
+        r"^api/v1/crashreports/(?P<id>[0-9]+)/$",
         rest_api_crashreports.RetrieveUpdateDestroyView.as_view(),
-        name='api_v1_crashreport'),
-    url(r'^api/v1/devices/(?P<device__uuid>[a-f0-9-]+)/crashreports/' +
-        '(?P<device_local_id>[0-9]+)/$',
+        name="api_v1_crashreport",
+    ),
+    url(
+        r"^api/v1/devices/(?P<device__uuid>[a-f0-9-]+)/crashreports/"
+        + "(?P<device_local_id>[0-9]+)/$",
         rest_api_crashreports.RetrieveUpdateDestroyView.as_view(),
-        name='api_v1_crashreport_by_uuid'),
-
+        name="api_v1_crashreport_by_uuid",
+    ),
     # logfiles
-    url(r'^api/v1/devices/(?P<uuid>[a-f0-9-]+)/crashreports/' +
-        '(?P<device_local_id>[0-9]+)/logfile_put/(?P<filename>[^/]+)/$',
+    url(
+        r"^api/v1/devices/(?P<uuid>[a-f0-9-]+)/crashreports/"
+        + "(?P<device_local_id>[0-9]+)/logfile_put/(?P<filename>[^/]+)/$",
         rest_api_logfiles.logfile_put,
-        name='api_v1_putlogfile_for_device_id'),
-
-    url(r'^api/v1/logfiles/$',
-         rest_api_logfiles.ListCreateView.as_view(),
-         name='api_v1_logfiles'),
-    url(r'^api/v1/logfiles/(?P<pk>[0-9]+)/$',
+        name="api_v1_putlogfile_for_device_id",
+    ),
+    url(
+        r"^api/v1/logfiles/$",
+        rest_api_logfiles.ListCreateView.as_view(),
+        name="api_v1_logfiles",
+    ),
+    url(
+        r"^api/v1/logfiles/(?P<pk>[0-9]+)/$",
         rest_api_logfiles.RetrieveUpdateDestroyView.as_view(),
-        name='api_v1_logfiles_by_id'),
-
+        name="api_v1_logfiles_by_id",
+    ),
     # heartbeats
-    url(r'^api/v1/heartbeats/$',
+    url(
+        r"^api/v1/heartbeats/$",
         rest_api_heartbeats.ListCreateView.as_view(),
-        name='api_v1_heartbeats'),
-    url(r'^api/v1/devices/(?P<uuid>[a-f0-9-]+)/heartbeats/$',
+        name="api_v1_heartbeats",
+    ),
+    url(
+        r"^api/v1/devices/(?P<uuid>[a-f0-9-]+)/heartbeats/$",
         rest_api_heartbeats.ListCreateView.as_view(),
-        name='api_v1_heartbeats_by_uuid'),
-    url(r'^api/v1/heartbeats/(?P<id>[0-9]+)/$',
+        name="api_v1_heartbeats_by_uuid",
+    ),
+    url(
+        r"^api/v1/heartbeats/(?P<id>[0-9]+)/$",
         rest_api_heartbeats.RetrieveUpdateDestroyView.as_view(),
-        name='api_v1_heartbeat'),
-    url(r'^api/v1/devices/(?P<uuid>[a-f0-9-]+)/heartbeats/' +
-        '(?P<device_local_id>[0-9]+)/$',
+        name="api_v1_heartbeat",
+    ),
+    url(
+        r"^api/v1/devices/(?P<uuid>[a-f0-9-]+)/heartbeats/"
+        + "(?P<device_local_id>[0-9]+)/$",
         rest_api_heartbeats.RetrieveUpdateDestroyView.as_view(),
-        name='api_v1_heartbeat_by_uuid'),
-
+        name="api_v1_heartbeat_by_uuid",
+    ),
     # devices
-    url(r'^api/v1/devices/$', rest_api_devices.ListCreateDevices.as_view(),
-        name='api_v1_list_devices'),
-    url(r'^api/v1/devices/(?P<uuid>[a-f0-9-]+)/$',
+    url(
+        r"^api/v1/devices/$",
+        rest_api_devices.ListCreateDevices.as_view(),
+        name="api_v1_list_devices",
+    ),
+    url(
+        r"^api/v1/devices/(?P<uuid>[a-f0-9-]+)/$",
         rest_api_devices.RetrieveUpdateDestroyDevice.as_view(),
-        name='api_v1_retrieve_device'),
-    url(r'^api/v1/devices/register/$', rest_api_devices.register_device,
-        name='api_v1_register_device'),
+        name="api_v1_retrieve_device",
+    ),
+    url(
+        r"^api/v1/devices/register/$",
+        rest_api_devices.register_device,
+        name="api_v1_register_device",
+    ),
 ]
diff --git a/hiccup/allauth_adapters.py b/hiccup/allauth_adapters.py
index 268d590..4eb3a06 100644
--- a/hiccup/allauth_adapters.py
+++ b/hiccup/allauth_adapters.py
@@ -3,27 +3,29 @@
 from django.core.exceptions import PermissionDenied
 from django.contrib.auth.models import Group
 
+
 class FairphoneAccountAdapter(DefaultSocialAccountAdapter):
-    
     def is_open_for_signup(self, request, sociallogin):
         return True
-    
+
     def save_user(self, request, sociallogin, form=None):
-        u =DefaultSocialAccountAdapter.save_user(self, request, sociallogin, form=None)
-        if u.email.split('@')[1] == "fairphone.com":
-            g = Group.objects.get(name='FairphoneSoftwareTeam') 
+        u = DefaultSocialAccountAdapter.save_user(
+            self, request, sociallogin, form=None
+        )
+        if u.email.split("@")[1] == "fairphone.com":
+            g = Group.objects.get(name="FairphoneSoftwareTeam")
             g.user_set.add(u)
         return u
-            
-    def populate_user(self,
-                      request,
-                      sociallogin,
-                      data):
-        u = DefaultSocialAccountAdapter.populate_user(self,request,sociallogin,data)
-        if not u.email.split('@')[1] == "fairphone.com":
-             raise PermissionDenied()
+
+    def populate_user(self, request, sociallogin, data):
+        u = DefaultSocialAccountAdapter.populate_user(
+            self, request, sociallogin, data
+        )
+        if not u.email.split("@")[1] == "fairphone.com":
+            raise PermissionDenied()
         return u
 
+
 class FormAccountAdapter(DefaultAccountAdapter):
     def is_open_for_signup(self, request):
         return False
diff --git a/hiccup/apps.py b/hiccup/apps.py
index d651203..dacae51 100644
--- a/hiccup/apps.py
+++ b/hiccup/apps.py
@@ -4,4 +4,4 @@
 
 
 class crashreportsConfig(AppConfig):
-    name = 'crashreports'
+    name = "crashreports"
diff --git a/hiccup/settings.py b/hiccup/settings.py
index f20c3c8..a401d04 100644
--- a/hiccup/settings.py
+++ b/hiccup/settings.py
@@ -20,85 +20,84 @@
 # See https://docs.djangoproject.com/en/1.9/howto/deployment/checklist/
 
 # SECURITY WARNING: keep the secret key used in production secret!
-SECRET_KEY = '7u+#ha3hk!x+*)clhs46%n*)w1q+5s4+yoc#1!nm0b%fwwrud@'
+SECRET_KEY = "7u+#ha3hk!x+*)clhs46%n*)w1q+5s4+yoc#1!nm0b%fwwrud@"
 
 # SECURITY WARNING: don't run with debug turned on in production!
 DEBUG = True
 
-ALLOWED_HOSTS = ['*']
+ALLOWED_HOSTS = ["*"]
 
 
 # Application definition
 
 INSTALLED_APPS = [
-    'django.contrib.admin',
-    'django.contrib.auth',
-    'django.contrib.contenttypes',
-    'django.contrib.sessions',
-    'django.contrib.sites',
-    'django.contrib.messages',
-    'django.contrib.staticfiles',
-    'rest_framework',
-    'rest_framework.authtoken',
-    'crashreports',
-    'crashreport_stats',
-    'taggit',
-    'crispy_forms',
-    'bootstrap3',
-    'bootstrapform',
-    'django_extensions',
-    'django_filters',
-    'djfrontend',
-    'djfrontend.skeleton',
-    'allauth',
-    'allauth.account',
-    'allauth.socialaccount',
-    'allauth.socialaccount.providers.google',
-    'drf_yasg'
+    "django.contrib.admin",
+    "django.contrib.auth",
+    "django.contrib.contenttypes",
+    "django.contrib.sessions",
+    "django.contrib.sites",
+    "django.contrib.messages",
+    "django.contrib.staticfiles",
+    "rest_framework",
+    "rest_framework.authtoken",
+    "crashreports",
+    "crashreport_stats",
+    "taggit",
+    "crispy_forms",
+    "bootstrap3",
+    "bootstrapform",
+    "django_extensions",
+    "django_filters",
+    "djfrontend",
+    "djfrontend.skeleton",
+    "allauth",
+    "allauth.account",
+    "allauth.socialaccount",
+    "allauth.socialaccount.providers.google",
+    "drf_yasg",
 ]
 
 MIDDLEWARE_CLASSES = [
-    'django.middleware.security.SecurityMiddleware',
-    'django.contrib.sessions.middleware.SessionMiddleware',
-    'django.middleware.common.CommonMiddleware',
-    'django.middleware.csrf.CsrfViewMiddleware',
-    'django.contrib.auth.middleware.AuthenticationMiddleware',
-    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
-    'django.contrib.messages.middleware.MessageMiddleware',
-    'django.middleware.clickjacking.XFrameOptionsMiddleware',
+    "django.middleware.security.SecurityMiddleware",
+    "django.contrib.sessions.middleware.SessionMiddleware",
+    "django.middleware.common.CommonMiddleware",
+    "django.middleware.csrf.CsrfViewMiddleware",
+    "django.contrib.auth.middleware.AuthenticationMiddleware",
+    "django.contrib.auth.middleware.SessionAuthenticationMiddleware",
+    "django.contrib.messages.middleware.MessageMiddleware",
+    "django.middleware.clickjacking.XFrameOptionsMiddleware",
 ]
 
-ROOT_URLCONF = 'hiccup.urls'
+ROOT_URLCONF = "hiccup.urls"
 
 TEMPLATE_LOADERS = (
-    'django.template.loaders.filesystem.Loader',
-    'django.template.loaders.app_directories.Loader',
+    "django.template.loaders.filesystem.Loader",
+    "django.template.loaders.app_directories.Loader",
 )
 
 TEMPLATES = [
     {
-        'BACKEND': 'django.template.backends.django.DjangoTemplates',
-        'DIRS': [os.path.join(BASE_DIR, 'hiccup', 'templates')],
-        'APP_DIRS': True,
-        'OPTIONS': {
-            'context_processors': [
-                'django.template.context_processors.debug',
-                'django.template.context_processors.request',
-                'django.contrib.auth.context_processors.auth',
-                'django.contrib.messages.context_processors.messages',
+        "BACKEND": "django.template.backends.django.DjangoTemplates",
+        "DIRS": [os.path.join(BASE_DIR, "hiccup", "templates")],
+        "APP_DIRS": True,
+        "OPTIONS": {
+            "context_processors": [
+                "django.template.context_processors.debug",
+                "django.template.context_processors.request",
+                "django.contrib.auth.context_processors.auth",
+                "django.contrib.messages.context_processors.messages",
                 # `allauth` needs this from django
-                'django.template.context_processors.request',
-            ],
+                "django.template.context_processors.request",
+            ]
         },
-    },
+    }
 ]
 
 AUTHENTICATION_BACKENDS = (
     # Needed to login by username in Django admin, regardless of `allauth`
-    'django.contrib.auth.backends.ModelBackend',
-
+    "django.contrib.auth.backends.ModelBackend",
     # `allauth` specific authentication methods, such as login by e-mail
-    'allauth.account.auth_backends.AuthenticationBackend',
+    "allauth.account.auth_backends.AuthenticationBackend",
 )
 
 # WSGI_APPLICATION = 'hiccup_server.wsgi.application'
@@ -108,9 +107,9 @@
 # https://docs.djangoproject.com/en/1.9/ref/settings/#databases
 
 DATABASES = {
-    'default': {
-        'ENGINE': 'django.db.backends.sqlite3',
-        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
+    "default": {
+        "ENGINE": "django.db.backends.sqlite3",
+        "NAME": os.path.join(BASE_DIR, "db.sqlite3"),
     }
 }
 
@@ -120,46 +119,46 @@
 
 AUTH_PASSWORD_VALIDATORS = [
     {
-        'NAME': 'django.contrib.auth.password_validation'
-                '.UserAttributeSimilarityValidator',
+        "NAME": "django.contrib.auth.password_validation"
+        ".UserAttributeSimilarityValidator"
     },
     {
-        'NAME': 'django.contrib.auth.password_validation'
-                '.MinimumLengthValidator',
+        "NAME": "django.contrib.auth.password_validation"
+        ".MinimumLengthValidator"
     },
     {
-        'NAME': 'django.contrib.auth.password_validation'
-                '.CommonPasswordValidator',
+        "NAME": "django.contrib.auth.password_validation"
+        ".CommonPasswordValidator"
     },
     {
-        'NAME': 'django.contrib.auth.password_validation'
-                '.NumericPasswordValidator',
+        "NAME": "django.contrib.auth.password_validation"
+        ".NumericPasswordValidator"
     },
 ]
 
 # Internationalization
 # https://docs.djangoproject.com/en/1.9/topics/i18n/
 
-LANGUAGE_CODE = 'en-us'
-TIME_ZONE = 'Europe/Amsterdam'
+LANGUAGE_CODE = "en-us"
+TIME_ZONE = "Europe/Amsterdam"
 USE_I18N = True
 USE_L10N = True
 USE_TZ = True
 
 REST_FRAMEWORK = {
-    'DEFAULT_AUTHENTICATION_CLASSES': (
-        'rest_framework.authentication.BasicAuthentication',
-        'rest_framework.authentication.SessionAuthentication',
-        'rest_framework.authentication.TokenAuthentication',
+    "DEFAULT_AUTHENTICATION_CLASSES": (
+        "rest_framework.authentication.BasicAuthentication",
+        "rest_framework.authentication.SessionAuthentication",
+        "rest_framework.authentication.TokenAuthentication",
     ),
-    'DEFAULT_PERMISSION_CLASSES': (
-        'rest_framework.permissions.IsAuthenticated',
+    "DEFAULT_PERMISSION_CLASSES": (
+        "rest_framework.permissions.IsAuthenticated",
     ),
-    'DEFAULT_FILTER_BACKENDS':
-        ('django_filters.rest_framework.DjangoFilterBackend',),
-    'DEFAULT_PAGINATION_CLASS':
-        'rest_framework.pagination.LimitOffsetPagination',
-    'PAGE_SIZE': 100
+    "DEFAULT_FILTER_BACKENDS": (
+        "django_filters.rest_framework.DjangoFilterBackend",
+    ),
+    "DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.LimitOffsetPagination",
+    "PAGE_SIZE": 100,
 }
 
 SITE_ID = 1
@@ -172,44 +171,35 @@
 ACCOUNT_LOGOUT_REDIRECT_URL = "/accounts/login/"
 
 SOCIALACCOUNT_PROVIDERS = {
-    'google': {
-        'SCOPE': [
-            'profile',
-            'email',
-        ],
-        'AUTH_PARAMS': {
-            'access_type': 'online',
-        }
+    "google": {
+        "SCOPE": ["profile", "email"],
+        "AUTH_PARAMS": {"access_type": "online"},
     }
 }
 
 # Static files (CSS, JavaScript, Images)
 # https://docs.djangoproject.com/en/1.9/howto/static-files/
 
-STATIC_URL = '/static/'
+STATIC_URL = "/static/"
 
-STATIC_ROOT = os.path.join(BASE_DIR, 'static')
+STATIC_ROOT = os.path.join(BASE_DIR, "static")
 
 
 # Logging
 # https://docs.djangoproject.com/en/2.0/topics/logging/#examples
 
 LOGGING = {
-    'version': 1,
-    'disable_existing_loggers': False,
-    'handlers': {
-        'file': {
-            'level': 'DEBUG',
-            'class': 'logging.FileHandler',
-            'filename': os.path.join(BASE_DIR, 'debug.log'),
-        },
+    "version": 1,
+    "disable_existing_loggers": False,
+    "handlers": {
+        "file": {
+            "level": "DEBUG",
+            "class": "logging.FileHandler",
+            "filename": os.path.join(BASE_DIR, "debug.log"),
+        }
     },
-    'loggers': {
-        'django': {
-            'handlers': ['file'],
-            'level': 'DEBUG',
-            'propagate': True,
-        },
+    "loggers": {
+        "django": {"handlers": ["file"], "level": "DEBUG", "propagate": True}
     },
 }
 
@@ -217,9 +207,7 @@
 # Automatic documentation generation
 # https://drf-yasg.readthedocs.io/en/stable/index.html
 
-SWAGGER_SETTINGS = {
-   'DEFAULT_INFO': 'hiccup.urls.api_info',
-}
+SWAGGER_SETTINGS = {"DEFAULT_INFO": "hiccup.urls.api_info"}
 
 try:
     from local_settings import *  # noqa: F403, F401
diff --git a/hiccup/urls.py b/hiccup/urls.py
index 3a6cf76..83fb1e0 100644
--- a/hiccup/urls.py
+++ b/hiccup/urls.py
@@ -4,14 +4,11 @@
 from django.contrib import admin
 from drf_yasg import openapi
 
-api_info = openapi.Info(
-    title="Hiccup API",
-    default_version='v1',
-)
+api_info = openapi.Info(title="Hiccup API", default_version="v1")
 
 urlpatterns = [
-    url(r'^hiccup/admin/', admin.site.urls),
-    url(r'^hiccup/', include('crashreports.urls')),
-    url(r'^hiccup_stats/', include('crashreport_stats.urls')),
-    url(r'^accounts/', include('allauth.urls')),
+    url(r"^hiccup/admin/", admin.site.urls),
+    url(r"^hiccup/", include("crashreports.urls")),
+    url(r"^hiccup_stats/", include("crashreport_stats.urls")),
+    url(r"^accounts/", include("allauth.urls")),
 ]
diff --git a/hiccup/wsgi.py b/hiccup/wsgi.py
index 7f02368..025bc4e 100644
--- a/hiccup/wsgi.py
+++ b/hiccup/wsgi.py
@@ -6,7 +6,9 @@
 """
 
 import os
+
 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "hiccup.settings")
 
 from django.core.wsgi import get_wsgi_application
+
 application = get_wsgi_application()
diff --git a/tools/bench.py b/tools/bench.py
index 6d43672..4e40194 100644
--- a/tools/bench.py
+++ b/tools/bench.py
@@ -4,47 +4,51 @@
 clients = []
 
 
-BASE_URL = 'http://127.0.0.1:8000/hiccup/'
+BASE_URL = "http://127.0.0.1:8000/hiccup/"
+
 
 def create_client():
     ret_client = {}
-    register_url = 'api/v1/devices/register/'
-    params =  {
-        'board_date': "2017-01-01",
-        'chipset': "HICCUPBENCH"
-    }
-    resp = requests.post(BASE_URL+register_url, params)
+    register_url = "api/v1/devices/register/"
+    params = {"board_date": "2017-01-01", "chipset": "HICCUPBENCH"}
+    resp = requests.post(BASE_URL + register_url, params)
     data = json.loads(resp.text)
-    ret_client['token'] = data['token']
-    ret_client['uuid'] = data['uuid']
+    ret_client["token"] = data["token"]
+    ret_client["uuid"] = data["uuid"]
     return ret_client
 
 
 def send_heartbeat(client):
-    heartbeat_url = 'api/v1/heartbeats/'
+    heartbeat_url = "api/v1/heartbeats/"
     params = {
-        'uuid': client['uuid'],
-        'build_fingerprint': 'HICCUPBENCH',
-        'uptime': "string",
-        'date': "1984-06-02T19:05:00.000Z",
-        'app_version' : 2000000
+        "uuid": client["uuid"],
+        "build_fingerprint": "HICCUPBENCH",
+        "uptime": "string",
+        "date": "1984-06-02T19:05:00.000Z",
+        "app_version": 2000000,
     }
-    resp = requests.post(BASE_URL + heartbeat_url, params,
-            headers = {'Authorization': 'Token '+ client['token']})
+    resp = requests.post(
+        BASE_URL + heartbeat_url,
+        params,
+        headers={"Authorization": "Token " + client["token"]},
+    )
     return resp
 
+
 import time
 
+
 def bench(client):
     start_time = time.time()
     for i in range(50):
         send_heartbeat(client)
     end_time = time.time()
-    print(end_time-start_time)
+    print(end_time - start_time)
+
 
 clients = []
-for  i in range(20):
-    clients =  clients + [create_client()]
+for i in range(20):
+    clients = clients + [create_client()]
 
 with Pool(20) as p:
     p.map(bench, clients)