From 0b28c5ba091662c286672d78dd382fd6d9fcc492 Mon Sep 17 00:00:00 2001
From: Nicolas ROCHE <nroche@entrouvert.com>
Date: Mon, 12 Apr 2021 09:31:41 +0200
Subject: [PATCH 2/3] misc: apply isort (#52937)

---
 functests/cmis/conftest.py                    |  2 +-
 functests/cmis/tests_cmis.py                  |  3 +-
 functests/planitech/test_planitech.py         |  2 +-
 functests/toulouse_axel/test_toulouse_axel.py |  1 +
 functests/vivaticket/test_vivaticket.py       |  6 ++-
 passerelle/api/views.py                       |  3 +-
 passerelle/apps/actesweb/models.py            |  4 +-
 passerelle/apps/api_entreprise/models.py      | 12 +++---
 .../migrations/0001_initial.py                |  2 +-
 passerelle/apps/api_particulier/models.py     |  1 +
 passerelle/apps/arcgis/forms.py               |  1 +
 .../migrations/0005_auto_20200310_1517.py     |  3 +-
 .../migrations/0006_auto_20200401_1025.py     |  2 +-
 passerelle/apps/arcgis/models.py              |  8 ++--
 passerelle/apps/arcgis/views.py               |  2 +-
 passerelle/apps/arpege_ecp/models.py          |  8 ++--
 .../apps/astregs/migrations/0001_initial.py   |  2 +-
 passerelle/apps/astregs/models.py             |  8 ++--
 passerelle/apps/atal/models.py                |  4 +-
 .../atos_genesys/migrations/0001_initial.py   |  4 +-
 passerelle/apps/atos_genesys/models.py        |  4 +-
 passerelle/apps/atos_genesys/utils.py         |  2 +-
 .../base_adresse/migrations/0001_initial.py   |  2 +-
 .../migrations/0002_auto_20150705_0330.py     |  2 +-
 .../migrations/0003_baseaddresse_log_level.py |  2 +-
 .../migrations/0004_auto_20160316_0910.py     |  2 +-
 .../migrations/0005_auto_20160407_0456.py     |  2 +-
 .../0008_delete_updatestreetmodel.py          |  2 +-
 .../0009_streetmodel_simple_name.py           |  2 +-
 .../migrations/0010_auto_20160914_0826.py     |  2 +-
 .../migrations/0011_auto_20160919_0949.py     |  2 +-
 .../migrations/0015_auto_20191206_1244.py     |  3 +-
 .../migrations/0016_auto_20200130_1604.py     |  2 +-
 passerelle/apps/base_adresse/models.py        | 10 ++---
 .../apps/bdp/migrations/0001_initial.py       |  2 +-
 .../apps/bdp/migrations/0002_bdp_log_level.py |  2 +-
 .../bdp/migrations/0003_auto_20160316_0910.py |  2 +-
 .../bdp/migrations/0004_auto_20160407_0456.py |  2 +-
 passerelle/apps/bdp/models.py                 |  6 +--
 passerelle/apps/bdp/urls.py                   |  5 ++-
 passerelle/apps/bdp/views.py                  |  4 +-
 .../cartads_cs/migrations/0001_initial.py     |  1 +
 .../migrations/0002_cartadsdatacache.py       |  2 +-
 ...0004_cartadsdossier_cartads_steps_cache.py |  2 +-
 ...0011_cartadsdossier_cartads_cache_infos.py |  2 +-
 passerelle/apps/cartads_cs/models.py          | 15 +++-----
 .../apps/choosit/migrations/0001_initial.py   |  2 +-
 .../migrations/0002_auto_20160316_0528.py     |  2 +-
 .../migrations/0003_auto_20160316_0910.py     |  2 +-
 .../migrations/0004_auto_20160407_0456.py     |  2 +-
 ..._choositsmsgateway_default_trunk_prefix.py |  2 +-
 passerelle/apps/choosit/models.py             |  2 +-
 passerelle/apps/cityweb/cityweb.py            |  8 ++--
 passerelle/apps/cityweb/models.py             | 10 ++---
 .../apps/clicrdv/migrations/0001_initial.py   |  2 +-
 passerelle/apps/clicrdv/models.py             |  6 +--
 passerelle/apps/clicrdv/urls.py               |  5 +--
 passerelle/apps/clicrdv/views.py              |  5 +--
 .../apps/cmis/migrations/0001_initial.py      |  2 +-
 passerelle/apps/cmis/models.py                | 17 +++++----
 passerelle/apps/cmis/views.py                 |  1 -
 .../apps/cryptor/migrations/0001_initial.py   |  6 ++-
 passerelle/apps/cryptor/models.py             |  6 +--
 .../management/commands/change-csv.py         |  2 +-
 .../csvdatasource/migrations/0001_initial.py  |  2 +-
 .../0002_csvdatasource_log_level.py           |  2 +-
 .../migrations/0003_auto_20160316_0910.py     |  2 +-
 .../migrations/0004_auto_20160407_0456.py     |  2 +-
 .../0005_csvdatasource__dialect_options.py    |  2 +-
 .../migrations/0006_auto_20160905_1031.py     |  2 +-
 .../migrations/0009_auto_20161109_0353.py     |  2 +-
 .../migrations/0011_auto_20180905_0936.py     |  4 +-
 .../migrations/0016_auto_20200406_1702.py     |  2 +-
 .../migrations/0019_csv_upload_to.py          |  1 +
 .../migrations/0020_csv_upload_to.py          |  1 +
 passerelle/apps/csvdatasource/models.py       | 23 +++++-------
 passerelle/apps/csvdatasource/views.py        |  2 +-
 .../apps/esirius/migrations/0001_initial.py   |  1 +
 passerelle/apps/esirius/models.py             |  4 +-
 .../apps/family/loaders/concerto_fondettes.py |  4 +-
 .../apps/family/loaders/concerto_orleans.py   | 11 +++---
 .../apps/family/loaders/opus_fondettes.py     |  4 +-
 .../commands/import_orleans_data.py           |  6 +--
 .../apps/family/migrations/0001_initial.py    |  2 +-
 .../migrations/0007_auto_20161122_1816.py     |  3 +-
 passerelle/apps/family/models.py              | 12 +++---
 passerelle/apps/feeds/models.py               |  1 -
 .../apps/gdc/migrations/0001_initial.py       |  2 +-
 .../apps/gdc/migrations/0002_gdc_log_level.py |  2 +-
 .../gdc/migrations/0003_auto_20160316_0910.py |  2 +-
 .../gdc/migrations/0004_auto_20160407_0456.py |  2 +-
 passerelle/apps/gdc/urls.py                   |  5 ++-
 passerelle/apps/gdc/views.py                  |  4 +-
 .../apps/gesbac/migrations/0001_initial.py    |  5 ++-
 passerelle/apps/gesbac/models.py              |  8 ++--
 .../jsondatastore/migrations/0001_initial.py  |  3 +-
 passerelle/apps/jsondatastore/models.py       |  2 +-
 .../apps/maelis/migrations/0001_initial.py    |  2 +-
 passerelle/apps/maelis/models.py              |  9 ++---
 passerelle/apps/maelis/utils.py               |  4 +-
 passerelle/apps/mdel/mdel.py                  |  7 ++--
 .../migrations/0003_auto_20170125_0450.py     |  3 +-
 .../migrations/0006_auto_20210126_1440.py     |  1 +
 passerelle/apps/mdel/models.py                |  6 +--
 passerelle/apps/mdel_ddpacs/abstract.py       | 13 +++----
 .../mdel_ddpacs/migrations/0001_initial.py    |  5 ++-
 .../migrations/0002_auto_20200504_1402.py     |  1 +
 passerelle/apps/mdel_ddpacs/models.py         |  5 +--
 .../apps/mobyt/migrations/0001_initial.py     |  2 +-
 .../0002_mobytsmsgateway_log_level.py         |  2 +-
 .../migrations/0003_auto_20160316_0910.py     |  2 +-
 .../migrations/0004_auto_20160407_0456.py     |  2 +-
 ...05_mobytsmsgateway_default_trunk_prefix.py |  2 +-
 passerelle/apps/mobyt/models.py               |  3 +-
 passerelle/apps/opendatasoft/forms.py         |  1 +
 .../opendatasoft/migrations/0001_initial.py   |  3 +-
 passerelle/apps/opendatasoft/models.py        |  4 +-
 passerelle/apps/opendatasoft/views.py         |  2 +-
 passerelle/apps/opengis/forms.py              |  1 +
 .../migrations/0005_auto_20180227_1531.py     |  2 +-
 .../migrations/0007_auto_20200401_1032.py     |  2 +-
 .../opengis/migrations/0008_featurecache.py   |  4 +-
 passerelle/apps/opengis/models.py             |  6 +--
 passerelle/apps/opengis/views.py              |  2 +-
 .../apps/orange/migrations/0001_initial.py    |  2 +-
 .../0002_orangesmsgateway_log_level.py        |  2 +-
 .../migrations/0003_auto_20160316_0910.py     |  2 +-
 .../migrations/0004_auto_20160407_0456.py     |  2 +-
 passerelle/apps/orange/models.py              |  1 -
 .../apps/ovh/migrations/0001_initial.py       |  2 +-
 .../0002_ovhsmsgateway_log_level.py           |  2 +-
 .../ovh/migrations/0003_auto_20160316_0910.py |  2 +-
 .../ovh/migrations/0004_auto_20160407_0456.py |  2 +-
 ...0005_ovhsmsgateway_default_trunk_prefix.py |  2 +-
 passerelle/apps/ovh/models.py                 |  4 +-
 .../apps/oxyd/migrations/0001_initial.py      |  2 +-
 .../0002_oxydsmsgateway_log_level.py          |  2 +-
 .../migrations/0003_auto_20160316_0910.py     |  2 +-
 .../migrations/0004_auto_20160407_0456.py     |  2 +-
 ...005_oxydsmsgateway_default_trunk_prefix.py |  2 +-
 passerelle/apps/oxyd/models.py                |  3 +-
 .../phonecalls/migrations/0001_initial.py     |  4 +-
 passerelle/apps/phonecalls/models.py          |  6 +--
 passerelle/apps/photon/models.py              |  6 +--
 .../migrations/0003_auto_20171219_0800.py     |  1 +
 .../solis/migrations/0006_solisrsalink.py     |  2 +-
 passerelle/apps/solis/models.py               |  4 +-
 passerelle/apps/sp_fr/fields.py               |  4 +-
 passerelle/apps/sp_fr/forms.py                |  2 +-
 .../apps/sp_fr/migrations/0001_initial.py     |  5 ++-
 passerelle/apps/sp_fr/models.py               | 18 ++++-----
 passerelle/apps/sp_fr/views.py                |  6 +--
 passerelle/apps/sp_fr/xsd.py                  |  3 +-
 passerelle/apps/twilio/models.py              |  5 +--
 passerelle/base/admin.py                      |  4 +-
 passerelle/base/forms.py                      |  2 +-
 passerelle/base/management/commands/cron.py   |  3 +-
 .../base/management/commands/ensure_jsonb.py  |  2 +-
 passerelle/base/migrations/0001_initial.py    |  2 +-
 .../migrations/0002_auto_20151009_0326.py     |  2 +-
 .../migrations/0003_auto_20170116_1656.py     |  2 +-
 .../migrations/0004_auto_20170117_0326.py     |  2 +-
 .../base/migrations/0005_resourcelog.py       |  2 +-
 .../base/migrations/0007_loggingparameters.py |  2 +-
 .../migrations/0011_auto_20190205_1126.py     |  2 +-
 passerelle/base/migrations/0012_job.py        |  4 +-
 .../migrations/0014_auto_20190820_0914.py     |  1 +
 .../migrations/0015_auto_20190921_0347.py     |  1 +
 .../migrations/0017_auto_20200310_1806.py     |  3 +-
 passerelle/base/models.py                     | 26 ++++++-------
 passerelle/base/signature.py                  |  5 +--
 passerelle/base/templatetags/passerelle.py    |  9 +++--
 passerelle/base/urls.py                       | 10 ++---
 passerelle/base/views.py                      | 11 +++---
 passerelle/contrib/dpark/models.py            |  8 ++--
 .../contrib/fake_family/default_database.py   |  4 +-
 .../fake_family/migrations/0001_initial.py    |  2 +-
 .../migrations/0002_fakefamily_log_level.py   |  2 +-
 passerelle/contrib/fake_family/models.py      |  3 +-
 passerelle/contrib/gdema/models.py            |  2 +-
 passerelle/contrib/greco/models.py            | 15 +++-----
 passerelle/contrib/grenoble_gru/models.py     |  8 ++--
 .../iparapheur/migrations/0001_initial.py     |  2 +-
 .../migrations/0002_auto_20160406_1123.py     |  2 +-
 .../migrations/0003_iparapheur_log_level.py   |  2 +-
 passerelle/contrib/iparapheur/models.py       |  9 ++---
 passerelle/contrib/isere_ens/models.py        |  7 ++--
 passerelle/contrib/iws/models.py              |  7 ++--
 passerelle/contrib/lille_kimoce/models.py     |  5 +--
 .../contrib/mdph13/migrations/0001_initial.py |  2 +-
 passerelle/contrib/mdph13/models.py           |  9 ++---
 .../nancypoll/migrations/0001_initial.py      |  2 +-
 .../migrations/0004_csv_upload_to.py          |  1 +
 .../migrations/0005_csv_upload_to.py          |  1 +
 passerelle/contrib/nancypoll/models.py        |  3 +-
 .../0002_planitechconnector_custom_fields.py  |  2 +-
 .../planitech/migrations/0003_pairing.py      |  2 +-
 passerelle/contrib/planitech/models.py        |  6 +--
 passerelle/contrib/planitech/mste.py          |  3 +-
 passerelle/contrib/rsa13/models.py            |  3 +-
 passerelle/contrib/sigerly/models.py          |  1 -
 .../solis_apa/migrations/0001_initial.py      |  2 +-
 passerelle/contrib/solis_apa/models.py        |  9 ++---
 passerelle/contrib/solis_apa/suivi.py         |  2 +-
 passerelle/contrib/solis_apa/views.py         |  7 ++--
 passerelle/contrib/strasbourg_eu/models.py    |  2 +-
 passerelle/contrib/stub_invoices/models.py    |  4 +-
 passerelle/contrib/tcl/models.py              |  2 +-
 .../teamnet_axel/migrations/0001_initial.py   |  2 +-
 .../0002_management_billing_regies.py         |  2 +-
 .../migrations/0003_management_log_level.py   |  2 +-
 passerelle/contrib/teamnet_axel/models.py     |  6 +--
 passerelle/contrib/teamnet_axel/soap.py       |  4 +-
 .../toulouse_axel/migrations/0001_initial.py  |  2 +-
 .../migrations/0003_auto_20191205_0948.py     |  2 +-
 passerelle/contrib/toulouse_axel/models.py    |  4 +-
 passerelle/contrib/toulouse_axel/schemas.py   |  4 +-
 passerelle/contrib/toulouse_axel/utils.py     |  4 +-
 passerelle/plugins.py                         |  2 +-
 passerelle/settings.py                        |  5 ++-
 passerelle/sms/models.py                      |  1 -
 passerelle/soap.py                            |  2 +-
 passerelle/urls.py                            | 23 +++++-------
 passerelle/urls_utils.py                      |  3 +-
 passerelle/utils/__init__.py                  | 29 +++++++--------
 passerelle/utils/conversion.py                |  3 +-
 passerelle/utils/files.py                     |  4 +-
 passerelle/utils/http_authenticators.py       |  1 -
 passerelle/utils/json.py                      |  1 -
 passerelle/utils/jsonresponse.py              | 12 +++---
 passerelle/utils/paginator.py                 |  2 +-
 passerelle/utils/sftp.py                      | 16 ++++----
 passerelle/utils/soap.py                      |  4 +-
 passerelle/utils/templates.py                 |  3 +-
 passerelle/utils/wcs.py                       | 15 ++++----
 passerelle/utils/xml.py                       |  2 +-
 passerelle/utils/zip.py                       | 14 +++----
 passerelle/views.py                           | 37 +++++++++----------
 setup.py                                      |  6 +--
 tests/conftest.py                             | 11 +++---
 tests/test_actesweb.py                        |  5 +--
 tests/test_adict.py                           |  4 +-
 tests/test_airquality.py                      |  3 +-
 tests/test_api.py                             |  8 ++--
 tests/test_api_access.py                      | 12 +++---
 tests/test_api_entreprise.py                  |  9 ++---
 tests/test_api_particulier.py                 | 14 +++----
 tests/test_arcgis.py                          | 11 +++---
 tests/test_arcgis_nancy.py                    |  9 ++---
 tests/test_arpege_ecp.py                      |  5 +--
 tests/test_astregs.py                         | 14 +++----
 tests/test_atal.py                            |  8 ++--
 tests/test_atos_genesys.py                    |  6 +--
 tests/test_availability.py                    |  5 +--
 tests/test_base_adresse.py                    | 13 +++----
 tests/test_cartads_cs.py                      | 12 +++---
 tests/test_cityweb.py                         | 15 ++++----
 tests/test_clicrdv.py                         |  9 ++---
 tests/test_cmis.py                            | 31 ++++++++--------
 tests/test_cron.py                            |  1 -
 tests/test_cryptor.py                         |  9 ++---
 tests/test_csv_datasource.py                  | 22 +++++------
 tests/test_dpark.py                           | 12 +++---
 tests/test_ensure_jsonbfields.py              |  1 -
 tests/test_esirius.py                         |  7 ++--
 tests/test_fake_family.py                     |  2 +-
 tests/test_family.py                          | 34 +++++++++--------
 tests/test_feeds.py                           |  3 +-
 tests/test_gdema.py                           |  7 ++--
 tests/test_generic_endpoint.py                | 20 ++++++----
 tests/test_gesbac.py                          |  6 +--
 tests/test_grandlyon_streetsections.py        |  5 +--
 tests/test_greco.py                           | 10 ++---
 tests/test_grenoble_gru.py                    |  3 +-
 tests/test_import_export.py                   | 14 +++----
 tests/test_iparapheur.py                      | 18 ++++-----
 tests/test_isere_ens.py                       |  3 +-
 tests/test_iws.py                             |  4 +-
 tests/test_jobs.py                            | 13 ++-----
 tests/test_jsondatastore.py                   |  5 +--
 tests/test_jsonresponse.py                    |  6 +--
 tests/test_lille_kimoce.py                    |  3 +-
 tests/test_lille_urban_card.py                |  6 +--
 tests/test_maelis.py                          | 14 +++----
 tests/test_manager.py                         | 10 ++---
 tests/test_mdel.py                            | 12 +++---
 tests/test_mdel_ddpacs.py                     |  6 +--
 tests/test_mdph13.py                          | 10 ++---
 tests/test_misc.py                            | 12 +++---
 tests/test_nancypoll.py                       |  8 ++--
 tests/test_okina.py                           |  7 ++--
 tests/test_opendatasoft.py                    |  8 ++--
 tests/test_opengis.py                         | 10 ++---
 tests/test_orange.py                          |  7 +---
 tests/test_phonecalls.py                      |  8 ++--
 tests/test_photon.py                          | 10 ++---
 tests/test_planitech.py                       | 10 ++---
 tests/test_proxylogger.py                     | 14 +++----
 tests/test_requests.py                        | 14 +++----
 tests/test_rsa13.py                           |  1 -
 tests/test_sigerly.py                         |  4 +-
 tests/test_sms.py                             | 16 ++++----
 tests/test_soap.py                            |  7 ++--
 tests/test_solis.py                           |  5 +--
 tests/test_solis_afi_mss.py                   |  1 -
 tests/test_solis_apa.py                       | 10 ++---
 tests/test_strasbourg_eu.py                   |  8 ++--
 tests/test_tcl.py                             |  7 ++--
 tests/test_teamnet_axel.py                    |  6 +--
 tests/test_toulouse_axel.py                   | 23 +++++-------
 tests/test_toulouse_axel_schema.py            |  4 +-
 tests/test_toulouse_axel_utils.py             |  3 +-
 tests/test_utils_files.py                     |  2 +-
 tests/test_utils_json.py                      |  6 +--
 tests/test_utils_sftp.py                      |  3 +-
 tests/test_utils_xml.py                       |  7 ++--
 tests/test_utils_zip.py                       |  2 +-
 tests/test_vivaticket.py                      |  4 +-
 tests/utils.py                                |  5 +--
 tests/wcs/conftest.py                         | 19 +++++-----
 tests/wcs/test_conftest.py                    |  3 +-
 tests/wcs/test_sp_fr.py                       |  8 ++--
 322 files changed, 807 insertions(+), 950 deletions(-)

diff --git a/functests/cmis/conftest.py b/functests/cmis/conftest.py
index 5eac0663..8d2d7c24 100644
--- a/functests/cmis/conftest.py
+++ b/functests/cmis/conftest.py
@@ -1,12 +1,12 @@
 import random
 
-import pytest
 import cmislib
+import pytest
 
 
 def pytest_addoption(parser):
     parser.addoption("--cmis-connector-url", help="Url of a passerelle CMIS connector instance")
     parser.addoption("--cmis-endpoint", help="Url of a passerelle CMIS endpoint")
     parser.addoption("--cmis-username", help="Username for the CMIS endpoint")
     parser.addoption("--cmis-password", help="Password for the CMIS endpoint")
     parser.addoption("--preserve-tree", action="store_true", default=False, help="Preserve test directory")
diff --git a/functests/cmis/tests_cmis.py b/functests/cmis/tests_cmis.py
index 63178e41..d4e6bbcf 100644
--- a/functests/cmis/tests_cmis.py
+++ b/functests/cmis/tests_cmis.py
@@ -1,16 +1,15 @@
 import base64
 import hashlib
 import os
 
-from django.utils.six.moves.urllib import parse as urlparse
 import pytest
 import requests
-
+from django.utils.six.moves.urllib import parse as urlparse
 
 SPECIAL_CHARS = '!#$%&+-^_`;[]{}+='
 
 
 @pytest.mark.parametrize(
     "path,file_name",
     [
         ('', 'some.file'),
diff --git a/functests/planitech/test_planitech.py b/functests/planitech/test_planitech.py
index 4f6baa4d..08d904f1 100644
--- a/functests/planitech/test_planitech.py
+++ b/functests/planitech/test_planitech.py
@@ -1,13 +1,13 @@
 import pprint
 import random
 
-from django.utils.six.moves.urllib import parse
 import requests
+from django.utils.six.moves.urllib import parse
 
 
 def test_main(conn):
     # get days
     query_string = parse.urlencode(
         {'start_days': 1, 'end_days': 90, 'start_time': '10:00', 'end_time': '11:00', 'display': 'date'}
     )
     url = conn + '/getfreegaps?%s' % query_string
diff --git a/functests/toulouse_axel/test_toulouse_axel.py b/functests/toulouse_axel/test_toulouse_axel.py
index 427eb16d..8678516c 100644
--- a/functests/toulouse_axel/test_toulouse_axel.py
+++ b/functests/toulouse_axel/test_toulouse_axel.py
@@ -1,9 +1,10 @@
 import pprint
+
 import requests
 
 
 def test_link(conn, user):
     print("Get update management dates")
     url = conn + '/management_dates'
     resp = requests.get(url)
     resp.raise_for_status()
diff --git a/functests/vivaticket/test_vivaticket.py b/functests/vivaticket/test_vivaticket.py
index f61979fd..7c14b876 100644
--- a/functests/vivaticket/test_vivaticket.py
+++ b/functests/vivaticket/test_vivaticket.py
@@ -1,14 +1,16 @@
 from __future__ import print_function
-import pprint
+
 import datetime
-import requests
+import pprint
 import random
 
+import requests
+
 
 def call_generic(conn, endpoint):
     print("%s \n" % endpoint)
     url = conn + '/%s' % endpoint
     resp = requests.get(url)
     resp.raise_for_status()
     res = resp.json()
     assert res['err'] == 0
diff --git a/passerelle/api/views.py b/passerelle/api/views.py
index 0124b805..edf7e073 100644
--- a/passerelle/api/views.py
+++ b/passerelle/api/views.py
@@ -10,18 +10,17 @@
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 from django.core.exceptions import PermissionDenied
-from django.http import Http404
-from django.http import JsonResponse
+from django.http import Http404, JsonResponse
 from django.views.generic import DetailView
 
 from passerelle.base.models import Job
 from passerelle.utils import is_authorized
 
 
 class JobDetailView(DetailView):
     model = Job
diff --git a/passerelle/apps/actesweb/models.py b/passerelle/apps/actesweb/models.py
index dc7b383a..b3a66ac1 100644
--- a/passerelle/apps/actesweb/models.py
+++ b/passerelle/apps/actesweb/models.py
@@ -10,33 +10,33 @@
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 from __future__ import unicode_literals
 
+import contextlib
 import os
 import stat
 import tempfile
-import contextlib
 
 from django.core.files.storage import default_storage
 from django.template.loader import get_template
 from django.utils.dateparse import parse_date
 from django.utils.encoding import force_bytes
 from django.utils.timezone import now
 from django.utils.translation import ugettext_lazy as _
 
 from passerelle.base.models import BaseResource
 from passerelle.compat import json_loads
 from passerelle.utils.api import endpoint
-from passerelle.utils.jsonresponse import APIError
 from passerelle.utils.conversion import ensure_encoding
+from passerelle.utils.jsonresponse import APIError
 
 
 @contextlib.contextmanager
 def named_tempfile(*args, **kwargs):
     with tempfile.NamedTemporaryFile(*args, **kwargs) as fp:
         yield fp
 
 
diff --git a/passerelle/apps/api_entreprise/models.py b/passerelle/apps/api_entreprise/models.py
index be6c8723..5d127028 100644
--- a/passerelle/apps/api_entreprise/models.py
+++ b/passerelle/apps/api_entreprise/models.py
@@ -13,26 +13,24 @@
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 '''Gateway to API-Entreprise web-service from SGMAP:
    https://entreprise.api.gouv.fr
 '''
 
-from six.moves.urllib_parse import urljoin
 import requests
-
-
-from django.db import models
-from django.utils.translation import ugettext_lazy as _
-from django.utils.timezone import datetime, make_aware, timedelta
-from django.http import HttpResponse, Http404
 from django.core import signing
+from django.db import models
+from django.http import Http404, HttpResponse
 from django.urls import reverse
+from django.utils.timezone import datetime, make_aware, timedelta
+from django.utils.translation import ugettext_lazy as _
+from six.moves.urllib_parse import urljoin
 
 from passerelle.base.models import BaseResource
 from passerelle.utils.api import endpoint
 from passerelle.utils.jsonresponse import APIError, exception_to_text
 from passerelle.views import WrongParameter
 
 DOCUMENT_SIGNATURE_MAX_AGE = timedelta(days=7)
 
diff --git a/passerelle/apps/api_particulier/migrations/0001_initial.py b/passerelle/apps/api_particulier/migrations/0001_initial.py
index 8e5b5498..64e0b031 100644
--- a/passerelle/apps/api_particulier/migrations/0001_initial.py
+++ b/passerelle/apps/api_particulier/migrations/0001_initial.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('base', '0002_auto_20151009_0326'),
     ]
 
diff --git a/passerelle/apps/api_particulier/models.py b/passerelle/apps/api_particulier/models.py
index f53a8aa3..7ed6f4b5 100644
--- a/passerelle/apps/api_particulier/models.py
+++ b/passerelle/apps/api_particulier/models.py
@@ -14,16 +14,17 @@
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 '''Gateway to API-Particulier web-service from SGMAP:
    https://particulier.api.gouv.fr/
 '''
 
 from collections import OrderedDict
+
 import requests
 
 try:
     from json.decoder import JSONDecodeError
 except ImportError:
     JSONDecodeError = ValueError
 
 
diff --git a/passerelle/apps/arcgis/forms.py b/passerelle/apps/arcgis/forms.py
index a13ddaf1..d1ab4118 100644
--- a/passerelle/apps/arcgis/forms.py
+++ b/passerelle/apps/arcgis/forms.py
@@ -12,16 +12,17 @@
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 from django import forms
 
 from passerelle.base.forms import BaseQueryFormMixin
+
 from . import models
 
 
 class QueryForm(BaseQueryFormMixin, forms.ModelForm):
     class Meta:
         model = models.Query
         fields = '__all__'
         exclude = ['resource']
diff --git a/passerelle/apps/arcgis/migrations/0005_auto_20200310_1517.py b/passerelle/apps/arcgis/migrations/0005_auto_20200310_1517.py
index 1e63e049..1dd1ec48 100644
--- a/passerelle/apps/arcgis/migrations/0005_auto_20200310_1517.py
+++ b/passerelle/apps/arcgis/migrations/0005_auto_20200310_1517.py
@@ -1,14 +1,15 @@
 # -*- coding: utf-8 -*-
 # Generated by Django 1.11.20 on 2020-03-10 20:17
 from __future__ import unicode_literals
 
-from django.db import migrations, models
 import django.db.models.deletion
+from django.db import migrations, models
+
 import passerelle.apps.arcgis.models
 import passerelle.utils.templates
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('arcgis', '0004_remove_arcgis_log_level'),
diff --git a/passerelle/apps/arcgis/migrations/0006_auto_20200401_1025.py b/passerelle/apps/arcgis/migrations/0006_auto_20200401_1025.py
index e5379a82..5a88c61f 100644
--- a/passerelle/apps/arcgis/migrations/0006_auto_20200401_1025.py
+++ b/passerelle/apps/arcgis/migrations/0006_auto_20200401_1025.py
@@ -1,14 +1,14 @@
 # -*- coding: utf-8 -*-
 # Generated by Django 1.11.18 on 2020-04-01 08:25
 from __future__ import unicode_literals
 
-from django.db import migrations, models
 import django.db.models.deletion
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('arcgis', '0005_auto_20200310_1517'),
     ]
 
diff --git a/passerelle/apps/arcgis/models.py b/passerelle/apps/arcgis/models.py
index 0b7fbb31..0dde6976 100644
--- a/passerelle/apps/arcgis/models.py
+++ b/passerelle/apps/arcgis/models.py
@@ -12,31 +12,31 @@
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import string
 
 from django.core.exceptions import ValidationError
-from django.urls import reverse
 from django.db import models
 from django.http import HttpResponse
 from django.shortcuts import get_object_or_404
-from django.utils.six.moves.urllib import parse as urlparse
+from django.urls import reverse
 from django.utils import six
+from django.utils.six.moves.urllib import parse as urlparse
 from django.utils.text import slugify
 from django.utils.translation import ugettext_lazy as _
 
+from passerelle.base.models import BaseQuery, BaseResource, HTTPResource
 from passerelle.utils import mark_safe_lazy
-from passerelle.utils.jsonresponse import APIError
 from passerelle.utils.api import endpoint
 from passerelle.utils.conversion import num2deg
+from passerelle.utils.jsonresponse import APIError
 from passerelle.utils.templates import render_to_string, validate_template
-from passerelle.base.models import BaseResource, HTTPResource, BaseQuery
 
 
 class ArcGISError(APIError):
     pass
 
 
 class ArcGIS(BaseResource, HTTPResource):
     category = _('Geographic information system')
diff --git a/passerelle/apps/arcgis/views.py b/passerelle/apps/arcgis/views.py
index a4778665..8d4d1f33 100644
--- a/passerelle/apps/arcgis/views.py
+++ b/passerelle/apps/arcgis/views.py
@@ -9,17 +9,17 @@
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-from django.views.generic import UpdateView, CreateView, DeleteView
+from django.views.generic import CreateView, DeleteView, UpdateView
 
 from passerelle.base.mixins import ResourceChildViewMixin
 
 from . import models
 from .forms import QueryForm
 
 
 class QueryNew(ResourceChildViewMixin, CreateView):
diff --git a/passerelle/apps/arpege_ecp/models.py b/passerelle/apps/arpege_ecp/models.py
index 6b396626..fd54d011 100644
--- a/passerelle/apps/arpege_ecp/models.py
+++ b/passerelle/apps/arpege_ecp/models.py
@@ -11,24 +11,22 @@
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import json
 
-from requests import RequestException
-
 from django.db import models
-from django.utils import six
+from django.utils import six, timezone
+from django.utils.dateparse import parse_date, parse_time
 from django.utils.six.moves.urllib import parse as urlparse
 from django.utils.translation import ugettext_lazy as _
-from django.utils.dateparse import parse_date, parse_time
-from django.utils import timezone
+from requests import RequestException
 
 from passerelle.base.models import BaseResource
 from passerelle.utils.api import endpoint
 from passerelle.utils.http_authenticators import HawkAuth
 from passerelle.utils.jsonresponse import APIError
 
 
 class ArpegeECP(BaseResource):
diff --git a/passerelle/apps/astregs/migrations/0001_initial.py b/passerelle/apps/astregs/migrations/0001_initial.py
index 03c96b9e..e1116761 100644
--- a/passerelle/apps/astregs/migrations/0001_initial.py
+++ b/passerelle/apps/astregs/migrations/0001_initial.py
@@ -1,14 +1,14 @@
 # -*- coding: utf-8 -*-
 # Generated by Django 1.11.20 on 2019-06-19 10:24
 from __future__ import unicode_literals
 
-from django.db import migrations, models
 import django.db.models.deletion
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     initial = True
 
     dependencies = [
         ('base', '0012_job'),
diff --git a/passerelle/apps/astregs/models.py b/passerelle/apps/astregs/models.py
index 62f38501..1702cfb4 100644
--- a/passerelle/apps/astregs/models.py
+++ b/passerelle/apps/astregs/models.py
@@ -10,23 +10,23 @@
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import base64
-import zeep
-from zeep.helpers import serialize_object
 
+import zeep
 from django.db import models
-from django.utils.translation import ugettext_lazy as _
-from django.utils.six.moves.urllib import parse as urlparse
 from django.http import Http404
+from django.utils.six.moves.urllib import parse as urlparse
+from django.utils.translation import ugettext_lazy as _
+from zeep.helpers import serialize_object
 
 from passerelle.base.models import BaseResource
 from passerelle.utils.api import endpoint
 from passerelle.utils.jsonresponse import APIError
 from passerelle.utils.validation import is_number
 
 ASSOCIATION_SCHEMA = {
     "$schema": "http://json-schema.org/draft-04/schema#",
diff --git a/passerelle/apps/atal/models.py b/passerelle/apps/atal/models.py
index 5929b661..6d3dd603 100644
--- a/passerelle/apps/atal/models.py
+++ b/passerelle/apps/atal/models.py
@@ -12,30 +12,30 @@
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import base64
 import binascii
 
+import lxml.etree
 from django.db import models
 from django.utils import dateformat, dateparse
 from django.utils.encoding import force_text
 from django.utils.six.moves import urllib
 from django.utils.translation import ugettext_lazy as _
-import lxml.etree
 from zeep import helpers
 from zeep.exceptions import Fault
 
 from passerelle.base.models import BaseResource
 from passerelle.utils.api import endpoint
 from passerelle.utils.jsonresponse import APIError
-from . import schemas
 
+from . import schemas
 
 DATE_FORMAT = 'l d F Y, G:i'
 
 
 def process_response(demande_number):
     if demande_number.startswith('DIT') or demande_number.startswith('DPR'):
         return {'data': {'demande_number': demande_number}}
     raise APIError(demande_number)
diff --git a/passerelle/apps/atos_genesys/migrations/0001_initial.py b/passerelle/apps/atos_genesys/migrations/0001_initial.py
index 46afa293..aff2698c 100644
--- a/passerelle/apps/atos_genesys/migrations/0001_initial.py
+++ b/passerelle/apps/atos_genesys/migrations/0001_initial.py
@@ -1,15 +1,15 @@
 # -*- coding: utf-8 -*-
 # Generated by Django 1.11.10 on 2018-09-18 09:42
 from __future__ import unicode_literals
 
-from django.db import migrations, models
-import django.db.models.deletion
 import django.contrib.postgres.fields.jsonb
+import django.db.models.deletion
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     initial = True
 
     dependencies = [
         ('base', '0006_resourcestatus'),
diff --git a/passerelle/apps/atos_genesys/models.py b/passerelle/apps/atos_genesys/models.py
index 49990d7d..1ba00722 100644
--- a/passerelle/apps/atos_genesys/models.py
+++ b/passerelle/apps/atos_genesys/models.py
@@ -10,31 +10,31 @@
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import datetime
-import requests
 import xml.etree.ElementTree as ET
 
+import requests
 from django.contrib.postgres.fields import JSONField
 from django.db import models
 from django.utils import six
 from django.utils.six.moves.urllib import parse as urlparse
 from django.utils.translation import ugettext_lazy as _
 
+from passerelle.base.models import BaseResource, HTTPResource
 from passerelle.utils import xml as xmlutils
 from passerelle.utils.api import endpoint
 from passerelle.utils.conversion import to_ascii
 from passerelle.utils.jsonresponse import APIError
 from passerelle.utils.validation import is_number
-from passerelle.base.models import BaseResource, HTTPResource
 
 from . import utils
 
 
 class Resource(BaseResource, HTTPResource):
     category = _('Business Process Connectors')
 
     webservice_base_url = models.URLField(_('Webservice Base URL'))
diff --git a/passerelle/apps/atos_genesys/utils.py b/passerelle/apps/atos_genesys/utils.py
index c009888e..893000bc 100644
--- a/passerelle/apps/atos_genesys/utils.py
+++ b/passerelle/apps/atos_genesys/utils.py
@@ -1,13 +1,13 @@
 import time
 from contextlib import contextmanager
 
-from django.db import transaction
 from django.core.cache import cache
+from django.db import transaction
 from django.utils import six
 
 from passerelle.utils.jsonresponse import APIError
 
 DEFAULT_DURATION = 5 * 60  # 5 minutes
 
 # keep data in cache for 1 day, i.e. we can answer a request from cache for 1 day
 # day
diff --git a/passerelle/apps/base_adresse/migrations/0001_initial.py b/passerelle/apps/base_adresse/migrations/0001_initial.py
index 997a3277..baa9b316 100644
--- a/passerelle/apps/base_adresse/migrations/0001_initial.py
+++ b/passerelle/apps/base_adresse/migrations/0001_initial.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('base', '0001_initial'),
     ]
 
diff --git a/passerelle/apps/base_adresse/migrations/0002_auto_20150705_0330.py b/passerelle/apps/base_adresse/migrations/0002_auto_20150705_0330.py
index 9626bd98..6add7cc4 100644
--- a/passerelle/apps/base_adresse/migrations/0002_auto_20150705_0330.py
+++ b/passerelle/apps/base_adresse/migrations/0002_auto_20150705_0330.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('base_adresse', '0001_initial'),
     ]
 
diff --git a/passerelle/apps/base_adresse/migrations/0003_baseaddresse_log_level.py b/passerelle/apps/base_adresse/migrations/0003_baseaddresse_log_level.py
index 753baea6..9a594fdb 100644
--- a/passerelle/apps/base_adresse/migrations/0003_baseaddresse_log_level.py
+++ b/passerelle/apps/base_adresse/migrations/0003_baseaddresse_log_level.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('base_adresse', '0002_auto_20150705_0330'),
     ]
 
diff --git a/passerelle/apps/base_adresse/migrations/0004_auto_20160316_0910.py b/passerelle/apps/base_adresse/migrations/0004_auto_20160316_0910.py
index 37f4b239..6a100402 100644
--- a/passerelle/apps/base_adresse/migrations/0004_auto_20160316_0910.py
+++ b/passerelle/apps/base_adresse/migrations/0004_auto_20160316_0910.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('base_adresse', '0003_baseaddresse_log_level'),
     ]
 
