trivial: apply black (#49820)

wip/55285-opengis-pyproj-upgrading-to-pyproj-2
Frédéric Péters 2 years ago
parent 4540043a25
commit 3d9df1e526

@ -9,6 +9,6 @@ STATIC_ROOT = 'collected-static'
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'passerelle.sqlite3',
'NAME': 'passerelle.sqlite3',
}
}

34
debian/settings.py vendored

@ -12,12 +12,12 @@
# This file is sourced by "execfile" from /usr/lib/passerelle/debian_config.py
# SECURITY WARNING: don't run with debug turned on in production!
#DEBUG = False
# DEBUG = False
#ADMINS = (
# ADMINS = (
# ('User 1', 'poulpe@example.org'),
# ('User 2', 'janitor@example.net'),
#)
# )
# ALLOWED_HOSTS must be correct in production!
# See https://docs.djangoproject.com/en/dev/ref/settings/#allowed-hosts
@ -29,26 +29,26 @@ ALLOWED_HOSTS = ['*']
# Database
# Warning: don't change ENGINE, it must be 'tenant_schemas.postgresql_backend'
#DATABASES['default']['NAME'] = 'passerelle'
#DATABASES['default']['USER'] = 'passerelle'
#DATABASES['default']['PASSWORD'] = '******'
#DATABASES['default']['HOST'] = 'localhost'
#DATABASES['default']['PORT'] = '5432'
# DATABASES['default']['NAME'] = 'passerelle'
# DATABASES['default']['USER'] = 'passerelle'
# DATABASES['default']['PASSWORD'] = '******'
# DATABASES['default']['HOST'] = 'localhost'
# DATABASES['default']['PORT'] = '5432'
LANGUAGE_CODE = 'fr-fr'
TIME_ZONE = 'Europe/Paris'
# Email configuration
#EMAIL_SUBJECT_PREFIX = '[passerelle] '
#SERVER_EMAIL = 'root@passerelle.example.org'
#DEFAULT_FROM_EMAIL = 'webmaster@passerelle.example.org'
# EMAIL_SUBJECT_PREFIX = '[passerelle] '
# SERVER_EMAIL = 'root@passerelle.example.org'
# DEFAULT_FROM_EMAIL = 'webmaster@passerelle.example.org'
# SMTP configuration
#EMAIL_HOST = 'localhost'
#EMAIL_HOST_USER = ''
#EMAIL_HOST_PASSWORD = ''
#EMAIL_PORT = 25
# EMAIL_HOST = 'localhost'
# EMAIL_HOST_USER = ''
# EMAIL_HOST_PASSWORD = ''
# EMAIL_PORT = 25
# HTTPS
#CSRF_COOKIE_SECURE = True
#SESSION_COOKIE_SECURE = True
# CSRF_COOKIE_SECURE = True
# SESSION_COOKIE_SECURE = True

@ -9,15 +9,16 @@ def pytest_addoption(parser):
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")
parser.addoption("--preserve-tree", action="store_true", default=False, help="Preserve test directory")
@pytest.fixture(scope='session')
def cmisclient(request):
return cmislib.CmisClient(
request.config.getoption("--cmis-endpoint"), request.config.getoption("--cmis-username"),
request.config.getoption("--cmis-password"))
request.config.getoption("--cmis-endpoint"),
request.config.getoption("--cmis-username"),
request.config.getoption("--cmis-password"),
)
@pytest.fixture(scope='session')

@ -10,11 +10,16 @@ import requests
SPECIAL_CHARS = '!#$%&+-^_`;[]{}+='
@pytest.mark.parametrize("path,file_name", [
('', 'some.file'), ('/toto', 'some.file'), ('/toto/tata', 'some.file'),
('/toto', 'some.other'),
('/%s' % SPECIAL_CHARS, '%(spe)s.%(spe)s' % {'spe': SPECIAL_CHARS})
])
@pytest.mark.parametrize(
"path,file_name",
[
('', 'some.file'),
('/toto', 'some.file'),
('/toto/tata', 'some.file'),
('/toto', 'some.other'),
('/%s' % SPECIAL_CHARS, '%(spe)s.%(spe)s' % {'spe': SPECIAL_CHARS}),
],
)
def test_uploadfile(cmisclient, cmis_connector, cmis_tmpdir, tmpdir, monkeypatch, path, file_name):
result_filename = 'result.file'
monkeypatch.chdir(tmpdir)
@ -25,9 +30,12 @@ def test_uploadfile(cmisclient, cmis_connector, cmis_tmpdir, tmpdir, monkeypatch
with orig_file.open('rb') as f:
file_b64_content = base64.b64encode(f.read())
response = requests.post(
url, json={"path": cmis_tmpdir + path,
"file": {"content": file_b64_content, "filename": file_name,
"content_type": "image/jpeg"}})
url,
json={
"path": cmis_tmpdir + path,
"file": {"content": file_b64_content, "filename": file_name, "content_type": "image/jpeg"},
},
)
assert response.status_code == 200
resp_data = response.json()
assert resp_data['err'] == 0
@ -50,17 +58,23 @@ def test_uploadfile_conflict(cmisclient, cmis_connector, cmis_tmpdir, tmpdir, mo
url = urlparse.urljoin(cmis_connector, 'uploadfile')
file_b64_content = base64.b64encode('file_content')
response = requests.post(
url, json={"path": cmis_tmpdir + '/uploadconflict',
"file": {"content": file_b64_content, "filename": 'some.file',
"content_type": "image/jpeg"}})
url,
json={
"path": cmis_tmpdir + '/uploadconflict',
"file": {"content": file_b64_content, "filename": 'some.file', "content_type": "image/jpeg"},
},
)
assert response.status_code == 200
resp_data = response.json()
assert resp_data['err'] == 0
file_b64_content = base64.b64encode('other_file_content')
response = requests.post(
url, json={"path": cmis_tmpdir + '/uploadconflict',
"file": {"content": file_b64_content, "filename": 'some.file',
"content_type": "image/jpeg"}})
url,
json={
"path": cmis_tmpdir + '/uploadconflict',
"file": {"content": file_b64_content, "filename": 'some.file', "content_type": "image/jpeg"},
},
)
assert response.status_code == 200
resp_data = response.json()
assert resp_data['err'] == 1

