diff --git a/ippisite/ippidb/models.py b/ippisite/ippidb/models.py
index 41d9fcfe7c4d7fd3d1e7885ee478bbb100508ab0..7358a3cd45761d861a60f19dddc0c6f9416bb211 100644
--- a/ippisite/ippidb/models.py
+++ b/ippisite/ippidb/models.py
@@ -37,9 +37,9 @@ class AutoFillableModel(models.Model):
 
 
 class Bibliography(AutoFillableModel):
-
     """
-    Bibliography data table
+    Bibliography references
+    (publications or patents)
     """
     SOURCES = (
         ('PM', 'PubMed ID'),
@@ -63,6 +63,10 @@ class Bibliography(AutoFillableModel):
     xray = models.BooleanField('X-Ray data', default=False)
 
     def autofill(self):
+        """
+        fetch information from external services
+        (Pubmed or Google patents)
+        """
         if self.source == 'PM':
             info = get_pubmed_info(self.id_source)
         else:
@@ -80,11 +84,19 @@ class Bibliography(AutoFillableModel):
 
 
 class Taxonomy(AutoFillableModel):
+    """
+    Taxonomy IDs (from NCBI Taxonomy) 
+    and the corresponding human-readable name
+    """
     taxonomy_id = models.DecimalField(
         'NCBI TaxID', unique=True, max_digits=9, decimal_places=0)
     name = models.CharField('Organism name', max_length=200)
 
     def autofill(self):
+        """
+        fetch information from external services
+        (NCBI Entrez)
+        """
         info = get_taxonomy_info(self.taxonomy_id)
         self.name = info['scientific_name']
 
@@ -96,11 +108,19 @@ class Taxonomy(AutoFillableModel):
 
 
 class MolecularFunction(AutoFillableModel):
+    """
+    Molecular functions (from Gene Ontology) 
+    and the corresponding human-readable description
+    """
     go_id = models.CharField('Gene Ontology ID', unique=True, max_length=10)
     # GO term id format: 'GO:0000000'
     description = models.CharField('description', max_length=500)
 
     def autofill(self):
+        """
+        fetch information from external services
+        (EBI OLS)
+        """
         info = get_go_info(self.go_id)
         self.description = info['label']
 
@@ -113,6 +133,10 @@ class MolecularFunction(AutoFillableModel):
 
 
 class Protein(AutoFillableModel):
+    """
+    Protein information (from Uniprot) 
+    and the corresponding human-readable name
+    """
     uniprot_id = models.CharField('Uniprot ID', unique=True, max_length=10)
     recommended_name_long = models.CharField(
         'Uniprot Recommended Name (long)', max_length=75)
@@ -123,6 +147,10 @@ class Protein(AutoFillableModel):
     molecular_functions = models.ManyToManyField(MolecularFunction)
 
     def autofill(self):
+        """
+        fetch information from external services
+        (Uniprot) and create Taxonomy/Molecular Functions if needed
+        """
         info = get_uniprot_info(self.uniprot_id)
         self.recommended_name_long = info['recommended_name']
         self.gene_name = info['gene']
@@ -150,6 +178,9 @@ class Protein(AutoFillableModel):
 
 
 class Domain(AutoFillableModel):
+    """
+    Domain (i.e. Protein domain) information (from PFAM) 
+    """
     pfam_acc = models.CharField('Pfam Accession', max_length=10, unique=True)
     pfam_id = models.CharField('Pfam Family Identifier', max_length=20)
     pfam_description = models.CharField('Pfam Description', max_length=100)
@@ -158,6 +189,10 @@ class Domain(AutoFillableModel):
     # contents
 
     def autofill(self):
+        """
+        fetch information from external services
+        (PFAM)
+        """
         info = get_pfam_info(self.pfam_acc)
         self.pfam_id = info['id']
         self.pfam_description = info['description']
@@ -171,6 +206,9 @@ class Domain(AutoFillableModel):
 
 
 class ProteinDomainComplex(models.Model):
+    """
+    Protein-Domain association 
+    """
     protein = models.ForeignKey('Protein', models.CASCADE)
     domain = models.ForeignKey('Domain', models.CASCADE)
     ppc_copy_nb = models.IntegerField(
@@ -187,6 +225,9 @@ class ProteinDomainComplex(models.Model):
 
 
 class ProteinDomainBoundComplex(ProteinDomainComplex):
+    """
+    Protein-Domain association with a "bound complex" role
+    """
     ppp_copy_nb_per_p = models.IntegerField(
         'Number of copies of the protein in the pocket')
 
@@ -195,12 +236,18 @@ class ProteinDomainBoundComplex(ProteinDomainComplex):
 
 
 class ProteinDomainPartnerComplex(ProteinDomainComplex):
+    """
+    Protein-Domain association with a "partner complex" role
+    """
 
     class Meta:
         verbose_name_plural = "partner complexes"
 
 
 class Symmetry(models.Model):
+    """
+    Symmetry of a PPI
+    """
     code = models.CharField('Symmetry code', max_length=2)
     description = models.CharField('Description', max_length=300)
 
@@ -219,6 +266,9 @@ class Disease(models.Model):
         return self.name
 
 class PpiFamily(models.Model):
+    """
+    PPI Family
+    """
     name = models.CharField('Name', max_length=30, unique=True)
 
     class Meta:
@@ -229,6 +279,9 @@ class PpiFamily(models.Model):
 
 
 class Ppi(AutoFillableModel):
+    """
+    PPI
+    """
     pdb_id = models.CharField('PDB ID', max_length=4, null=True, blank=True)
     pockets_nb = models.IntegerField(
         'Total number of pockets in the complex', default=1)
@@ -266,6 +319,9 @@ class Ppi(AutoFillableModel):
 
 
 class PpiComplex(models.Model):
+    """
+    PPI Complex
+    """
     ppi = models.ForeignKey(Ppi, models.CASCADE)
     complex = models.ForeignKey(ProteinDomainComplex, models.CASCADE)
     cc_nb = models.IntegerField(
@@ -279,6 +335,10 @@ class PpiComplex(models.Model):
 
 
 class CompoundManager(models.Manager):
+    """
+    CompoundManager adds automatically a number of annotations to the results
+    of the database query, used for filters and compound card
+    """
 
     def get_queryset(self):
         qs = super().get_queryset()
@@ -344,6 +404,9 @@ class CompoundManager(models.Manager):
         return qs
 
 class Compound(AutoFillableModel):
+    """
+    Chemical compound
+    """
     objects = CompoundManager() 
     canonical_smile = models.TextField(
         'Canonical Smile', unique=True)
@@ -546,6 +609,10 @@ class CompoundTanimoto(models.Model):
             ('canonical_smiles', 'fingerprint', 'compound'))
 
 def create_tanimoto(smiles_query, fingerprint):
+    """
+    Compute the Tanimoto similarity between a given SMILES and the compounds
+    then insert the results in CompoundTanimoto
+    """
     if CompoundTanimoto.objects.filter(canonical_smiles=smiles_query, fingerprint=fingerprint).count()==0:
         smiles_dict = {c.id:c.canonical_smile for c in Compound.objects.all()}
         fingerprinter = FingerPrinter(fingerprint)
@@ -558,16 +625,27 @@ def create_tanimoto(smiles_query, fingerprint):
         CompoundTanimoto.objects.bulk_create(cts)
 
 class PcaBiplotData(models.Model):
+    """
+    PCA biplot data
+    the table contains all the data as one JSON text in one row
+    """
     pca_biplot_data = models.TextField(
         'PCA biplot JSON data', blank=True, null=True)
 
 
 class LeLleBiplotData(models.Model):
+    """
+    LE-LLE biplot data
+    the table contains all the data as one JSON text in one row
+    """
     le_lle_biplot_data = models.TextField(
         'LE-LLE biplot JSON data', blank=True, null=True)
 
 
 class CellLine(models.Model):
+    """
+    Cell lines
+    """
     name = models.CharField('Name', max_length=50, unique=True)
 
     def __str__(self):
@@ -575,6 +653,9 @@ class CellLine(models.Model):
 
 
 class TestActivityDescription(models.Model):
+    """
+    Activity test descriptions
+    """
     TEST_TYPES = (
         ('BIOCH', 'Biochemical assay'),
         ('CELL', 'Cellular assay')
@@ -630,6 +711,9 @@ class TestActivityDescription(models.Model):
 
 
 class CompoundActivityResult(models.Model):
+    """
+    Activity test results on a compound
+    """
     MODULATION_TYPES = (
         ('I', 'Inhibition'),
         ('S', 'Stabilization')
@@ -664,6 +748,9 @@ class CompoundActivityResult(models.Model):
 
 
 class TestCytotoxDescription(models.Model):
+    """
+    Cytotoxicity test descriptions
+    """
     biblio = models.ForeignKey(Bibliography, models.CASCADE)
     test_name = models.CharField('Cytotoxicity test name', max_length=100)
     cell_line = models.ForeignKey(CellLine, models.CASCADE)
@@ -672,6 +759,9 @@ class TestCytotoxDescription(models.Model):
 
 
 class CompoundCytotoxicityResult(models.Model):
+    """
+    Cytotoxicity test results on a compound
+    """
     compound = models.ForeignKey(Compound, models.CASCADE)
     test_cytotoxicity_description = models.ForeignKey(
         TestCytotoxDescription, models.CASCADE)
@@ -685,6 +775,9 @@ class CompoundCytotoxicityResult(models.Model):
 
 
 class TestPKDescription(models.Model):
+    """
+    Pharmacokinetic test descriptions
+    """
     ADMINISTRATION_MODES = (
         ('IV', ''),
         ('PO', ''),
@@ -705,6 +798,9 @@ class TestPKDescription(models.Model):
 
 
 class CompoundPKResult(models.Model):
+    """
+    Pharmacokinetic test results on a compound
+    """
     compound = models.ForeignKey(Compound, models.CASCADE)
     test_pk_description = models.ForeignKey(TestPKDescription, models.CASCADE)
     tolerated = models.NullBooleanField('Tolerated', null=True)
@@ -729,6 +825,9 @@ class CompoundPKResult(models.Model):
 
 
 class CompoundAction(models.Model):
+    """
+    Compound action
+    """
     ACTIVATION_MODES = (
         ('O', 'Orthosteric'),
         ('A', 'Allosteric'),
@@ -756,6 +855,9 @@ class CompoundAction(models.Model):
         return 'Action of {} on {}'.format(self.compound, self.ppi)
 
 class RefCompoundBiblio(models.Model):
+    """
+    Compound-Bibliographic reference association
+    """
     compound = models.ForeignKey(Compound, models.CASCADE)
     bibliography = models.ForeignKey(Bibliography, models.CASCADE)
     compound_name = models.CharField(
@@ -765,6 +867,9 @@ class RefCompoundBiblio(models.Model):
         unique_together = (('compound', 'bibliography'),)
 
 class DrugBankCompound(models.Model):
+    """
+    Drugbank compound
+    """
     id = models.TextField(
         'Drugbank ID', unique=True, primary_key=True)
     common_name = models.TextField('Common name')
@@ -772,6 +877,9 @@ class DrugBankCompound(models.Model):
         'Canonical SMILES')
 
 class DrugbankCompoundTanimoto(models.Model):
+    """
+    Drugbank compound-compound tanimoto similarity
+    """
     compound = models.ForeignKey(Compound, models.CASCADE)
     drugbank_compound = models.ForeignKey(DrugBankCompound, models.CASCADE)
     tanimoto = models.DecimalField(
diff --git a/ippisite/ippidb/tests.py b/ippisite/ippidb/tests.py
index ea1a73f8f5e0e528db4402582841222a6a73d883..5fc938e61a76b2964a8eeab772b14e58a057d1e0 100644
--- a/ippisite/ippidb/tests.py
+++ b/ippisite/ippidb/tests.py
@@ -47,6 +47,9 @@ class SmiInchi(TestCase):
 
 
 class FingerPrinterTestCase(TestCase):
+    """
+    Test FingerPrinter class
+    """
 
     def setUp(self):
         self.fingerprinter = FingerPrinter("FP4")
diff --git a/ippisite/ippidb/views/compound_query.py b/ippisite/ippidb/views/compound_query.py
index da4d49859816b2500fe42cfef89766d1d1a02ad7..4462b28a8f4013923238cdd07cfeba54792099d2 100644
--- a/ippisite/ippidb/views/compound_query.py
+++ b/ippisite/ippidb/views/compound_query.py
@@ -381,6 +381,9 @@ class TrueListFilterHandler(object):
 
 
 class CompoundListView(ListView):
+    """
+    Compounds list view
+    """
 
     model = Compound
     template_name = "compound_list.html"
@@ -515,6 +518,9 @@ class CompoundDetailView(DetailView):
         return context
 
 class CompoundCardBDCHEMRedirectView(RedirectView):
+    """
+    redirection of BD-CHEM-issued URLs
+    """
 
     def get_redirect_url(self, *args, **kwargs):
         kwargs['compound_id'] = str(int(kwargs['compound_id']))
@@ -522,6 +528,9 @@ class CompoundCardBDCHEMRedirectView(RedirectView):
 
 
 def convert_mol2smi(request):
+    """
+    convert MOL2 file to SMILES
+    """
     mol_string = request.GET.get('molString')
     smiles_string = mol2smi(mol_string)
     resp = {'smiles': smiles_string}
@@ -529,6 +538,10 @@ def convert_mol2smi(request):
 
 
 def convert_smi2mol(request):
+    """
+    convert SMILES file to MOL2
+    (and generate 2D coordinates)
+    """
     smi_string = request.GET.get('smiString')
     mol_string = smi2mol(smi_string)
     resp = {'mol': mol_string}