Antidot Engineering practices

Software quality and robustness largely depend on the development methods in place. We can proudly say that Antidot applies state-of-the-art practices, with a constant effort to sharpen our methodology.

Software engineering

We apply state of the art techniques and good practices when coding. Our software is built using the continuous delivery paradigm.

  • Code is versioned in an internal Git source control system: all changes are logged and monitored
  • Our products are built using the latest versions of C++ , Java and Python (currently C++14, Java 8 and Python 3.5). We apply security patches and bug fixes to the third libraries that we use. Software is built using the continuous delivery paradigm
  • For every feature or bug fix, a topic branch is created. Jira epic/stories/tasks are created to track the development and our SCM tools (Gitlab CI and Jenkins) are linked to Jira.
  • A bug fix commit is not accepted without a test proving the issue is really fixed.
  • Code is written in pair mode and/or a merge request is created for review.
  • Code includes unit tests, functional tests and large tests involving all components.
  • These tests are run for every commit (several thousand tests).
  • Branches can be merged into a release branch only after review and if CI status is still ok.
  • Every commit on a release branch that leaves CI green (including large tests) creates an installation candidate. It usually takes about an hour for a valid commit to produce an installation candidate.
  • Each night additional tests that recreate a full day of production are run on the latest installation candidate, including stress and recovery tests.
  • Every week (or more often if required) we cherry pick the « best » candidate of the week (usually the latest) and deliver it to our customers (release note + updated package repository).

Code analysis

  • Code coverage and static analysis tools are frequently run (Sonar,CppCheck, SafeHTML …).
  • Penetration tools are frequently run.

DevOps

  • DevOps feedback loop provides quick feedback to developers about installation, upgrade or production issues.
  • Our Ops team can (and will) refuse to install a version if they are not confident with its quality.
  • Our Ops team uses state of the art monitoring and automated deployment tools (Puppet, Ansible, FAI …).  Our servers are regularly cleaned and reinstalled automatically.
  • Container technologies (LXD, Docker) are heavily used to isolate environments and to ensure that our software can be built, installed and run from a bare OS installation.
  • When preparing rollout of major update, DevOps transversal teams perform non-regression, performance and stress tests of the new binaries (“you build it, you run it”).
  • A/B techniques are used to progressively roll out new versions in our Cloud. Changes and user behavior are monitored in real time and can remove a new version from production if required without having the need to rollback software or databases.
  • Feature toggles enable progressive rollout of new features to selected customers.
  • HipChat rooms are used internally for efficient communication between Dev, Ops, internal Professional Services users, …

Agility

  • Teams work in Agile mode, using Scrum, Kanban or in-house mix of various Agile methods.
  • All teams use the same rhythm: iterations of 3 weeks, at the end of which retrospectives and review ceremonies are held.
  • Our managers and developers frequently attend Agile Tour meetings to challenge and update their skills.

Culture

  • Our developers are passionate, they attend several conferences per year (DockerCon, Fosdem, Devoxx …) and go to local meetups and JUGs.
  • Every week a developer talks in front of his peers of a specific technological topic (30 minutes).
  • Hackathons are held to foster innovation.
  • Frequent meetings are held between stakeholders (Product owner, Support and Professional Services managers, Pre-sales staff, Top management ….) to ensure that everybody is focused on providing value to our Customers.
  • Professional Services teams lead a review meeting after completion of customer’s projects. This review provides feedback to developers and ops, allow fine tuning of the backlogs. This also allow Support staff members to gain project knowledge.

Le Magentolive est de retour en France pour notre plus grand plaisir.

Le Bargento et le Magentolive ont fusionné, nous serons encore plus nombreux à participer à ce grand rassemblement de l’écosystème Magento, les 06 et 07 Février à Paris.

Le programme a été dévoilé et de nombreuses animations en plus des conférences et tables rondes sont proposées. On espère donc vous retrouver lors des nombreux moments dédiés au networking et bien sûr sur notre stand 😃.

Magentolive : l’événement incontournable pour échanger sur les bonnes pratiques et trouver de nouveaux partenaires.

Le programme varié de Magentolive cette année permettra au plus grand nombre de trouver son bonheur :

  • Participer à des créneaux horaires dédiés au networking pour faire de nouvelles rencontres entre professionnels.
  • Assister à des conférences pour mieux appréhender les nouvelles tendances.
  • Découvrir les nouveautés de Magento 2, les prouesses techniques de cette nouvelle version.
  • S’informer sur les nouvelles solutions techniques qui permettront à tous de proposer des sites e-commerce plus efficients.
  • Faire le tour des stands pour rencontrer de nouveaux partenaires, fournisseurs, clients …

Découvrez sans tarder l’intégralité du programme et préparez votre venue !

 

Antidot et Open Source : Pyckson

Antidot et l’Open Source

Antidot utilise pour le développement de ses produits beaucoup de logiciels Open Source. Et nous essayons, chaque fois que cela est possible, d’apporter en retour notre contribution à la communauté.