@ -2,8 +2,7 @@ import pytest
def pytest_addoption(parser):
parser.addoption(
"--url", help="Url of a passerelle Planitech connector instance")
parser.addoption("--url", help="Url of a passerelle Planitech connector instance")
@pytest.fixture(scope='session')

@ -7,10 +7,9 @@ import requests
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'
})
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
resp = requests.get(url)
resp.raise_for_status()
@ -20,10 +19,9 @@ def test_main(conn):
assert data
# get places
query_string = parse.urlencode({
'start_days': 1, 'end_days': 90, 'start_time': '10:00', 'end_time': '11:00',
'display': 'place'
})
query_string = parse.urlencode(
{'start_days': 1, 'end_days': 90, 'start_time': '10:00', 'end_time': '11:00', 'display': 'place'}
)
url = conn + '/getfreegaps?%s' % query_string
resp = requests.get(url)
resp.raise_for_status()
@ -34,10 +32,16 @@ def test_main(conn):
place = data[random.randint(0, len(data) - 1)]['id']
# get days on one place
query_string = parse.urlencode({
'start_days': 1, 'end_days': 90, 'start_time': '10:00', 'end_time': '11:00',
'place_id': place, 'display': 'date'
})
query_string = parse.urlencode(
{
'start_days': 1,
'end_days': 90,
'start_time': '10:00',
'end_time': '11:00',
'place_id': place,
'display': 'date',
}
)
url = conn + '/getfreegaps?%s' % query_string
resp = requests.get(url)
resp.raise_for_status()
@ -55,10 +59,19 @@ def test_main(conn):
chosen_date = data[0]['id']
# create reservation
params = {
'date': chosen_date, 'start_time': '10:00', 'end_time': '11:00',
'place_id': place, 'price': 200, 'name_id': 'john-doe', 'type_id': resa_type_id,
'first_name': 'jon', 'last_name': 'doe', 'activity_id': activity_id,
'email': 'jon.doe@localhost', 'object': 'reservation object', 'vat_rate': 200
'date': chosen_date,
'start_time': '10:00',
'end_time': '11:00',
'place_id': place,
'price': 200,
'name_id': 'john-doe',
'type_id': resa_type_id,
'first_name': 'jon',
'last_name': 'doe',
'activity_id': activity_id,
'email': 'jon.doe@localhost',
'object': 'reservation object',
'vat_rate': 200,
}
print('Create reservation parameters \n')
pprint.pprint(params)
@ -76,9 +89,7 @@ def test_main(conn):
reservation_id = data['reservation_id']
# confirm reservation
params = {
'reservation_id': reservation_id, 'status': 'standard'
}
params = {'reservation_id': reservation_id, 'status': 'standard'}
url = conn + '/updatereservation'
resp = requests.post(url, json=params)
resp.raise_for_status()

@ -2,8 +2,7 @@ import pytest
def pytest_addoption(parser):
parser.addoption(
"--url", help="Url of a passerelle Toulouse Axel connector instance")
parser.addoption("--url", help="Url of a passerelle Toulouse Axel connector instance")
parser.addoption("--nameid", help="Publik Name ID")
parser.addoption("--firstname", help="first name of a user")
parser.addoption("--lastname", help="Last name of a user")