diff --git a/passerelle/apps/base_adresse/migrations/0005_auto_20160407_0456.py b/passerelle/apps/base_adresse/migrations/0005_auto_20160407_0456.py
index 52410033..1bdde0b6 100644
--- a/passerelle/apps/base_adresse/migrations/0005_auto_20160407_0456.py
+++ b/passerelle/apps/base_adresse/migrations/0005_auto_20160407_0456.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('base_adresse', '0004_auto_20160316_0910'),
     ]
 
diff --git a/passerelle/apps/base_adresse/migrations/0008_delete_updatestreetmodel.py b/passerelle/apps/base_adresse/migrations/0008_delete_updatestreetmodel.py
index 44d85990..ea591e12 100644
--- a/passerelle/apps/base_adresse/migrations/0008_delete_updatestreetmodel.py
+++ b/passerelle/apps/base_adresse/migrations/0008_delete_updatestreetmodel.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('base_adresse', '0007_auto_20160729_1540'),
     ]
 
diff --git a/passerelle/apps/base_adresse/migrations/0009_streetmodel_simple_name.py b/passerelle/apps/base_adresse/migrations/0009_streetmodel_simple_name.py
index bd99efca..95ea1faf 100644
--- a/passerelle/apps/base_adresse/migrations/0009_streetmodel_simple_name.py
+++ b/passerelle/apps/base_adresse/migrations/0009_streetmodel_simple_name.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('base_adresse', '0008_delete_updatestreetmodel'),
     ]
 
diff --git a/passerelle/apps/base_adresse/migrations/0010_auto_20160914_0826.py b/passerelle/apps/base_adresse/migrations/0010_auto_20160914_0826.py
index 6a2a7a1b..c3c6b540 100644
--- a/passerelle/apps/base_adresse/migrations/0010_auto_20160914_0826.py
+++ b/passerelle/apps/base_adresse/migrations/0010_auto_20160914_0826.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('base_adresse', '0009_streetmodel_simple_name'),
     ]
 
diff --git a/passerelle/apps/base_adresse/migrations/0011_auto_20160919_0949.py b/passerelle/apps/base_adresse/migrations/0011_auto_20160919_0949.py
index 181f6b7b..709bda0d 100644
--- a/passerelle/apps/base_adresse/migrations/0011_auto_20160919_0949.py
+++ b/passerelle/apps/base_adresse/migrations/0011_auto_20160919_0949.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('base_adresse', '0010_auto_20160914_0826'),
     ]
 
diff --git a/passerelle/apps/base_adresse/migrations/0015_auto_20191206_1244.py b/passerelle/apps/base_adresse/migrations/0015_auto_20191206_1244.py
index 49ff6895..20a5289f 100644
--- a/passerelle/apps/base_adresse/migrations/0015_auto_20191206_1244.py
+++ b/passerelle/apps/base_adresse/migrations/0015_auto_20191206_1244.py
@@ -1,14 +1,15 @@
 # -*- coding: utf-8 -*-
 # Generated by Django 1.11.18 on 2019-12-06 11:44
 from __future__ import unicode_literals
 
-from django.db import migrations, models
 import django.db.models.deletion
+from django.db import migrations, models
+
 import passerelle.apps.base_adresse.models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('base_adresse', '0014_auto_20190207_0456'),
     ]
diff --git a/passerelle/apps/base_adresse/migrations/0016_auto_20200130_1604.py b/passerelle/apps/base_adresse/migrations/0016_auto_20200130_1604.py
index f08d3131..1109f131 100644
--- a/passerelle/apps/base_adresse/migrations/0016_auto_20200130_1604.py
+++ b/passerelle/apps/base_adresse/migrations/0016_auto_20200130_1604.py
@@ -1,14 +1,14 @@
 # -*- coding: utf-8 -*-
 # Generated by Django 1.11.18 on 2020-01-30 15:04
 from __future__ import unicode_literals
 
-from django.db import migrations, models
 import django.contrib.postgres.fields.jsonb
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('base_adresse', '0015_auto_20191206_1244'),
     ]
 
diff --git a/passerelle/apps/base_adresse/models.py b/passerelle/apps/base_adresse/models.py
index c9a0a903..69da1060 100644
--- a/passerelle/apps/base_adresse/models.py
+++ b/passerelle/apps/base_adresse/models.py
@@ -1,23 +1,21 @@
 import datetime
 import gzip
 
-from requests import RequestException
-from requests.exceptions import ConnectionError
-
 from django.contrib.postgres.fields import JSONField
 from django.db import connection, models
 from django.db.models import Q
+from django.utils import six, timezone
 from django.utils.http import urlencode
-from django.utils.translation import ugettext_lazy as _
-from django.utils import timezone
-from django.utils import six
 from django.utils.six import StringIO
 from django.utils.six.moves.urllib import parse as urlparse
+from django.utils.translation import ugettext_lazy as _
+from requests import RequestException
+from requests.exceptions import ConnectionError
 
 from passerelle.base.models import BaseResource
 from passerelle.compat import json_loads
 from passerelle.utils.api import endpoint
 from passerelle.utils.conversion import simplify
 from passerelle.utils.jsonresponse import APIError
 
 
diff --git a/passerelle/apps/bdp/migrations/0001_initial.py b/passerelle/apps/bdp/migrations/0001_initial.py
index 503e736a..4f547717 100644
--- a/passerelle/apps/bdp/migrations/0001_initial.py
+++ b/passerelle/apps/bdp/migrations/0001_initial.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('base', '0001_initial'),
     ]
 
diff --git a/passerelle/apps/bdp/migrations/0002_bdp_log_level.py b/passerelle/apps/bdp/migrations/0002_bdp_log_level.py
index ade9793b..9b75018f 100644
--- a/passerelle/apps/bdp/migrations/0002_bdp_log_level.py
+++ b/passerelle/apps/bdp/migrations/0002_bdp_log_level.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('bdp', '0001_initial'),
     ]
 
diff --git a/passerelle/apps/bdp/migrations/0003_auto_20160316_0910.py b/passerelle/apps/bdp/migrations/0003_auto_20160316_0910.py
index 0058f98e..28c6e183 100644
--- a/passerelle/apps/bdp/migrations/0003_auto_20160316_0910.py
+++ b/passerelle/apps/bdp/migrations/0003_auto_20160316_0910.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('bdp', '0002_bdp_log_level'),
     ]
 
diff --git a/passerelle/apps/bdp/migrations/0004_auto_20160407_0456.py b/passerelle/apps/bdp/migrations/0004_auto_20160407_0456.py
index 8a75b1a5..f13c72f7 100644
--- a/passerelle/apps/bdp/migrations/0004_auto_20160407_0456.py
+++ b/passerelle/apps/bdp/migrations/0004_auto_20160407_0456.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('bdp', '0003_auto_20160316_0910'),
     ]
 
diff --git a/passerelle/apps/bdp/models.py b/passerelle/apps/bdp/models.py
index 411a2d55..a3b4282e 100644
--- a/passerelle/apps/bdp/models.py
+++ b/passerelle/apps/bdp/models.py
@@ -1,15 +1,15 @@
 import json
-import requests
-from requests.auth import HTTPBasicAuth
 
-from django.urls import reverse
+import requests
 from django.db import models
+from django.urls import reverse
 from django.utils.translation import ugettext_lazy as _
+from requests.auth import HTTPBasicAuth
 
 from passerelle.base.models import BaseResource
 
 
 class Bdp(BaseResource):
     service_url = models.CharField(
         max_length=128, blank=False, verbose_name=_('Service URL'), help_text=_('BDP Web Service URL')
     )
diff --git a/passerelle/apps/bdp/urls.py b/passerelle/apps/bdp/urls.py
index 174db442..69e9f354 100644
--- a/passerelle/apps/bdp/urls.py
+++ b/passerelle/apps/bdp/urls.py
@@ -1,11 +1,12 @@
-from django.views.decorators.csrf import csrf_exempt
 from django.conf.urls import url
-from .views import BdpDetailView, ResourcesView, PostAdherentView
+from django.views.decorators.csrf import csrf_exempt
+
+from .views import BdpDetailView, PostAdherentView, ResourcesView
 
 urlpatterns = [
     url(r'^(?P<slug>[\w,-]+)/$', BdpDetailView.as_view(), name='bdp-view'),
     url(r'^(?P<slug>[\w,-]+)/(?P<resources>[\w,-]+)/$', ResourcesView.as_view(), name='bdp-resources'),
     url(
         r'^(?P<slug>[\w,-]+)/post/adherent/$',
         csrf_exempt(PostAdherentView.as_view()),
         name='bdp-post-adherent',
diff --git a/passerelle/apps/bdp/views.py b/passerelle/apps/bdp/views.py
index 947e58cd..a20c3955 100644
--- a/passerelle/apps/bdp/views.py
+++ b/passerelle/apps/bdp/views.py
@@ -1,14 +1,14 @@
 from django.http import Http404
 from django.views.generic.base import View
-from django.views.generic.detail import SingleObjectMixin, DetailView
+from django.views.generic.detail import DetailView, SingleObjectMixin
 
-from passerelle.compat import json_loads
 import passerelle.utils as utils
+from passerelle.compat import json_loads
 
 from .models import Bdp
 
 # See documentation:
 # https://dev.entrouvert.org/projects/bdp/wiki/WebServices
 
 
 class ResourcesView(View, SingleObjectMixin):
diff --git a/passerelle/apps/cartads_cs/migrations/0001_initial.py b/passerelle/apps/cartads_cs/migrations/0001_initial.py
index 41bc8675..e295e686 100644
--- a/passerelle/apps/cartads_cs/migrations/0001_initial.py
+++ b/passerelle/apps/cartads_cs/migrations/0001_initial.py
@@ -1,13 +1,14 @@
 # -*- coding: utf-8 -*-
 # Generated by Django 1.11.12 on 2019-02-20 10:38
 from __future__ import unicode_literals
 
 from django.db import migrations, models
+
 import passerelle.apps.cartads_cs.models
 
 
 class Migration(migrations.Migration):
 
     initial = True
 
     dependencies = [
diff --git a/passerelle/apps/cartads_cs/migrations/0002_cartadsdatacache.py b/passerelle/apps/cartads_cs/migrations/0002_cartadsdatacache.py
index 2c83fb82..9501b997 100644
--- a/passerelle/apps/cartads_cs/migrations/0002_cartadsdatacache.py
+++ b/passerelle/apps/cartads_cs/migrations/0002_cartadsdatacache.py
@@ -1,14 +1,14 @@
 # -*- coding: utf-8 -*-
 # Generated by Django 1.11.12 on 2019-08-31 09:48
 from __future__ import unicode_literals
 
-from django.db import migrations, models
 import django.contrib.postgres.fields.jsonb
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('cartads_cs', '0001_initial'),
     ]
 
diff --git a/passerelle/apps/cartads_cs/migrations/0004_cartadsdossier_cartads_steps_cache.py b/passerelle/apps/cartads_cs/migrations/0004_cartadsdossier_cartads_steps_cache.py
index 3676af4f..4e7aa02b 100644
--- a/passerelle/apps/cartads_cs/migrations/0004_cartadsdossier_cartads_steps_cache.py
+++ b/passerelle/apps/cartads_cs/migrations/0004_cartadsdossier_cartads_steps_cache.py
@@ -1,14 +1,14 @@
 # -*- coding: utf-8 -*-
 # Generated by Django 1.11.12 on 2019-09-03 07:19
 from __future__ import unicode_literals
 
-from django.db import migrations
 import django.contrib.postgres.fields.jsonb
+from django.db import migrations
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('cartads_cs', '0003_cartadsdossier_name_id'),
     ]
 
diff --git a/passerelle/apps/cartads_cs/migrations/0011_cartadsdossier_cartads_cache_infos.py b/passerelle/apps/cartads_cs/migrations/0011_cartadsdossier_cartads_cache_infos.py
index f87a508a..e40a94e4 100644
--- a/passerelle/apps/cartads_cs/migrations/0011_cartadsdossier_cartads_cache_infos.py
+++ b/passerelle/apps/cartads_cs/migrations/0011_cartadsdossier_cartads_cache_infos.py
@@ -1,14 +1,14 @@
 # -*- coding: utf-8 -*-
 # Generated by Django 1.11.12 on 2019-09-30 15:42
 from __future__ import unicode_literals
 
-from django.db import migrations
 import django.contrib.postgres.fields.jsonb
+from django.db import migrations
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('cartads_cs', '0010_cartadsdossier_cartads_cache_code_acces'),
     ]
 
diff --git a/passerelle/apps/cartads_cs/models.py b/passerelle/apps/cartads_cs/models.py
index 5ac14102..3e2ec795 100644
--- a/passerelle/apps/cartads_cs/models.py
+++ b/passerelle/apps/cartads_cs/models.py
@@ -12,44 +12,41 @@
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import base64
 import datetime
-from ftplib import FTP
 import json
 import os
 import random
 import re
-from xml.etree import ElementTree as etree
 import zipfile
+from ftplib import FTP
+from xml.etree import ElementTree as etree
 
 import pdfrw
 import pdfrw.findobjs
-
+import zeep.exceptions
+import zeep.helpers as zeep_helpers
 from Crypto.Cipher import AES
-
 from django.conf import settings
 from django.contrib.postgres.fields import JSONField
 from django.core.files.storage import default_storage
 from django.core.signing import Signer
-from django.urls import reverse
 from django.db import models
 from django.http import HttpResponse
+from django.urls import reverse
 from django.utils.encoding import force_text
+from django.utils.six.moves.urllib import parse as urlparse
 from django.utils.text import slugify
 from django.utils.timezone import now
 from django.utils.translation import ugettext_lazy as _
-from django.utils.six.moves.urllib import parse as urlparse
-
-import zeep.exceptions
-import zeep.helpers as zeep_helpers
 
 from passerelle.base.models import BaseResource
 from passerelle.base.signature import sign_url
 from passerelle.utils.api import endpoint
 from passerelle.utils.jsonresponse import APIError, JSONEncoder
 
 
 def cartads_file_location(instance, filename):
diff --git a/passerelle/apps/choosit/migrations/0001_initial.py b/passerelle/apps/choosit/migrations/0001_initial.py
index 4500cf92..39617018 100644
--- a/passerelle/apps/choosit/migrations/0001_initial.py
+++ b/passerelle/apps/choosit/migrations/0001_initial.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('base', '0001_initial'),
     ]
 
diff --git a/passerelle/apps/choosit/migrations/0002_auto_20160316_0528.py b/passerelle/apps/choosit/migrations/0002_auto_20160316_0528.py
index fa6dc52a..cb2bc463 100644
--- a/passerelle/apps/choosit/migrations/0002_auto_20160316_0528.py
+++ b/passerelle/apps/choosit/migrations/0002_auto_20160316_0528.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('choosit', '0001_initial'),
     ]
 
diff --git a/passerelle/apps/choosit/migrations/0003_auto_20160316_0910.py b/passerelle/apps/choosit/migrations/0003_auto_20160316_0910.py
index 8b0a1bf9..8da310c6 100644
--- a/passerelle/apps/choosit/migrations/0003_auto_20160316_0910.py
+++ b/passerelle/apps/choosit/migrations/0003_auto_20160316_0910.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('choosit', '0002_auto_20160316_0528'),
     ]
 
diff --git a/passerelle/apps/choosit/migrations/0004_auto_20160407_0456.py b/passerelle/apps/choosit/migrations/0004_auto_20160407_0456.py
index 7e125e1f..03af97be 100644
--- a/passerelle/apps/choosit/migrations/0004_auto_20160407_0456.py
+++ b/passerelle/apps/choosit/migrations/0004_auto_20160407_0456.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('choosit', '0003_auto_20160316_0910'),
     ]
 
diff --git a/passerelle/apps/choosit/migrations/0005_choositsmsgateway_default_trunk_prefix.py b/passerelle/apps/choosit/migrations/0005_choositsmsgateway_default_trunk_prefix.py
index 8a1fad75..2fbb46cb 100644
--- a/passerelle/apps/choosit/migrations/0005_choositsmsgateway_default_trunk_prefix.py
+++ b/passerelle/apps/choosit/migrations/0005_choositsmsgateway_default_trunk_prefix.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('choosit', '0004_auto_20160407_0456'),
     ]
 
diff --git a/passerelle/apps/choosit/models.py b/passerelle/apps/choosit/models.py
index 48fd1892..4c58ebff 100644
--- a/passerelle/apps/choosit/models.py
+++ b/passerelle/apps/choosit/models.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 import json
-import requests
 
+import requests
 from django.db import models
 from django.utils.six import string_types
 from django.utils.translation import ugettext_lazy as _
 
 from passerelle.sms.models import SMSResource
 from passerelle.utils.jsonresponse import APIError
 
 
diff --git a/passerelle/apps/cityweb/cityweb.py b/passerelle/apps/cityweb/cityweb.py
index c63bd5ed..09d03a82 100644
--- a/passerelle/apps/cityweb/cityweb.py
+++ b/passerelle/apps/cityweb/cityweb.py
@@ -11,27 +11,27 @@
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import os
 import stat
-from lxml import etree, objectify as xobject
 
-from django.core.files.storage import default_storage
 from django.core.files.base import ContentFile
+from django.core.files.storage import default_storage
 from django.utils import six
 from django.utils.dateparse import parse_date
 from django.utils.encoding import force_bytes
+from lxml import etree
+from lxml import objectify as xobject
 
-from passerelle.utils.jsonresponse import APIError
 from passerelle.utils.files import atomic_write
-
+from passerelle.utils.jsonresponse import APIError
 
 CERTIFICATE_TYPES = [
     {"id": "NAI", "text": "Naissance"},
     {"id": "MAR", "text": "Mariage"},
     {"id": "REC", "text": "Reconnaissance"},
     {"id": "DEC", "text": "Décès"},
 ]
 
diff --git a/passerelle/apps/cityweb/models.py b/passerelle/apps/cityweb/models.py
index dc1dfd18..74548bce 100644
--- a/passerelle/apps/cityweb/models.py
+++ b/passerelle/apps/cityweb/models.py
@@ -11,32 +11,32 @@
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import os
 
-from django.utils.translation import ugettext_lazy as _
 from django.core.files.storage import default_storage
+from django.utils.translation import ugettext_lazy as _
 
 from passerelle.base.models import BaseResource
 from passerelle.compat import json_loads
 from passerelle.utils.api import endpoint
 from passerelle.utils.jsonresponse import APIError
 
 from .cityweb import (
-    CivilStatusApplication,
-    TITLES,
-    SEXES,
-    DOCUMENT_TYPES,
     CERTIFICATE_TYPES,
     CONCERNED,
+    DOCUMENT_TYPES,
     ORIGINS,
+    SEXES,
+    TITLES,
+    CivilStatusApplication,
 )
 
 
 class CityWeb(BaseResource):
     category = _('Civil Status Connectors')
 
     class Meta:
         verbose_name = u"CityWeb - Demande d'acte d'état civil"
diff --git a/passerelle/apps/clicrdv/migrations/0001_initial.py b/passerelle/apps/clicrdv/migrations/0001_initial.py
index 8d89150a..4b87a038 100644
--- a/passerelle/apps/clicrdv/migrations/0001_initial.py
+++ b/passerelle/apps/clicrdv/migrations/0001_initial.py
@@ -1,11 +1,11 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = []
 
     operations = []