Open-SourceCela se fait sous forme de patches / pull request (nous proposons des correctifs qui sont intégrés au logiciel), d’éléments permettant d’enrichir nos plateformes (API, modules…) ou de logiciels autonomes (comme par exemple db2triples qui permet d’exploiter le contenu de bases de données relationnelles avec les technologies du Web Sémantique).

shutterstock_194620346

Il arrive que nos développeurs passionnés commencent sur leur temps personnel une brique technologique qui s’avère être particulièrement utile à notre travail. Nous encourageons alors cet effort et fournissons du temps et des ressources pour accompagner la finalisation d’une première version du projet et sa diffusion (par exemple lors de nos Brown Bags hebdomadaires)

La suite de ce billet de blog est rédigée par Jean Giard, développeur senior à la R&D d’Antidot, qui présente Pyckson, un outil permettant à un logiciel en Python d’importer / exporter facilement des objets en JSON.

Stéphane Loesel

PS – Vous retrouverez nos logiciels OpenSource sur le github d’Antidot à l’adresse :
https://github.com/Antidot

GitHub-Mark  GitHub-Logo

N’hésitez pas à utiliser notre code, le relire, nous poser des questions ou nous proposer des améliorations. Vous pouvez nous joindre à l’adresse opensource@antidot.net


Pyckson : un outil de mapping objet-JSON en python

Un peu d’histoire

Je travaille chez Antidot depuis plus de 5 ans, à ma sortie d’école.

J’ai travaillé pendant 4 ans en Python / C++ sur le moteur de recherche Antidot Finder Suite, où j’ai développé mes connaissances de bases en développement et méthodologie.

Il y a un an et demi je suis passé dans l’équipe qui travaille sur le produit Fluid Topics et développe en Java / Python. J’ai découvert tout un tas de nouveau design-pattern inaccessibles en Java : injection, orm, streams.

D’un autre coté je continuais à m’améliorer en Python mais un truc principal m’embêtait : sérialiser mes objets Python en JSON.

Alors qu’en Java tout avait l’air si simple avec un mix de Jackson / AutoValue, en Python je devais continuer à écrire des classes de sérialisation /désérialisation, ça ne pouvait plus durer !

Quelles solutions ?

J’ai cherché quelques temps si Python avait une librairie pour faire ce genre d’opérations mais je n’ai rien trouvé. Ce qui s’en rapprochait le plus était le module pickle mais il ne correspondait pas à mes principaux besoins :

  •  produire / lire du JSON « propre », i.e. sans contournement bizarre du genre insérer des infos pour parser l’objet
  •  du camelCase automatique pour respecter le coding-style Python tout en étant compatible avec le style des objects des web-services du serveur en Java
  •  la classe Python doit pouvoir être simple : rien d’autre qu’un constructeur et des attributs

Je me suis donc décidé à écrire ma propre librairie qui répondait a ce besoin : Pyckson

Principes de Pyckson

Pyckson fonctionne en introspectant les constructeurs des classes annotées et celles ci doivent correspondre à une structure bien particulière

  •  tous les paramètres doivent être annotés par leur type.
  •  les paramètres du constructeur doivent être assignés à des attributs du même nom.
  •  Pyckson camelCase automatiquement les noms des attributs pour la sérialisation.
  •  tous les attributs de type non primitif doivent aussi être annotés avec pyckson

Inconvénients

Bien entendu Python n’est pas aussi complet que Java en ce qui concerne le typage / l’introspection et on tombe vite sur quelques contraintes.

Les listes ne peuvent pas être typées, du coup Pyckson utilise une annotation supplémentaire pour indiquer le type du contenu d’une liste.

Les enum python3 ont un nom et une valeur, Pyckson utilise le nom de l’enum pour sérialiser, case sensitive par défaut.

Petits bonus

Pyckson utilise la librairie standard JSON et se charge de la transformation objet -> dictionnaire, du coup on peut aussi utiliser Pyckson pour faire du Yaml ou du Bson (avec MongoDB par exemple).

Pyckson supporte le fait d’utiliser une string pour typer un paramètre, par exemple pour définir une structure récursive.

Pyckson comprend qu’un paramètre est optionnel quand il a une valeur par défaut.

Exemple

Je définis mes objets en Python :

@pyckson
class Foo:
    def __init__(self, value: str):
        self.value = value

@pyckson
@listtype('my_foo_list', Foo)
class Bar:
    def __init__(self, my_foo_list: list):
        self.my_foo_list = my_foo_list

Puis j’appelle Pyckson :

:::python
foos = [Foo('first'), Foo('second')]
bar = Bar(foos)
print(serialize(bar))

> {"myFooList": [{"value": "first"}, {"value": "second"}]}

Lien vers le projet github : https://github.com/antidot/Pyckson

Voilà, vous savez tout sur Pyckson !

Jean Giard