@ -45,19 +45,58 @@ def test_link(conn, user):
payload['DROITALIMAGE'] = 'NON'
payload['REVENUS']['CHOIXREVENU'] = ''
# remove non editable fields
for key in ['SITUATIONFAMILIALE', 'SITUATIONFAMILIALE_label', 'NBENFANTACTIF', 'NBRLACTIF', 'IDDUI', 'CODEMISEAJOUR',
'management_dates', 'annee_reference', 'annee_reference_label', 'annee_reference_short']:
for key in [
'SITUATIONFAMILIALE',
'SITUATIONFAMILIALE_label',
'NBENFANTACTIF',
'NBRLACTIF',
'IDDUI',
'CODEMISEAJOUR',
'management_dates',
'annee_reference',
'annee_reference_label',
'annee_reference_short',
]:
payload.pop(key)
for key in ['IDPERSONNE', 'NOM', 'PRENOM', 'NOMJEUNEFILLE', 'DATENAISSANCE', 'CIVILITE', 'INDICATEURRL', 'CSP_label']:
for key in [
'IDPERSONNE',
'NOM',
'PRENOM',
'NOMJEUNEFILLE',
'DATENAISSANCE',
'CIVILITE',
'INDICATEURRL',
'CSP_label',
]:
if 'RL1' in payload:
payload['RL1'].pop(key)
if 'RL2' in payload:
payload['RL2'].pop(key)
for key in ['MONTANTTOTAL', 'DATEVALIDITE', 'SFI', 'IREVENUS', 'RNF', 'NBENFANTSACHARGE', 'TYPEREGIME_label']:
for key in [
'MONTANTTOTAL',
'DATEVALIDITE',
'SFI',
'IREVENUS',
'RNF',
'NBENFANTSACHARGE',
'TYPEREGIME_label',
]:
payload['REVENUS'].pop(key, None)
for enfant in payload['ENFANT']:
for key in ['id', 'text', 'NOM', 'DATENAISSANCE', 'SEXE', 'PRENOMPERE', 'PRENOMMERE', 'NOMPERE', 'NOMMERE', 'RATTACHEAUTREDUI', 'PRENOM',
'clae_cantine_current']:
for key in [
'id',
'text',
'NOM',
'DATENAISSANCE',
'SEXE',
'PRENOMPERE',
'PRENOMMERE',
'NOMPERE',
'NOMMERE',
'RATTACHEAUTREDUI',
'PRENOM',
'clae_cantine_current',
]:
enfant.pop(key)
enfant['AUTORISATIONURGENCEMEDICALE'] = 'OUI'
# manage contact fields
@ -98,8 +137,10 @@ def test_link(conn, user):
# add partial update flags
flags = [
'maj:adresse',
'maj:rl1', 'maj:rl1_adresse_employeur',
'maj:rl2', 'maj:rl2_adresse_employeur',
'maj:rl1',
'maj:rl1_adresse_employeur',
'maj:rl2',
'maj:rl2_adresse_employeur',
'maj:revenus',
]
for i in range(0, 6):

@ -2,8 +2,7 @@ import pytest
def pytest_addoption(parser):
parser.addoption(
"--url", help="Url of a passerelle Vivaticket connector instance")
parser.addoption("--url", help="Url of a passerelle Vivaticket connector instance")
@pytest.fixture(scope='session')