diff --git a/passerelle/apps/clicrdv/models.py b/passerelle/apps/clicrdv/models.py
index 0c3dba4a..8e045966 100644
--- a/passerelle/apps/clicrdv/models.py
+++ b/passerelle/apps/clicrdv/models.py
@@ -2,25 +2,25 @@
 Datasource for a ClicRDV instance.
 
 It is a gateway to http://developers.clicrdv.com/fr/rest-api.html
 '''
 
 import base64
 import datetime
 import json
-import requests
 
+import requests
 from django.conf import settings
-from django.urls import reverse
 from django.db import models
+from django.urls import reverse
 from django.utils.dateformat import format as date_format
 from django.utils.dateformat import time_format
-from django.utils.translation import ugettext_lazy as _
 from django.utils.http import urlquote
+from django.utils.translation import ugettext_lazy as _
 
 from passerelle.base.models import BaseResource
 from passerelle.utils.api import endpoint
 
 CLICRDV_SERVERS = (
     ('www.clicrdv.com', 'Production (www.clicrdv.com)'),
     ('sandbox.clicrdv.com', 'SandBox (sandbox.clicrdv.com)'),
 )
diff --git a/passerelle/apps/clicrdv/urls.py b/passerelle/apps/clicrdv/urls.py
index ed2273eb..427bec84 100644
--- a/passerelle/apps/clicrdv/urls.py
+++ b/passerelle/apps/clicrdv/urls.py
@@ -1,14 +1,13 @@
-from django.views.decorators.csrf import csrf_exempt
 from django.conf.urls import include, url
-
-from passerelle.urls_utils import decorated_includes, required, app_enabled
+from django.views.decorators.csrf import csrf_exempt
 
 from passerelle.apps.clicrdv.views import *
+from passerelle.urls_utils import app_enabled, decorated_includes, required
 
 urlpatterns = [
     url(r'^(?P<slug>[\w,-]+)/$', ClicRdvDetailView.as_view(), name='clicrdv-view'),
     url(
         r'^(?P<slug>[\w,-]+)/interventions/(?P<intervention_id>\d+)/datetimes/$',
         DateTimesView.as_view(),
         name='clicrdv-datetimes',
     ),
diff --git a/passerelle/apps/clicrdv/views.py b/passerelle/apps/clicrdv/views.py
index 3c9f1e68..4a6816cd 100644
--- a/passerelle/apps/clicrdv/views.py
+++ b/passerelle/apps/clicrdv/views.py
@@ -1,15 +1,14 @@
 from django.views.generic.base import View
-from django.views.generic.detail import SingleObjectMixin, DetailView
+from django.views.generic.detail import DetailView, SingleObjectMixin
 
-from passerelle.compat import json_loads
 import passerelle.utils as utils
-
 from passerelle.apps.clicrdv.models import ClicRdv
+from passerelle.compat import json_loads
 
 
 class ClicRdvDetailView(DetailView):
     model = ClicRdv
 
 
 class DateTimesView(View, SingleObjectMixin):
     """list of free date&times in a intervention
diff --git a/passerelle/apps/cmis/migrations/0001_initial.py b/passerelle/apps/cmis/migrations/0001_initial.py
index 8518197e..fc967bf2 100644
--- a/passerelle/apps/cmis/migrations/0001_initial.py
+++ b/passerelle/apps/cmis/migrations/0001_initial.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('base', '0005_resourcelog'),
     ]
 
diff --git a/passerelle/apps/cmis/models.py b/passerelle/apps/cmis/models.py
index 14c4f6f5..a96d7c73 100644
--- a/passerelle/apps/cmis/models.py
+++ b/passerelle/apps/cmis/models.py
@@ -12,35 +12,36 @@
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import base64
 import binascii
 import functools
-import httplib2
 import re
 
+import httplib2
 from cmislib import CmisClient
-from cmislib.exceptions import CmisException
-from cmislib.exceptions import ObjectNotFoundException
-from cmislib.exceptions import PermissionDeniedException
-from cmislib.exceptions import UpdateConflictException
-from cmislib.exceptions import InvalidArgumentException
+from cmislib.exceptions import (
+    CmisException,
+    InvalidArgumentException,
+    ObjectNotFoundException,
+    PermissionDeniedException,
+    UpdateConflictException,
+)
 from django.db import models
-from django.utils.translation import ugettext_lazy as _
 from django.utils.six import BytesIO
 from django.utils.six.moves.urllib import error as urllib2
+from django.utils.translation import ugettext_lazy as _
 
 from passerelle.base.models import BaseResource
 from passerelle.utils.api import endpoint
 from passerelle.utils.jsonresponse import APIError
 
-
 SPECIAL_CHARS = '!#$%&+-^_`~;[]{}+=~'
 FILE_PATH_PATTERN = r'^(/|(/[\w%s]+)+)$' % re.escape(SPECIAL_CHARS)
 FILE_NAME_PATTERN = r'[\w%s\.]+$' % re.escape(SPECIAL_CHARS)
 
 
 UPLOAD_SCHEMA = {
     'type': 'object',
     'properties': {
diff --git a/passerelle/apps/cmis/views.py b/passerelle/apps/cmis/views.py
index 6da98c17..6b5975ee 100644
--- a/passerelle/apps/cmis/views.py
+++ b/passerelle/apps/cmis/views.py
@@ -11,17 +11,16 @@
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 from cmislib import CmisClient
 from cmislib.exceptions import ObjectNotFoundException
-
 from django.http import Http404
 from django.utils.translation import ugettext_lazy as _
 from django.views.generic import TemplateView
 
 from .models import CmisConnector
 
 
 class CmisTypeView(TemplateView):
diff --git a/passerelle/apps/cryptor/migrations/0001_initial.py b/passerelle/apps/cryptor/migrations/0001_initial.py
index 49bf9989..27a7a3dd 100644
--- a/passerelle/apps/cryptor/migrations/0001_initial.py
+++ b/passerelle/apps/cryptor/migrations/0001_initial.py
@@ -1,16 +1,18 @@
 # -*- coding: utf-8 -*-
 # Generated by Django 1.11.18 on 2020-03-04 10:25
 from __future__ import unicode_literals
 
-from django.db import migrations, models
+import uuid
+
 import django.db.models.deletion
+from django.db import migrations, models
+
 import passerelle.apps.cryptor.models
-import uuid
 
 
 class Migration(migrations.Migration):
 
     initial = True
 
     dependencies = [
         ('base', '0016_auto_20191002_1443'),
diff --git a/passerelle/apps/cryptor/models.py b/passerelle/apps/cryptor/models.py
index 4877c377..ada3a6c3 100644
--- a/passerelle/apps/cryptor/models.py
+++ b/passerelle/apps/cryptor/models.py
@@ -15,34 +15,32 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import base64
 import binascii
 import json
 import os
 from uuid import uuid4
 
-from Cryptodome.PublicKey import RSA
-from Cryptodome.Random import get_random_bytes
 from Cryptodome.Cipher import AES, PKCS1_OAEP
 from Cryptodome.Hash import SHA512
-
+from Cryptodome.PublicKey import RSA
+from Cryptodome.Random import get_random_bytes
 from django.core.exceptions import ValidationError
 from django.core.files.storage import default_storage
 from django.db import models
 from django.http import HttpResponse
 from django.utils.six.moves.urllib_parse import urljoin
 from django.utils.translation import ugettext_lazy as _
 
 from passerelle.base.models import BaseResource
 from passerelle.utils.api import endpoint
 from passerelle.utils.files import atomic_write
 from passerelle.utils.jsonresponse import APIError
 
-
 FILE_SCHEMA = {
     "$schema": "http://json-schema.org/draft-04/schema#",
     "title": "File to encrypt",
     "description": "",
     "type": "object",
     "required": ["file"],
     "properties": {
         "file": {
diff --git a/passerelle/apps/csvdatasource/management/commands/change-csv.py b/passerelle/apps/csvdatasource/management/commands/change-csv.py
index b1926116..dfa0aace 100644
--- a/passerelle/apps/csvdatasource/management/commands/change-csv.py
+++ b/passerelle/apps/csvdatasource/management/commands/change-csv.py
@@ -9,18 +9,18 @@
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-import os
 import argparse
+import os
 
 from django.core.files import File
 from django.core.management.base import BaseCommand, CommandError
 
 from passerelle.apps.csvdatasource.models import CsvDataSource
 
 
 class Command(BaseCommand):
diff --git a/passerelle/apps/csvdatasource/migrations/0001_initial.py b/passerelle/apps/csvdatasource/migrations/0001_initial.py
index c25b605c..19680ae4 100644
--- a/passerelle/apps/csvdatasource/migrations/0001_initial.py
+++ b/passerelle/apps/csvdatasource/migrations/0001_initial.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('base', '0001_initial'),
     ]
 
diff --git a/passerelle/apps/csvdatasource/migrations/0002_csvdatasource_log_level.py b/passerelle/apps/csvdatasource/migrations/0002_csvdatasource_log_level.py
index c493127b..f5e58ff9 100644
--- a/passerelle/apps/csvdatasource/migrations/0002_csvdatasource_log_level.py
+++ b/passerelle/apps/csvdatasource/migrations/0002_csvdatasource_log_level.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('csvdatasource', '0001_initial'),
     ]
 
diff --git a/passerelle/apps/csvdatasource/migrations/0003_auto_20160316_0910.py b/passerelle/apps/csvdatasource/migrations/0003_auto_20160316_0910.py
index bd3311a3..f3d9a7ae 100644
--- a/passerelle/apps/csvdatasource/migrations/0003_auto_20160316_0910.py
+++ b/passerelle/apps/csvdatasource/migrations/0003_auto_20160316_0910.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('csvdatasource', '0002_csvdatasource_log_level'),
     ]
 
diff --git a/passerelle/apps/csvdatasource/migrations/0004_auto_20160407_0456.py b/passerelle/apps/csvdatasource/migrations/0004_auto_20160407_0456.py
index 00fbc8f9..ce59c3a6 100644
--- a/passerelle/apps/csvdatasource/migrations/0004_auto_20160407_0456.py
+++ b/passerelle/apps/csvdatasource/migrations/0004_auto_20160407_0456.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('csvdatasource', '0003_auto_20160316_0910'),
     ]
 
diff --git a/passerelle/apps/csvdatasource/migrations/0005_csvdatasource__dialect_options.py b/passerelle/apps/csvdatasource/migrations/0005_csvdatasource__dialect_options.py
index e24f063c..b62512c3 100644
--- a/passerelle/apps/csvdatasource/migrations/0005_csvdatasource__dialect_options.py
+++ b/passerelle/apps/csvdatasource/migrations/0005_csvdatasource__dialect_options.py
@@ -1,13 +1,13 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
 import django.contrib.postgres.fields.jsonb
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('csvdatasource', '0004_auto_20160407_0456'),
     ]
 
diff --git a/passerelle/apps/csvdatasource/migrations/0006_auto_20160905_1031.py b/passerelle/apps/csvdatasource/migrations/0006_auto_20160905_1031.py
index 353865f1..0a6ec95c 100644
--- a/passerelle/apps/csvdatasource/migrations/0006_auto_20160905_1031.py
+++ b/passerelle/apps/csvdatasource/migrations/0006_auto_20160905_1031.py
@@ -1,13 +1,13 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import migrations, models
 import django.contrib.postgres.fields.jsonb
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('csvdatasource', '0005_csvdatasource__dialect_options'),
     ]
 
diff --git a/passerelle/apps/csvdatasource/migrations/0009_auto_20161109_0353.py b/passerelle/apps/csvdatasource/migrations/0009_auto_20161109_0353.py
index 7948fd50..8938f6d6 100644
--- a/passerelle/apps/csvdatasource/migrations/0009_auto_20161109_0353.py
+++ b/passerelle/apps/csvdatasource/migrations/0009_auto_20161109_0353.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('csvdatasource', '0008_auto_20161025_1156'),
     ]
 
diff --git a/passerelle/apps/csvdatasource/migrations/0011_auto_20180905_0936.py b/passerelle/apps/csvdatasource/migrations/0011_auto_20180905_0936.py
index baaf98a5..3d95ed03 100644
--- a/passerelle/apps/csvdatasource/migrations/0011_auto_20180905_0936.py
+++ b/passerelle/apps/csvdatasource/migrations/0011_auto_20180905_0936.py
@@ -1,15 +1,15 @@
 # -*- coding: utf-8 -*-
 # Generated by Django 1.11.12 on 2018-09-05 14:36
 from __future__ import unicode_literals
 
-from django.db import migrations, models
-import django.db.models.deletion
 import django.contrib.postgres.fields.jsonb
+import django.db.models.deletion
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('csvdatasource', '0010_auto_20170920_0951'),
     ]
 
diff --git a/passerelle/apps/csvdatasource/migrations/0016_auto_20200406_1702.py b/passerelle/apps/csvdatasource/migrations/0016_auto_20200406_1702.py
index 6e2a67f3..8cfa9980 100644
--- a/passerelle/apps/csvdatasource/migrations/0016_auto_20200406_1702.py
+++ b/passerelle/apps/csvdatasource/migrations/0016_auto_20200406_1702.py
@@ -1,14 +1,14 @@
 # -*- coding: utf-8 -*-
 # Generated by Django 1.11.18 on 2020-04-06 15:02
 from __future__ import unicode_literals
 
-from django.db import migrations, models
 import django.db.models.deletion
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('csvdatasource', '0015_query_slug_unicity'),
     ]
 
diff --git a/passerelle/apps/csvdatasource/migrations/0019_csv_upload_to.py b/passerelle/apps/csvdatasource/migrations/0019_csv_upload_to.py
index fa25a86d..1a88667b 100644
--- a/passerelle/apps/csvdatasource/migrations/0019_csv_upload_to.py
+++ b/passerelle/apps/csvdatasource/migrations/0019_csv_upload_to.py
@@ -1,12 +1,13 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
 from django.db import migrations, models
+
 import passerelle.apps.csvdatasource.models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('csvdatasource', '0018_text_to_jsonb'),
     ]
diff --git a/passerelle/apps/csvdatasource/migrations/0020_csv_upload_to.py b/passerelle/apps/csvdatasource/migrations/0020_csv_upload_to.py
index ccc6f072..58ea03aa 100644
--- a/passerelle/apps/csvdatasource/migrations/0020_csv_upload_to.py
+++ b/passerelle/apps/csvdatasource/migrations/0020_csv_upload_to.py
@@ -1,10 +1,11 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
+
 import os
 
 from django.db import migrations
 
 
 def move_files(apps, schema_editor):
     CsvDataSource = apps.get_model('csvdatasource', 'CsvDataSource')
     CsvDataSource.get_connector_slug = lambda *args, **kwargs: 'csvdatasource'
diff --git a/passerelle/apps/csvdatasource/models.py b/passerelle/apps/csvdatasource/models.py
index 0970e6d7..096a12cb 100644
--- a/passerelle/apps/csvdatasource/models.py
+++ b/passerelle/apps/csvdatasource/models.py
@@ -9,44 +9,41 @@
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+import csv
 import datetime
 import os
 import re
-import csv
-from collections import OrderedDict
 import tempfile
+from collections import OrderedDict
 
-import six
 import pytz
-
-from pyexcel_ods import get_data as get_data_ods
-from pyexcel_xls import get_data as get_data_xls
-
-from django.contrib.postgres.fields import JSONField
-from django.utils.encoding import force_str, smart_text, force_text
-from django.utils.timezone import make_aware
+import six
 from django.conf import settings
-from django.db import models, transaction
+from django.contrib.postgres.fields import JSONField
 from django.core.exceptions import ValidationError
+from django.db import models, transaction
 from django.urls import reverse
-from django.utils.timezone import now
+from django.utils.encoding import force_str, force_text, smart_text
+from django.utils.timezone import make_aware, now
 from django.utils.translation import ugettext_lazy as _
+from pyexcel_ods import get_data as get_data_ods
+from pyexcel_xls import get_data as get_data_xls
 
 from passerelle.base.models import BaseResource
 from passerelle.utils import batch
-from passerelle.utils.jsonresponse import APIError
 from passerelle.utils.api import endpoint
 from passerelle.utils.conversion import normalize
+from passerelle.utils.jsonresponse import APIError
 
 identifier_re = re.compile(r"^[^\d\W]\w*\Z", re.UNICODE)
 
 
 code_cache = OrderedDict()
 
 
 def get_code(expr):
diff --git a/passerelle/apps/csvdatasource/views.py b/passerelle/apps/csvdatasource/views.py
index 1502b06e..f603d1c0 100644
--- a/passerelle/apps/csvdatasource/views.py
+++ b/passerelle/apps/csvdatasource/views.py
@@ -13,17 +13,17 @@
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import os
 
 from django.http import HttpResponse
 from django.shortcuts import get_object_or_404
-from django.views.generic import View, UpdateView, CreateView, DeleteView
+from django.views.generic import CreateView, DeleteView, UpdateView, View
 
 from .forms import QueryForm
 from .models import CsvDataSource, Query
 
 
 class NewQueryView(CreateView):
     model = Query
     form_class = QueryForm
diff --git a/passerelle/apps/esirius/migrations/0001_initial.py b/passerelle/apps/esirius/migrations/0001_initial.py
index d7396bd5..d7a9c2a0 100644
--- a/passerelle/apps/esirius/migrations/0001_initial.py
+++ b/passerelle/apps/esirius/migrations/0001_initial.py
@@ -1,13 +1,14 @@
 # -*- coding: utf-8 -*-
 # Generated by Django 1.11.18 on 2021-03-01 14:52
 from __future__ import unicode_literals
 
 from django.db import migrations, models
+
 import passerelle.apps.esirius.models
 
 
 class Migration(migrations.Migration):
 
     initial = True
 
     dependencies = [
diff --git a/passerelle/apps/esirius/models.py b/passerelle/apps/esirius/models.py
index 0368c868..d491fc0f 100644
--- a/passerelle/apps/esirius/models.py
+++ b/passerelle/apps/esirius/models.py
@@ -17,27 +17,25 @@
 
 import base64
 from copy import deepcopy
 from time import time
 from urllib.parse import urljoin
 
 from Cryptodome.Cipher import DES
 from Cryptodome.Util.Padding import pad
-
-from django.db import models
 from django.core.exceptions import ValidationError
+from django.db import models
 from django.utils.encoding import force_bytes
 from django.utils.translation import ugettext_lazy as _
 
 from passerelle.base.models import BaseResource, HTTPResource
 from passerelle.utils.api import endpoint
 from passerelle.utils.jsonresponse import APIError
 
-
 CREATE_APPOINTMENT_SCHEMA = {
     '$schema': 'http://json-schema.org/draft-04/schema#',
     "type": "object",
     'properties': {
         'idSys': {'type': 'string', 'pattern': '^[0-9]*$'},
         'codeRDV': {'type': 'string'},
         'beginDate': {'type': 'string', 'pattern': '^[0-9]{4}-[0-9]{2}-[0-9]{2}$'},
         'beginTime': {'type': 'string', 'pattern': '^[0-9]{2}:[0-9]{2}$'},
diff --git a/passerelle/apps/family/loaders/concerto_fondettes.py b/passerelle/apps/family/loaders/concerto_fondettes.py
index 79ea69c1..cc3f21de 100644
--- a/passerelle/apps/family/loaders/concerto_fondettes.py
+++ b/passerelle/apps/family/loaders/concerto_fondettes.py
@@ -11,25 +11,25 @@
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import csv
 import datetime
-from decimal import Decimal
 import json
 import os
 import sys
 import zipfile
+from decimal import Decimal
 
 from django.core.exceptions import ValidationError
-from django.utils.encoding import force_text
 from django.utils import six
+from django.utils.encoding import force_text
 from django.utils.translation import ugettext_lazy as _
 
 from ..models import Invoice
 
 
 def u(s):
     return force_text(s, 'iso-8859-15')
 
diff --git a/passerelle/apps/family/loaders/concerto_orleans.py b/passerelle/apps/family/loaders/concerto_orleans.py
index 48a0dbb0..d22401fa 100644
--- a/passerelle/apps/family/loaders/concerto_orleans.py
+++ b/passerelle/apps/family/loaders/concerto_orleans.py
@@ -9,29 +9,28 @@
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-import os
 import csv
+import os
 from decimal import Decimal
 
-from django.utils.timezone import make_aware, datetime
+from django.core.exceptions import ValidationError
+from django.core.files.storage import DefaultStorage
 from django.utils import six, timezone
 from django.utils.encoding import force_text
-from django.core.exceptions import ValidationError
+from django.utils.timezone import datetime, make_aware
 from django.utils.translation import ugettext_lazy as _
-from django.core.files.storage import DefaultStorage
 
-from ..models import Family, Adult, Child, Invoice
-from ..models import dict_cherry_pick, get_datetime, get_date
+from ..models import Adult, Child, Family, Invoice, dict_cherry_pick, get_date, get_datetime
 
 
 def normalize_adult(adult):
     sex = adult['typ_sexe']
     if sex == 'G':
         sex = 'M'
     return {
         'external_id': adult['id_per'],
diff --git a/passerelle/apps/family/loaders/opus_fondettes.py b/passerelle/apps/family/loaders/opus_fondettes.py
index e9ee86ed..25fd8b7f 100644
--- a/passerelle/apps/family/loaders/opus_fondettes.py
+++ b/passerelle/apps/family/loaders/opus_fondettes.py
@@ -11,25 +11,25 @@
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import csv
 import datetime
-from decimal import Decimal
 import json
 import os
 import sys
 import zipfile
+from decimal import Decimal
 
 from django.core.exceptions import ValidationError
-from django.utils.encoding import force_text
 from django.utils import six
+from django.utils.encoding import force_text
 from django.utils.translation import ugettext_lazy as _
 
 from ..models import Invoice
 
 
 def u(s):
     return force_text(s, 'iso-8859-15')
 
diff --git a/passerelle/apps/family/management/commands/import_orleans_data.py b/passerelle/apps/family/management/commands/import_orleans_data.py
index eb89991e..3457bbc9 100644
--- a/passerelle/apps/family/management/commands/import_orleans_data.py
+++ b/passerelle/apps/family/management/commands/import_orleans_data.py
@@ -9,25 +9,25 @@
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+import fcntl
 import os
 import sys
-import zipfile
 import tempfile
-import fcntl
+import zipfile
 
 from django.core.files.base import File
-from django.core.management.base import BaseCommand, CommandError
 from django.core.files.storage import DefaultStorage
+from django.core.management.base import BaseCommand, CommandError
 
 from passerelle.apps.family.models import GenericFamily, Invoice
 
 
 class Command(BaseCommand):
     def add_arguments(self, parser):
         parser.add_argument(
             '-a',
diff --git a/passerelle/apps/family/migrations/0001_initial.py b/passerelle/apps/family/migrations/0001_initial.py
index d7fc97fc..ed40e20e 100644
--- a/passerelle/apps/family/migrations/0001_initial.py
+++ b/passerelle/apps/family/migrations/0001_initial.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('base', '0002_auto_20151009_0326'),
     ]
 
diff --git a/passerelle/apps/family/migrations/0007_auto_20161122_1816.py b/passerelle/apps/family/migrations/0007_auto_20161122_1816.py
index 5115709d..9c5f6bf0 100644
--- a/passerelle/apps/family/migrations/0007_auto_20161122_1816.py
+++ b/passerelle/apps/family/migrations/0007_auto_20161122_1816.py
@@ -1,13 +1,14 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
 import datetime
+
+from django.db import migrations, models
 from django.utils.timezone import utc
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('family', '0006_invoice_no_online_payment_reason'),
     ]
diff --git a/passerelle/apps/family/models.py b/passerelle/apps/family/models.py
index 327957ce..43009272 100644
--- a/passerelle/apps/family/models.py
+++ b/passerelle/apps/family/models.py
@@ -11,32 +11,30 @@
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-from datetime import date
 import os
 import sys
 import zipfile
-
-import pytz
-
 from collections import defaultdict
+from datetime import date
 
+import pytz
 from django.core.exceptions import ValidationError
 from django.core.files.storage import default_storage
+from django.db import models, transaction
+from django.http import Http404, HttpResponse
 from django.utils import six
+from django.utils.timezone import datetime, is_naive, make_aware, now
 from django.utils.translation import ugettext_lazy as _
-from django.http import Http404, HttpResponse
-from django.db import models, transaction
-from django.utils.timezone import make_aware, datetime, now, is_naive
 
 from passerelle.base.models import BaseResource
 from passerelle.compat import json_loads
 from passerelle.utils.api import endpoint
 
 SEXES = (
     ('M', _('Male')),
     ('F', _('Female')),
diff --git a/passerelle/apps/feeds/models.py b/passerelle/apps/feeds/models.py
index 08ef452a..2f1476e8 100644
--- a/passerelle/apps/feeds/models.py
+++ b/passerelle/apps/feeds/models.py
@@ -10,17 +10,16 @@
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import feedparser
-
 from django.db import models
 from django.utils.translation import ugettext_lazy as _
 
 from passerelle.base.models import BaseResource
 from passerelle.utils.api import endpoint
 
 
 class Feed(BaseResource):
diff --git a/passerelle/apps/gdc/migrations/0001_initial.py b/passerelle/apps/gdc/migrations/0001_initial.py
index 8d710dc5..3b6e0646 100644
--- a/passerelle/apps/gdc/migrations/0001_initial.py
+++ b/passerelle/apps/gdc/migrations/0001_initial.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('base', '0001_initial'),
     ]
 
diff --git a/passerelle/apps/gdc/migrations/0002_gdc_log_level.py b/passerelle/apps/gdc/migrations/0002_gdc_log_level.py
index 6146d00c..fcfef93f 100644
--- a/passerelle/apps/gdc/migrations/0002_gdc_log_level.py
+++ b/passerelle/apps/gdc/migrations/0002_gdc_log_level.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('gdc', '0001_initial'),
     ]
 
diff --git a/passerelle/apps/gdc/migrations/0003_auto_20160316_0910.py b/passerelle/apps/gdc/migrations/0003_auto_20160316_0910.py
index d5c5b82c..00fb26b5 100644
--- a/passerelle/apps/gdc/migrations/0003_auto_20160316_0910.py
+++ b/passerelle/apps/gdc/migrations/0003_auto_20160316_0910.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('gdc', '0002_gdc_log_level'),
     ]
 
diff --git a/passerelle/apps/gdc/migrations/0004_auto_20160407_0456.py b/passerelle/apps/gdc/migrations/0004_auto_20160407_0456.py
index 08913a01..c7c25e25 100644
--- a/passerelle/apps/gdc/migrations/0004_auto_20160407_0456.py
+++ b/passerelle/apps/gdc/migrations/0004_auto_20160407_0456.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('gdc', '0003_auto_20160316_0910'),
     ]
 
diff --git a/passerelle/apps/gdc/urls.py b/passerelle/apps/gdc/urls.py
index a47d6844..d4985df9 100644
--- a/passerelle/apps/gdc/urls.py
+++ b/passerelle/apps/gdc/urls.py
@@ -9,18 +9,19 @@
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-from django.views.decorators.csrf import csrf_exempt
 from django.conf.urls import url
-from .views import GdcDetailView, VoiesView, PostDemandeView, StatusView
+from django.views.decorators.csrf import csrf_exempt
+
+from .views import GdcDetailView, PostDemandeView, StatusView, VoiesView
 
 urlpatterns = [
     url(r'^(?P<slug>[\w,-]+)/$', GdcDetailView.as_view(), name='gdc-view'),
     url(r'^(?P<slug>[\w,-]+)/voies/(?P<insee>\d+)$', VoiesView.as_view(), name='gdc-voies'),
     url(r'^(?P<slug>[\w,-]+)/post/demande$', csrf_exempt(PostDemandeView.as_view()), name='gdc-post'),
     url(r'^(?P<slug>[\w,-]+)/status/(?P<ref>\d+)', StatusView.as_view(), name='gdc-status'),
 ]
diff --git a/passerelle/apps/gdc/views.py b/passerelle/apps/gdc/views.py
index 5422a413..178429db 100644
--- a/passerelle/apps/gdc/views.py
+++ b/passerelle/apps/gdc/views.py
@@ -12,20 +12,20 @@
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 
 from django.utils.encoding import force_text
 from django.views.generic.base import View
-from django.views.generic.detail import SingleObjectMixin, DetailView
+from django.views.generic.detail import DetailView, SingleObjectMixin
 
-from passerelle.compat import json_loads
 import passerelle.utils as utils
+from passerelle.compat import json_loads
 from passerelle.utils.conversion import normalize
 
 from .models import Gdc, phpserialize, phpserialize_loads
 
 
 class GdcCrash(Exception):
     pass
 
diff --git a/passerelle/apps/gesbac/migrations/0001_initial.py b/passerelle/apps/gesbac/migrations/0001_initial.py
index 661930b8..5c060bd1 100644
--- a/passerelle/apps/gesbac/migrations/0001_initial.py
+++ b/passerelle/apps/gesbac/migrations/0001_initial.py
@@ -1,15 +1,16 @@
 # -*- coding: utf-8 -*-
 # Generated by Django 1.11.20 on 2019-09-19 15:23
 from __future__ import unicode_literals
 
-from django.db import migrations, models
-import django.db.models.deletion
 import django.contrib.postgres.fields.jsonb
+import django.db.models.deletion
+from django.db import migrations, models
+
 import passerelle.utils.sftp
 
 
 class Migration(migrations.Migration):
 
     initial = True
 
     dependencies = [
diff --git a/passerelle/apps/gesbac/models.py b/passerelle/apps/gesbac/models.py
index de2ae14e..e1c2499e 100644
--- a/passerelle/apps/gesbac/models.py
+++ b/passerelle/apps/gesbac/models.py
@@ -11,30 +11,28 @@
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import csv
 import io
-
 from collections import OrderedDict
 
 from django.contrib.postgres.fields import JSONField
-from django.db import models, transaction, IntegrityError
+from django.db import IntegrityError, models, transaction
+from django.http import Http404
 from django.utils import six
 from django.utils.encoding import force_bytes
 from django.utils.translation import ugettext_lazy as _
-from django.http import Http404
 
 from passerelle.base.models import BaseResource
-from passerelle.utils.api import endpoint, APIError
 from passerelle.utils import SFTPField
-
+from passerelle.utils.api import APIError, endpoint
 
 CSV_DELIMITER = ';'
 FILES_ENCODING = 'latin-1'
 
 APPLICANT_SCHEMA = OrderedDict(
     (
         (
             "form_id",
diff --git a/passerelle/apps/jsondatastore/migrations/0001_initial.py b/passerelle/apps/jsondatastore/migrations/0001_initial.py
index a73cbed8..1d1f5001 100644
--- a/passerelle/apps/jsondatastore/migrations/0001_initial.py
+++ b/passerelle/apps/jsondatastore/migrations/0001_initial.py
@@ -1,14 +1,15 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
+import django.contrib.postgres.fields.jsonb
 from django.db import migrations, models
+
 import passerelle.apps.jsondatastore.models
-import django.contrib.postgres.fields.jsonb
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('base', '0005_resourcelog'),
     ]
 
diff --git a/passerelle/apps/jsondatastore/models.py b/passerelle/apps/jsondatastore/models.py
index 4589ebc6..413a7124 100644
--- a/passerelle/apps/jsondatastore/models.py
+++ b/passerelle/apps/jsondatastore/models.py
@@ -18,17 +18,17 @@ import uuid
 
 from django.contrib.postgres.fields import JSONField
 from django.db import models
 from django.template import Context, Template
 from django.utils.translation import ugettext_lazy as _
 
 from passerelle.base.models import BaseResource
 from passerelle.compat import json_loads
-from passerelle.utils.api import endpoint, APIError
+from passerelle.utils.api import APIError, endpoint
 from passerelle.utils.conversion import simplify
 
 
 def get_hex_uuid():
     return uuid.uuid4().hex
 
 
 def clean_json_data(data):
diff --git a/passerelle/apps/maelis/migrations/0001_initial.py b/passerelle/apps/maelis/migrations/0001_initial.py
index 37a9a0ae..e8e5c4cc 100644
--- a/passerelle/apps/maelis/migrations/0001_initial.py
+++ b/passerelle/apps/maelis/migrations/0001_initial.py
@@ -1,14 +1,14 @@
 # -*- coding: utf-8 -*-
 # Generated by Django 1.11.29 on 2020-09-29 13:56
 from __future__ import unicode_literals
 
-from django.db import migrations, models
 import django.db.models.deletion
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     initial = True
 
     dependencies = [
         ('base', '0022_auto_20200715_1033'),
diff --git a/passerelle/apps/maelis/models.py b/passerelle/apps/maelis/models.py
index 140b49f0..f7593ca5 100644
--- a/passerelle/apps/maelis/models.py
+++ b/passerelle/apps/maelis/models.py
@@ -11,35 +11,32 @@
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 
 from collections import defaultdict
-
 from urllib.parse import urljoin
 
 import zeep
-from zeep.wsse.username import UsernameToken
-from zeep.helpers import serialize_object
-
 from django.db import models
-from django.utils.dateparse import parse_date
 from django.utils import timezone
+from django.utils.dateparse import parse_date
 from django.utils.translation import ugettext_lazy as _
+from zeep.helpers import serialize_object
+from zeep.wsse.username import UsernameToken
 
 from passerelle.base.models import BaseResource
 from passerelle.utils.api import endpoint
 from passerelle.utils.jsonresponse import APIError
 
 from . import utils
 
-
 LINK_SCHEMA = {
     "$schema": "http://json-schema.org/draft-04/schema#",
     "title": "Maelis",
     "description": "",
     "type": "object",
     "required": ["family_id", "password"],
     "properties": {
         "family_id": {
diff --git a/passerelle/apps/maelis/utils.py b/passerelle/apps/maelis/utils.py
index b6e16078..2d6b6ca7 100644
--- a/passerelle/apps/maelis/utils.py
+++ b/passerelle/apps/maelis/utils.py
@@ -12,21 +12,21 @@
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 from __future__ import unicode_literals
 
+import re
 from copy import copy, deepcopy
 from datetime import datetime
-from dateutil.relativedelta import relativedelta
-import re
 
+from dateutil.relativedelta import relativedelta
 from django.utils import timezone
 from django.utils.dateparse import parse_date
 
 from passerelle.utils.jsonresponse import APIError
 
 DATE_FORMAT = '%Y-%m-%d'
 TIME_FORMAT = '%H:%M:%S'
 DATETIME_FORMAT = DATE_FORMAT + ' ' + TIME_FORMAT
diff --git a/passerelle/apps/mdel/mdel.py b/passerelle/apps/mdel/mdel.py
index 163fa1a8..183c07de 100644
--- a/passerelle/apps/mdel/mdel.py
+++ b/passerelle/apps/mdel/mdel.py
@@ -9,26 +9,25 @@
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-import os
 import base64
 import datetime
-from xml.etree import ElementTree as etree
+import os
 from xml.dom import minidom
+from xml.etree import ElementTree as etree
 
 from dateutil.parser import parse as dateutil_parse
-
-from django.core.files.storage import default_storage
 from django.core.files.base import ContentFile
+from django.core.files.storage import default_storage
 
 from passerelle.apps.mdel.utils import ElementFactory
 from passerelle.utils.jsonresponse import APIError
 
 
 def get_resource_base_dir():
     return default_storage.path('mdel')
 
diff --git a/passerelle/apps/mdel/migrations/0003_auto_20170125_0450.py b/passerelle/apps/mdel/migrations/0003_auto_20170125_0450.py
index 371218c2..96469886 100644
--- a/passerelle/apps/mdel/migrations/0003_auto_20170125_0450.py
+++ b/passerelle/apps/mdel/migrations/0003_auto_20170125_0450.py
@@ -1,13 +1,14 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import migrations, models
 import datetime
+
+from django.db import migrations, models
 from django.utils.timezone import utc
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('mdel', '0002_auto_20170123_0311'),
     ]
diff --git a/passerelle/apps/mdel/migrations/0006_auto_20210126_1440.py b/passerelle/apps/mdel/migrations/0006_auto_20210126_1440.py
index 4d8c038e..58d40e4d 100644
--- a/passerelle/apps/mdel/migrations/0006_auto_20210126_1440.py
+++ b/passerelle/apps/mdel/migrations/0006_auto_20210126_1440.py
@@ -1,13 +1,14 @@
 # -*- coding: utf-8 -*-
 # Generated by Django 1.11.29 on 2021-01-26 13:40
 from __future__ import unicode_literals
 
 from django.db import migrations
+
 import passerelle.utils.sftp
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('mdel', '0005_remove_mdel_log_level'),
     ]
diff --git a/passerelle/apps/mdel/models.py b/passerelle/apps/mdel/models.py
index c6f58e57..8798a67a 100644
--- a/passerelle/apps/mdel/models.py
+++ b/passerelle/apps/mdel/models.py
@@ -18,25 +18,23 @@
 import os
 
 from django.db import models
 from django.utils import six
 from django.utils.translation import ugettext_lazy as _
 
 from passerelle.base.models import BaseResource
 from passerelle.compat import json_loads
+from passerelle.utils import SFTPField
 from passerelle.utils.api import endpoint
 from passerelle.utils.files import atomic_write
 from passerelle.utils.jsonresponse import APIError
-from passerelle.utils import SFTPField
 
 from . import mdel
-
-from .utils import zipdir, get_file_content_from_zip, parse_date
-
+from .utils import get_file_content_from_zip, parse_date, zipdir
 
 DEMAND_TYPES = ['ILE-LA', 'RCO-LA', 'AEC-LA']
 
 STATUS_MAPPING = {
     '100': 'closed',
     '20': 'rejected',
     '19': 'accepted',
     '17': 'information needed',
diff --git a/passerelle/apps/mdel_ddpacs/abstract.py b/passerelle/apps/mdel_ddpacs/abstract.py
index 841bb78d..927bc49b 100644
--- a/passerelle/apps/mdel_ddpacs/abstract.py
+++ b/passerelle/apps/mdel_ddpacs/abstract.py
@@ -12,37 +12,36 @@
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 from __future__ import unicode_literals
 
-from collections import namedtuple
 import inspect
 import os
 import re
 import xml.etree.ElementTree as ET
 import zipfile
+from collections import namedtuple
 
 from django.contrib.postgres.fields import JSONField
-from django.db import models, IntegrityError, transaction
-from django.urls import reverse
+from django.db import IntegrityError, models, transaction
 from django.http import HttpResponse
+from django.urls import reverse
+from django.utils import functional, six
 from django.utils.translation import ugettext_lazy as _
-from django.utils import six, functional
 
 from passerelle.base.models import BaseResource, SkipJob
+from passerelle.utils import sftp, xml
 from passerelle.utils.api import endpoint
+from passerelle.utils.conversion import exception_to_text
 from passerelle.utils.jsonresponse import APIError
 from passerelle.utils.zip import ZipTemplate
-from passerelle.utils.conversion import exception_to_text
-
-from passerelle.utils import xml, sftp
 
 '''Base abstract models for implementing MDEL compatible requests.
 '''
 
 MDELStatus = namedtuple('MDELStatus', ['code', 'slug', 'label'])
 
 MDEL_STATUSES = map(
     lambda t: MDELStatus(*t),
diff --git a/passerelle/apps/mdel_ddpacs/migrations/0001_initial.py b/passerelle/apps/mdel_ddpacs/migrations/0001_initial.py
index 535a0df7..b67c7a81 100644
--- a/passerelle/apps/mdel_ddpacs/migrations/0001_initial.py
+++ b/passerelle/apps/mdel_ddpacs/migrations/0001_initial.py
@@ -1,15 +1,16 @@
 # -*- coding: utf-8 -*-
 # Generated by Django 1.11.20 on 2019-10-24 08:59
 from __future__ import unicode_literals
 
-from django.db import migrations, models
-import django.db.models.deletion
 import django.contrib.postgres.fields.jsonb
+import django.db.models.deletion
+from django.db import migrations, models
+
 import passerelle.utils.sftp
 
 
 class Migration(migrations.Migration):
 
     initial = True
 
     dependencies = [
diff --git a/passerelle/apps/mdel_ddpacs/migrations/0002_auto_20200504_1402.py b/passerelle/apps/mdel_ddpacs/migrations/0002_auto_20200504_1402.py
index e263116b..e0f02065 100644
--- a/passerelle/apps/mdel_ddpacs/migrations/0002_auto_20200504_1402.py
+++ b/passerelle/apps/mdel_ddpacs/migrations/0002_auto_20200504_1402.py
@@ -1,14 +1,15 @@
 # -*- coding: utf-8 -*-
 # Generated by Django 1.11.18 on 2020-05-04 12:02
 from __future__ import unicode_literals
 
 import django.contrib.postgres.fields.jsonb
 from django.db import migrations, models
+
 import passerelle.utils.sftp
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('mdel_ddpacs', '0001_initial'),
     ]
diff --git a/passerelle/apps/mdel_ddpacs/models.py b/passerelle/apps/mdel_ddpacs/models.py
index e8d0e210..9fab543b 100644
--- a/passerelle/apps/mdel_ddpacs/models.py
+++ b/passerelle/apps/mdel_ddpacs/models.py
@@ -12,25 +12,24 @@
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 from __future__ import unicode_literals
 
+import xmlschema
 from django.db import models
-from django.utils.translation import ugettext_lazy as _
 from django.utils import six
+from django.utils.translation import ugettext_lazy as _
 
 from passerelle.utils.api import endpoint
 from passerelle.utils.xml import JSONSchemaFromXMLSchema
 
-import xmlschema
-
 from . import abstract
 
 
 class DDPACSSchema(JSONSchemaFromXMLSchema):
     type_map = {
         'CiviliteType': 'civilite',
         '{http://www.w3.org/2001/XMLSchema}double': 'double',
     }
diff --git a/passerelle/apps/mobyt/migrations/0001_initial.py b/passerelle/apps/mobyt/migrations/0001_initial.py
index 1ce4cfd9..ea43e75e 100644
--- a/passerelle/apps/mobyt/migrations/0001_initial.py
+++ b/passerelle/apps/mobyt/migrations/0001_initial.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('base', '0001_initial'),
     ]
 
diff --git a/passerelle/apps/mobyt/migrations/0002_mobytsmsgateway_log_level.py b/passerelle/apps/mobyt/migrations/0002_mobytsmsgateway_log_level.py
index 7d59cf79..0a53fbb9 100644
--- a/passerelle/apps/mobyt/migrations/0002_mobytsmsgateway_log_level.py
+++ b/passerelle/apps/mobyt/migrations/0002_mobytsmsgateway_log_level.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('mobyt', '0001_initial'),
     ]
 
diff --git a/passerelle/apps/mobyt/migrations/0003_auto_20160316_0910.py b/passerelle/apps/mobyt/migrations/0003_auto_20160316_0910.py
index e61f314f..4d2e0f0e 100644
--- a/passerelle/apps/mobyt/migrations/0003_auto_20160316_0910.py
+++ b/passerelle/apps/mobyt/migrations/0003_auto_20160316_0910.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('mobyt', '0002_mobytsmsgateway_log_level'),
     ]
 
diff --git a/passerelle/apps/mobyt/migrations/0004_auto_20160407_0456.py b/passerelle/apps/mobyt/migrations/0004_auto_20160407_0456.py
index 6c895f53..e62e52b3 100644
--- a/passerelle/apps/mobyt/migrations/0004_auto_20160407_0456.py
+++ b/passerelle/apps/mobyt/migrations/0004_auto_20160407_0456.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('mobyt', '0003_auto_20160316_0910'),
     ]
 
diff --git a/passerelle/apps/mobyt/migrations/0005_mobytsmsgateway_default_trunk_prefix.py b/passerelle/apps/mobyt/migrations/0005_mobytsmsgateway_default_trunk_prefix.py
index bba773dc..01b9f1c4 100644
--- a/passerelle/apps/mobyt/migrations/0005_mobytsmsgateway_default_trunk_prefix.py
+++ b/passerelle/apps/mobyt/migrations/0005_mobytsmsgateway_default_trunk_prefix.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('mobyt', '0004_auto_20160407_0456'),
     ]
 
diff --git a/passerelle/apps/mobyt/models.py b/passerelle/apps/mobyt/models.py
index 33c461c2..f713152d 100644
--- a/passerelle/apps/mobyt/models.py
+++ b/passerelle/apps/mobyt/models.py
@@ -1,13 +1,12 @@
+import requests
 from django.db import models
 from django.utils.translation import ugettext_lazy as _
 
-import requests
-
 from passerelle.sms.models import SMSResource
 from passerelle.utils.jsonresponse import APIError
 
 
 class MobytSMSGateway(SMSResource):
     URL = 'http://multilevel.mobyt.fr/sms/batch.php'
     MESSAGES_QUALITIES = (
         ('l', _('sms direct')),
diff --git a/passerelle/apps/opendatasoft/forms.py b/passerelle/apps/opendatasoft/forms.py
index a13ddaf1..d1ab4118 100644
--- a/passerelle/apps/opendatasoft/forms.py
+++ b/passerelle/apps/opendatasoft/forms.py
@@ -12,16 +12,17 @@
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 from django import forms
 
 from passerelle.base.forms import BaseQueryFormMixin
+
 from . import models
 
 
 class QueryForm(BaseQueryFormMixin, forms.ModelForm):
     class Meta:
         model = models.Query
         fields = '__all__'
         exclude = ['resource']
diff --git a/passerelle/apps/opendatasoft/migrations/0001_initial.py b/passerelle/apps/opendatasoft/migrations/0001_initial.py
index b2466890..4ba56f5f 100644
--- a/passerelle/apps/opendatasoft/migrations/0001_initial.py
+++ b/passerelle/apps/opendatasoft/migrations/0001_initial.py
@@ -1,14 +1,15 @@
 # -*- coding: utf-8 -*-
 # Generated by Django 1.11.18 on 2020-05-15 17:28
 from __future__ import unicode_literals
 
-from django.db import migrations, models
 import django.db.models.deletion
+from django.db import migrations, models
+
 import passerelle.utils.templates
 
 
 class Migration(migrations.Migration):
 
     initial = True
 
     dependencies = [
diff --git a/passerelle/apps/opendatasoft/models.py b/passerelle/apps/opendatasoft/models.py
index fb5e4d47..a9fd3473 100644
--- a/passerelle/apps/opendatasoft/models.py
+++ b/passerelle/apps/opendatasoft/models.py
@@ -15,19 +15,19 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 from django.db import models
 from django.shortcuts import get_object_or_404
 from django.urls import reverse
 from django.utils.six.moves.urllib import parse as urlparse
 from django.utils.translation import ugettext_lazy as _
 
-from passerelle.utils.templates import render_to_string, validate_template
-from passerelle.base.models import BaseResource, BaseQuery
+from passerelle.base.models import BaseQuery, BaseResource
 from passerelle.utils.api import endpoint
+from passerelle.utils.templates import render_to_string, validate_template
 
 
 class OpenDataSoft(BaseResource):
     service_url = models.CharField(
         _('Site URL'),
         max_length=256,
         blank=False,
         help_text=_('URL without ending "api/records/1.0/search/"'),
diff --git a/passerelle/apps/opendatasoft/views.py b/passerelle/apps/opendatasoft/views.py
index a2562839..88adf13d 100644
--- a/passerelle/apps/opendatasoft/views.py
+++ b/passerelle/apps/opendatasoft/views.py
@@ -9,17 +9,17 @@
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-from django.views.generic import UpdateView, CreateView, DeleteView
+from django.views.generic import CreateView, DeleteView, UpdateView
 
 from passerelle.base.mixins import ResourceChildViewMixin
 
 from . import models
 from .forms import QueryForm
 
 
 class QueryNew(ResourceChildViewMixin, CreateView):
diff --git a/passerelle/apps/opengis/forms.py b/passerelle/apps/opengis/forms.py
index 09a42b11..f36a27fa 100644
--- a/passerelle/apps/opengis/forms.py
+++ b/passerelle/apps/opengis/forms.py
@@ -15,16 +15,17 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 from xml.etree import ElementTree as ET
 
 from django import forms
 from django.utils.translation import ugettext_lazy as _
 
 from passerelle.base.forms import BaseQueryFormMixin
+
 from . import models
 
 
 class QueryForm(BaseQueryFormMixin, forms.ModelForm):
     class Meta:
         model = models.Query
         fields = '__all__'
         exclude = ['resource']
diff --git a/passerelle/apps/opengis/migrations/0005_auto_20180227_1531.py b/passerelle/apps/opengis/migrations/0005_auto_20180227_1531.py
index 6722d50c..bb710926 100644
--- a/passerelle/apps/opengis/migrations/0005_auto_20180227_1531.py
+++ b/passerelle/apps/opengis/migrations/0005_auto_20180227_1531.py
@@ -1,13 +1,13 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import migrations, models
 import django.contrib.postgres.fields.jsonb
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('opengis', '0004_auto_20180219_1613'),
     ]
 
diff --git a/passerelle/apps/opengis/migrations/0007_auto_20200401_1032.py b/passerelle/apps/opengis/migrations/0007_auto_20200401_1032.py
index 024556a7..1e4cfdb1 100644
--- a/passerelle/apps/opengis/migrations/0007_auto_20200401_1032.py
+++ b/passerelle/apps/opengis/migrations/0007_auto_20200401_1032.py
@@ -1,14 +1,14 @@
 # -*- coding: utf-8 -*-
 # Generated by Django 1.11.18 on 2020-04-08 09:54
 from __future__ import unicode_literals
 
-from django.db import migrations, models
 import django.db.models.deletion
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('opengis', '0006_auto_20181118_0807'),
     ]
 
diff --git a/passerelle/apps/opengis/migrations/0008_featurecache.py b/passerelle/apps/opengis/migrations/0008_featurecache.py
index ccd45c2c..fca2f95f 100644
--- a/passerelle/apps/opengis/migrations/0008_featurecache.py
+++ b/passerelle/apps/opengis/migrations/0008_featurecache.py
@@ -1,15 +1,15 @@
 # -*- coding: utf-8 -*-
 # Generated by Django 1.11.18 on 2020-04-01 09:21
 from __future__ import unicode_literals
 
-from django.db import migrations, models
-import django.db.models.deletion
 import django.contrib.postgres.fields.jsonb
+import django.db.models.deletion
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('opengis', '0007_auto_20200401_1032'),
     ]
 
diff --git a/passerelle/apps/opengis/models.py b/passerelle/apps/opengis/models.py
index 83c75fb4..e09c830d 100644
--- a/passerelle/apps/opengis/models.py
+++ b/passerelle/apps/opengis/models.py
@@ -13,32 +13,30 @@
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import html
 import math
 import xml.etree.ElementTree as ET
 
-import six
-
 import pyproj
-
+import six
 from django.contrib.postgres.fields import JSONField
 from django.core.cache import cache
 from django.db import models, transaction
 from django.http import HttpResponse
 from django.shortcuts import get_object_or_404
 from django.template import Context, Template
 from django.urls import reverse
 from django.utils import timezone
 from django.utils.text import slugify
 from django.utils.translation import ugettext_lazy as _
 
-from passerelle.base.models import BaseResource, BaseQuery
+from passerelle.base.models import BaseQuery, BaseResource
 from passerelle.utils.api import endpoint
 from passerelle.utils.conversion import num2deg, simplify
 from passerelle.utils.jsonresponse import APIError
 
 
 def build_dict_from_xml(elem):
     d = {}
     for child in elem.find('.'):
diff --git a/passerelle/apps/opengis/views.py b/passerelle/apps/opengis/views.py
index da7c402f..7113ed2d 100644
--- a/passerelle/apps/opengis/views.py
+++ b/passerelle/apps/opengis/views.py
@@ -9,17 +9,17 @@
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-from django.views.generic import UpdateView, CreateView, DeleteView
+from django.views.generic import CreateView, DeleteView, UpdateView
 
 from passerelle.base.mixins import ResourceChildViewMixin
 
 from . import models
 from .forms import QueryForm
 
 
 class QueryNew(ResourceChildViewMixin, CreateView):
diff --git a/passerelle/apps/orange/migrations/0001_initial.py b/passerelle/apps/orange/migrations/0001_initial.py
index a68c03a4..a17cea26 100644
--- a/passerelle/apps/orange/migrations/0001_initial.py
+++ b/passerelle/apps/orange/migrations/0001_initial.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('base', '0002_auto_20151009_0326'),
     ]
 
diff --git a/passerelle/apps/orange/migrations/0002_orangesmsgateway_log_level.py b/passerelle/apps/orange/migrations/0002_orangesmsgateway_log_level.py
index 34bbc283..4a2bfbd0 100644
--- a/passerelle/apps/orange/migrations/0002_orangesmsgateway_log_level.py
+++ b/passerelle/apps/orange/migrations/0002_orangesmsgateway_log_level.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('orange', '0001_initial'),
     ]
 
diff --git a/passerelle/apps/orange/migrations/0003_auto_20160316_0910.py b/passerelle/apps/orange/migrations/0003_auto_20160316_0910.py
index d18b723e..059ba006 100644
--- a/passerelle/apps/orange/migrations/0003_auto_20160316_0910.py
+++ b/passerelle/apps/orange/migrations/0003_auto_20160316_0910.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('orange', '0002_orangesmsgateway_log_level'),
     ]
 
diff --git a/passerelle/apps/orange/migrations/0004_auto_20160407_0456.py b/passerelle/apps/orange/migrations/0004_auto_20160407_0456.py
index a3f33837..4c2f34dd 100644
--- a/passerelle/apps/orange/migrations/0004_auto_20160407_0456.py
+++ b/passerelle/apps/orange/migrations/0004_auto_20160407_0456.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('orange', '0003_auto_20160316_0910'),
     ]
 
diff --git a/passerelle/apps/orange/models.py b/passerelle/apps/orange/models.py
index 24fe1db2..93f717a6 100644
--- a/passerelle/apps/orange/models.py
+++ b/passerelle/apps/orange/models.py
@@ -20,17 +20,16 @@
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 from django.db import models
 from django.utils.translation import ugettext_lazy as _
 
 from passerelle.sms.models import SMSResource
 from passerelle.utils.jsonresponse import APIError
 
-
 BASE_API = 'https://contact-everyone.orange-business.com/api/v1.2/'
 URL_TOKEN = BASE_API + 'oauth/token'
 URL_GROUPS = BASE_API + 'groups'
 URL_DIFFUSION = BASE_API + 'groups/%s/diffusion-requests'
 
 
 class OrangeError(APIError):
     pass
diff --git a/passerelle/apps/ovh/migrations/0001_initial.py b/passerelle/apps/ovh/migrations/0001_initial.py
index 2768677f..5895e56e 100644
--- a/passerelle/apps/ovh/migrations/0001_initial.py
+++ b/passerelle/apps/ovh/migrations/0001_initial.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('base', '0001_initial'),
     ]
 
diff --git a/passerelle/apps/ovh/migrations/0002_ovhsmsgateway_log_level.py b/passerelle/apps/ovh/migrations/0002_ovhsmsgateway_log_level.py
index 939359dc..59452a77 100644
--- a/passerelle/apps/ovh/migrations/0002_ovhsmsgateway_log_level.py
+++ b/passerelle/apps/ovh/migrations/0002_ovhsmsgateway_log_level.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('ovh', '0001_initial'),
     ]
 
diff --git a/passerelle/apps/ovh/migrations/0003_auto_20160316_0910.py b/passerelle/apps/ovh/migrations/0003_auto_20160316_0910.py
index b3962583..a1bcbb0c 100644
--- a/passerelle/apps/ovh/migrations/0003_auto_20160316_0910.py
+++ b/passerelle/apps/ovh/migrations/0003_auto_20160316_0910.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('ovh', '0002_ovhsmsgateway_log_level'),
     ]
 
diff --git a/passerelle/apps/ovh/migrations/0004_auto_20160407_0456.py b/passerelle/apps/ovh/migrations/0004_auto_20160407_0456.py
index 396d74c0..75848b21 100644
--- a/passerelle/apps/ovh/migrations/0004_auto_20160407_0456.py
+++ b/passerelle/apps/ovh/migrations/0004_auto_20160407_0456.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('ovh', '0003_auto_20160316_0910'),
     ]
 
diff --git a/passerelle/apps/ovh/migrations/0005_ovhsmsgateway_default_trunk_prefix.py b/passerelle/apps/ovh/migrations/0005_ovhsmsgateway_default_trunk_prefix.py
index 1d2fb8c7..9a2f8edd 100644
--- a/passerelle/apps/ovh/migrations/0005_ovhsmsgateway_default_trunk_prefix.py
+++ b/passerelle/apps/ovh/migrations/0005_ovhsmsgateway_default_trunk_prefix.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('ovh', '0004_auto_20160407_0456'),
     ]
 
diff --git a/passerelle/apps/ovh/models.py b/passerelle/apps/ovh/models.py
index c28e3f17..d3afd58b 100644
--- a/passerelle/apps/ovh/models.py
+++ b/passerelle/apps/ovh/models.py
@@ -1,17 +1,17 @@
 import hashlib
 import json
-import requests
 import time
 from datetime import timedelta
 from urllib.parse import urljoin
 
-from django.contrib.postgres.fields import ArrayField
+import requests
 from django.conf import settings
+from django.contrib.postgres.fields import ArrayField
 from django.core.mail import send_mail
 from django.db import models
 from django.template.loader import render_to_string
 from django.utils import timezone
 from django.utils.encoding import force_text
 from django.utils.translation import ugettext_lazy as _
 
 from passerelle.sms.models import SMSResource
diff --git a/passerelle/apps/oxyd/migrations/0001_initial.py b/passerelle/apps/oxyd/migrations/0001_initial.py
index 4995ed70..3c34b2f3 100644
--- a/passerelle/apps/oxyd/migrations/0001_initial.py
+++ b/passerelle/apps/oxyd/migrations/0001_initial.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('base', '0001_initial'),
     ]
 
diff --git a/passerelle/apps/oxyd/migrations/0002_oxydsmsgateway_log_level.py b/passerelle/apps/oxyd/migrations/0002_oxydsmsgateway_log_level.py
index 8872889c..22a38fda 100644
--- a/passerelle/apps/oxyd/migrations/0002_oxydsmsgateway_log_level.py
+++ b/passerelle/apps/oxyd/migrations/0002_oxydsmsgateway_log_level.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('oxyd', '0001_initial'),
     ]
 
diff --git a/passerelle/apps/oxyd/migrations/0003_auto_20160316_0910.py b/passerelle/apps/oxyd/migrations/0003_auto_20160316_0910.py
index 93125b97..d458c229 100644
--- a/passerelle/apps/oxyd/migrations/0003_auto_20160316_0910.py
+++ b/passerelle/apps/oxyd/migrations/0003_auto_20160316_0910.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('oxyd', '0002_oxydsmsgateway_log_level'),
     ]
 
diff --git a/passerelle/apps/oxyd/migrations/0004_auto_20160407_0456.py b/passerelle/apps/oxyd/migrations/0004_auto_20160407_0456.py
index b1be187f..178af43b 100644
--- a/passerelle/apps/oxyd/migrations/0004_auto_20160407_0456.py
+++ b/passerelle/apps/oxyd/migrations/0004_auto_20160407_0456.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('oxyd', '0003_auto_20160316_0910'),
     ]
 
diff --git a/passerelle/apps/oxyd/migrations/0005_oxydsmsgateway_default_trunk_prefix.py b/passerelle/apps/oxyd/migrations/0005_oxydsmsgateway_default_trunk_prefix.py
index 4154b5c7..c996cf85 100644
--- a/passerelle/apps/oxyd/migrations/0005_oxydsmsgateway_default_trunk_prefix.py
+++ b/passerelle/apps/oxyd/migrations/0005_oxydsmsgateway_default_trunk_prefix.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('oxyd', '0004_auto_20160407_0456'),
     ]
 
diff --git a/passerelle/apps/oxyd/models.py b/passerelle/apps/oxyd/models.py
index 53844c1e..786ae591 100644
--- a/passerelle/apps/oxyd/models.py
+++ b/passerelle/apps/oxyd/models.py
@@ -1,16 +1,15 @@
 import requests
-
 from django.db import models
 from django.utils.encoding import force_text
 from django.utils.translation import ugettext_lazy as _
 
-from passerelle.utils.jsonresponse import APIError
 from passerelle.sms.models import SMSResource
+from passerelle.utils.jsonresponse import APIError
 
 
 class OxydSMSGateway(SMSResource):
     username = models.CharField(verbose_name=_('Username'), max_length=64)
     password = models.CharField(verbose_name=_('Password'), max_length=64)
 
     TEST_DEFAULTS = {
         'create_kwargs': {
diff --git a/passerelle/apps/phonecalls/migrations/0001_initial.py b/passerelle/apps/phonecalls/migrations/0001_initial.py
index 0ed310c6..e6716582 100644
--- a/passerelle/apps/phonecalls/migrations/0001_initial.py
+++ b/passerelle/apps/phonecalls/migrations/0001_initial.py
@@ -1,15 +1,15 @@
 # -*- coding: utf-8 -*-
 # Generated by Django 1.11.17 on 2019-01-21 14:14
 from __future__ import unicode_literals
 
-from django.db import migrations, models
-import django.db.models.deletion
 import django.contrib.postgres.fields.jsonb
+import django.db.models.deletion
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     initial = True
 
     dependencies = [
         ('base', '0010_loggingparameters_trace_emails'),
diff --git a/passerelle/apps/phonecalls/models.py b/passerelle/apps/phonecalls/models.py
index 0fb98484..17ddbe17 100644
--- a/passerelle/apps/phonecalls/models.py
+++ b/passerelle/apps/phonecalls/models.py
@@ -11,21 +11,21 @@
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 from django.contrib.postgres.fields import JSONField
 from django.db import models
-from django.utils.http import urlencode
-from django.utils.timezone import now, timedelta, make_naive
-from django.utils.translation import ugettext_lazy as _
 from django.http import HttpResponseRedirect
 from django.shortcuts import render
+from django.utils.http import urlencode
+from django.utils.timezone import make_naive, now, timedelta
+from django.utils.translation import ugettext_lazy as _
 
 from passerelle.base.models import BaseResource
 from passerelle.utils.api import endpoint
 
 
 class PhoneCalls(BaseResource):
     category = _('Telephony')
 
diff --git a/passerelle/apps/photon/models.py b/passerelle/apps/photon/models.py
index 9bb7ea5b..48df7b43 100644
--- a/passerelle/apps/photon/models.py
+++ b/passerelle/apps/photon/models.py
@@ -10,24 +10,24 @@
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import datetime
-from requests import RequestException
 
 from django.contrib.postgres.fields import JSONField
 from django.db import models
-from django.utils.http import urlencode
-from django.utils.translation import ugettext_lazy as _
 from django.utils import timezone
+from django.utils.http import urlencode
 from django.utils.six.moves.urllib import parse as urlparse
+from django.utils.translation import ugettext_lazy as _
+from requests import RequestException
 
 from passerelle.base.models import BaseResource
 from passerelle.utils.api import endpoint
 from passerelle.utils.jsonresponse import APIError
 
 
 class AddressCacheModel(models.Model):
     api_id = models.CharField(max_length=32, unique=True)
diff --git a/passerelle/apps/solis/migrations/0003_auto_20171219_0800.py b/passerelle/apps/solis/migrations/0003_auto_20171219_0800.py
index 9795ed35..92fc1dad 100644
--- a/passerelle/apps/solis/migrations/0003_auto_20171219_0800.py
+++ b/passerelle/apps/solis/migrations/0003_auto_20171219_0800.py
@@ -1,12 +1,13 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
 from django.db import migrations, models
+
 import passerelle.apps.solis.models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('solis', '0002_solisapalink_text'),
     ]
diff --git a/passerelle/apps/solis/migrations/0006_solisrsalink.py b/passerelle/apps/solis/migrations/0006_solisrsalink.py
index 44db2910..154a9ecb 100644
--- a/passerelle/apps/solis/migrations/0006_solisrsalink.py
+++ b/passerelle/apps/solis/migrations/0006_solisrsalink.py
@@ -1,14 +1,14 @@
 # -*- coding: utf-8 -*-
 # Generated by Django 1.11.20 on 2019-05-09 07:18
 from __future__ import unicode_literals
 
-from django.db import migrations, models
 import django.db.models.deletion
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('solis', '0005_remove_solis_log_level'),
     ]
 
diff --git a/passerelle/apps/solis/models.py b/passerelle/apps/solis/models.py
index f3d29c16..17646cdd 100644
--- a/passerelle/apps/solis/models.py
+++ b/passerelle/apps/solis/models.py
@@ -16,24 +16,24 @@
 
 import base64
 import copy
 import re
 
 from django.db import models
 from django.template.loader import get_template
 from django.utils.encoding import force_text
-from django.utils.translation import ugettext_lazy as _
 from django.utils.http import urlencode
+from django.utils.translation import ugettext_lazy as _
 
 from passerelle.base.models import BaseResource
 from passerelle.compat import json_loads
 from passerelle.utils.api import endpoint
-from passerelle.utils.jsonresponse import APIError
 from passerelle.utils.conversion import simplify, to_pdf
+from passerelle.utils.jsonresponse import APIError
 
 
 def unflat(flatten_dict, separator='_'):
     """
     Expand a "flatten" dict:
     >>> unflat({'foo': 'bar', 'two_foo': 'one', 'two_bar': 'two'})
     {'foo': 'bar', 'two': {'foo': 'one', 'bar': 'two'}}
     """
diff --git a/passerelle/apps/sp_fr/fields.py b/passerelle/apps/sp_fr/fields.py
index 625cebdd..2a482c3e 100644
--- a/passerelle/apps/sp_fr/fields.py
+++ b/passerelle/apps/sp_fr/fields.py
@@ -9,19 +9,19 @@
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-from django.core.exceptions import ValidationError
-from django.template import engines, TemplateSyntaxError
 from django import forms
+from django.core.exceptions import ValidationError
+from django.template import TemplateSyntaxError, engines
 
 
 def validate_django_template(value):
     try:
         engines['django'].from_string(value)
     except TemplateSyntaxError as e:
         raise ValidationError('invalid template %s' % e)
 
diff --git a/passerelle/apps/sp_fr/forms.py b/passerelle/apps/sp_fr/forms.py
index e1402369..932409c9 100644
--- a/passerelle/apps/sp_fr/forms.py
+++ b/passerelle/apps/sp_fr/forms.py
@@ -11,17 +11,17 @@
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 from django import forms
 
-from . import models, fields
+from . import fields, models
 
 
 class MappingForm(forms.ModelForm):
     def __init__(self, *args, **kwargs):
         super(MappingForm, self).__init__(*args, **kwargs)
         if self.instance.procedure and self.instance and self.instance.formdef:
             choices = [('', '--------')] + [(v, v) for v in self.instance.variables]
             for i, field in enumerate(self.schema_fields()):
diff --git a/passerelle/apps/sp_fr/migrations/0001_initial.py b/passerelle/apps/sp_fr/migrations/0001_initial.py
index 13dfd96f..e100b129 100644
--- a/passerelle/apps/sp_fr/migrations/0001_initial.py
+++ b/passerelle/apps/sp_fr/migrations/0001_initial.py
@@ -1,15 +1,16 @@
 # -*- coding: utf-8 -*-
 # Generated by Django 1.11.20 on 2019-04-19 17:15
 from __future__ import unicode_literals
 
-from django.db import migrations, models
-import django.db.models.deletion
 import django.contrib.postgres.fields.jsonb
+import django.db.models.deletion
+from django.db import migrations, models
+
 import passerelle.apps.sp_fr.models
 import passerelle.utils.sftp
 import passerelle.utils.wcs
 
 
 class Migration(migrations.Migration):
 
     initial = True
diff --git a/passerelle/apps/sp_fr/models.py b/passerelle/apps/sp_fr/models.py
index 673ee917..c9a80ebb 100644
--- a/passerelle/apps/sp_fr/models.py
+++ b/passerelle/apps/sp_fr/models.py
@@ -10,40 +10,40 @@
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-import re
+import base64
+import collections
+import datetime
 import os
+import re
 import stat
 import zipfile
-import collections
-import base64
-import datetime
-
-from lxml import etree as ET
 
 from django.contrib.postgres.fields import JSONField
-from django.urls import reverse
 from django.core.files import File
 from django.db import models, transaction
 from django.template import engines
+from django.urls import reverse
 from django.utils import six
-from django.utils.translation import ugettext_lazy as _, ugettext
+from django.utils.translation import ugettext
+from django.utils.translation import ugettext_lazy as _
+from lxml import etree as ET
 
 from passerelle.base.models import BaseResource
 from passerelle.utils.api import endpoint
+from passerelle.utils.conversion import normalize
 from passerelle.utils.sftp import SFTPField
 from passerelle.utils.wcs import FormDefField, get_wcs_choices
 from passerelle.utils.xml import text_content
-from passerelle.utils.conversion import normalize
 
 from .xsd import Schema
 
 MAX_REQUESTS_PER_ITERATION = 200
 
 PROCEDURE_DOC = 'DOC'
 PROCEDURE_RCO = 'recensementCitoyen'
 PROCEDURE_DDPACS = 'depotDossierPACS'
diff --git a/passerelle/apps/sp_fr/views.py b/passerelle/apps/sp_fr/views.py
index 85da27f4..ee6927a9 100644
--- a/passerelle/apps/sp_fr/views.py
+++ b/passerelle/apps/sp_fr/views.py
@@ -9,23 +9,23 @@
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-from django.views.generic import UpdateView, CreateView, DeleteView
-from django.shortcuts import get_object_or_404
 from django.http import HttpResponseRedirect
+from django.shortcuts import get_object_or_404
+from django.views.generic import CreateView, DeleteView, UpdateView
 
 from passerelle.base.mixins import ResourceChildViewMixin
 
-from . import models, forms
+from . import forms, models
 
 
 class StayIfChanged(object):
     has_changed = False
 
     def form_valid(self, form):
         if set(form.changed_data) & set(['procedure', 'formdef']):
             self.has_changed = True
diff --git a/passerelle/apps/sp_fr/xsd.py b/passerelle/apps/sp_fr/xsd.py
index 503e722d..481fd658 100644
--- a/passerelle/apps/sp_fr/xsd.py
+++ b/passerelle/apps/sp_fr/xsd.py
@@ -11,19 +11,18 @@
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import datetime
 
-from django.utils import six
-
 import isodate
+from django.utils import six
 from lxml import etree as ET
 from zeep.utils import qname_attr
 
 
 def parse_bool(boolean):
     return boolean.lower() == 'true'
 
 
diff --git a/passerelle/apps/twilio/models.py b/passerelle/apps/twilio/models.py
index 7bfaf634..1d8898bb 100644
--- a/passerelle/apps/twilio/models.py
+++ b/passerelle/apps/twilio/models.py
@@ -9,23 +9,22 @@
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 import requests
-from requests.auth import HTTPBasicAuth
-
 from django.db import models
 from django.utils.translation import ugettext_lazy as _
+from requests.auth import HTTPBasicAuth
 
-from passerelle.utils.jsonresponse import APIError
 from passerelle.sms.models import SMSResource
+from passerelle.utils.jsonresponse import APIError
 
 
 class TwilioSMSGateway(SMSResource):
     hide_description_fields = ['account_sid']
 
     account_sid = models.CharField(verbose_name=_('Account Sid'), max_length=64)
     auth_token = models.CharField(verbose_name=_('Auth Token'), max_length=64)
 
diff --git a/passerelle/base/admin.py b/passerelle/base/admin.py
index b52fec82..e4c851bb 100644
--- a/passerelle/base/admin.py
+++ b/passerelle/base/admin.py
@@ -10,22 +10,22 @@
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 from django.contrib import admin
-from django.urls import reverse
 from django.shortcuts import redirect
+from django.urls import reverse
 from django.urls.exceptions import NoReverseMatch
 from django.views.decorators.cache import never_cache
 
-from .models import ApiUser, AccessRight
+from .models import AccessRight, ApiUser
 
 
 @never_cache
 def login(request, *args, **kwargs):
     try:
         auth_login_url = reverse('auth_login')
     except NoReverseMatch:
         return admin.site.orig_login(request, *args, **kwargs)
diff --git a/passerelle/base/forms.py b/passerelle/base/forms.py
index 5b94eaec..0360eded 100644
--- a/passerelle/base/forms.py
+++ b/passerelle/base/forms.py
@@ -1,12 +1,12 @@
 from django import forms
 from django.utils.translation import ugettext_lazy as _
 
-from .models import ApiUser, AccessRight, AvailabilityParameters
+from .models import AccessRight, ApiUser, AvailabilityParameters
 
 
 class ApiUserForm(forms.ModelForm):
     class Meta:
         model = ApiUser
         exclude = []
 
 
diff --git a/passerelle/base/management/commands/cron.py b/passerelle/base/management/commands/cron.py
index 34b89c3c..f1094cd9 100644
--- a/passerelle/base/management/commands/cron.py
+++ b/passerelle/base/management/commands/cron.py
@@ -10,20 +10,21 @@
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 from __future__ import print_function
+
 import traceback
 
-from django.core.management.base import BaseCommand, CommandError
 from django.conf import settings
+from django.core.management.base import BaseCommand, CommandError
 
 from passerelle.views import get_all_apps
 
 
 class Command(BaseCommand):
     help = 'Execute scheduled commands'
 
     def add_arguments(self, parser):
diff --git a/passerelle/base/management/commands/ensure_jsonb.py b/passerelle/base/management/commands/ensure_jsonb.py
index 1d7fed1b..d5fb4d02 100644
--- a/passerelle/base/management/commands/ensure_jsonb.py
+++ b/passerelle/base/management/commands/ensure_jsonb.py
@@ -10,18 +10,18 @@
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 from django.apps import apps
-from django.core.management.base import BaseCommand, CommandError
 from django.contrib.postgres.fields import JSONField
+from django.core.management.base import BaseCommand, CommandError
 from django.db import connection
 
 
 class Command(BaseCommand):
     help = 'Ensure all JSON fields are of type jsonb'
 
     def handle(self, **options):
         for app in apps.get_models():
diff --git a/passerelle/base/migrations/0001_initial.py b/passerelle/base/migrations/0001_initial.py
index 7160fb49..09ff8a79 100644
--- a/passerelle/base/migrations/0001_initial.py
+++ b/passerelle/base/migrations/0001_initial.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('contenttypes', '0001_initial'),
     ]
 
diff --git a/passerelle/base/migrations/0002_auto_20151009_0326.py b/passerelle/base/migrations/0002_auto_20151009_0326.py
index 4386433a..979da986 100644
--- a/passerelle/base/migrations/0002_auto_20151009_0326.py
+++ b/passerelle/base/migrations/0002_auto_20151009_0326.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('base', '0001_initial'),
     ]
 
diff --git a/passerelle/base/migrations/0003_auto_20170116_1656.py b/passerelle/base/migrations/0003_auto_20170116_1656.py
index 7f8e8ba7..0cc2c7a4 100644
--- a/passerelle/base/migrations/0003_auto_20170116_1656.py
+++ b/passerelle/base/migrations/0003_auto_20170116_1656.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('base', '0002_auto_20151009_0326'),
     ]
 
diff --git a/passerelle/base/migrations/0004_auto_20170117_0326.py b/passerelle/base/migrations/0004_auto_20170117_0326.py
index 9c4d4281..acefbed7 100644
--- a/passerelle/base/migrations/0004_auto_20170117_0326.py
+++ b/passerelle/base/migrations/0004_auto_20170117_0326.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('base', '0003_auto_20170116_1656'),
     ]
 
diff --git a/passerelle/base/migrations/0005_resourcelog.py b/passerelle/base/migrations/0005_resourcelog.py
index 4775831b..a48f0e83 100644
--- a/passerelle/base/migrations/0005_resourcelog.py
+++ b/passerelle/base/migrations/0005_resourcelog.py
@@ -1,13 +1,13 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import migrations, models
 import django.contrib.postgres.fields.jsonb
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('base', '0004_auto_20170117_0326'),
     ]
 
diff --git a/passerelle/base/migrations/0007_loggingparameters.py b/passerelle/base/migrations/0007_loggingparameters.py
index 3981731e..a8eb96d5 100644
--- a/passerelle/base/migrations/0007_loggingparameters.py
+++ b/passerelle/base/migrations/0007_loggingparameters.py
@@ -1,14 +1,14 @@
 # -*- coding: utf-8 -*-
 # Generated by Django 1.11.12 on 2018-11-18 13:16
 from __future__ import unicode_literals
 
-from django.db import migrations, models
 import django.db.models.deletion
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('contenttypes', '0002_remove_content_type_name'),
         ('base', '0006_resourcestatus'),
     ]
diff --git a/passerelle/base/migrations/0011_auto_20190205_1126.py b/passerelle/base/migrations/0011_auto_20190205_1126.py
index 9b1a20ee..2a3609e7 100644
--- a/passerelle/base/migrations/0011_auto_20190205_1126.py
+++ b/passerelle/base/migrations/0011_auto_20190205_1126.py
@@ -1,14 +1,14 @@
 # -*- coding: utf-8 -*-
 # Generated by Django 1.11.17 on 2019-02-05 10:26
 from __future__ import unicode_literals
 
-from django.db import migrations, models
 import django.db.models.deletion
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('contenttypes', '0002_remove_content_type_name'),
         ('base', '0010_loggingparameters_trace_emails'),
     ]
diff --git a/passerelle/base/migrations/0012_job.py b/passerelle/base/migrations/0012_job.py
index 5be1de1d..44f24a80 100644
--- a/passerelle/base/migrations/0012_job.py
+++ b/passerelle/base/migrations/0012_job.py
@@ -1,15 +1,15 @@
 # -*- coding: utf-8 -*-
 # Generated by Django 1.11.12 on 2019-02-20 09:00
 from __future__ import unicode_literals
 
-from django.db import migrations, models
-import django.db.models.deletion
 import django.contrib.postgres.fields.jsonb
+import django.db.models.deletion
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('contenttypes', '0002_remove_content_type_name'),
         ('base', '0011_auto_20190205_1126'),
     ]
diff --git a/passerelle/base/migrations/0014_auto_20190820_0914.py b/passerelle/base/migrations/0014_auto_20190820_0914.py
index 89724bdc..9ec570c5 100644
--- a/passerelle/base/migrations/0014_auto_20190820_0914.py
+++ b/passerelle/base/migrations/0014_auto_20190820_0914.py
@@ -1,13 +1,14 @@
 # -*- coding: utf-8 -*-
 # Generated by Django 1.11.20 on 2019-08-20 14:14
 from __future__ import unicode_literals
 
 from django.db import migrations, models
+
 import passerelle.base.models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('base', '0013_delete_templatevar'),
     ]
diff --git a/passerelle/base/migrations/0015_auto_20190921_0347.py b/passerelle/base/migrations/0015_auto_20190921_0347.py
index db7ab742..2a09a4fc 100644
--- a/passerelle/base/migrations/0015_auto_20190921_0347.py
+++ b/passerelle/base/migrations/0015_auto_20190921_0347.py
@@ -1,13 +1,14 @@
 # -*- coding: utf-8 -*-
 # Generated by Django 1.11.20 on 2019-09-21 08:47
 from __future__ import unicode_literals
 
 from django.db import migrations, models
+
 import passerelle.base.models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('base', '0014_auto_20190820_0914'),
     ]
diff --git a/passerelle/base/migrations/0017_auto_20200310_1806.py b/passerelle/base/migrations/0017_auto_20200310_1806.py
index 96d7a04a..508699d0 100644
--- a/passerelle/base/migrations/0017_auto_20200310_1806.py
+++ b/passerelle/base/migrations/0017_auto_20200310_1806.py
@@ -1,14 +1,15 @@
 # -*- coding: utf-8 -*-
 # Generated by Django 1.11.18 on 2020-03-10 17:06
 from __future__ import unicode_literals
 
-from django.db import migrations, models
 import django.contrib.postgres.fields.jsonb
+from django.db import migrations, models
+
 import passerelle.base.models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('base', '0016_auto_20191002_1443'),
     ]
diff --git a/passerelle/base/models.py b/passerelle/base/models.py
index e54a1f1d..fe676386 100644
--- a/passerelle/base/models.py
+++ b/passerelle/base/models.py
@@ -1,50 +1,48 @@
+import base64
 import collections
 import copy
 import datetime
 import inspect
+import itertools
 import logging
 import os
 import re
 import sys
 import traceback
-import base64
-import itertools
 import uuid
 
 from django import VERSION
 from django.apps import apps
 from django.conf import settings
-from django.contrib.postgres.fields import JSONField, ArrayField
-from django.core.exceptions import ValidationError, PermissionDenied
-from django.urls import reverse
+from django.contrib.contenttypes import fields
+from django.contrib.contenttypes.models import ContentType
+from django.contrib.postgres.fields import ArrayField, JSONField
+from django.core.exceptions import PermissionDenied, ValidationError
+from django.core.files.base import ContentFile
 from django.db import connection, models, transaction
 from django.db.models import Q
 from django.forms.models import modelform_factory
 from django.forms.widgets import ClearableFileInput
 from django.test import override_settings
-from django.utils.text import slugify
-from django.utils import timezone, six
+from django.urls import reverse
+from django.utils import six, timezone
 from django.utils.encoding import force_text
 from django.utils.six.moves.urllib.parse import urlparse
-from django.utils.translation import ugettext_lazy as _
+from django.utils.text import slugify
 from django.utils.timezone import now
-from django.core.files.base import ContentFile
-
-from django.contrib.contenttypes.models import ContentType
-from django.contrib.contenttypes import fields
-
+from django.utils.translation import ugettext_lazy as _
 from model_utils.managers import InheritanceManager as ModelUtilsInheritanceManager
 
 import passerelle
 from passerelle.forms import GenericConnectorForm
 from passerelle.utils.api import endpoint
 from passerelle.utils.jsonresponse import APIError
-from passerelle.utils.sftp import SFTPField, SFTP
+from passerelle.utils.sftp import SFTP, SFTPField
 
 KEYTYPE_CHOICES = (
     ('API', _('API Key')),
     ('SIGN', _('HMAC Signature')),
 )
 
 LOGLEVEL_CHOICES = (
     ('DEBUG', _('Debug')),
diff --git a/passerelle/base/signature.py b/passerelle/base/signature.py
index 30b936f3..63b4a126 100644
--- a/passerelle/base/signature.py
+++ b/passerelle/base/signature.py
@@ -1,20 +1,19 @@
-import datetime
 import base64
-import hmac
+import datetime
 import hashlib
+import hmac
 import random
 
 from django.utils import six
 from django.utils.encoding import smart_bytes
 from django.utils.http import quote, urlencode
 from django.utils.six.moves.urllib import parse as urlparse
 
-
 '''Simple signature scheme for query strings'''
 # from http://git.entrouvert.org/hobo.git/tree/hobo/signature.py
 
 
 def sign_url(url, key, algo='sha256', timestamp=None, nonce=None):
     parsed = urlparse.urlparse(url)
     new_query = sign_query(parsed.query, key, algo, timestamp, nonce)
     return urlparse.urlunparse(parsed[:4] + (new_query,) + parsed[5:])
diff --git a/passerelle/base/templatetags/passerelle.py b/passerelle/base/templatetags/passerelle.py
index 38207f53..10c9f715 100644
--- a/passerelle/base/templatetags/passerelle.py
+++ b/passerelle/base/templatetags/passerelle.py
@@ -17,24 +17,25 @@
 
 from __future__ import absolute_import, unicode_literals
 
 import collections
 import json
 import re
 
 from django import template
-from django.utils.html import mark_safe, format_html
-from django.utils.translation import ugettext as _
-from django.contrib.contenttypes.models import ContentType
 from django.contrib.auth import get_permission_codename
-from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
+from django.contrib.contenttypes.models import ContentType
+from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
 from django.template.defaultfilters import stringfilter
+from django.utils.html import format_html, mark_safe
+from django.utils.translation import ugettext as _
 
 from passerelle.utils import get_trusted_services
+
 from ..models import AccessRight, ResourceLog
 
 register = template.Library()
 
 
 @register.inclusion_tag('passerelle/includes/access-rights-table.html', takes_context=True)
 def access_rights_table(context, resource, permission):
     resource_type = ContentType.objects.get_for_model(resource)
diff --git a/passerelle/base/urls.py b/passerelle/base/urls.py
index 0e1cd429..eb76199d 100644
--- a/passerelle/base/urls.py
+++ b/passerelle/base/urls.py
@@ -1,21 +1,21 @@
 from django.conf.urls import url
 
 from .views import (
+    AccessRightCreateView,
+    AccessRightDeleteView,
     ApiUserCreateView,
-    ApiUserUpdateView,
     ApiUserDeleteView,
     ApiUserListView,
-    AccessRightDeleteView,
-    AccessRightCreateView,
+    ApiUserUpdateView,
+    ExportSiteView,
+    ImportSiteView,
     LoggingParametersUpdateView,
     ManageAvailabilityView,
-    ImportSiteView,
-    ExportSiteView,
 )
 
 access_urlpatterns = [
     url(r'^$', ApiUserListView.as_view(), name='apiuser-list'),
     url(r'^add$', ApiUserCreateView.as_view(), name='apiuser-add'),
     url(r'^(?P<pk>[\w,-]+)/edit$', ApiUserUpdateView.as_view(), name='apiuser-edit'),
     url(r'^(?P<pk>[\w,-]+)/delete$', ApiUserDeleteView.as_view(), name='apiuser-delete'),
     url(r'^(?P<pk>[\w,-]+)/remove$', AccessRightDeleteView.as_view(), name='access-right-remove'),
diff --git a/passerelle/base/views.py b/passerelle/base/views.py
index 3eee2a57..db568bfa 100644
--- a/passerelle/base/views.py
+++ b/passerelle/base/views.py
@@ -13,35 +13,34 @@
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import datetime
 import json
 
 from dateutil import parser as date_parser
-
 from django.conf import settings
 from django.contrib.contenttypes.models import ContentType
-from django.urls import reverse
 from django.core.exceptions import ObjectDoesNotExist, PermissionDenied
 from django.db.models import Q
 from django.forms import models as model_forms
-from django.views.generic import View, DetailView, ListView, CreateView, UpdateView, DeleteView, FormView
 from django.http import Http404, HttpResponse, HttpResponseRedirect
 from django.shortcuts import get_object_or_404
+from django.urls import reverse
 from django.utils.timezone import make_aware
 from django.utils.translation import ugettext_lazy as _
+from django.views.generic import CreateView, DeleteView, DetailView, FormView, ListView, UpdateView, View
 
 from passerelle.compat import json_loads
 
-from .models import ApiUser, AccessRight, LoggingParameters, ResourceStatus, Job
-from .forms import ApiUserForm, AccessRightForm, AvailabilityParametersForm, ImportSiteForm
+from ..utils import export_site, get_trusted_services, import_site
 from ..views import GenericConnectorMixin
-from ..utils import get_trusted_services, import_site, export_site
+from .forms import AccessRightForm, ApiUserForm, AvailabilityParametersForm, ImportSiteForm
+from .models import AccessRight, ApiUser, Job, LoggingParameters, ResourceStatus
 
 
 class ResourceView(DetailView):
     template_name = 'passerelle/base/view.html'
 
     def get_object(self, queryset=None):
         try:
             obj = self.model.objects.get_subclass(slug=self.kwargs['slug'])
diff --git a/passerelle/contrib/dpark/models.py b/passerelle/contrib/dpark/models.py
index 73be9cf1..12c93e23 100644
--- a/passerelle/contrib/dpark/models.py
+++ b/passerelle/contrib/dpark/models.py
@@ -11,35 +11,33 @@
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 from __future__ import unicode_literals
 
-import datetime
 import base64
+import datetime
 
 import pytz
-
 from django.conf import settings
+from django.core.cache import cache
 from django.db import models
 from django.utils import six, timezone
 from django.utils.translation import ugettext_lazy as _
-from django.core.cache import cache
-
 from zeep.exceptions import Fault as WebFault
 from zeep.helpers import serialize_object
 
 from passerelle.base.models import BaseResource
 from passerelle.compat import json_loads
 from passerelle.utils.api import endpoint
-from passerelle.utils.jsonresponse import APIError
 from passerelle.utils.conversion import to_pdf
+from passerelle.utils.jsonresponse import APIError
 from passerelle.views import WrongParameter
 
 
 class Error(object):
     def __init__(self, code, msg=None):
         self.code = code
         self.msg = msg
 
diff --git a/passerelle/contrib/fake_family/default_database.py b/passerelle/contrib/fake_family/default_database.py
index a49d081e..adbca6f3 100644
--- a/passerelle/contrib/fake_family/default_database.py
+++ b/passerelle/contrib/fake_family/default_database.py
@@ -11,19 +11,19 @@
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-from datetime import datetime, timedelta
-import random
 import json
+import random
+from datetime import datetime, timedelta
 
 from passerelle.contrib.fake_family import randomnames
 
 
 def default_database():
 
     now = datetime.now()
 
diff --git a/passerelle/contrib/fake_family/migrations/0001_initial.py b/passerelle/contrib/fake_family/migrations/0001_initial.py
index 54c9c8a8..f602437e 100644
--- a/passerelle/contrib/fake_family/migrations/0001_initial.py
+++ b/passerelle/contrib/fake_family/migrations/0001_initial.py
@@ -1,13 +1,13 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
 import django.contrib.postgres.fields.jsonb
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('base', '0001_initial'),
     ]
 
diff --git a/passerelle/contrib/fake_family/migrations/0002_fakefamily_log_level.py b/passerelle/contrib/fake_family/migrations/0002_fakefamily_log_level.py
index b5799d32..b1ce7bac 100644
--- a/passerelle/contrib/fake_family/migrations/0002_fakefamily_log_level.py
+++ b/passerelle/contrib/fake_family/migrations/0002_fakefamily_log_level.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('fake_family', '0001_initial'),
     ]
 
diff --git a/passerelle/contrib/fake_family/models.py b/passerelle/contrib/fake_family/models.py
index cfaed264..61f1cec5 100644
--- a/passerelle/contrib/fake_family/models.py
+++ b/passerelle/contrib/fake_family/models.py
@@ -10,21 +10,22 @@
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 from django.contrib.postgres.fields import JSONField
+from django.core.exceptions import MultipleObjectsReturned, ObjectDoesNotExist
 from django.urls import reverse
 from django.utils.translation import ugettext_lazy as _
-from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned
 
 from passerelle.base.models import BaseResource
+
 from .default_database import default_database
 
 
 class FakeFamily(BaseResource):
     jsondatabase = JSONField(_('Fake Database (JSON)'), blank=True)
 
     category = _('Business Process Connectors')
 
diff --git a/passerelle/contrib/gdema/models.py b/passerelle/contrib/gdema/models.py
index 0411052c..f4289a47 100644
--- a/passerelle/contrib/gdema/models.py
+++ b/passerelle/contrib/gdema/models.py
@@ -14,19 +14,19 @@
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import datetime
 import json
 import re
 
 from django.db import models
-from django.utils.timezone import get_fixed_timezone, utc, is_naive, make_aware
 from django.utils.dateparse import parse_date, parse_datetime
 from django.utils.six import string_types
+from django.utils.timezone import get_fixed_timezone, is_naive, make_aware, utc
 from django.utils.translation import ugettext_lazy as _
 
 from passerelle.base.models import BaseResource
 from passerelle.compat import json_loads
 from passerelle.utils.api import endpoint
 from passerelle.utils.jsonresponse import APIError
 
 # Only for documentation
diff --git a/passerelle/contrib/greco/models.py b/passerelle/contrib/greco/models.py
index f0796d1d..09ee5e04 100644
--- a/passerelle/contrib/greco/models.py
+++ b/passerelle/contrib/greco/models.py
@@ -10,38 +10,35 @@
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import base64
 import re
-
 from email.mime.base import MIMEBase
 from email.mime.multipart import MIMEMultipart
 from email.mime.text import MIMEText
 
-from suds.client import Client
-from suds.transport import Reply
-from suds.transport.http import HttpAuthenticated
 import suds.sudsobject
-
+from django.core.cache import cache
 from django.db import models
 from django.utils import six
 from django.utils.translation import ugettext_lazy as _
-from django.core.cache import cache
+from suds.client import Client
+from suds.transport import Reply
+from suds.transport.http import HttpAuthenticated
 
 from passerelle.base.models import BaseResource
 from passerelle.compat import json_loads
-from passerelle.utils.api import endpoint, APIError
 from passerelle.soap import sudsobject_to_dict
+from passerelle.utils.api import APIError, endpoint
 
-from .formdata import FormData, CREATION_SCHEMA, list_schema_fields
-
+from .formdata import CREATION_SCHEMA, FormData, list_schema_fields
 
 # taken from https://lsimons.wordpress.com/2011/03/17/stripping-illegal-characters-out-of-xml-in-python/
 _illegal_xml_chars_RE = re.compile(u'[\x00-\x08\x0b\x0c\x0e-\x1F\uD800-\uDFFF\uFFFE\uFFFF]')
 
 
 def escape_xml_illegal_chars(val, replacement='?'):
     return _illegal_xml_chars_RE.sub(replacement, val)
 
diff --git a/passerelle/contrib/grenoble_gru/models.py b/passerelle/contrib/grenoble_gru/models.py
index 82d191f4..34711282 100644
--- a/passerelle/contrib/grenoble_gru/models.py
+++ b/passerelle/contrib/grenoble_gru/models.py
@@ -9,33 +9,31 @@
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-from lxml import etree
-
 from django.core.cache import cache
 from django.db import models
-from django.utils.translation import ugettext_lazy as _
 from django.utils import dateparse
 from django.utils.http import urlencode
-from django.utils.text import slugify
 from django.utils.six.moves.urllib import parse as urlparse
+from django.utils.text import slugify
+from django.utils.translation import ugettext_lazy as _
+from lxml import etree
 
 from passerelle.base.models import BaseResource
 from passerelle.compat import json_loads
 from passerelle.utils.api import endpoint
 from passerelle.utils.jsonresponse import APIError
 from passerelle.views import WrongParameter
 
-
 RESPONSE_CODES = {
     '01': _('Success'),
     '02': _('Remote service error'),
     '10': _('Authentication failed'),
     '11': _('Collectivity not defined'),
     '20': _('Invalid input format'),
     '21': _('Required field not provided'),
     '22': _('Unexpected value (referentials)'),
diff --git a/passerelle/contrib/iparapheur/migrations/0001_initial.py b/passerelle/contrib/iparapheur/migrations/0001_initial.py
index c3c10c99..e7d618cb 100644
--- a/passerelle/contrib/iparapheur/migrations/0001_initial.py
+++ b/passerelle/contrib/iparapheur/migrations/0001_initial.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('base', '0002_auto_20151009_0326'),
     ]
 
diff --git a/passerelle/contrib/iparapheur/migrations/0002_auto_20160406_1123.py b/passerelle/contrib/iparapheur/migrations/0002_auto_20160406_1123.py
index 04599a26..3e6703e9 100644
--- a/passerelle/contrib/iparapheur/migrations/0002_auto_20160406_1123.py
+++ b/passerelle/contrib/iparapheur/migrations/0002_auto_20160406_1123.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('iparapheur', '0001_initial'),
     ]
 
diff --git a/passerelle/contrib/iparapheur/migrations/0003_iparapheur_log_level.py b/passerelle/contrib/iparapheur/migrations/0003_iparapheur_log_level.py
index 7a46889a..f7d5c134 100644
--- a/passerelle/contrib/iparapheur/migrations/0003_iparapheur_log_level.py
+++ b/passerelle/contrib/iparapheur/migrations/0003_iparapheur_log_level.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('iparapheur', '0002_auto_20160406_1123'),
     ]
 
diff --git a/passerelle/contrib/iparapheur/models.py b/passerelle/contrib/iparapheur/models.py
index fa5a1a02..30bcc9b3 100644
--- a/passerelle/contrib/iparapheur/models.py
+++ b/passerelle/contrib/iparapheur/models.py
@@ -10,32 +10,31 @@
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 import base64
 
-from requests.exceptions import ConnectionError
 from django.db import models
+from django.http import Http404, HttpResponse
 from django.utils.encoding import force_text
 from django.utils.six.moves.urllib import parse
 from django.utils.text import slugify
 from django.utils.translation import ugettext_lazy as _
-from django.http import HttpResponse, Http404
-
+from requests.exceptions import ConnectionError
 from zeep import Settings
-from zeep.exceptions import Fault as WebFault, TransportError, XMLSyntaxError
+from zeep.exceptions import Fault as WebFault
+from zeep.exceptions import TransportError, XMLSyntaxError
 
 from passerelle.base.models import BaseResource, HTTPResource
 from passerelle.utils.api import endpoint
 from passerelle.utils.jsonresponse import APIError
 
-
 CREATE_FILE_SCHEMA = {
     '$schema': 'http://json-schema.org/draft-04/schema#',
     'title': 'Iparapheur create file',
     'type': 'object',
     'required': ['file', 'title', 'type', 'subtype', 'visibility'],
     'properties': {
         'file': {
             'type': 'object',
diff --git a/passerelle/contrib/isere_ens/models.py b/passerelle/contrib/isere_ens/models.py
index 6a86af8e..1470fe5d 100644
--- a/passerelle/contrib/isere_ens/models.py
+++ b/passerelle/contrib/isere_ens/models.py
@@ -9,30 +9,29 @@
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-from collections import OrderedDict
 import datetime
+from collections import OrderedDict
 
 from django.core.cache import cache
 from django.db import models
 from django.utils.formats import date_format
 from django.utils.six.moves.urllib import parse as urlparse
 from django.utils.translation import ugettext_lazy as _
 
+from passerelle.base.models import BaseResource, HTTPResource
+from passerelle.utils.api import endpoint
 from passerelle.utils.conversion import simplify
 from passerelle.utils.jsonresponse import APIError
-from passerelle.utils.api import endpoint
-from passerelle.base.models import BaseResource, HTTPResource
-
 
 SITE_BOOKING_SCHOOL_SCHEMA = {
     "$schema": "http://json-schema.org/draft-04/schema#",
     "title": "ENS site/booking/school",
     "description": "",
     "type": "object",
     "required": [
         "code",
diff --git a/passerelle/contrib/iws/models.py b/passerelle/contrib/iws/models.py
index 5ed3dbdb..6e07b722 100644
--- a/passerelle/contrib/iws/models.py
+++ b/passerelle/contrib/iws/models.py
@@ -9,31 +9,30 @@
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-from datetime import datetime
 import json
+from datetime import datetime
 
+import lxml.etree
+import pkg_resources
 from django.db import models
 from django.utils import dateformat
 from django.utils.translation import ugettext_lazy as _
-import lxml.etree
-import pkg_resources
 
 from passerelle.base.models import BaseResource
 from passerelle.utils.api import endpoint
 from passerelle.utils.conversion import any2bool
 from passerelle.utils.jsonresponse import APIError
 
-
 TYPE_AGENDA = {"DECHET": "DECHETS VERTS", "ENCOMBRANT": "ENCOMBRANTS"}
 C_TYPEPB = {"DECHET": "8006", "ENCOMBRANT": "8008"}
 SYNDIC_C_TYPEPB = {"DECHET": "8007", "ENCOMBRANT": "8009"}
 
 NS = '{http://isilog.fr}'
 
 BOOKDATE_SCHEMA = {
     "$schema": "http://json-schema.org/draft-04/schema#",
diff --git a/passerelle/contrib/lille_kimoce/models.py b/passerelle/contrib/lille_kimoce/models.py
index 3e57697f..ba873fc4 100644
--- a/passerelle/contrib/lille_kimoce/models.py
+++ b/passerelle/contrib/lille_kimoce/models.py
@@ -10,27 +10,26 @@
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 
+from django.core.cache import cache
 from django.db import models
-from django.utils.translation import ugettext_lazy as _
 from django.utils.six.moves.urllib_parse import urljoin
-from django.core.cache import cache
+from django.utils.translation import ugettext_lazy as _
 
 from passerelle.base.models import BaseResource
 from passerelle.utils.api import endpoint
 from passerelle.utils.http_authenticators import HttpBearerAuth
 from passerelle.utils.jsonresponse import APIError
 
-
 DEMAND_SCHEMA = {
     '$schema': 'http://json-schema.org/draft-04/schema#',
     'title': 'KIMOCE',
     'description': '',
     'type': 'object',
     'required': ['category', 'type', 'subtype', 'form_url', 'first_name', 'last_name', 'email'],
     'properties': {
         'category': {
diff --git a/passerelle/contrib/mdph13/migrations/0001_initial.py b/passerelle/contrib/mdph13/migrations/0001_initial.py
index 9db03fef..98d5c826 100644
--- a/passerelle/contrib/mdph13/migrations/0001_initial.py
+++ b/passerelle/contrib/mdph13/migrations/0001_initial.py
@@ -1,14 +1,14 @@
 # -*- coding: utf-8 -*-
 # Generated by Django 1.11.10 on 2019-02-15 09:57
 from __future__ import unicode_literals
 
-from django.db import migrations, models
 import django.db.models.deletion
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     initial = True
 
     dependencies = [
         ('base', '0010_loggingparameters_trace_emails'),
diff --git a/passerelle/contrib/mdph13/models.py b/passerelle/contrib/mdph13/models.py
index 8bb01a95..dbeff402 100644
--- a/passerelle/contrib/mdph13/models.py
+++ b/passerelle/contrib/mdph13/models.py
@@ -15,26 +15,25 @@
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import base64
 import datetime
 import re
 
 import requests
-
 from django.db import models, transaction
-from django.utils import six, dateparse
+from django.utils import dateparse, six
 from django.utils.six.moves.urllib import parse as urlparse
-from django.utils.translation import ugettext_lazy as _
 from django.utils.timezone import now
+from django.utils.translation import ugettext_lazy as _
 
-from passerelle.utils.jsonresponse import APIError, to_json
-from passerelle.utils.api import endpoint
 from passerelle.base.models import BaseResource, HTTPResource
+from passerelle.utils.api import endpoint
+from passerelle.utils.jsonresponse import APIError, to_json
 
 
 def json_walker(value, func, path=None):
     """Walk a JSON structure of objects, arrays and scalar values, call
     func(value, path) on values."""
     path = path or []
     if isinstance(value, dict):
         for key in value:
diff --git a/passerelle/contrib/nancypoll/migrations/0001_initial.py b/passerelle/contrib/nancypoll/migrations/0001_initial.py
index af6a87b1..46c72cfd 100644
--- a/passerelle/contrib/nancypoll/migrations/0001_initial.py
+++ b/passerelle/contrib/nancypoll/migrations/0001_initial.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('base', '0002_auto_20151009_0326'),
     ]
 
diff --git a/passerelle/contrib/nancypoll/migrations/0004_csv_upload_to.py b/passerelle/contrib/nancypoll/migrations/0004_csv_upload_to.py
index 76240f88..42ad0507 100644
--- a/passerelle/contrib/nancypoll/migrations/0004_csv_upload_to.py
+++ b/passerelle/contrib/nancypoll/migrations/0004_csv_upload_to.py
@@ -1,12 +1,13 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
 from django.db import migrations, models
+
 import passerelle.contrib.nancypoll.models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('nancypoll', '0003_remove_nancypoll_log_level'),
     ]
diff --git a/passerelle/contrib/nancypoll/migrations/0005_csv_upload_to.py b/passerelle/contrib/nancypoll/migrations/0005_csv_upload_to.py
index 101c85a3..5393cfa8 100644
--- a/passerelle/contrib/nancypoll/migrations/0005_csv_upload_to.py
+++ b/passerelle/contrib/nancypoll/migrations/0005_csv_upload_to.py
@@ -1,10 +1,11 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
+
 import os
 
 from django.db import migrations
 
 
 def move_files(apps, schema_editor):
     NancyPoll = apps.get_model('nancypoll', 'NancyPoll')
     NancyPoll.get_connector_slug = lambda *args, **kwargs: 'nancypoll'
diff --git a/passerelle/contrib/nancypoll/models.py b/passerelle/contrib/nancypoll/models.py
index 5911fd61..27a724cd 100644
--- a/passerelle/contrib/nancypoll/models.py
+++ b/passerelle/contrib/nancypoll/models.py
@@ -1,21 +1,20 @@
 import csv
 
-from django.db import models
 from django.core.exceptions import ObjectDoesNotExist
+from django.db import models
 from django.utils import six
 from django.utils.encoding import force_text
 from django.utils.translation import ugettext_lazy as _
 
 from passerelle.base.models import BaseResource
 from passerelle.utils.api import endpoint
 from passerelle.utils.jsonresponse import APIError
 
-
 COLUMN_NAMES = (
     'street_start_number, street_end_number,,,street_side,,,,code,id,text,address,,,street_name,,canton,,,'
 )
 
 
 def to_unicode(value):
     return force_text(value, 'utf-8')
 
diff --git a/passerelle/contrib/planitech/migrations/0002_planitechconnector_custom_fields.py b/passerelle/contrib/planitech/migrations/0002_planitechconnector_custom_fields.py
index 322505ee..8e4ab1d3 100644
--- a/passerelle/contrib/planitech/migrations/0002_planitechconnector_custom_fields.py
+++ b/passerelle/contrib/planitech/migrations/0002_planitechconnector_custom_fields.py
@@ -1,14 +1,14 @@
 # -*- coding: utf-8 -*-
 # Generated by Django 1.11.17 on 2019-01-08 11:22
 from __future__ import unicode_literals
 
-from django.db import migrations
 import django.contrib.postgres.fields.jsonb
+from django.db import migrations
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('planitech', '0001_initial'),
     ]
 
diff --git a/passerelle/contrib/planitech/migrations/0003_pairing.py b/passerelle/contrib/planitech/migrations/0003_pairing.py
index d900410c..a1f3de38 100644
--- a/passerelle/contrib/planitech/migrations/0003_pairing.py
+++ b/passerelle/contrib/planitech/migrations/0003_pairing.py
@@ -1,14 +1,14 @@
 # -*- coding: utf-8 -*-
 # Generated by Django 1.11.17 on 2019-01-10 11:08
 from __future__ import unicode_literals
 
-from django.db import migrations, models
 import django.db.models.deletion
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('planitech', '0002_planitechconnector_custom_fields'),
     ]
 
diff --git a/passerelle/contrib/planitech/models.py b/passerelle/contrib/planitech/models.py
index 253eb2d2..46bd5651 100644
--- a/passerelle/contrib/planitech/models.py
+++ b/passerelle/contrib/planitech/models.py
@@ -10,38 +10,36 @@
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import collections
-from datetime import date, datetime, time, timedelta
 import hashlib
 import json
 import re
 import uuid
+from datetime import date, datetime, time, timedelta
 
 from django.contrib.postgres.fields import JSONField
 from django.core.cache import cache
 from django.db import models, transaction
-from django.utils import dateformat
-from django.utils import dateparse
+from django.utils import dateformat, dateparse
 from django.utils.encoding import force_bytes
 from django.utils.six.moves.urllib import parse as urlparse
 from django.utils.translation import ugettext_lazy as _
 from requests.exceptions import RequestException
 
 from passerelle.base.models import BaseResource
 from passerelle.contrib.planitech import mste
 from passerelle.utils.api import endpoint
 from passerelle.utils.jsonresponse import APIError
 
-
 DEFAULT_MIN_CAPACITY = 0
 DEFAULT_MAX_CAPACITY = 100000
 
 
 CREATE_RESERVATION_SCHEMA = {
     "$schema": "http://json-schema.org/draft-04/schema#",
     "title": "Planitech createreservation",
     "description": "",
diff --git a/passerelle/contrib/planitech/mste.py b/passerelle/contrib/planitech/mste.py
index e2679a5f..188f031d 100644
--- a/passerelle/contrib/planitech/mste.py
+++ b/passerelle/contrib/planitech/mste.py
@@ -9,22 +9,21 @@
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-from datetime import datetime
 import calendar
+from datetime import datetime
 
 from django.utils import six
 
-
 ENCODE_TOKENS = {
     'integer': 16,
     'real': 19,
     'nil': 0,
     'true': 1,
     'false': 2,
     'emptyString': 3,
     'emptyData': 4,
diff --git a/passerelle/contrib/rsa13/models.py b/passerelle/contrib/rsa13/models.py
index 723ed5c5..f545c9b7 100644
--- a/passerelle/contrib/rsa13/models.py
+++ b/passerelle/contrib/rsa13/models.py
@@ -14,21 +14,20 @@
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import csv
 from urllib.parse import urljoin
 
 import requests
-
 from django.db import models
 from django.http import HttpResponse
-from django.utils.translation import ugettext_lazy as _
 from django.utils.timezone import now
+from django.utils.translation import ugettext_lazy as _
 
 from passerelle.base.models import BaseResource, HTTPResource
 from passerelle.utils.api import endpoint
 from passerelle.utils.jsonresponse import APIError
 
 OUI_NON_ENUM = {'enum': ['Oui', 'Non']}
 DATE_SCHEMA = {'type': 'string', 'format': 'date'}
 
diff --git a/passerelle/contrib/sigerly/models.py b/passerelle/contrib/sigerly/models.py
index dffc09bc..544a90c3 100644
--- a/passerelle/contrib/sigerly/models.py
+++ b/passerelle/contrib/sigerly/models.py
@@ -18,17 +18,16 @@ from urllib.parse import urljoin
 
 from django.db import models
 from django.utils.translation import ugettext_lazy as _
 
 from passerelle.base.models import BaseResource, HTTPResource
 from passerelle.utils.api import endpoint
 from passerelle.utils.jsonresponse import APIError
 
-
 CREATE_SCHEMA = {
     '$schema': 'http://json-schema.org/draft-04/schema#',
     "type": "object",
     'required': ['demandeur', 'id_typeinterv', 'id_urgence', 'elements'],
     'properties': {
         'demandeur': {
             'description': "Nom du demandeur",
             'type': 'string',
diff --git a/passerelle/contrib/solis_apa/migrations/0001_initial.py b/passerelle/contrib/solis_apa/migrations/0001_initial.py
index f914a626..ec8c1ec3 100644
--- a/passerelle/contrib/solis_apa/migrations/0001_initial.py
+++ b/passerelle/contrib/solis_apa/migrations/0001_initial.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('base', '0002_auto_20151009_0326'),
     ]
 
diff --git a/passerelle/contrib/solis_apa/models.py b/passerelle/contrib/solis_apa/models.py
index b2deb1b4..2b06a542 100644
--- a/passerelle/contrib/solis_apa/models.py
+++ b/passerelle/contrib/solis_apa/models.py
@@ -9,30 +9,29 @@
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-import re
 import json
+import re
 
-from django.db import models
 from django.core.cache import cache
-from django.urls import reverse
 from django.db import models
+from django.http import HttpResponse
+from django.urls import reverse
 from django.utils.six.moves.urllib import parse as urlparse
 from django.utils.translation import ugettext_lazy as _
-from django.http import HttpResponse
 
 from passerelle.base.models import BaseResource
 from passerelle.compat import json_loads
-from passerelle.contrib.solis_apa import conciliation, suivi, integration
+from passerelle.contrib.solis_apa import conciliation, integration, suivi
 from passerelle.utils.jsonresponse import APIError
 
 HEADERS = {'Accept': 'application/json', 'Content-Type': 'application/json'}
 
 APPLICATION = 'AsgTeleprocedureApa14'
 
 
 class SolisAPA(BaseResource):
diff --git a/passerelle/contrib/solis_apa/suivi.py b/passerelle/contrib/solis_apa/suivi.py
index d1a9ba68..195ac2a5 100644
--- a/passerelle/contrib/solis_apa/suivi.py
+++ b/passerelle/contrib/solis_apa/suivi.py
@@ -9,18 +9,18 @@
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-import json
 import datetime
+import json
 
 PAYLOAD = {
     "visite": {},
     "plan-aide": {"DemandeAsg": {"DateDebut": "%(datedebut)s", "DateFin": "%(datefin)s"}},
     "presentation-commission": {"OrdreJourAsg": {"DateDebut": "%(datedebut)s", "DateFin": "%(datefin)s"}},
     "decision-commission": {
         "DemandeAsg": {
             "EtatDecision": "R",
diff --git a/passerelle/contrib/solis_apa/views.py b/passerelle/contrib/solis_apa/views.py
index 0882e19b..5ecd0f2b 100644
--- a/passerelle/contrib/solis_apa/views.py
+++ b/passerelle/contrib/solis_apa/views.py
@@ -9,21 +9,22 @@
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-from django.views.generic import DetailView as GenericDetailView, View
-from django.views.generic.detail import SingleObjectMixin
 from django.utils.decorators import method_decorator
-from django.views.decorators.csrf import csrf_exempt
 from django.utils.translation import ugettext_lazy as _
+from django.views.decorators.csrf import csrf_exempt
+from django.views.generic import DetailView as GenericDetailView
+from django.views.generic import View
+from django.views.generic.detail import SingleObjectMixin
 
 import passerelle.utils as utils
 
 from .models import SolisAPA
 
 
 class CommissionTypeNotFound(Exception):
     http_status = 404
diff --git a/passerelle/contrib/strasbourg_eu/models.py b/passerelle/contrib/strasbourg_eu/models.py
index b987a3bf..e3a6c19d 100644
--- a/passerelle/contrib/strasbourg_eu/models.py
+++ b/passerelle/contrib/strasbourg_eu/models.py
@@ -18,17 +18,17 @@ import datetime
 
 from django.db import models
 from django.utils.encoding import force_text
 from django.utils.six.moves.urllib import parse as urlparse
 from django.utils.translation import ugettext_lazy as _
 
 from passerelle.base.models import BaseResource
 from passerelle.compat import json_loads
-from passerelle.utils.api import endpoint, APIError
+from passerelle.utils.api import APIError, endpoint
 
 
 class StrasbourgEu(BaseResource):
     category = _('Misc')
 
     liferay_api_url = models.URLField(_('Liferay API URL'), max_length=256)
 
     class Meta:
diff --git a/passerelle/contrib/stub_invoices/models.py b/passerelle/contrib/stub_invoices/models.py
index 4bfecea9..160ad008 100644
--- a/passerelle/contrib/stub_invoices/models.py
+++ b/passerelle/contrib/stub_invoices/models.py
@@ -10,22 +10,22 @@
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import datetime
-from decimal import Decimal
 import random
+from decimal import Decimal
 
 from django.http import HttpResponse
-from django.utils.translation import ugettext_lazy as _
 from django.utils import timezone
+from django.utils.translation import ugettext_lazy as _
 
 from passerelle.base.models import BaseResource
 from passerelle.utils.api import endpoint
 
 
 class StubInvoicesConnector(BaseResource):
     category = _('Stub Connectors')
 
diff --git a/passerelle/contrib/tcl/models.py b/passerelle/contrib/tcl/models.py
index bed7423c..e214765e 100644
--- a/passerelle/contrib/tcl/models.py
+++ b/passerelle/contrib/tcl/models.py
@@ -13,18 +13,18 @@
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import re
 
 from django.conf import settings
 from django.db import models, transaction
-from django.utils.translation import ugettext_lazy as _
 from django.utils import timezone
+from django.utils.translation import ugettext_lazy as _
 
 from passerelle.base.models import BaseResource
 from passerelle.utils.api import endpoint
 
 
 def get_tcl_data_url(key):
     if key == 'tclarret':
         return settings.TCL_GEOJSON_URL_TEMPLATE % key
diff --git a/passerelle/contrib/teamnet_axel/migrations/0001_initial.py b/passerelle/contrib/teamnet_axel/migrations/0001_initial.py
index 71522529..734cad6b 100644
--- a/passerelle/contrib/teamnet_axel/migrations/0001_initial.py
+++ b/passerelle/contrib/teamnet_axel/migrations/0001_initial.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('base', '0001_initial'),
     ]
 
diff --git a/passerelle/contrib/teamnet_axel/migrations/0002_management_billing_regies.py b/passerelle/contrib/teamnet_axel/migrations/0002_management_billing_regies.py
index e63a1ae0..da504a9f 100644
--- a/passerelle/contrib/teamnet_axel/migrations/0002_management_billing_regies.py
+++ b/passerelle/contrib/teamnet_axel/migrations/0002_management_billing_regies.py
@@ -1,13 +1,13 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
 import django.contrib.postgres.fields.jsonb
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('teamnet_axel', '0001_initial'),
     ]
 
diff --git a/passerelle/contrib/teamnet_axel/migrations/0003_management_log_level.py b/passerelle/contrib/teamnet_axel/migrations/0003_management_log_level.py
index 041180d3..a89d0634 100644
--- a/passerelle/contrib/teamnet_axel/migrations/0003_management_log_level.py
+++ b/passerelle/contrib/teamnet_axel/migrations/0003_management_log_level.py
@@ -1,12 +1,12 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import models, migrations
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('teamnet_axel', '0002_management_billing_regies'),
     ]
 
diff --git a/passerelle/contrib/teamnet_axel/models.py b/passerelle/contrib/teamnet_axel/models.py
index 13531f6b..06b07706 100644
--- a/passerelle/contrib/teamnet_axel/models.py
+++ b/passerelle/contrib/teamnet_axel/models.py
@@ -10,35 +10,35 @@
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import base64
-from datetime import datetime
 import logging
 import xml.etree.ElementTree as ET
+from datetime import datetime
 
 from django.contrib.postgres.fields import JSONField
 from django.db import models
 from django.http import HttpResponse, HttpResponseNotFound
-from django.utils.translation import ugettext_lazy as _
 from django.utils.encoding import smart_text
+from django.utils.translation import ugettext_lazy as _
 
 from passerelle.base.models import BaseResource
 from passerelle.compat import json_loads
 from passerelle.soap import client_to_jsondict
 from passerelle.utils.api import endpoint
 from passerelle.utils.jsonresponse import APIError
 from passerelle.views import WrongParameter
 
 from . import soap
-from .utils import normalize_person, normalize_invoice
+from .utils import normalize_invoice, normalize_person
 
 logger = logging.getLogger('passerelle.contrib.teamnet_axel')
 
 ADULT1 = '1'
 ADULT2 = '2'
 CHILD = '3'
 
 DATE_IN_FORMAT = '%Y-%m-%dT%H:%M:%S'
diff --git a/passerelle/contrib/teamnet_axel/soap.py b/passerelle/contrib/teamnet_axel/soap.py
index 973e9880..ff98786c 100644
--- a/passerelle/contrib/teamnet_axel/soap.py
+++ b/passerelle/contrib/teamnet_axel/soap.py
@@ -13,19 +13,19 @@
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 # borrowed from https://pypi.python.org/pypi/suds_requests
 # and https://docs.oracle.com/cd/E50245_01/E50253/html/vmprg-soap-example-authentication-python.html
 
 from django.utils.six import BytesIO
-from suds.transport.http import HttpAuthenticated
-from suds.transport import Reply
 from suds.client import Client
+from suds.transport import Reply
+from suds.transport.http import HttpAuthenticated
 
 
 class Transport(HttpAuthenticated):
     def __init__(self, model, **kwargs):
         self.model = model
         HttpAuthenticated.__init__(self, **kwargs)  # oldstyle class...
 
     def get_requests_kwargs(self):
diff --git a/passerelle/contrib/toulouse_axel/migrations/0001_initial.py b/passerelle/contrib/toulouse_axel/migrations/0001_initial.py
index 1efd439c..a884f1e4 100644
--- a/passerelle/contrib/toulouse_axel/migrations/0001_initial.py
+++ b/passerelle/contrib/toulouse_axel/migrations/0001_initial.py
@@ -1,13 +1,13 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import migrations, models
 import django.db.models.deletion
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     initial = True
 
     dependencies = [
         ('base', '0016_auto_20191002_1443'),
diff --git a/passerelle/contrib/toulouse_axel/migrations/0003_auto_20191205_0948.py b/passerelle/contrib/toulouse_axel/migrations/0003_auto_20191205_0948.py
index 8d64115e..36560266 100644
--- a/passerelle/contrib/toulouse_axel/migrations/0003_auto_20191205_0948.py
+++ b/passerelle/contrib/toulouse_axel/migrations/0003_auto_20191205_0948.py
@@ -1,13 +1,13 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
-from django.db import migrations, models
 import django.db.models.deletion
+from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
 
     dependencies = [
         ('toulouse_axel', '0002_auto_20191122_0946'),
     ]
 
diff --git a/passerelle/contrib/toulouse_axel/models.py b/passerelle/contrib/toulouse_axel/models.py
index 2c513af2..eff4f4c6 100644
--- a/passerelle/contrib/toulouse_axel/models.py
+++ b/passerelle/contrib/toulouse_axel/models.py
@@ -25,18 +25,18 @@ from django.http import HttpResponse
 from django.utils import dateformat
 from django.utils.dates import WEEKDAYS as WEEKDAYS_LABELS
 from django.utils.translation import ugettext_lazy as _
 
 from passerelle.base.models import BaseResource
 from passerelle.compat import json_loads
 from passerelle.utils.api import endpoint
 from passerelle.utils.jsonresponse import APIError
-from . import schemas
-from . import utils
+
+from . import schemas, utils
 from .exceptions import AxelError
 
 logger = logging.getLogger('passerelle.contrib.toulouse_axel')
 
 BASE_XSD_PATH = os.path.join(os.path.dirname(__file__), 'xsd')
 
 WEEKDAYS = {
     0: 'monday',
diff --git a/passerelle/contrib/toulouse_axel/schemas.py b/passerelle/contrib/toulouse_axel/schemas.py
index 19da22aa..a8c7b670 100644
--- a/passerelle/contrib/toulouse_axel/schemas.py
+++ b/passerelle/contrib/toulouse_axel/schemas.py
@@ -16,21 +16,21 @@
 
 import copy
 import datetime
 import os
 import re
 import xml.etree.ElementTree as ET
 from collections import namedtuple
 
-from django.utils.encoding import force_text
-
 import xmlschema
+from django.utils.encoding import force_text
 
 from passerelle.utils.xml import JSONSchemaFromXMLSchema
+
 from . import utils
 from .exceptions import AxelError
 
 BASE_XSD_PATH = os.path.join(os.path.dirname(__file__), 'xsd')
 
 
 class AxelSchema(JSONSchemaFromXMLSchema):
     type_map = {
diff --git a/passerelle/contrib/toulouse_axel/utils.py b/passerelle/contrib/toulouse_axel/utils.py
index f8c8fa9d..cc1de700 100644
--- a/passerelle/contrib/toulouse_axel/utils.py
+++ b/passerelle/contrib/toulouse_axel/utils.py
@@ -12,28 +12,26 @@
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 from __future__ import unicode_literals
 
-from collections import OrderedDict
 import datetime
 import unicodedata
 import xml.etree.ElementTree as ET
+from collections import OrderedDict
 
 import pytz
-
 from django.utils.six import string_types
 
 from passerelle.utils.conversion import normalize
 
-
 boolean_type = {
     'oneOf': [
         {'type': 'boolean'},
         {
             'type': 'string',
             'pattern': '[Oo][Uu][Ii]|[Nn][Oo][Nn]|[Tt][Rr][Uu][Ee]|[Ff][Aa][Ll][Ss][Ee]|1|0',
         },
     ]
diff --git a/passerelle/plugins.py b/passerelle/plugins.py
index 64bfb7f6..828da858 100644
--- a/passerelle/plugins.py
+++ b/passerelle/plugins.py
@@ -12,17 +12,17 @@
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 from django.apps import apps
 from django.conf.urls import include, url
 
-from .urls_utils import decorated_includes, required, app_enabled, manager_required
+from .urls_utils import app_enabled, decorated_includes, manager_required, required
 
 
 def register_apps_urls(urlpatterns):
     """Call get_before_urls and get_after_urls on all apps providing them,
     add those urls to the given urlpatterns (before or after).
     """
     before_urls = []
     after_urls = []
diff --git a/passerelle/settings.py b/passerelle/settings.py
index f6c35039..722d7109 100644
--- a/passerelle/settings.py
+++ b/passerelle/settings.py
@@ -1,13 +1,14 @@
 # Django default settings for passerelle project.
 
-from django.conf import global_settings
-import os
 import logging
+import os
+
+from django.conf import global_settings
 
 try:
     from logging.handlers import NullHandler
 except ImportError:
     # python < 2.7
     class NullHandler(logging.Handler):
         def emit(self, record):
             pass
diff --git a/passerelle/sms/models.py b/passerelle/sms/models.py
index db86dec8..01918cee 100644
--- a/passerelle/sms/models.py
+++ b/passerelle/sms/models.py
@@ -23,17 +23,16 @@ from django.utils.module_loading import import_string
 from django.utils.translation import ugettext_lazy as _
 
 from passerelle.base.models import BaseResource
 from passerelle.compat import json_loads
 from passerelle.sms.forms import SMSConnectorForm
 from passerelle.utils.api import endpoint
 from passerelle.utils.jsonresponse import APIError
 
-
 SEND_SCHEMA = {
     '$schema': 'http://json-schema.org/draft-04/schema#',
     "type": "object",
     'required': ['message', 'from', 'to'],
     'properties': {
         'message': {
             'description': 'String message',
             'type': 'string',
diff --git a/passerelle/soap.py b/passerelle/soap.py
index 5c011f9f..b9cc99fd 100644
--- a/passerelle/soap.py
+++ b/passerelle/soap.py
@@ -1,10 +1,10 @@
-from django.utils.encoding import force_text
 import suds.sudsobject
+from django.utils.encoding import force_text
 
 
 def client_to_jsondict(client):
     """return description of the client, as dict (for json export)"""
     res = {}
     for i, sd in enumerate(client.sd):
         d = {}
         d['tns'] = sd.wsdl.tns[1]
diff --git a/passerelle/urls.py b/passerelle/urls.py
index d3de0209..2e5a761d 100644
--- a/passerelle/urls.py
+++ b/passerelle/urls.py
@@ -1,39 +1,36 @@
 from django.conf import settings
 from django.conf.urls import include, url
-
 from django.contrib import admin
-
 from django.contrib.auth.decorators import login_required
 from django.contrib.staticfiles.urls import staticfiles_urlpatterns
 from django.views.static import serve as static_serve
 
 from .api.urls import urlpatterns as api_urls
+from .base.urls import access_urlpatterns, import_export_urlpatterns
+from .base.views import GenericJobView, GenericRestartJobView, GenericViewJobsConnectorView
+from .plugins import register_apps_urls
+from .urls_utils import decorated_includes, manager_required
 from .views import (
-    HomePageView,
-    ManageView,
-    ManageAddView,
+    GenericConnectorView,
     GenericCreateConnectorView,
     GenericDeleteConnectorView,
     GenericEditConnectorView,
     GenericEndpointView,
-    GenericConnectorView,
-    GenericViewLogsConnectorView,
-    GenericLogView,
     GenericExportConnectorView,
+    GenericLogView,
+    GenericViewLogsConnectorView,
+    HomePageView,
+    ManageAddView,
+    ManageView,
     login,
     logout,
     menu_json,
 )
-from .base.views import GenericViewJobsConnectorView, GenericJobView, GenericRestartJobView
-from .urls_utils import decorated_includes, manager_required
-from .base.urls import access_urlpatterns, import_export_urlpatterns
-from .plugins import register_apps_urls
-
 
 admin.autodiscover()
 
 urlpatterns = [
     url(r'^$', HomePageView.as_view(), name='homepage'),
     url(r'^manage/$', manager_required(ManageView.as_view()), name='manage-home'),
     url(r'^manage/menu.json$', manager_required(menu_json), name='menu-json'),
     url(r'^manage/add$', manager_required(ManageAddView.as_view()), name='add-connector'),
diff --git a/passerelle/urls_utils.py b/passerelle/urls_utils.py
index d0436eee..819c9cca 100644
--- a/passerelle/urls_utils.py
+++ b/passerelle/urls_utils.py
@@ -6,18 +6,19 @@ from django.conf import settings
 from django.contrib.auth.decorators import user_passes_test
 from django.core.exceptions import PermissionDenied
 
 try:
     from django.urls import URLPattern, URLResolver
 except ImportError:
     # django < 2.0 compatibility
     from django.urls import RegexURLPattern as URLPattern, RegexURLResolver as URLResolver
-from django.views.debug import technical_404_response
+
 from django.http import Http404
+from django.views.debug import technical_404_response
 
 
 class DecoratedURLPattern(URLPattern):
     def resolve(self, *args, **kwargs):
         result = super(DecoratedURLPattern, self).resolve(*args, **kwargs)
         if result:
             result.func = self._decorate_with(result.func)
         return result
diff --git a/passerelle/utils/__init__.py b/passerelle/utils/__init__.py
index 8c886223..29ab5d05 100644
--- a/passerelle/utils/__init__.py
+++ b/passerelle/utils/__init__.py
@@ -11,44 +11,43 @@
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 from __future__ import absolute_import
 
 import base64
-from functools import wraps
 import hashlib
 import re
-from itertools import islice, chain
 import warnings
-
-from requests import Session as RequestSession, Response as RequestResponse
-from requests.adapters import HTTPAdapter
-from requests.structures import CaseInsensitiveDict
-from urllib3.exceptions import InsecureRequestWarning
+from functools import wraps
+from itertools import chain, islice
 
 from django.conf import settings
+from django.contrib.contenttypes.models import ContentType
 from django.core.cache import cache
 from django.core.exceptions import PermissionDenied
+from django.db import transaction
 from django.http import HttpResponse, HttpResponseBadRequest
-from django.template import Template, Context
+from django.template import Context, Template
 from django.utils.decorators import available_attrs
 from django.utils.encoding import force_bytes, force_text
 from django.utils.functional import lazy
 from django.utils.html import mark_safe
 from django.utils.six import BytesIO
 from django.views.generic.detail import SingleObjectMixin
-from django.contrib.contenttypes.models import ContentType
-from django.db import transaction
+from requests import Response as RequestResponse
+from requests import Session as RequestSession
+from requests.adapters import HTTPAdapter
+from requests.structures import CaseInsensitiveDict
+from urllib3.exceptions import InsecureRequestWarning
 
 from passerelle.base.signature import check_query, check_url
 
-
 mark_safe_lazy = lazy(mark_safe, str)
 
 
 def response_for_json(request, data):
     import json
 
     response = HttpResponse(content_type='application/json')
     json_str = json.dumps(data)
@@ -325,18 +324,17 @@ class Request(RequestSession):
         error_log = getattr(self.resource, 'log_requests_errors', True)
         log_http_request(
             self.logger, request=request, response=response, exception=exception, error_log=error_log
         )
 
 
 def export_site(slugs=None):
     '''Dump passerelle configuration (users, resources and ACLs) to JSON dumpable dictionnary'''
-    from passerelle.base.models import ApiUser
-    from passerelle.base.models import BaseResource
+    from passerelle.base.models import ApiUser, BaseResource
 
     d = {}
     d['apiusers'] = [apiuser.export_json() for apiuser in ApiUser.objects.all()]
     d['resources'] = resources = []
     for subclass in BaseResource.__subclasses__():
         if subclass._meta.abstract:
             continue
         for resource in subclass.objects.all():
@@ -348,18 +346,17 @@ def export_site(slugs=None):
                 break
     return d
 
 
 def import_site(d, if_empty=False, clean=False, overwrite=False, import_users=False):
     """Load passerelle configuration (users, resources and ACLs) from a dictionnary loaded from
     JSON
     """
-    from passerelle.base.models import ApiUser
-    from passerelle.base.models import BaseResource
+    from passerelle.base.models import ApiUser, BaseResource
 
     d = d.copy()
 
     def is_empty():
         if import_users:
             if ApiUser.objects.count():
                 return False
 
@@ -402,10 +399,10 @@ def batch(iterable, size):
         try:
             yield chain([next(batchiter)], batchiter)
         except StopIteration:
             return
 
 
 # legacy import, other modules keep importing to_json from passerelle.utils
 from .jsonresponse import to_json
+from .sftp import SFTP, SFTPField
 from .soap import SOAPClient, SOAPTransport
-from .sftp import SFTPField, SFTP
diff --git a/passerelle/utils/conversion.py b/passerelle/utils/conversion.py
index df2b5cd7..128e5845 100644
--- a/passerelle/utils/conversion.py
+++ b/passerelle/utils/conversion.py
@@ -15,21 +15,20 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import codecs
 import math
 import re
 import unicodedata
 import warnings
 
+import unidecode
 from django.utils import six
 from django.utils.encoding import force_str, force_text
 from django.utils.six import BytesIO
-
-import unidecode
 from PIL import Image
 
 
 def to_pdf(content):
     if content.startswith((b'%PDF', codecs.BOM + b'%PDF', codecs.BOM_UTF8 + b'%PDF')):
         return content
     try:
         with warnings.catch_warnings():
diff --git a/passerelle/utils/files.py b/passerelle/utils/files.py
index 8c634fbe..86e90dd8 100644
--- a/passerelle/utils/files.py
+++ b/passerelle/utils/files.py
@@ -8,20 +8,20 @@
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-import os.path
 import contextlib
-import tempfile
 import errno
+import os.path
+import tempfile
 
 from django.core.files.storage import default_storage
 
 
 @contextlib.contextmanager
 def atomic_write(filepath, **kwargs):
     """Return a file descriptor to a temporary file using NamedTemporaryFile
     which will be atomically renamed to filepath if possible.
diff --git a/passerelle/utils/http_authenticators.py b/passerelle/utils/http_authenticators.py
index 0c5b6cfd..a3313eac 100644
--- a/passerelle/utils/http_authenticators.py
+++ b/passerelle/utils/http_authenticators.py
@@ -13,17 +13,16 @@
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import base64
 import hashlib
 import hmac
 import time
-
 from uuid import uuid4
 
 from django.utils.encoding import force_bytes, force_text
 from django.utils.six.moves.urllib import parse as urlparse
 from requests.auth import AuthBase
 
 
 class HawkAuth(AuthBase):
diff --git a/passerelle/utils/json.py b/passerelle/utils/json.py
index 9ecb8f90..4d6572d1 100644
--- a/passerelle/utils/json.py
+++ b/passerelle/utils/json.py
@@ -30,17 +30,16 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 from __future__ import unicode_literals
 
 from django.utils import six
 
 from passerelle.utils.validation import is_number
 
-
 FLATTEN_SEPARATOR = '/'
 
 
 def unflatten(d, separator=FLATTEN_SEPARATOR):
     """Transform:
 
        {"a/b/0/x": "1234"}
 
diff --git a/passerelle/utils/jsonresponse.py b/passerelle/utils/jsonresponse.py
index eb986c6a..b8051772 100644
--- a/passerelle/utils/jsonresponse.py
+++ b/passerelle/utils/jsonresponse.py
@@ -1,35 +1,33 @@
 # This module is a modified copy of code of Yasha's Borevich library
 # django-jsonresponse (https://github.com/jjay/django-jsonresponse) distributed
 # under BSD license
 
 from __future__ import absolute_import
 
 import datetime
-import json
 import functools
+import json
 import logging
 import re
 import time
 
-from django.http import HttpResponse, Http404, HttpResponseBadRequest
-from django.http.response import HttpResponseBase
 from django.conf import settings
 from django.core.exceptions import ObjectDoesNotExist, PermissionDenied
 from django.core.serializers.json import DjangoJSONEncoder
-from django.utils.encoding import force_text
+from django.http import Http404, HttpResponse, HttpResponseBadRequest
+from django.http.response import HttpResponseBase
 from django.utils import six
-
-from requests import RequestException, HTTPError
+from django.utils.encoding import force_text
+from requests import HTTPError, RequestException
 
 from passerelle.utils import log_http_request
 from passerelle.utils.conversion import exception_to_text
 
-
 DEFAULT_DEBUG = getattr(settings, 'JSONRESPONSE_DEFAULT_DEBUG', False)
 CALLBACK_NAME = getattr(settings, 'JSONRESPONSE_CALLBACK_NAME', 'callback')
 
 
 class APIError(RuntimeError):
     '''Exception to raise when there is a remote application or business logic error.'''
 
     def __init__(self, *args, **kwargs):
diff --git a/passerelle/utils/paginator.py b/passerelle/utils/paginator.py
index 7062d24a..8e47c7d6 100644
--- a/passerelle/utils/paginator.py
+++ b/passerelle/utils/paginator.py
@@ -1,9 +1,9 @@
-from django.core.paginator import Paginator, Page, EmptyPage
+from django.core.paginator import EmptyPage, Page, Paginator
 from django.utils.functional import cached_property
 from django.utils.translation import ugettext_lazy as _
 
 
 class InfinitePaginator(Paginator):
     def page(self, number):
         number = self.validate_number(number)
         offset = (number - 1) * self.per_page
diff --git a/passerelle/utils/sftp.py b/passerelle/utils/sftp.py
index 82deb382..097d61a6 100644
--- a/passerelle/utils/sftp.py
+++ b/passerelle/utils/sftp.py
@@ -11,41 +11,39 @@
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 from __future__ import absolute_import
 
-import os
-import re
+import contextlib
 import io
 import json
-import contextlib
+import os
+import re
 
+import paramiko
 from django import forms
 from django.core import validators
 from django.db import models
 from django.utils import six
-from django.utils.encoding import force_text
-from django.utils.translation import ugettext_lazy as _
+from django.utils.encoding import force_bytes, force_text
 from django.utils.six.moves.urllib import parse as urlparse
-from django.utils.encoding import force_bytes
-
-import paramiko
+from django.utils.translation import ugettext_lazy as _
 from paramiko.dsskey import DSSKey
 from paramiko.ecdsakey import ECDSAKey
 
 try:
     from paramiko.ed25519key import Ed25519Key
 except ImportError:
     Ed25519Key = None
-from paramiko.rsakey import RSAKey
 from paramiko._version import __version_info__
+from paramiko.rsakey import RSAKey
 
 
 def _load_private_key(content_or_file, password=None):
     if not hasattr(content_or_file, 'read'):
         fd = io.TextIOWrapper(io.BytesIO(force_bytes(content_or_file)))
     else:
         fd = content_or_file
 
diff --git a/passerelle/utils/soap.py b/passerelle/utils/soap.py
index a228c901..9f9333a8 100644
--- a/passerelle/utils/soap.py
+++ b/passerelle/utils/soap.py
@@ -9,24 +9,22 @@
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+from django.utils.six.moves.urllib import parse as urlparse
 from requests import RequestException
-
 from zeep import Client
 from zeep.cache import InMemoryCache
 from zeep.transports import Transport
 
-from django.utils.six.moves.urllib import parse as urlparse
-
 from passerelle.utils.jsonresponse import APIError
 
 
 class SOAPError(APIError):
     pass
 
 
 class SOAPClient(Client):
diff --git a/passerelle/utils/templates.py b/passerelle/utils/templates.py
index fe44c109..8433a48e 100644
--- a/passerelle/utils/templates.py
+++ b/passerelle/utils/templates.py
@@ -15,19 +15,18 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 '''Simplify rendering of template to produce text values.
 
 Disable autoescaping.
 '''
 
 from django.core.exceptions import ValidationError
-
-from django.template.backends.django import DjangoTemplates
 from django.template import TemplateSyntaxError
+from django.template.backends.django import DjangoTemplates
 from django.utils.translation import ugettext as _
 
 
 def make_template(template_string):
     engine = DjangoTemplates(
         {
             'NAME': 'django',
             'DIRS': [],
diff --git a/passerelle/utils/wcs.py b/passerelle/utils/wcs.py
index 203a14fb..aa6e1d96 100644
--- a/passerelle/utils/wcs.py
+++ b/passerelle/utils/wcs.py
@@ -11,33 +11,32 @@
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 from __future__ import absolute_import
 
-import collections
 import base64
+import collections
+import contextlib
 import copy
-import logging
 import datetime
-import contextlib
 import json
+import logging
 
-import requests
 import isodate
-
+import requests
+from django import forms
 from django.conf import settings
-from django.db import models
 from django.core.cache import cache
-from django import forms
-from django.utils.six.moves.urllib import parse as urlparse
+from django.db import models
 from django.utils import six
+from django.utils.six.moves.urllib import parse as urlparse
 
 from passerelle.base import signature
 
 
 class WcsApiError(Exception):
     pass
 
 
diff --git a/passerelle/utils/xml.py b/passerelle/utils/xml.py
index 6a6618b6..58e53dc5 100644
--- a/passerelle/utils/xml.py
+++ b/passerelle/utils/xml.py
@@ -9,18 +9,18 @@
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-from collections import OrderedDict
 import copy
+from collections import OrderedDict
 
 import jsonschema
 import xmlschema
 
 
 def text_content(node):
     """Extract text content from node and all its children. Equivalent to
     xmlNodeGetContent from libxml."""
diff --git a/passerelle/utils/zip.py b/passerelle/utils/zip.py
index b05b1ee6..501c9b33 100644
--- a/passerelle/utils/zip.py
+++ b/passerelle/utils/zip.py
@@ -9,37 +9,35 @@
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-from __future__ import unicode_literals, absolute_import
+from __future__ import absolute_import, unicode_literals
 
 import difflib
 import io
-import os.path
 import json
+import os.path
 import re
 import xml.etree.ElementTree as ET
 import zipfile
 
-from jsonschema import validate, ValidationError
-
-from django.template import Template, Context, TemplateDoesNotExist, TemplateSyntaxError, engines
-from django.utils.functional import cached_property
+from django.template import Context, Template, TemplateDoesNotExist, TemplateSyntaxError, engines
+from django.template.loader import get_template
 from django.utils.encoding import force_str
+from django.utils.functional import cached_property
 from django.utils.six import python_2_unicode_compatible
-from django.template.loader import get_template
+from jsonschema import ValidationError, validate
 
 from passerelle.utils.files import atomic_write
 
-
 SCHEMA = {
     'type': 'object',
     'required': ['name_template'],
     'properties': {
         'name_template': {
             'type': 'string',
         },
         'part_templates': {
diff --git a/passerelle/views.py b/passerelle/views.py
index a50b8b5e..1df311cf 100644
--- a/passerelle/views.py
+++ b/passerelle/views.py
@@ -16,57 +16,56 @@
 
 import datetime
 import hashlib
 import inspect
 import json
 import logging
 import uuid
 
+from dateutil import parser as date_parser
 from django.apps import apps
+from django.conf import settings
 from django.conf.urls import url
-from django.core.cache import cache
-from django.core.exceptions import PermissionDenied
 from django.contrib.auth import logout as auth_logout
 from django.contrib.auth import views as auth_views
+from django.core.cache import cache
+from django.core.exceptions import PermissionDenied
 from django.db import transaction
 from django.db.models import Q
-from django.http import HttpResponse, HttpResponseRedirect, Http404
+from django.http import Http404, HttpResponse, HttpResponseRedirect
+from django.shortcuts import resolve_url
+from django.urls import reverse
+from django.utils.encoding import force_bytes, force_text
+from django.utils.six.moves.urllib.parse import quote
+from django.utils.timezone import make_aware
+from django.utils.translation import ugettext_lazy as _
 from django.views.decorators.csrf import csrf_exempt
 from django.views.generic import (
-    RedirectView,
-    View,
-    TemplateView,
     CreateView,
     DeleteView,
-    UpdateView,
     DetailView,
     ListView,
+    RedirectView,
+    TemplateView,
+    UpdateView,
+    View,
 )
 from django.views.generic.detail import SingleObjectMixin
-from django.conf import settings
-from django.shortcuts import resolve_url
-from django.urls import reverse
-from django.utils.timezone import make_aware
-from django.utils.translation import ugettext_lazy as _
-from django.utils.encoding import force_bytes, force_text
-from django.utils.six.moves.urllib.parse import quote
-
-from dateutil import parser as date_parser
-from jsonschema import validate, ValidationError
+from jsonschema import ValidationError, validate
 
 from passerelle.base.models import BaseResource, ResourceLog
 from passerelle.compat import json_loads
 from passerelle.utils.conversion import normalize
-from passerelle.utils.jsonresponse import APIError
 from passerelle.utils.json import unflatten
+from passerelle.utils.jsonresponse import APIError
 from passerelle.utils.paginator import InfinitePaginator
 
-from .utils import to_json, is_authorized
 from .forms import ResourceLogSearchForm
+from .utils import is_authorized, to_json
 
 if 'mellon' in settings.INSTALLED_APPS:
     from mellon.utils import get_idps
 else:
 
     def get_idps():
         return []
 
diff --git a/setup.py b/setup.py
index d7a20f73..a31a433f 100755
--- a/setup.py
+++ b/setup.py
@@ -1,19 +1,19 @@
 #!/usr/bin/python
 
 import os
 import subprocess
 import sys
+from distutils.cmd import Command
+from distutils.command.build import build as _build
 
+from setuptools import find_packages, setup
 from setuptools.command.install_lib import install_lib as _install_lib
 from setuptools.command.sdist import sdist
-from distutils.command.build import build as _build
-from distutils.cmd import Command
-from setuptools import setup, find_packages
 
 
 class eo_sdist(sdist):
     def run(self):
         if os.path.exists('VERSION'):
             os.remove('VERSION')
         version = get_version()
         version_file = open('VERSION', 'w')
diff --git a/tests/conftest.py b/tests/conftest.py
index 5b318956..fbe08831 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -1,19 +1,17 @@
-import pytest
-from httmock import urlmatch, HTTMock, response, remember_called
+from io import BytesIO
 
 import django_webtest
-
+import pytest
 from django.contrib.auth.models import User
-from django.core.files import File
 from django.core.cache import cache
+from django.core.files import File
 from django.utils import six
-from io import BytesIO
-
+from httmock import HTTMock, remember_called, response, urlmatch
 from utils import make_resource
 
 if six.PY2:
     collect_ignore = ['wcs/']
 
 
 @pytest.fixture(autouse=True)
 def media(settings, tmpdir):
@@ -106,16 +104,17 @@ def mock_api_adresse_data_gouv_fr_search():
 def mock_api_adresse_data_gouv_fr_reverse():
     with HTTMock(api_adresse_data_gouv_fr_reverse):
         yield None
 
 
 @pytest.fixture
 def endpoint_dummy_cache(monkeypatch):
     from django.core.cache import caches
+
     import passerelle.views
 
     monkeypatch.setattr(passerelle.views, 'cache', caches['dummy'])
 
 
 @urlmatch()
 def internal_server_error(url, request):
     return response(500, 'Internal server error')
diff --git a/tests/test_actesweb.py b/tests/test_actesweb.py
index 190db168..3c03e186 100644
--- a/tests/test_actesweb.py
+++ b/tests/test_actesweb.py
@@ -11,27 +11,26 @@
 # but WITHOUT ANY WARRANTY; exclude even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a.deepcopy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 from __future__ import unicode_literals
 
-import json
 import io
+import json
 import os
 import shutil
 import stat
 
 import pytest
-
+import utils
 from django.utils import six
 
-import utils
 from passerelle.apps.actesweb.models import ActesWeb
 
 
 def get_test_base_dir(name):
     return os.path.join(os.path.dirname(__file__), 'data', name)
 
 
 def get_file_from_test_base_dir(filename):
diff --git a/tests/test_adict.py b/tests/test_adict.py
index 94a5ff8f..2c2da5ca 100644
--- a/tests/test_adict.py
+++ b/tests/test_adict.py
@@ -1,16 +1,16 @@
 import json
+
 import mock
 import pytest
+import utils
 
 from passerelle.contrib.adict.models import Adict
 
-import utils
-
 FAKE_FEATURE_INFO = json.dumps(
     {
         'type': 'FeatureCollection',
         'features': [
             {
                 'type': 'Feature',
                 'properties': {
                     'id': 51,
diff --git a/tests/test_airquality.py b/tests/test_airquality.py
index 12f04d93..22634562 100644
--- a/tests/test_airquality.py
+++ b/tests/test_airquality.py
@@ -1,14 +1,13 @@
 # -*- coding: utf-8 -*-
 
+import freezegun
 import pytest
 import utils
-
-import freezegun
 from httmock import HTTMock, response
 
 from passerelle.apps.airquality.models import AirQuality
 
 SAMPLE_RESPONSE = {
     "licence": "https://opendatacommons.org/licenses/odbl/",
     "commune": "LYON-1ER-ARRONDISSEMENT",
     "code_insee": "69381",
diff --git a/tests/test_api.py b/tests/test_api.py
index 90713dcb..51bf84cb 100644
--- a/tests/test_api.py
+++ b/tests/test_api.py
@@ -11,25 +11,23 @@
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import mock
 import pytest
-
-from django.urls import reverse
 from django.contrib.contenttypes.models import ContentType
 from django.test import override_settings
+from django.urls import reverse
+from test_manager import login
 
 from passerelle.apps.ovh.models import OVHSMSGateway
-from passerelle.base.models import ApiUser, AccessRight, Job
-
-from test_manager import login
+from passerelle.base.models import AccessRight, ApiUser, Job
 
 pytestmark = pytest.mark.django_db
 
 API_KEY = '1234'
 
 
 @pytest.fixture
 def connector(db):
diff --git a/tests/test_api_access.py b/tests/test_api_access.py
index 67ee07f0..d700492c 100644
--- a/tests/test_api_access.py
+++ b/tests/test_api_access.py
@@ -1,23 +1,21 @@
 import re
 import sys
 
-from django.contrib.auth.models import User
-from django.contrib.contenttypes.models import ContentType
-from django.urls import reverse
-
 import pytest
 import utils
-
+from django.contrib.auth.models import User
+from django.contrib.contenttypes.models import ContentType
 from django.test import override_settings
+from django.urls import reverse
 
-from passerelle.base import signature
-from passerelle.base.models import ApiUser, AccessRight, ResourceLog
 from passerelle.apps.oxyd.models import OxydSMSGateway
+from passerelle.base import signature
+from passerelle.base.models import AccessRight, ApiUser, ResourceLog
 
 pytestmark = pytest.mark.django_db
 
 
 @pytest.fixture
 def oxyd(db):
     return OxydSMSGateway.objects.create(
         title='eservices', slug='eservices', username='user', description='oxyd', password='secret'
diff --git a/tests/test_api_entreprise.py b/tests/test_api_entreprise.py
index 7d3055d2..236c95cc 100644
--- a/tests/test_api_entreprise.py
+++ b/tests/test_api_entreprise.py
@@ -11,28 +11,25 @@
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-import pytest
 import mock
+import pytest
 import requests
-
-from httmock import urlmatch, HTTMock, response
-
 from django.utils import timezone
+from httmock import HTTMock, response, urlmatch
+from utils import FakedResponse, make_resource
 
 from passerelle.apps.api_entreprise.models import APIEntreprise
 
-from utils import make_resource, FakedResponse
-
 ETABLISSEMENTS_RESPONSE = {
     "etablissement": {
         "siege_social": True,
         "siret": "41816609600051",
         "naf": "6202A",
         "libelle_naf": "Conseil en systèmes et logiciels informatiques",
         "date_mise_a_jour": 1449183600,
         "tranche_effectif_salarie_etablissement": {
diff --git a/tests/test_api_particulier.py b/tests/test_api_particulier.py
index e08e0bb7..c2944db8 100644
--- a/tests/test_api_particulier.py
+++ b/tests/test_api_particulier.py
@@ -12,31 +12,27 @@
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import logging
-import pytest
-from httmock import urlmatch, HTTMock, response
-
-from django.urls import reverse
 
+import pytest
 import requests
+from django.urls import reverse
+from httmock import HTTMock, response, urlmatch
+from test_manager import login
+from utils import endpoint_get, make_resource
 
 from passerelle.apps.api_particulier.models import APIParticulier
 from passerelle.base.models import ResourceLog
 
-from utils import make_resource, endpoint_get
-
-from test_manager import login
-
-
 SVAIR_RESPONSE = {
     "declarant1": {
         "nom": "Martin",
         "nomNaissance": "Martin",
         "prenoms": "Pierre",
         "dateNaissance": "22/03/1985",
     },
     "declarant2": {
diff --git a/tests/test_arcgis.py b/tests/test_arcgis.py
index 4a14b3a3..8dfc3121 100644
--- a/tests/test_arcgis.py
+++ b/tests/test_arcgis.py
@@ -1,26 +1,25 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
 
 import json
-import pytest
+
 import mock
+import pytest
 import utils
-
 from django.contrib.auth.models import User
 from django.contrib.contenttypes.models import ContentType
 from django.core.exceptions import ValidationError
+from test_manager import login
 
-from passerelle.apps.arcgis.models import ArcGIS, validate_where, SqlFormatter, Query
-from passerelle.base.models import ApiUser, AccessRight
+from passerelle.apps.arcgis.models import ArcGIS, Query, SqlFormatter, validate_where
+from passerelle.base.models import AccessRight, ApiUser
 from passerelle.utils import import_site
 
-from test_manager import login
-
 pytestmark = pytest.mark.django_db
 
 # from http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/fold/serv/MapServer/1
 STATES = '''{
    "fieldAliases" : {
       "OBJECTID" : "OBJECTID",
       "STATE_NAME" : "STATE_NAME",
       "STATE_ABBR" : "STATE_ABBR"
diff --git a/tests/test_arcgis_nancy.py b/tests/test_arcgis_nancy.py
index ac9d0d33..d84d55d4 100644
--- a/tests/test_arcgis_nancy.py
+++ b/tests/test_arcgis_nancy.py
@@ -1,21 +1,18 @@
 import os
 
-import pytest
 import mock
-
-
-from django.urls import reverse
+import pytest
 from django.contrib.contenttypes.models import ContentType
+from django.urls import reverse
 
 from passerelle.apps.arcgis.models import ArcGIS
+from passerelle.base.models import AccessRight, ApiUser
 from passerelle.compat import json_loads
-from passerelle.base.models import ApiUser, AccessRight
-
 
 TEST_BASE_DIR = os.path.join(os.path.dirname(__file__), 'data', 'nancy_arcgis')
 
 
 def get_file_content(filename):
     with open(os.path.join(TEST_BASE_DIR, filename), 'rb') as fd:
         return fd.read()
 
diff --git a/tests/test_arpege_ecp.py b/tests/test_arpege_ecp.py
index 7079ba2c..500184d8 100644
--- a/tests/test_arpege_ecp.py
+++ b/tests/test_arpege_ecp.py
@@ -1,21 +1,20 @@
 # -*- coding: utf-8 -*-
 
 import json
+
 import mock
 import pytest
-
+import utils
 from django.urls import reverse
 
 from passerelle.apps.arpege_ecp.models import ArpegeECP
 from passerelle.utils.jsonresponse import APIError
 
-import utils
-
 FAKE_HELLO_RESPONSE = """{"IsSuccess":true,"CodErreur":null,"LibErreur":null,
 "Data":"InteropAPI v1 (c) Arpège 2017"}"""
 
 FAKE_LOGIN_OIDC_RESPONSE = """{
   "IsSuccess": true,
   "CodErreur": null,
   "LibErreur": null,
   "Data": {
diff --git a/tests/test_astregs.py b/tests/test_astregs.py
index e6424b10..bb923c6a 100644
--- a/tests/test_astregs.py
+++ b/tests/test_astregs.py
@@ -1,26 +1,24 @@
 # -*- coding: utf-8 -*-
 
-import os
 import logging
-import mock
-import pytest
+import os
 import re
 
-from requests.exceptions import ConnectionError
-from requests import Request
-
+import mock
+import pytest
+import utils
 from django.utils.encoding import force_bytes, force_str, force_text
 from django.utils.http import urlencode
+from requests import Request
+from requests.exceptions import ConnectionError
 
 from passerelle.apps.astregs.models import AstreGS, Link
 
-import utils
-
 BASE_URL = 'https://test-ws-astre-gs.departement06.fr/axis2/services/'
 
 
 def get_xml_file(filename):
     filepath = os.path.join(os.path.dirname(__file__), 'data', 'astregs', filename)
     with open(filepath, 'rb') as f:
         return f.read()
 
diff --git a/tests/test_atal.py b/tests/test_atal.py
index 03c93456..1f142d70 100644
--- a/tests/test_atal.py
+++ b/tests/test_atal.py
@@ -1,21 +1,21 @@
 # coding: utf-8
 
 import base64
-from datetime import datetime
 import os
+from datetime import datetime
 
-from django.contrib.contenttypes.models import ContentType
-from django.utils.http import urlencode
 import mock
 import pytest
+from django.contrib.contenttypes.models import ContentType
+from django.utils.http import urlencode
 
 from passerelle.apps.atal.models import ATALConnector
-from passerelle.base.models import ApiUser, AccessRight
+from passerelle.base.models import AccessRight, ApiUser
 
 
 def get_file(filename):
     with open(os.path.join(os.path.dirname(__file__), 'data', 'atal', filename), 'rb') as f:
         return f.read()
 
 
 @pytest.fixture()
diff --git a/tests/test_atos_genesys.py b/tests/test_atos_genesys.py
index 592ca1f1..d48533cc 100644
--- a/tests/test_atos_genesys.py
+++ b/tests/test_atos_genesys.py
@@ -1,18 +1,17 @@
 # -*- coding: utf-8 -*-
 
 import os
-import pytest
 
+import pytest
 import utils
-
 from django.utils.http import urlencode
 
-from passerelle.apps.atos_genesys.models import Resource, Link
+from passerelle.apps.atos_genesys.models import Link, Resource
 
 FAKE_URL = 'https://sirus.fr/'
 
 
 @pytest.fixture
 def genesys(db):
     return utils.make_resource(
         Resource, title='Test 1', slug='test1', description='Connecteur de test', webservice_base_url=FAKE_URL
@@ -216,16 +215,17 @@ def test_ws_dossiers(app, genesys):
         assert response.json['data']['id_per'] == '4567'
         assert response.json['data']['dossier']
         assert response.json['data']['id'] == str(link2.id)
         assert response.json['data']['text'] == u'%s - John DOE' % link2.id_per
 
 
 def test_row_locked_cache(genesys, freezer):
     import time
+
     from passerelle.apps.atos_genesys.utils import RowLockedCache
 
     freezer.move_to('2018-01-01 00:00:00')
     link = Link.objects.create(resource=genesys, name_id='zob', id_per='4567')
 
     class F(object):
         calls = 0
         value = 1
diff --git a/tests/test_availability.py b/tests/test_availability.py
index e7a5a7a2..2cf8b2c3 100644
--- a/tests/test_availability.py
+++ b/tests/test_availability.py
@@ -1,17 +1,16 @@
 # -*- coding: utf-8 -*-
 
 import pytest
-from httmock import all_requests, HTTMock
+import utils
+from httmock import HTTMock, all_requests
 
 from passerelle.apps.feeds.models import Feed
 
-import utils
-
 FEED_EXAMPLE = u"""<?xml version="1.0" encoding="UTF-8"?>
 <feed xmlns="http://www.w3.org/2005/Atom" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/">
   <title>Actualités de Strasbourg</title>
   <link rel="alternate" href="http://www.strasbourg.eu/fr/actualites/-/asset_publisher/lG7u/rss" />
   <subtitle>Actualités de Strasbourg</subtitle>
   <entry>
     <title>30 juin - 1er juillet : conditions de circulation et de stationnement</title>
     <link rel="alternate" href="http://www.strasbourg.eu/fr/actualites/-/asset_publisher/lG7u/content/id/5722879" />
diff --git a/tests/test_base_adresse.py b/tests/test_base_adresse.py
index 62bcdb53..334e64d6 100644
--- a/tests/test_base_adresse.py
+++ b/tests/test_base_adresse.py
@@ -1,30 +1,29 @@
 # -*- coding: utf-8 -*-
 
 import datetime
+import json
 import os
-import pytest
+
 import mock
+import pytest
 import utils
-import json
-
-from requests.exceptions import ConnectionError, HTTPError
-
 from django.core.management import call_command
 from django.core.management.base import CommandError
 from django.utils.six.moves.urllib.parse import urljoin
+from requests.exceptions import ConnectionError, HTTPError
 
 from passerelle.apps.base_adresse.models import (
+    AddressCacheModel,
     BaseAdresse,
-    StreetModel,
     CityModel,
     DepartmentModel,
     RegionModel,
-    AddressCacheModel,
+    StreetModel,
 )
 
 FAKED_CONTENT = json.dumps(
     {
         "limit": 1,
         "attribution": "BAN",
         "version": "draft",
         "licence": "ODbL 1.0",
diff --git a/tests/test_cartads_cs.py b/tests/test_cartads_cs.py
index 59182911..7ad87f5b 100644
--- a/tests/test_cartads_cs.py
+++ b/tests/test_cartads_cs.py
@@ -1,27 +1,25 @@
 # -*- coding: utf-8 -*-
 
-from collections import OrderedDict
 import datetime
 import json
 import os
+from collections import OrderedDict
 
 import mock
-from httmock import HTTMock
 import pytest
-
+import utils
 from django.core.files.storage import default_storage
 from django.test import override_settings
+from httmock import HTTMock
 
-from passerelle.apps.cartads_cs.models import CartaDSCS, CartaDSFile, CartaDSDossier
-from passerelle.compat import json_loads
+from passerelle.apps.cartads_cs.models import CartaDSCS, CartaDSDossier, CartaDSFile
 from passerelle.base.models import Job
-
-import utils
+from passerelle.compat import json_loads
 
 
 @pytest.fixture
 def connector(db):
     return utils.make_resource(
         CartaDSCS,
         title='Test',
         slug='test',
diff --git a/tests/test_cityweb.py b/tests/test_cityweb.py
index 5b131124..2d5f234d 100644
--- a/tests/test_cityweb.py
+++ b/tests/test_cityweb.py
@@ -11,34 +11,33 @@
 # but WITHOUT ANY WARRANTY; exclude even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a.deepcopy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 from __future__ import unicode_literals
 
-import os
 import json
+import os
 import shutil
 import stat
-
-import pytest
-import mock
-from lxml import etree, objectify as xobject
 import zipfile
 
+import mock
+import pytest
 import utils
+from django.core.files.storage import default_storage
+from lxml import etree
+from lxml import objectify as xobject
 
-from passerelle.apps.cityweb.models import CityWeb
 from passerelle.apps.cityweb.cityweb import DateType
+from passerelle.apps.cityweb.models import CityWeb
 from passerelle.utils.jsonresponse import APIError
 
-from django.core.files.storage import default_storage
-
 
 def get_test_base_dir(name):
     return os.path.join(os.path.dirname(__file__), 'data', name)
 
 
 def get_file_from_test_base_dir(filename):
     path = os.path.join(get_test_base_dir('cityweb'), filename)
     with open(path, 'r') as fd:
diff --git a/tests/test_clicrdv.py b/tests/test_clicrdv.py
index 51bb111b..bee821be 100644
--- a/tests/test_clicrdv.py
+++ b/tests/test_clicrdv.py
@@ -1,20 +1,17 @@
 import mock
 import pytest
-
-from requests.exceptions import HTTPError
-
 from django.contrib.contenttypes.models import ContentType
 from django.utils.six.moves.urllib import parse as urlparse
+from requests.exceptions import HTTPError
+from test_manager import login
 
-from passerelle.base.models import ApiUser, AccessRight
 from passerelle.apps.clicrdv.models import ClicRdv
-
-from test_manager import login
+from passerelle.base.models import AccessRight, ApiUser
 
 
 @pytest.fixture
 def connector(db):
     return ClicRdv.objects.create(
         slug='test', group_id='5242', apikey='test', username='test', password='test'
     )
 
diff --git a/tests/test_cmis.py b/tests/test_cmis.py
index 8fbbe427..d9c575a9 100644
--- a/tests/test_cmis.py
+++ b/tests/test_cmis.py
@@ -1,33 +1,34 @@
 import base64
-import httplib2
-import xml.etree.ElementTree as ET
-import mock
 import os
 import re
+import xml.etree.ElementTree as ET
 
+import httplib2
+import mock
+import py
+import pytest
 from cmislib import CmisClient
-from cmislib.exceptions import CmisException
-from cmislib.exceptions import ObjectNotFoundException
-from cmislib.exceptions import PermissionDeniedException
-from cmislib.exceptions import UpdateConflictException
-from cmislib.exceptions import InvalidArgumentException
+from cmislib.exceptions import (
+    CmisException,
+    InvalidArgumentException,
+    ObjectNotFoundException,
+    PermissionDeniedException,
+    UpdateConflictException,
+)
 from django.contrib.contenttypes.models import ContentType
 from django.urls import reverse
 from django.utils.encoding import force_bytes, force_text
 from django.utils.six.moves.urllib import error as urllib2
-from mock import call, Mock
-import py
-import pytest
+from mock import Mock, call
+from test_manager import login
 
-from passerelle.base.models import ApiUser, AccessRight
 from passerelle.apps.cmis.models import CmisConnector
-
-from test_manager import login
+from passerelle.base.models import AccessRight, ApiUser
 
 
 def b64encode(content):
     return force_text(base64.b64encode(force_bytes(content)))
 
 
 @pytest.fixture()
 def setup(db):
@@ -412,18 +413,18 @@ def test_create_doc():
         (urllib2.URLError, "connection error"),
         (PermissionDeniedException, "permission denied"),
         (UpdateConflictException, "update conflict"),
         (InvalidArgumentException, "invalid property"),
         (CmisException, "cmis binding error"),
     ],
 )
 def test_wrap_cmis_error(app, setup, monkeypatch, cmis_exc, err_msg):
-    from passerelle.utils.jsonresponse import APIError
     from passerelle.apps.cmis.models import wrap_cmis_error
+    from passerelle.utils.jsonresponse import APIError
 
     @wrap_cmis_error
     def dummy_func():
         raise cmis_exc("some error")
 
     with pytest.raises(APIError) as excinfo:
         dummy_func()
     assert str(excinfo.value).startswith(err_msg)
diff --git a/tests/test_cron.py b/tests/test_cron.py
index 53989677..5c9af22b 100644
--- a/tests/test_cron.py
+++ b/tests/test_cron.py
@@ -1,11 +1,10 @@
 import mock
 import pytest
-
 from django.core.management import call_command
 from django.core.management.base import CommandError
 
 from passerelle.apps.base_adresse.models import BaseAdresse
 
 
 def test_cron_frequencies(db):
     for frequency in ('hourly', 'daily', 'weekly', 'monthly'):
diff --git a/tests/test_cryptor.py b/tests/test_cryptor.py
index aa1ef162..65606fbf 100644
--- a/tests/test_cryptor.py
+++ b/tests/test_cryptor.py
@@ -1,21 +1,20 @@
 # -*- coding: utf-8 -*-
 
 import base64
-import pytest
 
+import pytest
+import utils
 from django.contrib.contenttypes.models import ContentType
 from django.core.exceptions import ValidationError
 from django.utils.encoding import force_text
 
-from passerelle.apps.cryptor.models import Cryptor, CryptedFile
-from passerelle.base.models import ApiUser, AccessRight
-
-import utils
+from passerelle.apps.cryptor.models import CryptedFile, Cryptor
+from passerelle.base.models import AccessRight, ApiUser
 
 PUBLIC_KEY = '''-----BEGIN CERTIFICATE-----
 MIICyjCCAbKgAwIBAgIUQQzM2eFYF+LpUR3t2euAjZAwLCEwDQYJKoZIhvcNAQEL
 BQAwDzENMAsGA1UEAwwEemVwbzAeFw0xOTA2MjIyMjMxMTVaFw0yOTA2MTkyMjMx
 MTVaMA8xDTALBgNVBAMMBHplcG8wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
 AoIBAQC8BM3xDylze0bOm76IjidyhmFqJlnRvcpbeZVTM7r3qYOHqXFG7/GZL4yd
 2bW5eL6TCUT3gLEgegGYGPwCkGPd1cq9h+2M7zvolGToRCvrBpxH5Vu6iRkEYyWN
 yPhc02EUqYlz1FBBYRgyYHQ4jy0vsPH55g536OKLI4rVykszjwD9p0Kh+T2I1D9Z
diff --git a/tests/test_csv_datasource.py b/tests/test_csv_datasource.py
index 4132d269..580644d7 100644
--- a/tests/test_csv_datasource.py
+++ b/tests/test_csv_datasource.py
@@ -14,40 +14,38 @@
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import datetime
 import os
 import time
-import pytest
-import mock
-import six
 import uuid
 from posix import stat_result
 from stat import ST_MTIME
 
-from django.core.files import File
-from django.urls import reverse
+import mock
+import pytest
+import six
+import webtest
 from django.contrib.contenttypes.models import ContentType
-from django.test import Client, override_settings
+from django.core.files import File
 from django.core.management import call_command
+from django.test import Client, override_settings
+from django.urls import reverse
 from django.utils.encoding import force_bytes, force_str, force_text
 from django.utils.six import StringIO
 from django.utils.six.moves.urllib.parse import urlencode
 from django.utils.timezone import now
-
-from passerelle.base.models import ApiUser, AccessRight
-from passerelle.compat import json_loads
-from passerelle.apps.csvdatasource.models import CsvDataSource, Query, TableRow
-
 from test_manager import login
 
-import webtest
+from passerelle.apps.csvdatasource.models import CsvDataSource, Query, TableRow
+from passerelle.base.models import AccessRight, ApiUser
+from passerelle.compat import json_loads
 
 data = """121;69981;DELANOUE;Eliot;H
 525;6;DANIEL WILLIAMS;Shanone;F
 253;67742;MARTIN;Sandra;F
 511;38142;MARCHETTI;Lucie;F
 235;22;MARTIN;Sandra;F
 620;52156;ARNAUD;Mathis;H
 902;36;BRIGAND;Coline;F
diff --git a/tests/test_dpark.py b/tests/test_dpark.py
index b4044f2c..c5ff7780 100644
--- a/tests/test_dpark.py
+++ b/tests/test_dpark.py
@@ -1,26 +1,24 @@
 # -*- coding: utf-8 -*-
 import base64
-import mock
 import os
-import pytest
 import xml.etree.ElementTree as ET
 
-from django.utils.encoding import force_text
 import httmock
-
-from zeep.exceptions import TransportError, Fault as WebFault
-
+import mock
+import pytest
+from django.utils.encoding import force_text
 from utils import make_resource
+from zeep.exceptions import Fault as WebFault
+from zeep.exceptions import TransportError
 
 from passerelle.contrib.dpark.models import DPark, Pairing
 from passerelle.utils.jsonresponse import APIError
 
-
 SLUG = 'test'
 WSDL_URL = 'https://example.net/dpark?wsdl'
 OPERATIONAL_URL = 'https://example.net/dpark'
 
 with open(os.path.join(os.path.dirname(__file__), 'data/dpark.awws.wsdl')) as f:
     WSDL_CONTENT = f.read()
 
 with open(os.path.join(os.path.dirname(__file__), 'data/small.jpg'), 'rb') as f:
diff --git a/tests/test_ensure_jsonbfields.py b/tests/test_ensure_jsonbfields.py
index 02b768e7..77de6d41 100644
--- a/tests/test_ensure_jsonbfields.py
+++ b/tests/test_ensure_jsonbfields.py
@@ -1,12 +1,11 @@
 # -*- coding: utf-8 -*-
 
 import pytest
-
 from django.core.files import File
 from django.core.management import call_command
 from django.db import connection
 from django.utils.six import BytesIO
 
 from passerelle.apps.csvdatasource.models import CsvDataSource
 from passerelle.contrib.teamnet_axel.models import TeamnetAxel
 
diff --git a/tests/test_esirius.py b/tests/test_esirius.py
index c76a55da..6c8e3bf9 100644
--- a/tests/test_esirius.py
+++ b/tests/test_esirius.py
@@ -10,26 +10,25 @@
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import json
+
 import httmock
 import pytest
+import utils
+from test_manager import login
 
 from passerelle.apps.esirius.models import ESirius
 from passerelle.utils.jsonresponse import APIError
 
-from test_manager import login
-import utils
-
-
 CREATE_APPOINTMENT_PAYLOAD = {
     'beginDate': '2021-02-24',
     'beginTime': '16:40',
     'endDate': '2021-02-24',
     'endTime': '17:00',
     'comment': 'commentaire',
     'isoLanguage': 'fr',
     'needsConfirmation': 'False',
diff --git a/tests/test_fake_family.py b/tests/test_fake_family.py
index 61a6ac28..adc344c0 100644
--- a/tests/test_fake_family.py
+++ b/tests/test_fake_family.py
@@ -1,15 +1,15 @@
 # -*- coding: utf-8 -*-
 
 import json
 
+import pytest
 from django.urls import reverse
 
-import pytest
 from passerelle.contrib.fake_family.models import FakeFamily
 
 pytestmark = pytest.mark.django_db
 
 
 def test_init_fake_family():
     fake = FakeFamily.objects.create()
     jsondb = fake.jsondatabase
diff --git a/tests/test_family.py b/tests/test_family.py
index b5085248..122fe403 100644
--- a/tests/test_family.py
+++ b/tests/test_family.py
@@ -1,35 +1,37 @@
 # -*- coding: utf-8 -*-
 
-import pytest
-import os
-from uuid import uuid4
-import zipfile
 import logging
+import os
 import shutil
+import zipfile
+from uuid import uuid4
 
+import pytest
+from django.contrib.contenttypes.models import ContentType
 from django.core.exceptions import ValidationError
 from django.core.files import File
+from django.core.files.storage import default_storage
+from django.core.management import call_command
+from django.core.management.base import CommandError
 from django.urls import reverse
 from django.utils import timezone
 from django.utils.http import urlencode
-from django.core.files import File
-from django.core.management import call_command
-from django.core.management.base import CommandError
-from django.core.files.storage import default_storage
-
-from passerelle.apps.family.models import GenericFamily, Family, FamilyLink
-from passerelle.apps.family.models import Invoice, Adult, Child, DATETIME_FORMAT
-
-from django.core.files import File
-from django.contrib.contenttypes.models import ContentType
-
-from passerelle.base.models import ApiUser, AccessRight
 
+from passerelle.apps.family.models import (
+    DATETIME_FORMAT,
+    Adult,
+    Child,
+    Family,
+    FamilyLink,
+    GenericFamily,
+    Invoice,
+)
+from passerelle.base.models import AccessRight, ApiUser
 
 pytestmark = pytest.mark.django_db
 
 nameid = 'foobarnameid'
 API_KEY = 'family'
 
 
 @pytest.fixture
diff --git a/tests/test_feeds.py b/tests/test_feeds.py
index 9a42b199..7b3d53c3 100644
--- a/tests/test_feeds.py
+++ b/tests/test_feeds.py
@@ -1,17 +1,16 @@
 # -*- coding: utf-8 -*-
 
 import mock
 import pytest
+import utils
 
 from passerelle.apps.feeds.models import Feed
 
-import utils
-
 FEED_EXAMPLE = u"""<?xml version="1.0" encoding="UTF-8"?>
 <feed xmlns="http://www.w3.org/2005/Atom" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/">
   <title>Actualités de Strasbourg</title>
   <link rel="alternate" href="http://www.strasbourg.eu/fr/actualites/-/asset_publisher/lG7u/rss" />
   <subtitle>Actualités de Strasbourg</subtitle>
   <entry>
     <title>30 juin - 1er juillet : conditions de circulation et de stationnement</title>
     <link rel="alternate" href="http://www.strasbourg.eu/fr/actualites/-/asset_publisher/lG7u/content/id/5722879" />
diff --git a/tests/test_gdema.py b/tests/test_gdema.py
index 53044ff1..103f911d 100644
--- a/tests/test_gdema.py
+++ b/tests/test_gdema.py
@@ -1,19 +1,18 @@
 # -*- coding: utf-8 -*-
 import json
-import pytest
+
 import mock
+import pytest
 import utils
-
 from django.contrib.contenttypes.models import ContentType
 
+from passerelle.base.models import AccessRight, ApiUser
 from passerelle.contrib.gdema.models import Gdema
-from passerelle.base.models import ApiUser, AccessRight
-
 
 SERVICES = '[{"AdminService":"ADMINISTRATEUR DIV - Transports et D\xc3\xa9placements","CommuneService":null,"Id":"16151","Label":"DMT - Mobilité et transports","Typology":[]},{"AdminService":"ADMINISTRATEUR DEP ADMINISTRATION","CommuneService":null,"Id":"10173","Label":"DESPU - Administration Direction environnement et services publics urbains","Typology":[{"Text":"Maintenance Cie","Value":"13067"},{"Text":"Sensibilisation en milieu scolaire","Value":"14948"},{"Text":"Demandes diverses","Value":"11532"},{"Text":"Demande de stage compostage","Value":"12992"},{"Text":"Pr\xc3\xa9sence de d\xc3\xa9chets verts","Value":"20432"}]},{"AdminService":"ADMINISTRATEUR DED3","CommuneService":null,"Id":"10426","Label":"DEE - Périscolaire et éducatif","Typology":[{"Text":"Activités périscolaires","Value":"10804"},{"Text":"Garderie","Value":"10805"},{"Text":"Restauration scolaire","Value":"10806"},{"Text":"Restauration scolaire \\/ Nutrition","Value":"11180"},{"Text":"Restauration scolaire \\/ Abonnements \\/cantine et r\xc3\xa9gie","Value":"10807"},{"Text":"Projets éducatifs en temps scolaire","Value":"10808"},{"Text":"Autres","Value":"10809"}]}]'
 
 CIVILITY = (
     '[{"Text":"Monsieur","Value":"1"},{"Text":"Madame","Value":"2"},{"Text":"Mademoiselle","Value":"3"}]'
 )
 
 REQUEST = r'{"AnswerToProvide":true,"AssigmentServiceName":"DEPE - Projets et maintenance du patrimoine","AssigmentStructure":"Cellule Travaux","AssociationId":0,"ClosingDate":"/Date(1306314926000+0200)/","Confidential":false,"DataEntryService":"Education","Description":"contrôle de toutes les portes extérieures des classes - gonds faibles pour le poids de la porte(N° 11353 v1)","DesiredResponseDate":null,"ExpectedDate":null,"ExpectedInterventionDate":null,"Files":[],"Handler":{"CUSStreetCode":null,"Cedex":null,"CellPhone":null,"Civility":null,"CivilityId":0,"Fax":null,"Firstname":null,"Information":null,"Lastname":"ANONYME","Mail":null,"Organization":0,"Phone":null,"SectionCode":null,"SectionLetter":null,"Street":null,"StreetLetter":null,"StreetNumber":null,"StructureLabel":null,"StructureShortLabel":null,"Title":null,"TitleId":0,"Town":null,"TownLabel":null,"ZipCode":null},"Id":1,"InputChannel":"Courrier","Localization":{"AdditionnalInformation":null,"CUSStreetCode":"2075","ElectedDistrict":"006","JobSector":null,"Other":"(sous-localisation : Bâtiment)","SectionCode":"1","SectionLetter":"_","Site":"Conseil","SiteId":1790,"Street":"RUE DE LA PLACE","StreetLetter":null,"StreetNumber":"2","TerritorialSector":"105","Town":"482","TownLabel":"STRASBOURG","ZipCode":"67000"},"Origin":2,"OriginLabel":"Usager","Priority":2,"PriorityLabel":"Normal","ReceptDate":"/Date(1165964400000+0100)/","Refused":false,"ReleaseDate":null,"Response":false,"ResponseFinal":true,"ResponseIntermediate":false,"Responses":[{"Date":"/Date(1306274400000+0200)/","OutputChannel":"Service X","Resume":"Intervention réalisée","SibeliusReference":null,"SignatureName":"UC","Type":2,"TypeLabel":"Finale"}],"SibeliusReference":null,"SiteCode":null,"SiteName":"Conseil","Sleeping":null,"State":64,"StateLabel":"Cloturée","Structure":"Cellule Travaux","Syscreationdate":"/Date(1165186800000+0100)/","Sysmodificationdate":"/Date(1306314926000+0200)/","Typology":{"Id":11168,"Label":"Maintenance"}}'
diff --git a/tests/test_generic_endpoint.py b/tests/test_generic_endpoint.py
index 3adbec34..124b9e90 100644
--- a/tests/test_generic_endpoint.py
+++ b/tests/test_generic_endpoint.py
@@ -13,39 +13,42 @@
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 from __future__ import unicode_literals
 
 import copy
-import os
 import json
+import os
 import random
 import warnings
 
 import mock
 import pytest
-
 import utils
-
 from django.contrib.contenttypes.models import ContentType
 from django.urls import reverse
+from test_manager import login
 
-from passerelle.apps.arcgis.models import ArcGIS
 from passerelle.apps.api_particulier.models import APIParticulier
-from passerelle.base.models import ResourceLog, ProxyLogger, BaseResource, HTTPResource, LoggingParameters
-from passerelle.base.models import ResourceStatus
+from passerelle.apps.arcgis.models import ArcGIS
 from passerelle.apps.mdel.models import MDEL
+from passerelle.base.models import (
+    BaseResource,
+    HTTPResource,
+    LoggingParameters,
+    ProxyLogger,
+    ResourceLog,
+    ResourceStatus,
+)
 from passerelle.contrib.stub_invoices.models import StubInvoicesConnector
 from passerelle.utils.api import endpoint
 
-from test_manager import login
-
 
 @pytest.fixture
 def mdel(db):
     return utils.setup_access_rights(MDEL.objects.create(slug='test'))
 
 
 @pytest.fixture
 def arcgis(db):
@@ -668,16 +671,17 @@ def test_endpoint_cookies(app, db, monkeypatch, httpbin):
     # to the other
     json_res = app.get('/stub-invoices/fake/httpcall').json
     assert json_res['cookie1'] is None
     assert json_res['cookie2'] == 'foo=bar'
 
 
 def test_https_warnings(app, db, monkeypatch, httpbin_secure, relax_openssl):
     from requests.exceptions import SSLError
+
     from passerelle.apps.arcgis.models import ArcGIS
 
     resource = utils.make_resource(ArcGIS, base_url='https://example.com/', slug='gis', verify_cert=True)
     with pytest.raises(SSLError):
         resource.requests.get(httpbin_secure.join('/get/'))
     resource.verify_cert = False
     with warnings.catch_warnings():
         warnings.simplefilter('error')
diff --git a/tests/test_gesbac.py b/tests/test_gesbac.py
index bf299f81..8d27665a 100644
--- a/tests/test_gesbac.py
+++ b/tests/test_gesbac.py
@@ -12,24 +12,24 @@
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import datetime
-import pytest
 
-from django.utils.timezone import now
+import pytest
 from django.utils.encoding import force_bytes, force_str, force_text
+from django.utils.timezone import now
 from utils import make_resource
 
+from passerelle.apps.gesbac.models import Form, Gesbac
 from passerelle.utils import SFTP
-from passerelle.apps.gesbac.models import Gesbac, Form
 
 
 @pytest.fixture
 def resource(db, sftpserver):
     return make_resource(
         Gesbac,
         slug='test',
         title='Gesbac',
diff --git a/tests/test_grandlyon_streetsections.py b/tests/test_grandlyon_streetsections.py
index 57d02105..ad04c443 100644
--- a/tests/test_grandlyon_streetsections.py
+++ b/tests/test_grandlyon_streetsections.py
@@ -1,14 +1,13 @@
+import pytest
 from django.contrib.contenttypes.models import ContentType
-
 from httmock import HTTMock
-import pytest
 
-from passerelle.base.models import ApiUser, AccessRight
+from passerelle.base.models import AccessRight, ApiUser
 from passerelle.contrib.grandlyon_streetsections.models import (
     GrandLyonStreetSections,
     StreetSection,
     normalize_street,
 )
 
 
 @pytest.fixture()
diff --git a/tests/test_greco.py b/tests/test_greco.py
index fa2ee9ed..0144e88e 100644
--- a/tests/test_greco.py
+++ b/tests/test_greco.py
@@ -8,29 +8,29 @@
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-from base64 import b64encode
 import copy
 import os
-import pytest
-import mock
-import utils
 import xml.etree.ElementTree as ET
+from base64 import b64encode
 
+import mock
+import pytest
+import utils
 from django.contrib.contenttypes.models import ContentType
 from django.urls import reverse
 from django.utils.encoding import force_str
 
-from passerelle.base.models import ApiUser, AccessRight
+from passerelle.base.models import AccessRight, ApiUser
 from passerelle.contrib.greco.models import Greco
 
 pytestmark = pytest.mark.django_db
 
 
 TEST_BASE_DIR = os.path.join(os.path.dirname(__file__), 'data', 'greco')
 WSDL_FILENAME = os.path.join(TEST_BASE_DIR, 'greco.wsdl')
 
diff --git a/tests/test_grenoble_gru.py b/tests/test_grenoble_gru.py
index 58330905..b5293266 100644
--- a/tests/test_grenoble_gru.py
+++ b/tests/test_grenoble_gru.py
@@ -12,22 +12,21 @@
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a.deepcopy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import json
 import os
+
 import mock
 import pytest
 import six
-
 import utils
-
 from django.urls import reverse
 
 from passerelle.contrib.grenoble_gru.models import GrenobleGRU
 
 
 @pytest.fixture
 def setup(db):
     return utils.setup_access_rights(
diff --git a/tests/test_import_export.py b/tests/test_import_export.py
index f740b26a..e6bf6077 100644
--- a/tests/test_import_export.py
+++ b/tests/test_import_export.py
@@ -1,29 +1,29 @@
 # -*- coding: utf-8 -*-
-import sys
 import json
 import os
-import pytest
+import sys
 import tempfile
 
+import pytest
+from django.contrib.contenttypes.models import ContentType
 from django.core.files import File
-from django.urls import reverse
 from django.core.management import call_command
-from django.contrib.contenttypes.models import ContentType
 from django.test import Client
+from django.urls import reverse
 from django.utils import timezone
 from django.utils.encoding import force_bytes, force_text
 from django.utils.six import BytesIO, StringIO
 
 from passerelle.apps.base_adresse.models import BaseAdresse
 from passerelle.apps.ovh.models import OVHSMSGateway
-from passerelle.base.models import ApiUser, AccessRight
+from passerelle.base.models import AccessRight, ApiUser
 from passerelle.compat import json_loads
-from passerelle.utils import import_site, export_site
+from passerelle.utils import export_site, import_site
 
 data = """121;69981;DELANOUE;Eliot;H
 525;6;DANIEL WILLIAMS;Shanone;F
 253;67742;MARTIN;Sandra;F
 511;38142;MARCHETTI;Lucie;F
 235;22;MARTIN;Sandra;F
 620;52156;ARNAUD;Mathis;H
 902;36;BRIGAND;Coline;F
@@ -39,18 +39,18 @@ data = """121;69981;DELANOUE;Eliot;H
 4809;75;COROLLER;Maelys;F
 5427;117;KANTE;Aliou;H
 116642;118;ZAHMOUM;Yaniss;H
 216352;38;Dupont;Benoît;H
 """
 
 data_bom = force_text(data, 'utf-8').encode('utf-8-sig')
 
-from passerelle.apps.csvdatasource.models import CsvDataSource, Query
 from passerelle.apps.bdp.models import Bdp
+from passerelle.apps.csvdatasource.models import CsvDataSource, Query
 
 pytestmark = pytest.mark.django_db
 
 TEST_BASE_DIR = os.path.join(os.path.dirname(__file__), 'data', 'csvdatasource')
 
 
 def get_file_content(filename):
     return open(os.path.join(TEST_BASE_DIR, filename), 'rb').read()
diff --git a/tests/test_iparapheur.py b/tests/test_iparapheur.py
index 29f4a036..eea87172 100644
--- a/tests/test_iparapheur.py
+++ b/tests/test_iparapheur.py
@@ -1,26 +1,26 @@
 # -*- coding: utf-8 -*-
 
-import pytest
-import mock
-import uuid
-import os
 import base64
+import os
+import uuid
 import xml.etree.ElementTree as ET
-from dateutil import parser
-from requests import Response
 
-from requests.exceptions import ConnectionError
-from django.urls import reverse
+import mock
+import pytest
+from dateutil import parser
 from django.contrib.contenttypes.models import ContentType
+from django.urls import reverse
 from django.utils import timezone
 from django.utils.encoding import force_bytes
+from requests import Response
+from requests.exceptions import ConnectionError
 
-from passerelle.base.models import ApiUser, AccessRight
+from passerelle.base.models import AccessRight, ApiUser
 from passerelle.contrib.iparapheur.models import IParapheur
 
 pytestmark = pytest.mark.django_db
 
 BASE_URL = 'https://secure-iparapheur.demonstrations.adullact.org:443/ws-iparapheur'
 WSDL_URL = '%s?wsdl' % BASE_URL
 API_KEY = 'iparapheur'
 SOAP_NAMESPACES = {
diff --git a/tests/test_isere_ens.py b/tests/test_isere_ens.py
index 90fd39f1..987db18b 100644
--- a/tests/test_isere_ens.py
+++ b/tests/test_isere_ens.py
@@ -13,21 +13,20 @@
 # GNU Affero General Public License for more details.
 #
 # You should have received a.deepcopy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 
 import json
 import os
+
 import mock
 import pytest
-
 import utils
-
 from django.urls import reverse
 
 from passerelle.contrib.isere_ens.models import IsereENS
 from passerelle.utils.jsonresponse import APIError
 
 
 @pytest.fixture
 def setup(db):
diff --git a/tests/test_iws.py b/tests/test_iws.py
index 45ede849..c1bdeff1 100644
--- a/tests/test_iws.py
+++ b/tests/test_iws.py
@@ -1,13 +1,13 @@
+import pytest
 from django.contrib.contenttypes.models import ContentType
 from mock import Mock
-import pytest
 
-from passerelle.base.models import ApiUser, AccessRight
+from passerelle.base.models import AccessRight, ApiUser
 from passerelle.contrib.iws.models import IWSConnector
 
 
 @pytest.fixture()
 def setup(db):
     api = ApiUser.objects.create(username='all', keytype='', key='')
     conn = IWSConnector.objects.create(
         wsdl_url='http://example.com/iws?wsdl',
diff --git a/tests/test_jobs.py b/tests/test_jobs.py
index b0966aec..b28eaeb6 100644
--- a/tests/test_jobs.py
+++ b/tests/test_jobs.py
@@ -1,26 +1,21 @@
 # -*- coding: utf-8 -*-
 
 import datetime
 import os
 
-from django.core.management import call_command
-
+import isodate
 import mock
 import pytest
-
 import utils
+from django.core.management import call_command
+from test_base_adresse import StreetModel, base_adresse
 
-import isodate
-
-
-from passerelle.base.models import Job, SkipJob, ResourceLog
-
-from test_base_adresse import base_adresse, StreetModel
+from passerelle.base.models import Job, ResourceLog, SkipJob
 
 
 @mock.patch('passerelle.utils.Request.get')
 def test_jobs(mocked_get, app, base_adresse, freezer):
     Job.objects.all().delete()  # remove jobs automatically added at connector creation
     filepath = os.path.join(os.path.dirname(__file__), 'data', 'update_streets_test.gz')
     with open(filepath, 'rb') as ban_file:
         mocked_get.return_value = utils.FakedResponse(content=ban_file.read(), status_code=200)
diff --git a/tests/test_jsondatastore.py b/tests/test_jsondatastore.py
index 2b82f4bf..a8d541ce 100644
--- a/tests/test_jsondatastore.py
+++ b/tests/test_jsondatastore.py
@@ -1,17 +1,16 @@
 # -*- coding: utf-8 -*-
 
 import pytest
-
 from django.contrib.contenttypes.models import ContentType
 from django.core.serializers.json import DjangoJSONEncoder
 
-from passerelle.apps.jsondatastore.models import JsonDataStore, JsonData
-from passerelle.base.models import ApiUser, AccessRight
+from passerelle.apps.jsondatastore.models import JsonData, JsonDataStore
+from passerelle.base.models import AccessRight, ApiUser
 
 
 @pytest.fixture
 def jsondatastore(db):
     datastore = JsonDataStore.objects.create(slug='foobar')
     api = ApiUser.objects.create(username='all', keytype='', key='')
     obj_type = ContentType.objects.get_for_model(datastore)
     AccessRight.objects.create(
diff --git a/tests/test_jsonresponse.py b/tests/test_jsonresponse.py
index d0fad637..1ab75c2f 100644
--- a/tests/test_jsonresponse.py
+++ b/tests/test_jsonresponse.py
@@ -1,14 +1,14 @@
 import logging
-import pytest
 
-from django.test.client import RequestFactory
-from django.http import Http404
+import pytest
 from django.core.exceptions import ObjectDoesNotExist, PermissionDenied
+from django.http import Http404
+from django.test.client import RequestFactory
 
 from passerelle.compat import json_loads
 from passerelle.utils import to_json
 
 
 class WrappedException(Exception):
     pass
 
diff --git a/tests/test_lille_kimoce.py b/tests/test_lille_kimoce.py
index 0f7fafba..9311b72b 100644
--- a/tests/test_lille_kimoce.py
+++ b/tests/test_lille_kimoce.py
@@ -13,21 +13,20 @@
 # GNU Affero General Public License for more details.
 #
 # You should have received a.deepcopy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 
 import json
 import os
+
 import mock
 import pytest
-
 import utils
-
 from django.urls import reverse
 
 from passerelle.contrib.lille_kimoce.models import Kimoce
 from passerelle.utils.jsonresponse import APIError
 
 
 @pytest.fixture
 def setup(db):
diff --git a/tests/test_lille_urban_card.py b/tests/test_lille_urban_card.py
index 3c1d6e2a..8aea68f5 100644
--- a/tests/test_lille_urban_card.py
+++ b/tests/test_lille_urban_card.py
@@ -1,21 +1,21 @@
 # -*- coding: utf-8 -*-
 
-from httmock import HTTMock
 import json
+
 import mock
 import pytest
+import utils
+from httmock import HTTMock
 
 from passerelle.compat import json_loads
 from passerelle.contrib.lille_urban_card.models import LilleUrbanCard
 from passerelle.utils.jsonresponse import APIError
 
-import utils
-
 
 @pytest.fixture
 def connector(db):
     return utils.setup_access_rights(
         LilleUrbanCard.objects.create(
             slug='test', base_url='http://localhost', username='test', password='secret'
         )
     )
diff --git a/tests/test_maelis.py b/tests/test_maelis.py
index e1f9d4e5..89b14ea1 100644
--- a/tests/test_maelis.py
+++ b/tests/test_maelis.py
@@ -1,30 +1,28 @@
 # -*- coding: utf-8 -*-
 
 import json
-import mock
 import os
-import pytest
 
+import mock
+import pytest
+import utils
 from django.test import override_settings
 from django.utils.dateparse import parse_date
 
-from passerelle.apps.maelis.models import Maelis, Link
+from passerelle.apps.maelis.models import Link, Maelis
 from passerelle.apps.maelis.utils import (
+    decompose_event,
     get_school_year,
-    week_boundaries_datetimes,
     month_range,
-    decompose_event,
+    week_boundaries_datetimes,
 )
-
 from passerelle.utils.jsonresponse import APIError
 
-import utils
-
 pytestmark = pytest.mark.django_db
 
 TEST_BASE_DIR = os.path.join(os.path.dirname(__file__), 'data', 'maelis')
 
 
 def get_xml_file(filename):
     with open(os.path.join(TEST_BASE_DIR, filename), 'rb') as desc:
         return desc.read()
diff --git a/tests/test_manager.py b/tests/test_manager.py
index fababf97..3f0c7bc4 100644
--- a/tests/test_manager.py
+++ b/tests/test_manager.py
@@ -1,25 +1,23 @@
 import datetime
 import re
 import uuid
 
-from webtest import Upload
-
+import freezegun
+import pytest
 from django.contrib.contenttypes.models import ContentType
 from django.core.files import File
 from django.utils.six import StringIO
 from django.utils.timezone import now
+from webtest import Upload
 
-import freezegun
-import pytest
-
-from passerelle.base.models import ApiUser, AccessRight, ResourceStatus, Job, ResourceLog
 from passerelle.apps.csvdatasource.models import CsvDataSource, Query
 from passerelle.apps.photon.models import Photon
+from passerelle.base.models import AccessRight, ApiUser, Job, ResourceLog, ResourceStatus
 
 pytestmark = pytest.mark.django_db
 
 
 def login(app, username='admin', password='admin'):
     login_page = app.get('/login/')
     login_form = login_page.forms[0]
     login_form['username'] = username
diff --git a/tests/test_mdel.py b/tests/test_mdel.py
index d5ae5a6f..00a36712 100644
--- a/tests/test_mdel.py
+++ b/tests/test_mdel.py
@@ -11,35 +11,33 @@
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a.deepcopy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 from __future__ import unicode_literals
 
-import shutil
-import os
 import base64
 import copy
+import os
+import shutil
 import zipfile
-
 from xml.etree import ElementTree as etree
-from lxml import etree as letree
 
 import pytest
+import utils
+from lxml import etree as letree
 
+from passerelle.apps.mdel.mdel import AttachedFile, Description, Message, get_resource_base_dir
 from passerelle.apps.mdel.models import MDEL, Demand
-from passerelle.apps.mdel.mdel import Message, Description, AttachedFile, get_resource_base_dir
 from passerelle.apps.mdel.utils import parse_date
 from passerelle.compat import json_loads
 from passerelle.utils import SFTP
 
-import utils
-
 AEC_XSD = 'ActeEtatCivil-V1.A.xsd'
 ILE_XSD = 'ILE_v1.1.xsd'
 
 
 def get_mdel_base_dir():
     return os.path.join(os.path.dirname(__file__), 'data', 'mdel')
 
 
diff --git a/tests/test_mdel_ddpacs.py b/tests/test_mdel_ddpacs.py
index 47c9f171..9d391009 100644
--- a/tests/test_mdel_ddpacs.py
+++ b/tests/test_mdel_ddpacs.py
@@ -18,23 +18,21 @@
 from __future__ import unicode_literals
 
 import io
 import logging
 import os
 
 import pytest
 import utils
-
 import xmlschema
 
-from passerelle.apps.mdel_ddpacs.models import Resource, Demand
-
+from passerelle.apps.mdel_ddpacs.models import Demand, Resource
 from passerelle.utils import json, sftp
-from passerelle.utils.zip import diff_zip, ZipTemplate
+from passerelle.utils.zip import ZipTemplate, diff_zip
 
 
 def build_response_zip(**kwargs):
     zip_template = ZipTemplate(os.path.abspath('tests/data/mdel_ddpacs/response_manifest.json'), ctx=kwargs)
     return zip_template.name, zip_template.render_to_bytes()
 
 
 @pytest.fixture(autouse=True)
diff --git a/tests/test_mdph13.py b/tests/test_mdph13.py
index 5f9ee76f..ad467cd7 100644
--- a/tests/test_mdph13.py
+++ b/tests/test_mdph13.py
@@ -10,31 +10,29 @@
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-import json
 import base64
 import datetime
+import json
 import logging
 
-import requests
-import requests.exceptions
-
 import httmock
 import pytest
-
+import requests
+import requests.exceptions
 import utils
 
+from passerelle.contrib.mdph13.models import Link, MDPH13Resource
 from passerelle.utils.jsonresponse import APIError
-from passerelle.contrib.mdph13.models import MDPH13Resource, Link
 
 NAME_ID = 'xyz'
 FILE_NUMBER = '1234'
 DOB = datetime.date(1993, 5, 4)
 DOB_ISOFORMAT = '1993-05-04'
 EMAIL = 'john.doe@example.com'
 SECRET = 'secret'
 IP = '88.34.56.56'
diff --git a/tests/test_misc.py b/tests/test_misc.py
index 91eb8c66..05f2df94 100644
--- a/tests/test_misc.py
+++ b/tests/test_misc.py
@@ -1,25 +1,24 @@
 import datetime
-import pytest
-from mock import patch
 
+import pytest
 from django.contrib.contenttypes.models import ContentType
 from django.core.files import File
 from django.db import connection
 from django.db.migrations.executor import MigrationExecutor
 from django.urls import reverse
 from django.utils import timezone
 from django.utils.six import StringIO
+from mock import patch
+from test_manager import login
 
-from passerelle.base.models import ResourceLog
-from passerelle.apps.opengis.models import OpenGIS
 from passerelle.apps.clicrdv.models import ClicRdv
-
-from test_manager import login
+from passerelle.apps.opengis.models import OpenGIS
+from passerelle.base.models import ResourceLog
 
 
 def test_get_description_url_fields(db):
     connector = OpenGIS(slug='plop', wms_service_url='http://www.example.net')
     assert 'http://www.example.net' in [x[1] for x in connector.get_description_fields()]
 
     connector = OpenGIS(slug='plop', wms_service_url='http://username:secret@www.example.net')
     assert 'http://***:***@www.example.net' in [x[1] for x in connector.get_description_fields()]
@@ -83,16 +82,17 @@ def test_log_cleaning(app, db, admin_user, settings):
     resp.form.submit()
     connector.daily()
     assert ResourceLog.objects.all().count() == 1
 
 
 @pytest.fixture
 def email_handler():
     import logging
+
     from django.utils.log import AdminEmailHandler
 
     root = logging.getLogger()
     handler = AdminEmailHandler(include_html=True)
     handler.level = logging.ERROR
     root.handlers.append(handler)
     try:
         yield
diff --git a/tests/test_nancypoll.py b/tests/test_nancypoll.py
index 566900e0..f70afb35 100644
--- a/tests/test_nancypoll.py
+++ b/tests/test_nancypoll.py
@@ -1,18 +1,16 @@
 import pytest
-
-from django.core.files import File
-from django.urls import reverse
 from django.contrib.contenttypes.models import ContentType
+from django.core.files import File
 from django.test import Client
+from django.urls import reverse
 from django.utils.six import StringIO
 
-from passerelle.base.models import ApiUser, AccessRight
-
+from passerelle.base.models import AccessRight, ApiUser
 from passerelle.compat import json_loads
 from passerelle.contrib.nancypoll.models import NancyPoll
 
 data = """
 0,999,,,S,A,Z,,34,28,ECOLE MATERNELLE DIDION,16 RUE SAINT THIEBAUT,,JOFFRE,BOULEVARD JOFFRE,4,NANCY 1,0,1083,1
 0,121,,,I,A,Z,,46,3,GYMNASE MARTINY,10 RUE VICTOR,,LOBAU,BOULEVARD LOBAU,2,NANCY  3,0,1083,1
 0,999,,,I,A,Z,,28,37,ECOLE MATERNELLE CHARLEMAGNE,RUE DU CHANOINE BLAISE,,BLANC,RUE DU CHEMIN BLANC,4,NANCY 1,0,1083,1
 0,999,,,P,A,Z,,22,39,ECOLE MATERNELLE DE BUTHEGNEMONT,45 RUE ANNE FERIET,,BLANC,RUE DU CHEMIN BLANC,4,NANCY 1,0,1083,1
diff --git a/tests/test_okina.py b/tests/test_okina.py
index df449ca6..260fe14c 100644
--- a/tests/test_okina.py
+++ b/tests/test_okina.py
@@ -1,19 +1,18 @@
 # -*- coding: utf-8 -*-
 import json
-import pytest
+
 import mock
+import pytest
 import utils
-
 from django.contrib.contenttypes.models import ContentType
 
 from passerelle.apps.okina.models import Okina
-from passerelle.base.models import ApiUser, AccessRight
-
+from passerelle.base.models import AccessRight, ApiUser
 
 CITIES = '''[ {
   "city" : 83355,
   "cityObject" : {
     "id" : 83355,
     "insee" : "36005",
     "nameCity" : "ARDENTES",
     "zipCode" : "36120",
diff --git a/tests/test_opendatasoft.py b/tests/test_opendatasoft.py
index bb272a26..69eb6cfb 100644
--- a/tests/test_opendatasoft.py
+++ b/tests/test_opendatasoft.py
@@ -10,29 +10,27 @@
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-import mock
 import json
-import pytest
 
+import mock
+import pytest
 import utils
-
 from django.contrib.auth.models import User
+from test_manager import login
 
 from passerelle.apps.opendatasoft.models import OpenDataSoft, Query
 from passerelle.utils import import_site
 
-from test_manager import login
-
 pytestmark = pytest.mark.django_db
 
 
 FAKED_CONTENT_Q_SEARCH = json.dumps(
     {
         "nhits": 76,
         "parameters": {
             "dataset": "referentiel-adresse-test",
diff --git a/tests/test_opengis.py b/tests/test_opengis.py
index d4e4ad57..2626121b 100644
--- a/tests/test_opengis.py
+++ b/tests/test_opengis.py
@@ -1,23 +1,21 @@
 import json
+
 import mock
 import pytest
-
+import utils
 from django.contrib.auth.models import User
 from django.core.management import call_command
+from test_manager import login
 
-from passerelle.apps.opengis.models import OpenGIS, Query, FeatureCache
+from passerelle.apps.opengis.models import FeatureCache, OpenGIS, Query
 from passerelle.base.models import Job
 from passerelle.utils import import_site
 
-from test_manager import login
-
-import utils
-
 pytestmark = pytest.mark.django_db
 
 FAKE_FEATURE_INFO = '''<?xml version="1.0" encoding="UTF-8"?>
 <msGMLOutput
       xmlns:gml="http://www.opengis.net/gml"
       xmlns:xlink="http://www.w3.org/1999/xlink"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <cad_cadastre.cadparcelle_layer>
diff --git a/tests/test_orange.py b/tests/test_orange.py
index 89fbb60f..7dabd9c1 100644
--- a/tests/test_orange.py
+++ b/tests/test_orange.py
@@ -14,26 +14,23 @@
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import json
 
 import httmock
 import pytest
-
 from django.contrib.contenttypes.models import ContentType
 from django.utils.encoding import force_text
 
-from passerelle.apps.orange.models import OrangeSMSGateway, OrangeError
-
-from passerelle.base.models import ApiUser, AccessRight, Job
+from passerelle.apps.orange.models import OrangeError, OrangeSMSGateway
+from passerelle.base.models import AccessRight, ApiUser, Job
 from passerelle.utils.jsonresponse import APIError
 
-
 NETLOC = 'contact-everyone.orange-business.com'
 JSON_HEADERS = {'content-type': 'application/json'}
 PAYLOAD = {
     'message': 'hello',
     'from': '+33699999999',
     'to': ['+33688888888', '+33677777777'],
 }
 
diff --git a/tests/test_phonecalls.py b/tests/test_phonecalls.py
index 9517bd77..7408624f 100644
--- a/tests/test_phonecalls.py
+++ b/tests/test_phonecalls.py
@@ -1,17 +1,17 @@
-import pytest
-import utils
 import re
 
+import pytest
+import utils
 from django.contrib.contenttypes.models import ContentType
 from django.utils.timezone import now, timedelta
 
-from passerelle.apps.phonecalls.models import PhoneCalls, Call
-from passerelle.base.models import ApiUser, AccessRight
+from passerelle.apps.phonecalls.models import Call, PhoneCalls
+from passerelle.base.models import AccessRight, ApiUser
 
 
 @pytest.fixture
 def phonecalls(db):
     phonecalls = PhoneCalls.objects.create(slug='test')
     apikey = ApiUser.objects.create(username='all', keytype='API', key='123')
     obj_type = ContentType.objects.get_for_model(phonecalls)
     AccessRight.objects.create(
diff --git a/tests/test_photon.py b/tests/test_photon.py
index ecbe7878..79b7aff8 100644
--- a/tests/test_photon.py
+++ b/tests/test_photon.py
@@ -10,28 +10,26 @@
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import datetime
-from httmock import urlmatch, HTTMock, response, remember_called
 import json
+
 import mock
 import pytest
 import utils
-
-from requests.exceptions import HTTPError
-
 from django.core.management import call_command
+from httmock import HTTMock, remember_called, response, urlmatch
+from requests.exceptions import HTTPError
 
-from passerelle.apps.photon.models import Photon, AddressCacheModel
-
+from passerelle.apps.photon.models import AddressCacheModel, Photon
 
 CONTENT = {
     "features": [
         {
             "geometry": {"coordinates": [4.8522272, 45.7587414], "type": "Point"},
             "properties": {
                 "city": "Lyon 3ème Arrondissement",
                 "country": "France",
diff --git a/tests/test_planitech.py b/tests/test_planitech.py
index 7ff1df7f..9f95afe6 100644
--- a/tests/test_planitech.py
+++ b/tests/test_planitech.py
@@ -1,21 +1,21 @@
 import collections
 from datetime import datetime
 
-from django.contrib.contenttypes.models import ContentType
-from django.core.cache import cache
-from httmock import urlmatch, HTTMock
 import mock
 import pytest
 import requests
+from django.contrib.contenttypes.models import ContentType
+from django.core.cache import cache
+from httmock import HTTMock, urlmatch
 
-from passerelle.base.models import ApiUser, AccessRight
+from passerelle.base.models import AccessRight, ApiUser
 from passerelle.contrib.planitech import mste
-from passerelle.contrib.planitech.models import PlanitechConnector, Pairing, get_extensions
+from passerelle.contrib.planitech.models import Pairing, PlanitechConnector, get_extensions
 from passerelle.utils.jsonresponse import APIError
 
 
 def assert_mste(data, ref_data):
     """skip CRC verification"""
     assert len(data) == len(ref_data)
     for i in range(len(data)):
         if i != 2:
diff --git a/tests/test_proxylogger.py b/tests/test_proxylogger.py
index af61769a..96b1df60 100644
--- a/tests/test_proxylogger.py
+++ b/tests/test_proxylogger.py
@@ -1,30 +1,28 @@
 # -*- coding: utf-8 -*-
 
-import logging
 import datetime
 import itertools
+import logging
 
 import pytest
-from httmock import HTTMock
-
+import utils
 from django.core.exceptions import ValidationError
-from django.utils.six import PY2
 from django.utils.log import AdminEmailHandler
+from django.utils.six import PY2
+from httmock import HTTMock
+from test_availability import down_mock, up_mock
 
-from passerelle.base.models import ProxyLogger, ResourceLog
 from passerelle.apps.feeds.models import Feed
+from passerelle.base.models import ProxyLogger, ResourceLog
 from passerelle.contrib.stub_invoices.models import StubInvoicesConnector
 from passerelle.utils.api import endpoint
 from passerelle.utils.jsonresponse import APIError
 
-from test_availability import down_mock, up_mock
-import utils
-
 
 @pytest.fixture
 def connector():
     connector, created = Feed.objects.get_or_create(slug='some-slug')
     connector.set_log_level('DEBUG')
     connector.url = 'http://example.net/'
     connector.save()
     return connector
diff --git a/tests/test_requests.py b/tests/test_requests.py
index e2a96770..d3581def 100644
--- a/tests/test_requests.py
+++ b/tests/test_requests.py
@@ -1,23 +1,21 @@
 import logging
 
-import pytest
-import mohawk
 import mock
+import mohawk
+import pytest
 import requests
-
-from httmock import urlmatch, HTTMock, response
-
+import utils
 from django.test import override_settings
+from httmock import HTTMock, response, urlmatch
+from utils import FakedResponse
 
-from passerelle.utils import Request, CaseInsensitiveDict, log_http_request
+from passerelle.utils import CaseInsensitiveDict, Request, log_http_request
 from passerelle.utils.http_authenticators import HawkAuth
-import utils
-from utils import FakedResponse
 
 
 class MockFileField(object):
     def __init__(self, path):
         self.path = path
 
 
 class MockResource(object):
diff --git a/tests/test_rsa13.py b/tests/test_rsa13.py
index 16d5fe4f..4f14a7d8 100644
--- a/tests/test_rsa13.py
+++ b/tests/test_rsa13.py
@@ -16,17 +16,16 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import functools
 import json
 from urllib.parse import parse_qs
 
 import httmock
 import pytest
-
 import utils
 
 from passerelle.contrib.rsa13.models import RSA13Resource
 
 
 @pytest.fixture
 def rsa13(db):
     return utils.make_resource(
diff --git a/tests/test_sigerly.py b/tests/test_sigerly.py
index e2015e23..309e4e1f 100644
--- a/tests/test_sigerly.py
+++ b/tests/test_sigerly.py
@@ -14,21 +14,19 @@
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import json
 import os
 
 import httmock
 import pytest
-
-from passerelle.contrib.sigerly.models import Sigerly
-
 import utils
 
+from passerelle.contrib.sigerly.models import Sigerly
 
 TEST_BASE_DIR = os.path.join(os.path.dirname(__file__), 'data', 'sigerly')
 
 
 @pytest.fixture
 def connector(db):
     return utils.setup_access_rights(
         Sigerly.objects.create(slug='test', base_url='https://sigerly.example.net')
diff --git a/tests/test_sms.py b/tests/test_sms.py
index 36879b87..c0ed21d4 100644
--- a/tests/test_sms.py
+++ b/tests/test_sms.py
@@ -8,38 +8,36 @@
 #
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
-import isodate
 import json
 import logging
+
+import isodate
 import mock
 import pytest
-from requests import RequestException
-
+import utils
 from django.conf import settings
 from django.contrib.contenttypes.models import ContentType
 from django.urls import reverse
 from django.utils.translation import ugettext as _
+from requests import RequestException
+from test_manager import login
 
 from passerelle.apps.choosit.models import ChoositSMSGateway
 from passerelle.apps.ovh.models import OVHSMSGateway
-from passerelle.base.models import ApiUser, AccessRight, Job, ResourceLog
-from passerelle.sms.models import SMSResource, SMSLog
+from passerelle.base.models import AccessRight, ApiUser, Job, ResourceLog
+from passerelle.sms.models import SMSLog, SMSResource
 from passerelle.utils.jsonresponse import APIError
 
-from test_manager import login
-
-import utils
-
 pytestmark = pytest.mark.django_db
 
 klasses = SMSResource.__subclasses__()
 
 
 def test_clean_numbers():
     connector = OVHSMSGateway()
     assert connector.clean_numbers(['+ 33 12']) == ['003312']
diff --git a/tests/test_soap.py b/tests/test_soap.py
index e493329a..5e81c628 100644
--- a/tests/test_soap.py
+++ b/tests/test_soap.py
@@ -8,27 +8,26 @@
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-from django.utils.encoding import force_bytes
-import pytest
 import mock
+import pytest
 import requests
+from django.utils.encoding import force_bytes
 from zeep import Settings
+from zeep.exceptions import TransportError, XMLParseError
 from zeep.plugins import Plugin
-from zeep.exceptions import XMLParseError, TransportError
 
 from passerelle.utils.soap import SOAPClient
 
-
 WSDL = 'tests/data/soap.wsdl'
 
 
 class FooPlugin(Plugin):
     pass
 
 
 class BarPlugin(Plugin):
diff --git a/tests/test_solis.py b/tests/test_solis.py
index d0601709..e2d6e1dd 100644
--- a/tests/test_solis.py
+++ b/tests/test_solis.py
@@ -1,20 +1,19 @@
 # -*- coding: utf-8 -*-
 
-import pytest
 import mock
+import pytest
 import utils
-
 from django.contrib.contenttypes.models import ContentType
 from django.core.files import File
 from django.utils.six import StringIO
 
 from passerelle.apps.solis.models import Solis, SolisAPALink, SolisRSALink, unflat
-from passerelle.base.models import ApiUser, AccessRight
+from passerelle.base.models import AccessRight, ApiUser
 
 NAMEID = 'bebe'
 APATOKEN = '''{"token":"1c2562e6-b0a9-4bcf-b669-e33a42397147","endDate":"2017-10-11T10:22:40.342"}'''
 APATOKEN_403 = '''[{"logref":"db15cb8a-4d05-4e4f-b4e1-44ec39dc11e3","message":"Erreur d'authentification m\xc3\xa9tier ASG APA: Code confidentiel non valide pour l'individu 2823255","links":[]}]'''
 APAINFOS = {
     'exportDonneesIndividu': '{"individu":{"civilite":"Mme","nomUsuel":"PYPPENNE","nomNaissance":"NPYNEZ","prenom":"Pecile","dateNaissance":"1922-12-17","contact":{"telephone":"0344480774","mail":""},"adresse":{"complementDestinataire":"compl dest","numeroLieu":"38","natureLieu":null,"nomLieu":"RUE MARTIN","complementLieu":"MARPA LES NACRES - APPARTEMENT 9","finLieu":"fin adresse","codePostal":"80370","commune":"BERNAVILLE"},"tutelles":{"tutelle":[{"type":"Organisme","identite":"Association Tut\xc3\xa9laire de la  Somme","mesure":null,"natureAccord":"Juridique","dateEffet":"2014-01-01","dateFin":null,"adresse":{"numeroLieu":"21","natureLieu":null,"nomLieu":"RUE SULLY","complementLieu":"BP 11660","finLieu":"","codePostal":"80016","commune":"AMIENS","cedex":"1"}},{"type":"Individu/Particulier","identite":"Ehmet TYEP","mesure":"Curatelle simple","natureAccord":"Juridique","dateEffet":"2017-01-01","dateFin":"2017-12-31","adresse":{"numeroLieu":"89","natureLieu":null,"nomLieu":"AVENUE LEON BLUM","complementLieu":"","finLieu":"","codePostal":"80100","commune":"ABBEVILLE","cedex":""}},{"type":"Individu/Particulier","identite":"Esg TYTEYP PE PEPPOXE OEX","mesure":null,"natureAccord":null,"dateEffet":null,"dateFin":null,"adresse":{"numeroLieu":"1","natureLieu":null,"nomLieu":"BOULEVARD DU PORT","complementLieu":"CAD","finLieu":"","codePostal":"80000","commune":"AMIENS","cedex":""}}]},"apa":{"classotheque":"05-2834","centreAutonomie":"Centre Autonomie nord ouest"}}}',
     'consultationDeMesDroits': '{"demandeAsg":[{"demande":{"indexDemande":42,"type":"Allocation Personnalis\xc3\xa9e Autonomie","nature":"Domicile"},"droit":{"dateDebut":"2017-01-05","dateFin":"2019-01-31"},"complementDossier":{"dateDepot":"2016-11-15","dateArrivee":"2016-11-16","dateDossierComplet":"2016-11-17"},"gir":{"type":"Synth\xc3\xa8se","gir":3,"dateEvaluation":"2017-02-01"},"suivi":{"instructeur":{"civilite":"madame","nom":"ZEPEQPE","prenom":"EPOZOE","telephone":"0344974383","mail":"e.zepeqpe@xoppe.pp"},"dateDecision":"2017-01-05"},"bilan":{"pourcentageTM":2.1973443031311035},"prestationAccordeeAsg":[{"prestation":"Accueil de jour GIR 1-2","periode":{"dateEffet":"2017-01-05","dateFin":"2019-01-31"},"tiers":{"type":"Ind\xc3\xa9termin\xc3\xa9","identite":null,"tarif":null,"quantitatif":null},"quantite":0,"montant":{"accorde":0,"participation":0,"verse":0},"attributaire":{"type":"Tuteur","identite":"Association Tut\xc3\xa9laire de la  Somme"}},{"prestation":"Articles d\'hygi\xc3\xa8ne forfait 45\xc2\x80","periode":{"dateEffet":"2017-01-05","dateFin":null},"tiers":{"type":"Ind\xc3\xa9termin\xc3\xa9","identite":null,"tarif":45,"quantitatif":"Mois"},"quantite":1,"montant":{"accorde":45,"participation":1.68,"verse":43.32},"attributaire":{"type":"B\xc3\xa9n\xc3\xa9ficiaire","identite":"PYPPENNE Pecile"}},{"prestation":"Petite structure","periode":{"dateEffet":"2017-01-05","dateFin":"2019-01-31"},"tiers":{"type":"Etablissement","identite":"MARPA LES NACRES","tarif":null,"quantitatif":null},"quantite":0,"montant":{"accorde":440.42,"participation":7.68,"verse":432.74},"attributaire":{"type":"Etablissement","identite":"MARPA LES NACRES"}},{"prestation":"Aide humaine prestataire","periode":{"dateEffet":"2017-01-05","dateFin":"2019-01-31"},"tiers":{"type":"Prestataire","identite":"COMMUNAUTE DE COMMUNES DU TERRITOIRE NORD PICARDIE BERNAVILLE","tarif":19,"quantitatif":"Heure(s)"},"quantite":45.5,"montant":{"accorde":864.5,"participation":18.93,"verse":845.57},"attributaire":{"type":"Prestataire","identite":"COMMUNAUTE DE COMMUNES DU TERRITOIRE NORD PICARDIE BERNAVILLE"}},{"prestation":"Articles d\'hygi\xc3\xa8ne forfait 90\xc2\x80","periode":{"dateEffet":"2017-01-05","dateFin":null},"tiers":{"type":"Ind\xc3\xa9termin\xc3\xa9","identite":null,"tarif":90,"quantitatif":"Mois"},"quantite":1,"montant":{"accorde":90,"participation":3.35,"verse":86.65},"attributaire":{"type":"B\xc3\xa9n\xc3\xa9ficiaire","identite":"PYPPENNE Pecile"}}]}]}',
     'suiviDemandeEnInstruction': '{"demandeAsg":[]}',
diff --git a/tests/test_solis_afi_mss.py b/tests/test_solis_afi_mss.py
index 658ba3ae..f17a18c7 100644
--- a/tests/test_solis_afi_mss.py
+++ b/tests/test_solis_afi_mss.py
@@ -14,17 +14,16 @@
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import json
 import os
 
 import mock
 import pytest
-
 import utils
 
 from passerelle.contrib.solis_afi_mss.models import SolisAfiMss
 from passerelle.utils.jsonresponse import APIError
 
 
 @pytest.fixture
 def connector(db):
diff --git a/tests/test_solis_apa.py b/tests/test_solis_apa.py
index fed1a565..c41cf4df 100644
--- a/tests/test_solis_apa.py
+++ b/tests/test_solis_apa.py
@@ -1,23 +1,21 @@
 import copy
-import os
 import json
+import os
 from decimal import Decimal
 
 import mock
 import pytest
-
-from django.urls import reverse
 from django.contrib.contenttypes.models import ContentType
+from django.urls import reverse
 
-from passerelle.base.models import ApiUser, AccessRight
-from passerelle.contrib.solis_apa.models import SolisAPA
+from passerelle.base.models import AccessRight, ApiUser
 from passerelle.contrib.solis_apa import integration
-
+from passerelle.contrib.solis_apa.models import SolisAPA
 
 TEST_BASE_DIR = os.path.join(os.path.dirname(__file__), 'data', 'solis_apa')
 
 
 def json_get_data(filename):
     with open(os.path.join(TEST_BASE_DIR, filename)) as fd:
         return json.load(fd)
 
diff --git a/tests/test_strasbourg_eu.py b/tests/test_strasbourg_eu.py
index 8eba3528..e710d498 100644
--- a/tests/test_strasbourg_eu.py
+++ b/tests/test_strasbourg_eu.py
@@ -1,19 +1,17 @@
 # -*- coding: utf-8 -*-
 
-from httmock import all_requests, HTTMock
 import pytest
-
+import utils
 from django.contrib.contenttypes.models import ContentType
+from httmock import HTTMock, all_requests
 
+from passerelle.base.models import AccessRight, ApiUser
 from passerelle.contrib.strasbourg_eu.models import StrasbourgEu
-from passerelle.base.models import ApiUser, AccessRight
-
-import utils
 
 INTERESTS_EXAMPLE = u"""{
     "interests": [
         {
             "id": "275305",
             "name": "Centre d'intérêt 2",
             "description": "Centre d'intérêt 2",
             "typeId": "275302",
diff --git a/tests/test_tcl.py b/tests/test_tcl.py
index 1bda8041..a06c65bf 100644
--- a/tests/test_tcl.py
+++ b/tests/test_tcl.py
@@ -1,17 +1,16 @@
 import copy
 
-from django.utils.six.moves.urllib import parse as urlparse
 import mock
 import pytest
-
-from passerelle.contrib.tcl.models import Tcl, Line, Stop
-
 import utils
+from django.utils.six.moves.urllib import parse as urlparse
+
+from passerelle.contrib.tcl.models import Line, Stop, Tcl
 
 LIGNE_BUS = {
     "values": [
         {
             "indice": "",
             "last_update_fme": "2017-06-27 06:01:10",
             "infos": "",
             "couleur": "164 203 38",
diff --git a/tests/test_teamnet_axel.py b/tests/test_teamnet_axel.py
index dccb1900..95ad2a91 100644
--- a/tests/test_teamnet_axel.py
+++ b/tests/test_teamnet_axel.py
@@ -1,16 +1,14 @@
-from requests.exceptions import ConnectionError
 import mock
 import pytest
-
 import utils
+from requests.exceptions import ConnectionError
 
-from passerelle.contrib.teamnet_axel.models import TeamnetAxel
-from passerelle.contrib.teamnet_axel.models import Link
+from passerelle.contrib.teamnet_axel.models import Link, TeamnetAxel
 from passerelle.utils.jsonresponse import APIError
 
 
 @pytest.fixture
 def setup(db):
     return utils.make_resource(
         TeamnetAxel,
         **{
diff --git a/tests/test_toulouse_axel.py b/tests/test_toulouse_axel.py
index 317d3d37..f59b5d52 100644
--- a/tests/test_toulouse_axel.py
+++ b/tests/test_toulouse_axel.py
@@ -12,50 +12,45 @@
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 from __future__ import unicode_literals
 
-from contextlib import contextmanager
 import copy
 import datetime
 import decimal
 import json
-import mock
 import os
 import xml.etree.ElementTree as ET
-
-from django.core.cache import cache
+from contextlib import contextmanager
 
 import freezegun
+import jsonschema
+import mock
 import pytest
+import utils
 import xmlschema
-import jsonschema
+from django.core.cache import cache
 
-from passerelle.contrib.toulouse_axel.exceptions import AxelError
-from passerelle.contrib.toulouse_axel.models import (
-    Link,
-    Lock,
-    ToulouseAxel,
-)
 from passerelle.contrib.toulouse_axel import schemas
+from passerelle.contrib.toulouse_axel.exceptions import AxelError
+from passerelle.contrib.toulouse_axel.models import Link, Lock, ToulouseAxel
 from passerelle.contrib.toulouse_axel.utils import (
-    situation_familiale_mapping,
     csp_mapping,
     lien_parente_mapping,
-    type_regime_mapping,
     regime_mapping,
+    situation_familiale_mapping,
+    type_regime_mapping,
     upperize,
 )
 from passerelle.utils.jsonresponse import APIError
 from passerelle.utils.soap import SOAPError
-import utils
 
 
 @pytest.fixture
 def resource(db):
     return utils.make_resource(
         ToulouseAxel, slug='test', wsdl_url='http://example.net/AXEL_WS/AxelWS.php?wsdl'
     )
 
diff --git a/tests/test_toulouse_axel_schema.py b/tests/test_toulouse_axel_schema.py
index fead4fae..b3a39316 100644
--- a/tests/test_toulouse_axel_schema.py
+++ b/tests/test_toulouse_axel_schema.py
@@ -11,21 +11,21 @@
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import os
 
-from passerelle.contrib.toulouse_axel.schemas import AxelSchema
-
 import pytest
 import xmlschema
 
+from passerelle.contrib.toulouse_axel.schemas import AxelSchema
+
 XSD_BASE_DIR = os.path.join(
     os.path.dirname(os.path.abspath(__file__)), '../passerelle/contrib/toulouse_axel/xsd'
 )
 
 
 @pytest.mark.parametrize('date_type', ['DATEREQUIREDType', 'DATEType'])
 def test_date_mapping(date_type):
     xsd = """<?xml version="1.0" encoding="utf-8" ?>
diff --git a/tests/test_toulouse_axel_utils.py b/tests/test_toulouse_axel_utils.py
index ffe87d66..a85b6da4 100644
--- a/tests/test_toulouse_axel_utils.py
+++ b/tests/test_toulouse_axel_utils.py
@@ -10,25 +10,26 @@
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import datetime
+
 import pytest
 
 from passerelle.contrib.toulouse_axel.utils import (
-    parse_datetime,
     encode_datetime,
     get_booking,
     get_reference_year_from_date,
     get_week_dates_from_date,
     json_date_format,
+    parse_datetime,
 )
 
 
 def test_parse_datetime():
     # wrong format
     assert parse_datetime('foo') is None
     assert parse_datetime('2019-12-12') is None
     assert parse_datetime('2019-12-12T12:01:72') is None
diff --git a/tests/test_utils_files.py b/tests/test_utils_files.py
index 294107c2..d9a5c877 100644
--- a/tests/test_utils_files.py
+++ b/tests/test_utils_files.py
@@ -10,19 +10,19 @@
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import os
 
+import pytest
 from django.core.files.storage import default_storage
 from django.utils.encoding import force_bytes
-import pytest
 
 from passerelle.utils.files import atomic_write
 
 
 def test_atomic_write(tmpdir):
     target_dir = tmpdir.mkdir('target')
     filepath = str(target_dir.join('test'))
 
diff --git a/tests/test_utils_json.py b/tests/test_utils_json.py
index 24a2d547..b408d4d3 100644
--- a/tests/test_utils_json.py
+++ b/tests/test_utils_json.py
@@ -24,21 +24,21 @@
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-import pytest
-
 import jsonschema
+import pytest
 
-from passerelle.utils.json import flatten, unflatten, flatten_json_schema, FLATTEN_SEPARATOR as SEP
+from passerelle.utils.json import FLATTEN_SEPARATOR as SEP
+from passerelle.utils.json import flatten, flatten_json_schema, unflatten
 
 
 def test_unflatten_base():
     assert unflatten('') == ''
     assert unflatten('a') == 'a'
     assert unflatten([]) == []
     assert unflatten([1]) == [1]
     assert unflatten({}) == {}
diff --git a/tests/test_utils_sftp.py b/tests/test_utils_sftp.py
index 7c80f8b8..2e860b4f 100644
--- a/tests/test_utils_sftp.py
+++ b/tests/test_utils_sftp.py
@@ -12,22 +12,21 @@
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import os
 
 import pytest
-
 from django.core.files.uploadedfile import SimpleUploadedFile
 from django.db import models
 from django.utils.encoding import force_text
 
-from passerelle.utils.sftp import SFTP, SFTPFormField, SFTPField
+from passerelle.utils.sftp import SFTP, SFTPField, SFTPFormField
 
 
 @pytest.fixture
 def ssh_key():
     with open(os.path.join(os.path.dirname(__file__), 'ssh_key'), 'rb') as fd:
         yield fd.read()
 
 
diff --git a/tests/test_utils_xml.py b/tests/test_utils_xml.py
index cdca4f01..87c18563 100644
--- a/tests/test_utils_xml.py
+++ b/tests/test_utils_xml.py
@@ -11,22 +11,21 @@
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import xml.etree.ElementTree as ET
 
-import xmlschema
-
 import jsonschema
+import xmlschema
 
-from passerelle.utils.xml import to_json, text_content, JSONSchemaFromXMLSchema
-from passerelle.utils.json import flatten_json_schema, flatten, unflatten
+from passerelle.utils.json import flatten, flatten_json_schema, unflatten
+from passerelle.utils.xml import JSONSchemaFromXMLSchema, text_content, to_json
 
 
 def test_text_content():
     root = ET.fromstring('<root>aa<b>bb</b>cc</root>')
     assert text_content(root) == 'aabbcc'
 
 
 def test_to_json():
diff --git a/tests/test_utils_zip.py b/tests/test_utils_zip.py
index 4e31441d..5176541d 100644
--- a/tests/test_utils_zip.py
+++ b/tests/test_utils_zip.py
@@ -22,18 +22,18 @@ import json
 import uuid
 import zipfile
 
 import pytest
 
 from passerelle.utils.zip import (
     ZipTemplate,
     ZipTemplateDoesNotExist,
-    ZipTemplateSyntaxError,
     ZipTemplateError,
+    ZipTemplateSyntaxError,
 )
 
 
 @pytest.fixture
 def templates_path(tmpdir, settings):
     path = tmpdir.mkdir('templates')
     settings.TEMPLATES = settings.TEMPLATES[:]
     settings.TEMPLATES[0] = settings.TEMPLATES[0].copy()
diff --git a/tests/test_vivaticket.py b/tests/test_vivaticket.py
index 26525f43..f93457c8 100644
--- a/tests/test_vivaticket.py
+++ b/tests/test_vivaticket.py
@@ -1,18 +1,16 @@
 # -*- coding: utf-8 -*-
 import mock
 import pytest
+import utils
 
 from passerelle.apps.vivaticket.models import VivaTicket
-
 from passerelle.utils.jsonresponse import APIError
 
-import utils
-
 ERROR_RESPONSE = """{
   "Message": "Une erreur s’est produite."
 }"""
 
 KEY_RESPONSE = """{
   "Key": "86569D0CA1B1CBEF8D77DD5BDC9F5CBAE5C99074",
   "ReturnCode": 0,
   "Error": null
diff --git a/tests/utils.py b/tests/utils.py
index 1c0f5a80..dc0be7be 100644
--- a/tests/utils.py
+++ b/tests/utils.py
@@ -1,18 +1,17 @@
 import json
 
-import mock
 import httmock
-
+import mock
 from django.contrib.contenttypes.models import ContentType
 from django.urls import reverse
 from django.utils.six.moves.urllib import parse as urlparse
 
-from passerelle.base.models import ApiUser, AccessRight
+from passerelle.base.models import AccessRight, ApiUser
 from passerelle.compat import json_loads
 
 
 def generic_endpoint_url(connector, endpoint, slug='test'):
     return reverse('generic-endpoint', kwargs={'connector': connector, 'slug': slug, 'endpoint': endpoint})
 
 
 def setup_access_rights(obj):
diff --git a/tests/wcs/conftest.py b/tests/wcs/conftest.py
index 41cfd6bb..8716906b 100644
--- a/tests/wcs/conftest.py
+++ b/tests/wcs/conftest.py
@@ -11,30 +11,30 @@
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 
-import pickle
-import sys
-import time
+import contextlib
 import os
-import shutil
+import pickle
 import random
+import shutil
 import socket
+import sys
 import tempfile
-import contextlib
+import time
 
-from django.utils.six.moves import configparser as ConfigParser
+import httmock
 import psycopg2
 import pytest
-import httmock
+from django.utils.six.moves import configparser as ConfigParser
 
 
 def find_free_tcp_port():
     with contextlib.closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s:
         s.bind(('', 0))
         s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
         return s.getsockname()[1]
 
@@ -328,18 +328,18 @@ class DefaultWcsHost(WcsHost):
     def wcs_init_01_setup_auth(self):
         from quixote import get_publisher
 
         get_publisher().cfg['identification'] = {'methods': ['password']}
         get_publisher().cfg['debug'] = {'display_exceptions': 'text'}
         get_publisher().write_cfg()
 
     def wcs_init_02_create_user(self):
-        from quixote import get_publisher
         from qommon.ident.password_accounts import PasswordAccount
+        from quixote import get_publisher
 
         pub = get_publisher()
         Role = pub.role_class
         User = pub.user_class
         user = User()
         user.name = 'foo bar'
         user.email = 'foo@example.net'
         user.store()
@@ -361,21 +361,22 @@ class DefaultWcsHost(WcsHost):
         account = PasswordAccount(id='admin')
         account.set_password('admin')
         account.user_id = user.id
         account.store()
 
     def wcs_init_03_create_data(self):
         import datetime
         import random
+
         from quixote import get_publisher
 
+        from wcs import fields
         from wcs.categories import Category
         from wcs.formdef import FormDef
-        from wcs import fields
 
         pub = get_publisher()
         Role = pub.role_class
         User = pub.user_class
         cat = Category()
         cat.name = 'Catégorie'
         cat.description = ''
         cat.store()
diff --git a/tests/wcs/test_conftest.py b/tests/wcs/test_conftest.py
index beb1739e..ec400f3d 100644
--- a/tests/wcs/test_conftest.py
+++ b/tests/wcs/test_conftest.py
@@ -11,19 +11,18 @@
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import pytest
-
-from django.utils.six.moves.urllib import parse as urlparse
 import requests
+from django.utils.six.moves.urllib import parse as urlparse
 
 
 def test_wcs_fixture(wcs_host):
     assert wcs_host.url.startswith('http://127.0.0.1:')
     requests.get(wcs_host.url)
     response = requests.get(urlparse.urljoin(wcs_host.url, '/api/categories/'))
     assert response.json()['data'][0]['title'] == u'Catégorie'
 
diff --git a/tests/wcs/test_sp_fr.py b/tests/wcs/test_sp_fr.py
index b35ed1b2..46d40673 100644
--- a/tests/wcs/test_sp_fr.py
+++ b/tests/wcs/test_sp_fr.py
@@ -10,25 +10,23 @@
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU Affero General Public License for more details.
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-import pytest
 import mock
+import pytest
+import utils
 
 from passerelle.apps.sp_fr.models import Resource
 from passerelle.utils.sftp import SFTP
-from passerelle.utils.wcs import get_wcs_choices, FormDefRef
-
-import utils
-
+from passerelle.utils.wcs import FormDefRef, get_wcs_choices
 
 DUMMY_CONTENT = {
     'DILA': {
         'a.zip': 'a',
     }
 }
 
 
-- 
2.30.2

