Welcome | Get started | Dive | Contribute | Topics | Reference | Changes | More
beid
: Belgian ID card holders¶
The lino_xl.lib.beid
plugin adds functionality for reading
Belgian eID cards and storing that data in the database.
Side note: Code snippets (lines starting with >>>
) in this document get
tested as part of our development workflow. The following
initialization snippet tells you which demo project is being used in
this document.
>>> import lino
>>> lino.startup('lino_book.projects.avanti1.settings')
>>> from lino.api.doctest import *
See also unit tests in lino_welfare.tests.test_beid
.
Introduction¶
Installing this package makes sense only if there is exactly one
subclass of the BeIdCardHolder
model mixin among your
application’s models. That model is referrable as
lino_xl.lib.beid.Plugin.holder_model
.
>>> dd.plugins.beid.holder_model
<class 'lino_avanti.lib.avanti.models.Client'>
See unit tests in lino_welfare.tests.test_beid
.
- class lino_xl.lib.beid.SSIN¶
A mixin that adds two fields
national_id
andnationality
.You can use this mixin also when the plugin is not installed.
Class attributes:
- validate_national_id = False
Whether to validate the
national_id
immediately before saving a record. If this is False, thenational_id
might contain invalid values which would later be reported as data problem messages.
- national_id¶
The SSIN. It is a nullable char field declared unique. It is not validated directly because that would cause problems with legacy data where SSINs need manual control. See also
BeIdCardHolderChecker
.
Database fields:
- nationality¶
The nationality. This is a pointer to
countries.Country
which should contain also entries for refugee statuses.Note that the nationality is not being read from eID card because it is stored there as a language and gender specific plain text.
- class lino_xl.lib.beid.BeIdCardHolder¶
Mixin for models which represent an eid card holder. Currently only Belgian eid cards are tested. Concrete subclasses must also inherit from
lino.mixins.Born
.Database fields:
- birth_country¶
- nationality_text¶
The nationality in plain text as it was on the eid card. For a French citizen the value on the eid card can be “Français”, “Française”, “Frans”, “Franzose”, “Französin”, “French” depending on the sex and the issuing municipality. This field is just informative, Lino does not automatically map it to the
nationality
field.
- birth_place¶
The birth place in plain text as it was on the eid card.
- card_number¶
- card_valid_from¶
- card_valid_until¶
- card_type¶
The type of id card.
Choices are defined in
BeIdCardTypes
- card_issuer¶
The administration who issued this ID card.
- noble_condition¶
The eventual noble condition of this person.
- read_beid()¶
Update card holder data from eID card
Read eId card and store the data on the selected holder.
This is a row action (called on a given holder).
When the selected holder has an empty national_id, and when there is no holder yet with that national_id in the database, then we want to update the existing holder from the card.
- find_by_beid()¶
Find or create card holder from eID card
Read an eID card, then either show the existing holder or ask to create a new holder.
This is a list action, usually called from a quicklink or a main menu item.
- image¶
Virtual field which displays the picture.
ID card types¶
>>> show_choicelist(beid.BeIdCardTypes)
======= ================== ======================================== ==================================================================================== ==============================================
value name en de fr
------- ------------------ ---------------------------------------- ------------------------------------------------------------------------------------ ----------------------------------------------
01 belgian_citizen Belgian citizen Belgischer Staatsbürger Citoyen belge
06 kids_card Kids card (< 12 year) Kind unter 12 Jahren Kids card (< 12 year)
11 foreigner_a Foreigner card A A (Bescheinigung der Eintragung im Ausländerregister - Vorübergehender Aufenthalt) Étranger A (Séjour temporaire)
12 foreigner_b Foreigner card B B (Bescheinigung der Eintragung im Ausländerregister) Foreigner card B
13 foreigner_c Foreigner card C C (Personalausweis für Ausländer) Foreigner card C
14 foreigner_d Foreigner card D D (Daueraufenthalt - EG) Foreigner card D
15 foreigner_e Foreigner card E E (Anmeldebescheinigung) Foreigner card E
16 foreigner_e_plus Foreigner card E+ E+ Foreigner card E+
17 foreigner_f Foreigner card F F (Aufenthaltskarte für Familienangehörige eines Unionsbürgers) Foreigner card F
18 foreigner_f_plus Foreigner card F+ F+ Foreigner card F+
99 orange_card Registration certificate (Orange card) Eintragungsbescheinigung (Orange Karte) Attestation d’immatriculation (Carte orange)
======= ================== ======================================== ==================================================================================== ==============================================
- class lino_xl.lib.beid.BeIdCardTypes¶
A list of Belgian identity card types.
We didn’t yet find any official reference document.
The eID applet returns a field documentType which contains a numeric code. For example 1 is for “Belgian citizen”, 6 for “Kids card”,…
The eID viewer, when saving a card as xml file, doesn’t save these values nowhere, it saves a string equivalent (1 becomes “belgian_citizen”, 6 becomes “kids_card”, 17 becomes “foreigner_f”, 16 becomes “foreigner_e_plus”,…
Sources:
[1] kuleuven.be
[2] The be.fedict.commons.eid.consumer.DocumentType enum.
Excerpts from [1]:
Johan: A document type of 7 is used for bootstrap cards – What is a bootstrap card (maybe some kind of test card?) Danny: A bootstrap card was an eID card that was used in the early start of the eID card introduction to bootstrap the computers at the administration. This type is no longer issued.
Johan: A document type of 8 is used for a “habilitation/machtigings” card – Is this for refugees or asylum seekers? Danny: A habilitation/machtigings card was aimed at civil servants. This type is also no longer used.
Residence types¶
>>> rt.show(beid.ResidenceTypes)
======= ====== ========================
value name text
------- ------ ------------------------
1 Register of citizens
2 Register of foreigners
3 Waiting register
======= ====== ========================
- class lino_xl.lib.beid.ResidenceTypes¶
The list of Belgian resident registers (Einwohnerregister, Registre de résidents).
https://en.wikipedia.org/wiki/Resident_registration
de
fr
nl
Bevölkerungsregister
Registre de la population
Bevolkingsregister
Fremdenregister
Registre des étrangers
Vreemdelingenregister
Warteregister
Registre d’attente
- class lino_xl.lib.beid.BeIdCardHolderChecker¶
Invalid NISSes are not refused à priori using a ValidationError (see
BeIdCardHolder.national_id
), but this checker reports them.Belgian NISSes are stored including the formatting characters (see
lino.utils.ssin
) in order to guarantee uniqueness.
Tests¶
The national_id
field of a client. It nullable and unique: it can be empty, but must
be empty when it isn’t.
>>> fld = rt.models.avanti.Client._meta.get_field('national_id')
>>> print(fld.help_text)
The SSIN. It is a nullable char field declared unique. It is not validated
directly because that would cause problems with legacy data where SSINs need
manual control. See also BeIdCardHolderChecker.
>>> print(fld.null)
True
>>> print(fld.unique)
True
>>> from lino_xl.lib.beid.views import read_card_data_from_file
>>> from pathlib import Path
>>> fn = "tests/beid/20190311.json"
>>> data = read_card_data_from_file(fn)
>>> print(data.success)
True
>>> print(data.issuing_municipality)
Charleroi
>>> img_file = Path(rt.models.avanti.Client.card_number_to_image_path(data.card_number))
>>> str(img_file).endswith("/beid/592400976752.jpg")
True
>>> img_dir = Path(settings.MEDIA_ROOT) / 'beid'
>>> str(img_file).startswith(str(img_dir))
True
>>> settings.SITE.makedirs_if_missing(img_dir)
>>> kwargs = rt.models.avanti.Client.find_by_beid.card2client(data)
>>> img_file.unlink()
>>> # img_dir.rmdir()
>>> fn = "tests/beid/nocard.json"
>>> data = read_card_data_from_file(fn)
Traceback (most recent call last):
...
Warning: No card data found: Could not find any reader with a card inserted
>>> # skip because under Python 2 it is another exception
>>> data = read_card_data_from_file("foo")
Traceback (most recent call last):
...
FileNotFoundError: [Errno 2] No such file or directory: 'foo'
- class lino_xl.lib.beid.SSINChecker¶
A data checker that reports invalid SSINs.