@ -4,6 +4,7 @@ import datetime
import requests
import random
def call_generic(conn, endpoint):
print("%s \n" % endpoint)
url = conn + '/%s' % endpoint
@ -21,17 +22,24 @@ def call_generic(conn, endpoint):
def test_get_events(conn):
call_generic(conn, 'events')
def test_get_rooms(conn):
call_generic(conn, 'rooms')
def test_get_themes(conn):
call_generic(conn, 'themes')
def test_book_event(conn):
url = conn + '/book'
payload = {'id': 'formid', 'email': 'foo@example.com',
'datetime': datetime.datetime.now().strftime('%Y-%m-%dT%H:%M'),
'room': '001', 'theme': 'A0001', 'quantity': 1
payload = {
'id': 'formid',
'email': 'foo@example.com',
'datetime': datetime.datetime.now().strftime('%Y-%m-%dT%H:%M'),
'room': '001',
'theme': 'A0001',
'quantity': 1,
}
events = call_generic(conn, 'events')
random.shuffle(events)
@ -42,7 +50,7 @@ def test_book_event(conn):
themes = call_generic(conn, 'themes')
random.shuffle(themes)
payload['theme'] = themes[0]['id']
print("Creating booking with the following payload:\n%s" % payload)
print("Creating booking with the following payload:\n%s" % payload)
resp = requests.post(url, json=payload)
resp.raise_for_status()
res = resp.json()

@ -14,12 +14,38 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='ActesWeb',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
(
'id',
models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True),
),
('title', models.CharField(max_length=50, verbose_name='Title')),
('description', models.TextField(verbose_name='Description')),
('slug', models.SlugField(verbose_name='Identifier', unique=True)),
('log_level', models.CharField(default=b'INFO', max_length=10, verbose_name='Log Level', choices=[(b'NOTSET', b'NOTSET'), (b'DEBUG', b'DEBUG'), (b'INFO', b'INFO'), (b'WARNING', b'WARNING'), (b'ERROR', b'ERROR'), (b'CRITICAL', b'CRITICAL')])),
('users', models.ManyToManyField(to='base.ApiUser', related_name='_actesweb_users_+', related_query_name='+', blank=True)),
(
'log_level',
models.CharField(
default=b'INFO',
max_length=10,
verbose_name='Log Level',
choices=[
(b'NOTSET', b'NOTSET'),
(b'DEBUG', b'DEBUG'),
(b'INFO', b'INFO'),
(b'WARNING', b'WARNING'),
(b'ERROR', b'ERROR'),
(b'CRITICAL', b'CRITICAL'),
],
),
),
(
'users',
models.ManyToManyField(
to='base.ApiUser',
related_name='_actesweb_users_+',
related_query_name='+',
blank=True,
),
),
],
options={
'verbose_name': "ActesWeb - Demande d'acte d'\xe9tat civil",

@ -32,6 +32,8 @@ 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
@contextlib.contextmanager
def named_tempfile(*args, **kwargs):
with tempfile.NamedTemporaryFile(*args, **kwargs) as fp:
@ -46,8 +48,7 @@ class ActesWeb(BaseResource):
@property
def basepath(self):
return os.path.join(
default_storage.path('actesweb'), self.slug)
return os.path.join(default_storage.path('actesweb'), self.slug)
@endpoint(perm='can_access', methods=['post'], description=_('Create demand'))
def create(self, request, *args, **kwargs):
@ -88,6 +89,6 @@ class ActesWeb(BaseResource):
tempfile_name = tpf.name
os.rename(tempfile_name, filepath)
# set read only permission for owner and group
os.chmod(filepath, stat.S_IRUSR|stat.S_IRGRP|stat.S_IWGRP)
os.chmod(filepath, stat.S_IRUSR | stat.S_IRGRP | stat.S_IWGRP)
demand_id = '%s_%s' % (application_id, os.path.basename(filepath))
return {'data': {'demand_id': demand_id}}

@ -14,12 +14,38 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='AirQuality',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
(
'id',
models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True),
),
('title', models.CharField(verbose_name='Title', max_length=50)),
('slug', models.SlugField(verbose_name='Identifier', unique=True)),
('description', models.TextField(verbose_name='Description')),
('log_level', models.CharField(default=b'INFO', max_length=10, verbose_name='Log Level', choices=[(b'NOTSET', b'NOTSET'), (b'DEBUG', b'DEBUG'), (b'INFO', b'INFO'), (b'WARNING', b'WARNING'), (b'ERROR', b'ERROR'), (b'CRITICAL', b'CRITICAL')])),
('users', models.ManyToManyField(to='base.ApiUser', related_name='_airquality_users_+', related_query_name='+', blank=True)),
(
'log_level',
models.CharField(
default=b'INFO',
max_length=10,
verbose_name='Log Level',
choices=[
(b'NOTSET', b'NOTSET'),
(b'DEBUG', b'DEBUG'),
(b'INFO', b'INFO'),
(b'WARNING', b'WARNING'),
(b'ERROR', b'ERROR'),
(b'CRITICAL', b'CRITICAL'),
],
),
),
(
'users',
models.ManyToManyField(
to='base.ApiUser',
related_name='_airquality_users_+',
related_query_name='+',
blank=True,
),
),
],
options={
'verbose_name': 'Air Quality',

@ -28,24 +28,28 @@ from passerelle.utils.jsonresponse import APIError
class AirQuality(BaseResource):
category = _('Misc')
api_description = _(u'''
api_description = _(
u'''
This API provides a unique format for the air quality data of various places.
(But only supports the Rhône-Alpes region for now).
''')
'''
)
atmo_aura_api_token = models.CharField(max_length=100,
verbose_name=_('ATMO AURA API token'),
blank=True, null=True)
atmo_aura_api_token = models.CharField(
max_length=100, verbose_name=_('ATMO AURA API token'), blank=True, null=True
)
class Meta:
verbose_name = _('Air Quality')
@endpoint(pattern='^(?P<country>\w+)/(?P<city>\w+)/$',
example_pattern='{country}/{city}/',
parameters={
'country': {'description': _('Country Code'), 'example_value': 'fr'},
'city': {'description': _('City Name'), 'example_value': 'lyon'},
})
@endpoint(
pattern='^(?P<country>\w+)/(?P<city>\w+)/$',
example_pattern='{country}/{city}/',
parameters={
'country': {'description': _('Country Code'), 'example_value': 'fr'},
'city': {'description': _('City Name'), 'example_value': 'lyon'},
},
)
def details(self, request, country, city, **kwargs):
methods = {
('fr', 'albertville'): 'air_rhonealpes',
@ -82,7 +86,8 @@ class AirQuality(BaseResource):
'vienne': '38544',
}
insee_code = insee_codes.get(city.lower())
response = self.requests.get('https://api.atmo-aura.fr/communes/%s/indices' % insee_code,
response = self.requests.get(
'https://api.atmo-aura.fr/communes/%s/indices' % insee_code,
params={'api_token': self.atmo_aura_api_token},
)
json_response = response.json()
@ -106,12 +111,13 @@ class AirQuality(BaseResource):
break
if 'latest' in response_data:
comment_response = self.requests.get('https://api.atmo-aura.fr/commentaire',
params={
'date': response_data['latest']['date'],
'api_token': self.atmo_aura_api_token,
}
)
comment_response = self.requests.get(
'https://api.atmo-aura.fr/commentaire',
params={
'date': response_data['latest']['date'],
'api_token': self.atmo_aura_api_token,
},
)
if comment_response.ok:
response_data['comment'] = comment_response.json().get('commentaire')

@ -17,13 +17,29 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='APIEntreprise',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
(
'id',
models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
),
('title', models.CharField(max_length=50, verbose_name='Title')),
('description', models.TextField(verbose_name='Description')),
('slug', models.SlugField(unique=True, verbose_name='Identifier')),
('url', models.URLField(default=b'https://entreprise.api.gouv.fr/v2/', max_length=256, verbose_name='API URL')),
(
'url',
models.URLField(
default=b'https://entreprise.api.gouv.fr/v2/', max_length=256, verbose_name='API URL'
),
),
('token', models.CharField(max_length=1024, verbose_name='API token')),
('users', models.ManyToManyField(blank=True, related_name='_apientreprise_users_+', related_query_name='+', to='base.ApiUser')),
(
'users',
models.ManyToManyField(
blank=True,
related_name='_apientreprise_users_+',
related_query_name='+',
to='base.ApiUser',
),
),
],
options={
'verbose_name': 'API Entreprise',

@ -15,8 +15,8 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='apientreprise',
name='recipient',
field=models.CharField(default='', max_length=1024, verbose_name='Recipient',
help_text='default value'
field=models.CharField(
default='', max_length=1024, verbose_name='Recipient', help_text='default value'
),
preserve_default=False,
),

@ -69,7 +69,7 @@ def normalize_results(data):
if tstamp > 0:
try:
aware_date = make_aware(datetime.fromtimestamp(int(data[key])))
timestamp_to_datetime[key[:-len('timestamp')] + 'datetime'] = aware_date
timestamp_to_datetime[key[: -len('timestamp')] + 'datetime'] = aware_date
except (ValueError, TypeError):
pass
# add converted timestamps to initial data
@ -81,8 +81,9 @@ class APIEntreprise(BaseResource):
url = models.URLField(_('API URL'), max_length=256, default='https://entreprise.api.gouv.fr/v2/')
token = models.CharField(max_length=1024, verbose_name=_('API token'))
recipient = models.CharField(max_length=1024, verbose_name=_('Recipient'), blank=False,
help_text=_('default value'))
recipient = models.CharField(
max_length=1024, verbose_name=_('Recipient'), blank=False, help_text=_('default value')
)
category = _('Business Process Connectors')
@ -102,20 +103,20 @@ class APIEntreprise(BaseResource):
try:
response = self.requests.get(url, data=params, cache_duration=300)
except requests.RequestException as e:
raise APIError(u'API-entreprise connection error: %s' %
exception_to_text(e), data=[])
raise APIError(u'API-entreprise connection error: %s' % exception_to_text(e), data=[])
try:
data = response.json()
except ValueError as e:
content = response.text[:1000]
raise APIError(
u'API-entreprise returned non-JSON content with status %s: %s' %
(response.status_code, content),
u'API-entreprise returned non-JSON content with status %s: %s'
% (response.status_code, content),
data={
'status_code': response.status_code,
'exception': exception_to_text(e),
'content': content,
})
},
)
if response.status_code != 200:
if data.get('error') == 'not_found':
return {
@ -123,12 +124,12 @@ class APIEntreprise(BaseResource):
'err_desc': data.get('message', 'not-found'),
}
raise APIError(
u'API-entreprise returned a non 200 status %s: %s' %
(response.status_code, data),
u'API-entreprise returned a non 200 status %s: %s' % (response.status_code, data),
data={
'status_code': response.status_code,
'content': data,
})
},
)
normalize_results(data)
return {
'err': 0,
@ -138,13 +139,10 @@ class APIEntreprise(BaseResource):
# description of common endpoint parameters
ASSOCIATION_PARAM = {
'description': _('association SIREN or RNA/WALDEC number'),
'example_value': '44317013900036'
'example_value': '44317013900036',
}
CONTEXT_PARAM = {
'description': _('request context: MPS, APS...'),
'example_value': 'APS'
}
CONTEXT_PARAM = {'description': _('request context: MPS, APS...'), 'example_value': 'APS'}
MONTH_PARAM = {
'description': _('requested month'),
@ -153,12 +151,12 @@ class APIEntreprise(BaseResource):
OBJECT_PARAM = {
'description': _('request object: form number, file identifier...'),
'example_value': '42'
'example_value': '42',
}
RECIPIENT_PARAM = {
'description': _('request recipient: usually customer number'),
'example_value': '44317013900036'
'example_value': '44317013900036',
}
SIREN_PARAM = {
@ -166,26 +164,25 @@ class APIEntreprise(BaseResource):
'example_value': '443170139',
}
SIRET_PARAM = {
'description': _('firms SIRET number'),
'example_value': '44317013900036'
}
SIRET_PARAM = {'description': _('firms SIRET number'), 'example_value': '44317013900036'}
YEAR_PARAM = {
'description': _('requested year'),
'example_value': '2019',
}
@endpoint(perm='can_access',
pattern=r'(?P<association_id>\w+)/$',
example_pattern='{association_id}/',
description=_('Get association\'s documents'),
parameters={
'association_id': ASSOCIATION_PARAM,
'object': OBJECT_PARAM,
'context': CONTEXT_PARAM,
'recipient': RECIPIENT_PARAM
})
@endpoint(
perm='can_access',
pattern=r'(?P<association_id>\w+)/$',
example_pattern='{association_id}/',
description=_('Get association\'s documents'),
parameters={
'association_id': ASSOCIATION_PARAM,
'object': OBJECT_PARAM,
'context': CONTEXT_PARAM,
'recipient': RECIPIENT_PARAM,
},
)
def documents_associations(self, request, association_id, **kwargs):
data = []
resp = self.get('documents_associations/%s/' % association_id, **kwargs)
@ -193,19 +190,24 @@ class APIEntreprise(BaseResource):
# ignore documents with no type
if not item.get('type'):
continue
signature_elements = {'url': item['url'],
'context': kwargs['context'],
'object': kwargs['object'],
'recipient': kwargs['recipient']}
signature_elements = {
'url': item['url'],
'context': kwargs['context'],
'object': kwargs['object'],
'recipient': kwargs['recipient'],
}
signature = signing.dumps(signature_elements)
document_url = request.build_absolute_uri(
reverse('generic-endpoint',
kwargs={
'connector': self.get_connector_slug(),
'slug': self.slug,
'endpoint': 'document',
'rest': '%s/%s/' % (association_id, signature),
}))
reverse(
'generic-endpoint',
kwargs={
'connector': self.get_connector_slug(),
'slug': self.slug,
'endpoint': 'document',
'rest': '%s/%s/' % (association_id, signature),
},
)
)
item['id'] = item['timestamp']
item['text'] = item['type']
item['url'] = document_url
@ -214,19 +216,21 @@ class APIEntreprise(BaseResource):
data.sort(key=lambda i: i['id'])
return {'err': 0, 'data': data}
@endpoint(pattern=r'(?P<association_id>\w+)/(?P<document_id>[\:\w-]+)/$',
example_pattern='{association_id}/{document_id}/',
description=_('Get association\'s document'),
parameters={
'association_id': ASSOCIATION_PARAM,
'document_id': {
'description': _('document id'),
'example_value': 'A1500660325',
},
'object': OBJECT_PARAM,
'context': CONTEXT_PARAM,
'recipient': RECIPIENT_PARAM,
})
@endpoint(
pattern=r'(?P<association_id>\w+)/(?P<document_id>[\:\w-]+)/$',
example_pattern='{association_id}/{document_id}/',
description=_('Get association\'s document'),
parameters={
'association_id': ASSOCIATION_PARAM,
'document_id': {
'description': _('document id'),
'example_value': 'A1500660325',
},
'object': OBJECT_PARAM,
'context': CONTEXT_PARAM,
'recipient': RECIPIENT_PARAM,
},
)
def document(self, request, association_id, document_id, **kwargs):
try:
params = signing.loads(document_id, max_age=DOCUMENT_SIGNATURE_MAX_AGE)
@ -237,20 +241,22 @@ class APIEntreprise(BaseResource):
return HttpResponse(response, content_type='application/pdf')
raise Http404('document not found')
@endpoint(name='document_association',
pattern=r'(?P<association_id>\w+)/get-last/$',
example_pattern='{association_id}/get-last/',
description=_('Get association\'s last document of type'),
parameters={
'association_id': ASSOCIATION_PARAM,
'document_type': {
'description': _('document type'),
'example_value': 'Statuts',
},
'object': OBJECT_PARAM,
'context': CONTEXT_PARAM,
'recipient': RECIPIENT_PARAM,
})
@endpoint(
name='document_association',
pattern=r'(?P<association_id>\w+)/get-last/$',
example_pattern='{association_id}/get-last/',
description=_('Get association\'s last document of type'),
parameters={
'association_id': ASSOCIATION_PARAM,
'document_type': {
'description': _('document type'),
'example_value': 'Statuts',
},
'object': OBJECT_PARAM,
'context': CONTEXT_PARAM,
'recipient': RECIPIENT_PARAM,
},
)
def get_last_document_of_type(self, request, association_id, document_type, **kwargs):
document = None
resp = self.get('documents_associations/%s/' % association_id, **kwargs)
@ -260,46 +266,49 @@ class APIEntreprise(BaseResource):
document = documents[-1]
return {'data': document}
@endpoint(perm='can_access',
pattern=r'(?P<siren>\w+)/$',
example_pattern='{siren}/',
description=_('Get firm\'s data from Infogreffe'),
parameters={
'siren': SIREN_PARAM,
'object': OBJECT_PARAM,
'context': CONTEXT_PARAM,
'recipient': RECIPIENT_PARAM,
})
@endpoint(
perm='can_access',
pattern=r'(?P<siren>\w+)/$',
example_pattern='{siren}/',
description=_('Get firm\'s data from Infogreffe'),
parameters={
'siren': SIREN_PARAM,
'object': OBJECT_PARAM,
'context': CONTEXT_PARAM,
'recipient': RECIPIENT_PARAM,
},
)
def extraits_rcs(self, request, siren, **kwargs):
return self.get('extraits_rcs_infogreffe/%s/' % siren, **kwargs)
@endpoint(perm='can_access',
pattern=r'(?P<association_id>\w+)/$',
example_pattern='{association_id}/',
description=_('Get association\'s related informations'),
parameters={
'association_id': ASSOCIATION_PARAM,
'object': OBJECT_PARAM,
'context': CONTEXT_PARAM,
'recipient': RECIPIENT_PARAM,
})
@endpoint(
perm='can_access',
pattern=r'(?P<association_id>\w+)/$',
example_pattern='{association_id}/',
description=_('Get association\'s related informations'),
parameters={
'association_id': ASSOCIATION_PARAM,
'object': OBJECT_PARAM,
'context': CONTEXT_PARAM,
'recipient': RECIPIENT_PARAM,
},
)
def associations(self, request, association_id, **kwargs):
return self.get('associations/%s/' % association_id, **kwargs)
@endpoint(perm='can_access',
pattern=r'(?P<siren>\w+)/$',
example_pattern='{siren}/',
description=_('Get firm\'s related informations'),
parameters={
'siren': SIREN_PARAM,
'object': OBJECT_PARAM,
'context': CONTEXT_PARAM,
'recipient': RECIPIENT_PARAM,
'include_private': {
'description': _('Include private informations'),
'example_value': 'true'
}
})
@endpoint(
perm='can_access',
pattern=r'(?P<siren>\w+)/$',
example_pattern='{siren}/',
description=_('Get firm\'s related informations'),
parameters={
'siren': SIREN_PARAM,
'object': OBJECT_PARAM,
'context': CONTEXT_PARAM,
'recipient': RECIPIENT_PARAM,
'include_private': {'description': _('Include private informations'), 'example_value': 'true'},
},
)
def entreprises(self, request, siren, include_private=False, **kwargs):
if len(siren) != 9:
raise APIError(_('invalid SIREN length (must be 9 characters)'))
@ -307,60 +316,68 @@ class APIEntreprise(BaseResource):
kwargs['non_diffusables'] = True
return self.get('entreprises/%s/' % siren, **kwargs)
@endpoint(perm='can_access',
methods=['get'],
pattern=r'(?P<siret>\w+)/$',
example_pattern='{siret}/',
description_get=_('Get firms\'s related informations'),
parameters={
'siret': SIRET_PARAM,
'object': OBJECT_PARAM,
'context': CONTEXT_PARAM,
'recipient': RECIPIENT_PARAM,
})
@endpoint(
perm='can_access',
methods=['get'],
pattern=r'(?P<siret>\w+)/$',
example_pattern='{siret}/',
description_get=_('Get firms\'s related informations'),
parameters={
'siret': SIRET_PARAM,
'object': OBJECT_PARAM,
'context': CONTEXT_PARAM,
'recipient': RECIPIENT_PARAM,
},
)
def etablissements(self, request, siret, **kwargs):
return self.get('etablissements/%s/' % siret, **kwargs)
@endpoint(perm='can_access',
methods=['get'],
pattern=r'(?P<siret>\w+)/$',
example_pattern='{siret}/',
description_get=_('Get firms\'s financial year informations'),
parameters={
'siret': SIRET_PARAM,
'object': OBJECT_PARAM,
'context': CONTEXT_PARAM,
'recipient': RECIPIENT_PARAM,
})
@endpoint(
perm='can_access',
methods=['get'],
pattern=r'(?P<siret>\w+)/$',
example_pattern='{siret}/',
description_get=_('Get firms\'s financial year informations'),
parameters={
'siret': SIRET_PARAM,
'object': OBJECT_PARAM,
'context': CONTEXT_PARAM,
'recipient': RECIPIENT_PARAM,
},
)
def exercices(self, request, siret, **kwargs):
return self.get('exercices/%s/' % siret, **kwargs)
@endpoint(perm='can_access',
pattern=r'(?P<siren>\w+)/$',
example_pattern='{siren}/',
description=_('Get firm\'s annual workforce data'),
parameters={
'siren': SIREN_PARAM,
'object': OBJECT_PARAM,
'context': CONTEXT_PARAM,
'recipient': RECIPIENT_PARAM,
})
@endpoint(
perm='can_access',
pattern=r'(?P<siren>\w+)/$',
example_pattern='{siren}/',
description=_('Get firm\'s annual workforce data'),
parameters={
'siren': SIREN_PARAM,
'object': OBJECT_PARAM,
'context': CONTEXT_PARAM,
'recipient': RECIPIENT_PARAM,
},
)
def effectifs_annuels_acoss_covid(self, request, siren, **kwargs):
if len(siren) != 9:
raise APIError(_('invalid SIREN length (must be 9 characters)'))
return self.get('effectifs_annuels_acoss_covid/%s/' % siren, **kwargs)
@endpoint(perm='can_access',
pattern=r'(?P<year>\w+)/(?P<month>\w+)/(?P<siren>\w+)/$',
description=_('Get firm\'s monthly workforce data, by SIREN'),
parameters={
'year': YEAR_PARAM,
'month': MONTH_PARAM,
'siren': SIREN_PARAM,
'object': OBJECT_PARAM,
'context': CONTEXT_PARAM,
'recipient': RECIPIENT_PARAM,
})
@endpoint(
perm='can_access',
pattern=r'(?P<year>\w+)/(?P<month>\w+)/(?P<siren>\w+)/$',
description=_('Get firm\'s monthly workforce data, by SIREN'),
parameters={
'year': YEAR_PARAM,
'month': MONTH_PARAM,
'siren': SIREN_PARAM,
'object': OBJECT_PARAM,
'context': CONTEXT_PARAM,
'recipient': RECIPIENT_PARAM,
},
)
def entreprise_effectifs_mensuels_acoss_covid(self, request, year, month, siren, **kwargs):
if len(siren) != 9:
raise APIError(_('invalid SIREN length (must be 9 characters)'))
@ -369,17 +386,19 @@ class APIEntreprise(BaseResource):
'effectifs_mensuels_acoss_covid/%s/%s/entreprise/%s/' % (year, month, siren), **kwargs
)
@endpoint(perm='can_access',
pattern=r'(?P<year>\w+)/(?P<month>\w+)/(?P<siret>\w+)/$',
description=_('Get firm\'s monthly workforce data, by SIRET'),
parameters={
'year': YEAR_PARAM,
'month': MONTH_PARAM,
'siret': SIRET_PARAM,
'object': OBJECT_PARAM,
'context': CONTEXT_PARAM,
'recipient': RECIPIENT_PARAM,
})
@endpoint(
perm='can_access',
pattern=r'(?P<year>\w+)/(?P<month>\w+)/(?P<siret>\w+)/$',
description=_('Get firm\'s monthly workforce data, by SIRET'),
parameters={
'year': YEAR_PARAM,
'month': MONTH_PARAM,
'siret': SIRET_PARAM,
'object': OBJECT_PARAM,
'context': CONTEXT_PARAM,
'recipient': RECIPIENT_PARAM,
},
)
def etablissement_effectifs_mensuels_acoss_covid(self, request, year, month, siret, **kwargs):
month = month.zfill(2)
return self.get(

@ -29,7 +29,7 @@ KNOWN_ERRORS = {
'Il existe au moins un enfant pour lequel il existe un droit sur le dossier et/ou à la période demandée',
'Il existe des droits pour la prestation sélectionnée sur le dossier et/ou la période demandée',
'Il existe des droits pour la prestation sélectionnée sur le dossier et/ou la période demandée (après date du jour)',
'Lopérateurs téléphonique» ne propose pas de raccordement SMS avec un prestataire externe (raccordement avec un numéro court). '
'Lopérateurs téléphonique» ne propose pas de raccordement SMS avec un prestataire externe (raccordement avec un numéro court). ',
},
500: {
'Les informations souhaitées sont momentanément indisponibles. Merci de renouveler votre demande ultérieurement.',
@ -42,6 +42,6 @@ KNOWN_ERRORS = {
"Votre demande n'a pu aboutir en raison d'un incident technique momentané. Merci de renouveler votre demande ultérieurement.",
"Votre demande n'a pu aboutir en raison d'une erreur fonctionnelle lié à l'appel au service IMC.",
"Votre demande n'a pu aboutir en raison d'une erreur technique lié à l'appel au service IMC.",
"Votre demande na pu aboutir en raison d'un problème technique lié aux données entrantes du webservice. Merci de renouveler votre demande ultérieurement."
}
"Votre demande na pu aboutir en raison d'un problème technique lié aux données entrantes du webservice. Merci de renouveler votre demande ultérieurement.",
},
}

@ -14,14 +14,50 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='APIParticulier',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
(
'id',
models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True),
),
('title', models.CharField(max_length=50, verbose_name='Title')),
('slug', models.SlugField(verbose_name='Identifier', unique=True)),
('description', models.TextField(verbose_name='Description')),
('log_level', models.CharField(default=b'NOTSET', max_length=10, verbose_name='Log Level', choices=[(b'NOTSET', b'NOTSET'), (b'DEBUG', b'DEBUG'), (b'INFO', b'INFO'), (b'WARNING', b'WARNING'), (b'ERROR', b'ERROR'), (b'CRITICAL', b'CRITICAL')])),
('_platform', models.CharField(choices=[(b'prod', 'Production'), (b'test', 'Test')], max_length=8, verbose_name='Platform')),
('_api_key', models.CharField(default=b'', max_length=64, verbose_name='API key', blank=True)),
('users', models.ManyToManyField(to='base.ApiUser', related_name='_apiparticulier_users_+', related_query_name='+', blank=True)),
(
'log_level',
models.CharField(
default=b'NOTSET',
max_length=10,
verbose_name='Log Level',
choices=[
(b'NOTSET', b'NOTSET'),
(b'DEBUG', b'DEBUG'),
(b'INFO', b'INFO'),
(b'WARNING', b'WARNING'),
(b'ERROR', b'ERROR'),
(b'CRITICAL', b'CRITICAL'),
],
),
),
(
'_platform',
models.CharField(
choices=[(b'prod', 'Production'), (b'test', 'Test')],
max_length=8,
verbose_name='Platform',
),
),
(
'_api_key',
models.CharField(default=b'', max_length=64, verbose_name='API key', blank=True),
),
(
'users',
models.ManyToManyField(
to='base.ApiUser',
related_name='_apiparticulier_users_+',
related_query_name='+',
blank=True,
),
),
],
options={
'abstract': False,

@ -42,11 +42,7 @@ from .known_errors import KNOWN_ERRORS
class APIParticulier(BaseResource):
PLATFORMS = [
{
'name': 'prod',
'label': _('Production'),
'url': 'https://particulier.api.gouv.fr/api/'
},
{'name': 'prod', 'label': _('Production'), 'url': 'https://particulier.api.gouv.fr/api/'},
{
'name': 'test',
'label': _('Test'),
@ -58,13 +54,10 @@ class APIParticulier(BaseResource):
platform = models.CharField(
verbose_name=_('Platform'),
max_length=8,
choices=[(key, platform['label']) for key, platform in PLATFORMS.items()])
choices=[(key, platform['label']) for key, platform in PLATFORMS.items()],
)
api_key = models.CharField(
max_length=256,
default='',
blank=True,