SlideShare uma empresa Scribd logo
1 de 29
Un serveur métier en Python / C++ 
Meet-up C++ 
02/10/2014 
Pierre Marquis & Alexandre Bonnasseau
Plan 
• Retour d’expérience 
• En pratique, quelques lignes de code
L'équipe dev carto 
Info 
trafic 
Itinéraire 
Plan 
Moteur de 
recherche 
géolocalisée 
Moteur de 
suggestion 
Géolocalisation 
Itinéraire 
transports 
en commun
Python WTF ??!
Python WTF ??! 
- Simplicité de code 
- Framework web léger 
- Richesse des modules 
- Facilité d'industrialisation
Notre philosophie 
- Python quand on peut 
- C++ quand c’est nécessaire
Chemin de l’équipe 
● Fonctions plus atomiques 
● Test U 
● Lint 
● Dojo 
● Pair programming 
● Code review
Schéma d’archi du plan
Chaîne d’industrialisation
Aujourd’hui 
+ 80% des serveurs migrés 
+ Langage très intéressant 
+ Framework mieux 
maîtrisé 
+ Dev plus rapide 
+ Plus d’agilité 
- Moins de maîtrise C++ 
- Multithread 
- Débogage binding
En pratique : 
appeler du C++ depuis Python
Cadre 
– Existence d’une base de code C++ fiable et testée 
– On souhaite prototyper rapidement (besoin mouvant) 
– Besoin d’exécution rapide pour des fonctions critiques
L'existant 
#define _USE_MATH_DEFINES 
#include <cmath> 
#include "geo.hpp" 
#include <sstream> 
#include <stdexcept> 
string geocoord2string(double angle) { 
if ( (angle > 180) || (angle < -180) ) 
throw invalid_argument("Invalid argument : angle must be beetween -180° and 180°"); 
int deg = int(floor(angle)); 
double rest = angle - deg; 
int minute = int(floor( rest * 60)); 
rest = rest * 60 - minute; 
int second = int(floor( rest * 60)); 
ostringstream result; 
result << deg << "° " << minute << "' " << second <<"''"; 
return result.str(); 
} 
double deg2rad(double deg) { 
return (deg * M_PI / 180); 
} 
GeoPoint::GeoPoint(double lat, double lng) : lat(lat), lng(lng) {} 
double GeoPoint::distance(const GeoPoint &other) { 
double nDLat = deg2rad(other.lat - this->lat); 
double nDLon = deg2rad(other.lng - this->lng); 
double thisLatRad = deg2rad(this->lat); 
double otherLatRad = deg2rad(other.lat); 
double nA = pow ( sin(nDLat/2), 2 ) + cos(thisLatRad) * cos(otherLatRad) * pow ( sin(nDLon/2), 2 ); 
double nC = 2 * atan2( sqrt(nA), sqrt( 1 - nA )); 
double nD = EARTH_RADIUS * nC; 
return nD; // Return our calculated distance 
}
Objectif 
Utiliser les fonctions C++ en python : 
$ python 
Python 2.7.3 
>>> import geo 
>>> print geo.geocoord2string(5.36) 
5° 21’ 36‘’ 
Projet complet disponible sur github : 
https://github.com/Mappy/un-serveur-metier-en-python-cpp
Un module python écrit en C++ 
D'après : https://docs.python.org/2/extending/extending.html 
geomodule.cpp 
#include "Python.h" 
#include "geo.hpp" 
static PyObject * geocoord2string_py(PyObject *self, PyObject *args) 
{ 
double angle = 0; 
if (!PyArg_ParseTuple(args, "d", &angle)) 
return NULL; 
string res = geocoord2string(angle); 
return Py_BuildValue("s", res.c_str()); 
} 
// La liste des fonctions qu'on expose en Python 
static PyMethodDef geoMethods[] = { 
{ "geocoord2string", geocoord2string_py, METH_VARARGS, 
"Convert a latitude or a longitude as an angle in a string in the form : d° m' s''." }, 
{ NULL, NULL, 0, NULL } /* Sentinel */ 
}; 
// La fonction initnomdumodule est appelée par l'interpréteur Python 
// à l'import du module 
PyMODINIT_FUNC initgeo(void) 
{ 
(void) Py_InitModule("geo", geoMethods); 
}
Avec Boost.Python ? 
geomudule.cpp 
#include <boost/python.hpp> 
#include <boost/python/module.hpp> 
#include "geo.hpp" 
using namespace boost::python; 
BOOST_PYTHON_MODULE(geo) 
{ 
def("geocoord2string", geocoord2string); 
class_<GeoPoint>("GeoPoint", init<double, double>()) 
.def("distance", &GeoPoint::distance) 
… C’est tout ! 
; 
}
Avec Boost.Python, on peut 
– Exposer des fonctions C++ en Python 
– Exposer des classes C++ en Python 
– Choisir quelles méthodes exposer pour une classe 
– Utiliser Boost::optional pour gérer les paramètres 
optionnels
Packager une extension Python 
Le fichier setup.py s’occupe de la compilation : 
from distutils.core import setup, Extension 
geo_module = Extension('geo', 
include_dirs = ['/usr/local/include',], 
library_dirs = ['/usr/local/lib',], 
extra_compile_args=['-std=c++11'], 
sources = ['geomodule.cpp', 'geo.cpp']) 
setup (name = 'Geo', 
version = '1.0', 
description = 'A geo package from Mappy', 
author = 'LBS team', 
author_email = 'lbs@mappy.com', 
url = 'http://github.com/mappy', 
long_description = ‘A demo package with geo functions', 
ext_modules = [geo_module]) 
Installer avec : 
python setup.py install 
Ou packager : 
python setup.py bdist
Focus : Gestion de la mémoire 
– Un code C++ qui conserve une référence sur 
un objet Python doit appeler la macro 
Py_INCREF() pour s'assurer que l'objet ne 
sera pas détruit 
– Il faut appeler Py_DECREF() pour libérer 
l'objet
Focus : Gestion des erreurs 
Le code suivant lève une exception C++ : 
import geo 
print geo.geocoord2string(181) 
Sans Boost.Python : 
terminate called after throwing an instance of 'std::invalid_argument' 
what(): Invalid argument : angle must be beetween -180° and 180° 
Avec Boost.Python : 
Traceback (most recent call last): 
File "<stdin>", line 1, in <module> 
ValueError: Invalid argument : angle must be beetween -180° and 180° 
Boost.Python permet également d'affiner la gestion des erreurs en associant des 
erreurs spécifiques Python aux exceptions C++
Un serveur de distance géographiques 
geoserveur.py 
from bottle import route, run, template 
from geo import GeoPoint 
@route('/distance/<lat1:float>,<lng1:float>/<lat2:float>,<lng2:float>') 
def index(lat1, lng1, lat2, lng2): 
dep = GeoPoint(lat1, lng1) 
arr = GeoPoint(lat2, lng2) 
return template("Distance = {{distance}}", distance=dep.distance(arr)) 
run(host='localhost', port=8888) 
A lancer par : 
python geoserver.py 
Tester l’url : http://localhost:8888/distance/48.85,2.35/43.30,5.38
Une autre approche : Producteur / Consommateur 
– Le code python peut appeler des méthodes C++ à 
distance 
– Par exemple via un bus RabbitMQ ou bien des 
appels distants ZMQ 
– Au final, le code Python délègue l‘exécution des 
sections critiques à des workers C++
Les difficultés en Python 
quand on vient du C++
Typage dynamique 
– En C++ le typage statique offre une première 
validation du code 
– En Python, on ne détecte les erreurs de type qu'à 
l'exécution ! 
 il faut exécuter le code pour le tester 
 les tests unitaires sont indispensables !
Threads 
– Le Global Interpreter Lock (GIL) assure que les traitements 
concurrents ne se marchent pas dessus : 
https://docs.python.org/2/glossary.html#term-global-interpreter-lock 
http://dabeaz.blogspot.fr/2010/01/python-gil-visualized.html 
– Les modules thread / threading 
– encapsulent les primitives système de thread 
– fournissent des primitives de synchronisation : verrous, 
sémaphores, etc. 
– ... Mais à aucun moment deux instructions peuvent être 
exécutées en même temps à cause du GIL ! 
 Mieux vaut utiliser multiprocessing
Mémoire partagée 
– Le module mmap (Memory-mapped file) permet de partager de 
la mémoire entre plusieurs process 
– On peut accéder à cette mémoire comme un fichier en lecture / 
écriture 
– On accède à cette mémoire comme un tableau de char 
– Mais on ne peut pas utiliser de types complexes (listes, 
dictionnaires, objets définis sur mesures) 
 Pas aussi souple qu’en C++
Conclusion
Où va Mappy ? 
– Amélioration continue de l’outillage 
– Nouveaux services asynchrones en Python 
– … Et bientôt un nouveau serveur d'itinéraire en Python / C++ ?
Merci 
Enjoy : http://fr.mappy.com/ 
Pierre Marquis : pierre.marquis@mappy.com 
Alexandre Bonnasseau : https://github.com/abonnasseau

Mais conteúdo relacionado

Mais procurados

Cours de C++ / Tronc commun deuxième année ISIMA
Cours de C++ / Tronc commun deuxième année ISIMACours de C++ / Tronc commun deuxième année ISIMA
Cours de C++ / Tronc commun deuxième année ISIMALoic Yon
 
Développement informatique : Gestion de projet, versioning, debugging, testin...
Développement informatique : Gestion de projet, versioning, debugging, testin...Développement informatique : Gestion de projet, versioning, debugging, testin...
Développement informatique : Gestion de projet, versioning, debugging, testin...ECAM Brussels Engineering School
 
Cours de C++, en français, 2002 - Cours 2.1
Cours de C++, en français, 2002 - Cours 2.1Cours de C++, en français, 2002 - Cours 2.1
Cours de C++, en français, 2002 - Cours 2.1Laurent BUNIET
 
TP4 Atelier C++ /GL2 INSAT / Tunisie
TP4 Atelier C++ /GL2 INSAT / TunisieTP4 Atelier C++ /GL2 INSAT / Tunisie
TP4 Atelier C++ /GL2 INSAT / TunisieMariem ZAOUALI
 
Incorporer du C dans R, créer son package
Incorporer du C dans R, créer son packageIncorporer du C dans R, créer son package
Incorporer du C dans R, créer son packageCdiscount
 
Python For Data Science - French Course
Python For Data Science - French CoursePython For Data Science - French Course
Python For Data Science - French CourseHaytam EL YOUSSFI
 
Cours c#
Cours c#Cours c#
Cours c#zan
 
C2 - Langage C - ISIMA 1 - Deuxieme partie
C2 - Langage C - ISIMA 1 - Deuxieme partieC2 - Langage C - ISIMA 1 - Deuxieme partie
C2 - Langage C - ISIMA 1 - Deuxieme partieLoic Yon
 
Scala : programmation fonctionnelle
Scala : programmation fonctionnelleScala : programmation fonctionnelle
Scala : programmation fonctionnelleMICHRAFY MUSTAFA
 
La programmation GPU avec C++ AMP pour les performances extrêmes
La programmation GPU avec C++ AMP pour les performances extrêmesLa programmation GPU avec C++ AMP pour les performances extrêmes
La programmation GPU avec C++ AMP pour les performances extrêmesMicrosoft
 
Langage C
Langage  CLangage  C
Langage Cjwilili
 
Programmation orientée objet : Object, classe et encapsulation
Programmation orientée objet : Object, classe et encapsulationProgrammation orientée objet : Object, classe et encapsulation
Programmation orientée objet : Object, classe et encapsulationECAM Brussels Engineering School
 
Seance 3- Programmation en langage C
Seance 3- Programmation en langage C Seance 3- Programmation en langage C
Seance 3- Programmation en langage C Fahad Golra
 
Seance 4- Programmation en langage C
Seance 4- Programmation en langage CSeance 4- Programmation en langage C
Seance 4- Programmation en langage CFahad Golra
 
Cours de C++, en français, 2002 - Cours 1.5
Cours de C++, en français, 2002 - Cours 1.5Cours de C++, en français, 2002 - Cours 1.5
Cours de C++, en français, 2002 - Cours 1.5Laurent BUNIET
 

Mais procurados (20)

Cours de C++ / Tronc commun deuxième année ISIMA
Cours de C++ / Tronc commun deuxième année ISIMACours de C++ / Tronc commun deuxième année ISIMA
Cours de C++ / Tronc commun deuxième année ISIMA
 
Développement informatique : Gestion de projet, versioning, debugging, testin...
Développement informatique : Gestion de projet, versioning, debugging, testin...Développement informatique : Gestion de projet, versioning, debugging, testin...
Développement informatique : Gestion de projet, versioning, debugging, testin...
 
Développement informatique : Programmation graphique
Développement informatique : Programmation graphiqueDéveloppement informatique : Programmation graphique
Développement informatique : Programmation graphique
 
Carré Magique Cpp
Carré Magique CppCarré Magique Cpp
Carré Magique Cpp
 
Cours de C++, en français, 2002 - Cours 2.1
Cours de C++, en français, 2002 - Cours 2.1Cours de C++, en français, 2002 - Cours 2.1
Cours de C++, en français, 2002 - Cours 2.1
 
TP4 Atelier C++ /GL2 INSAT / Tunisie
TP4 Atelier C++ /GL2 INSAT / TunisieTP4 Atelier C++ /GL2 INSAT / Tunisie
TP4 Atelier C++ /GL2 INSAT / Tunisie
 
Boost.SIMD
Boost.SIMDBoost.SIMD
Boost.SIMD
 
Incorporer du C dans R, créer son package
Incorporer du C dans R, créer son packageIncorporer du C dans R, créer son package
Incorporer du C dans R, créer son package
 
Python For Data Science - French Course
Python For Data Science - French CoursePython For Data Science - French Course
Python For Data Science - French Course
 
Cours c#
Cours c#Cours c#
Cours c#
 
C2 - Langage C - ISIMA 1 - Deuxieme partie
C2 - Langage C - ISIMA 1 - Deuxieme partieC2 - Langage C - ISIMA 1 - Deuxieme partie
C2 - Langage C - ISIMA 1 - Deuxieme partie
 
Scala : programmation fonctionnelle
Scala : programmation fonctionnelleScala : programmation fonctionnelle
Scala : programmation fonctionnelle
 
La programmation GPU avec C++ AMP pour les performances extrêmes
La programmation GPU avec C++ AMP pour les performances extrêmesLa programmation GPU avec C++ AMP pour les performances extrêmes
La programmation GPU avec C++ AMP pour les performances extrêmes
 
Langage C
Langage  CLangage  C
Langage C
 
Programmation orientée objet : Object, classe et encapsulation
Programmation orientée objet : Object, classe et encapsulationProgrammation orientée objet : Object, classe et encapsulation
Programmation orientée objet : Object, classe et encapsulation
 
Johnny-Five : Robotique et IoT en JavaScript
Johnny-Five : Robotique et IoT en JavaScriptJohnny-Five : Robotique et IoT en JavaScript
Johnny-Five : Robotique et IoT en JavaScript
 
Seance 3- Programmation en langage C
Seance 3- Programmation en langage C Seance 3- Programmation en langage C
Seance 3- Programmation en langage C
 
La programmation fonctionnelle en javascript / PF
La programmation fonctionnelle en javascript / PFLa programmation fonctionnelle en javascript / PF
La programmation fonctionnelle en javascript / PF
 
Seance 4- Programmation en langage C
Seance 4- Programmation en langage CSeance 4- Programmation en langage C
Seance 4- Programmation en langage C
 
Cours de C++, en français, 2002 - Cours 1.5
Cours de C++, en français, 2002 - Cours 1.5Cours de C++, en français, 2002 - Cours 1.5
Cours de C++, en français, 2002 - Cours 1.5
 

Semelhante a Comment développer un serveur métier en python/C++

Tp2: Installation d'une couche d’abstraction entre un robot physique et ros
Tp2: Installation d'une couche d’abstraction entre un robot physique et rosTp2: Installation d'une couche d’abstraction entre un robot physique et ros
Tp2: Installation d'une couche d’abstraction entre un robot physique et rosSaid Benaissa
 
Retour d'expérience technique Go, gRPC, Kubernetes
Retour d'expérience technique Go, gRPC, KubernetesRetour d'expérience technique Go, gRPC, Kubernetes
Retour d'expérience technique Go, gRPC, KubernetesVincent Composieux
 
Android Optimisations Greendroid
Android Optimisations GreendroidAndroid Optimisations Greendroid
Android Optimisations GreendroidGDG Nantes
 
Au secours, mon chef m'a demandé de passer au DevOps
Au secours, mon chef m'a demandé de passer au DevOpsAu secours, mon chef m'a demandé de passer au DevOps
Au secours, mon chef m'a demandé de passer au DevOpsantony_guilloteau
 
PHPTour-2011-PHP_Extensions
PHPTour-2011-PHP_ExtensionsPHPTour-2011-PHP_Extensions
PHPTour-2011-PHP_Extensionsjulien pauli
 
OWF12/PAUG Conf Days Render script, sylvain galand, software engineer at geny...
OWF12/PAUG Conf Days Render script, sylvain galand, software engineer at geny...OWF12/PAUG Conf Days Render script, sylvain galand, software engineer at geny...
OWF12/PAUG Conf Days Render script, sylvain galand, software engineer at geny...Paris Open Source Summit
 
Node.js, le pavé dans la mare
Node.js, le pavé dans la mareNode.js, le pavé dans la mare
Node.js, le pavé dans la mareValtech
 
gRPC, ECHANGES A HAUTE FREQUENCE !
gRPC, ECHANGES A HAUTE FREQUENCE !gRPC, ECHANGES A HAUTE FREQUENCE !
gRPC, ECHANGES A HAUTE FREQUENCE !Carles Sistare
 
gRPC, échange à haute fréquence!
gRPC, échange à haute fréquence!gRPC, échange à haute fréquence!
gRPC, échange à haute fréquence!David Caramelo
 
Monitoring d'un compteur EDF avec node.js @bdx.io
Monitoring d'un compteur EDF avec node.js @bdx.ioMonitoring d'un compteur EDF avec node.js @bdx.io
Monitoring d'un compteur EDF avec node.js @bdx.iolaurenthuet
 
Hacking your Home @bdx.io
Hacking your Home @bdx.ioHacking your Home @bdx.io
Hacking your Home @bdx.iolaurenthuet
 
201303 - Java8
201303 - Java8201303 - Java8
201303 - Java8lyonjug
 
PFE PSA Peugeot Citroen - Prototypage rapide
PFE PSA Peugeot Citroen - Prototypage rapide PFE PSA Peugeot Citroen - Prototypage rapide
PFE PSA Peugeot Citroen - Prototypage rapide Régis Castéran
 
Sizing PoC LSF & PowerAI for Engineers schools workloads
Sizing PoC LSF & PowerAI for Engineers schools workloadsSizing PoC LSF & PowerAI for Engineers schools workloads
Sizing PoC LSF & PowerAI for Engineers schools workloadsPhilippeBrogi
 

Semelhante a Comment développer un serveur métier en python/C++ (20)

Tp2: Installation d'une couche d’abstraction entre un robot physique et ros
Tp2: Installation d'une couche d’abstraction entre un robot physique et rosTp2: Installation d'une couche d’abstraction entre un robot physique et ros
Tp2: Installation d'une couche d’abstraction entre un robot physique et ros
 
Retour d'expérience technique Go, gRPC, Kubernetes
Retour d'expérience technique Go, gRPC, KubernetesRetour d'expérience technique Go, gRPC, Kubernetes
Retour d'expérience technique Go, gRPC, Kubernetes
 
Android Optimisations Greendroid
Android Optimisations GreendroidAndroid Optimisations Greendroid
Android Optimisations Greendroid
 
Chapitre 5 Linux
Chapitre 5 LinuxChapitre 5 Linux
Chapitre 5 Linux
 
Au secours, mon chef m'a demandé de passer au DevOps
Au secours, mon chef m'a demandé de passer au DevOpsAu secours, mon chef m'a demandé de passer au DevOps
Au secours, mon chef m'a demandé de passer au DevOps
 
PHPTour-2011-PHP_Extensions
PHPTour-2011-PHP_ExtensionsPHPTour-2011-PHP_Extensions
PHPTour-2011-PHP_Extensions
 
OWF12/PAUG Conf Days Render script, sylvain galand, software engineer at geny...
OWF12/PAUG Conf Days Render script, sylvain galand, software engineer at geny...OWF12/PAUG Conf Days Render script, sylvain galand, software engineer at geny...
OWF12/PAUG Conf Days Render script, sylvain galand, software engineer at geny...
 
Node.js, le pavé dans la mare
Node.js, le pavé dans la mareNode.js, le pavé dans la mare
Node.js, le pavé dans la mare
 
Python + ansible = ♥
Python + ansible = ♥Python + ansible = ♥
Python + ansible = ♥
 
gRPC, ECHANGES A HAUTE FREQUENCE !
gRPC, ECHANGES A HAUTE FREQUENCE !gRPC, ECHANGES A HAUTE FREQUENCE !
gRPC, ECHANGES A HAUTE FREQUENCE !
 
gRPC, échange à haute fréquence!
gRPC, échange à haute fréquence!gRPC, échange à haute fréquence!
gRPC, échange à haute fréquence!
 
Monitoring d'un compteur EDF avec node.js @bdx.io
Monitoring d'un compteur EDF avec node.js @bdx.ioMonitoring d'un compteur EDF avec node.js @bdx.io
Monitoring d'un compteur EDF avec node.js @bdx.io
 
Hacking your Home @bdx.io
Hacking your Home @bdx.ioHacking your Home @bdx.io
Hacking your Home @bdx.io
 
201303 - Java8
201303 - Java8201303 - Java8
201303 - Java8
 
PFE PSA Peugeot Citroen - Prototypage rapide
PFE PSA Peugeot Citroen - Prototypage rapide PFE PSA Peugeot Citroen - Prototypage rapide
PFE PSA Peugeot Citroen - Prototypage rapide
 
HTML5 en projet
HTML5 en projetHTML5 en projet
HTML5 en projet
 
Paris RailsCamp 2009
Paris RailsCamp 2009Paris RailsCamp 2009
Paris RailsCamp 2009
 
Paug renderscript-mars-2013
Paug renderscript-mars-2013Paug renderscript-mars-2013
Paug renderscript-mars-2013
 
Sizing PoC LSF & PowerAI for Engineers schools workloads
Sizing PoC LSF & PowerAI for Engineers schools workloadsSizing PoC LSF & PowerAI for Engineers schools workloads
Sizing PoC LSF & PowerAI for Engineers schools workloads
 
Ogre 3D : une introduction
Ogre 3D : une introductionOgre 3D : une introduction
Ogre 3D : une introduction
 

Comment développer un serveur métier en python/C++

  • 1. Un serveur métier en Python / C++ Meet-up C++ 02/10/2014 Pierre Marquis & Alexandre Bonnasseau
  • 2. Plan • Retour d’expérience • En pratique, quelques lignes de code
  • 3. L'équipe dev carto Info trafic Itinéraire Plan Moteur de recherche géolocalisée Moteur de suggestion Géolocalisation Itinéraire transports en commun
  • 5. Python WTF ??! - Simplicité de code - Framework web léger - Richesse des modules - Facilité d'industrialisation
  • 6. Notre philosophie - Python quand on peut - C++ quand c’est nécessaire
  • 7. Chemin de l’équipe ● Fonctions plus atomiques ● Test U ● Lint ● Dojo ● Pair programming ● Code review
  • 10. Aujourd’hui + 80% des serveurs migrés + Langage très intéressant + Framework mieux maîtrisé + Dev plus rapide + Plus d’agilité - Moins de maîtrise C++ - Multithread - Débogage binding
  • 11. En pratique : appeler du C++ depuis Python
  • 12. Cadre – Existence d’une base de code C++ fiable et testée – On souhaite prototyper rapidement (besoin mouvant) – Besoin d’exécution rapide pour des fonctions critiques
  • 13. L'existant #define _USE_MATH_DEFINES #include <cmath> #include "geo.hpp" #include <sstream> #include <stdexcept> string geocoord2string(double angle) { if ( (angle > 180) || (angle < -180) ) throw invalid_argument("Invalid argument : angle must be beetween -180° and 180°"); int deg = int(floor(angle)); double rest = angle - deg; int minute = int(floor( rest * 60)); rest = rest * 60 - minute; int second = int(floor( rest * 60)); ostringstream result; result << deg << "° " << minute << "' " << second <<"''"; return result.str(); } double deg2rad(double deg) { return (deg * M_PI / 180); } GeoPoint::GeoPoint(double lat, double lng) : lat(lat), lng(lng) {} double GeoPoint::distance(const GeoPoint &other) { double nDLat = deg2rad(other.lat - this->lat); double nDLon = deg2rad(other.lng - this->lng); double thisLatRad = deg2rad(this->lat); double otherLatRad = deg2rad(other.lat); double nA = pow ( sin(nDLat/2), 2 ) + cos(thisLatRad) * cos(otherLatRad) * pow ( sin(nDLon/2), 2 ); double nC = 2 * atan2( sqrt(nA), sqrt( 1 - nA )); double nD = EARTH_RADIUS * nC; return nD; // Return our calculated distance }
  • 14. Objectif Utiliser les fonctions C++ en python : $ python Python 2.7.3 >>> import geo >>> print geo.geocoord2string(5.36) 5° 21’ 36‘’ Projet complet disponible sur github : https://github.com/Mappy/un-serveur-metier-en-python-cpp
  • 15. Un module python écrit en C++ D'après : https://docs.python.org/2/extending/extending.html geomodule.cpp #include "Python.h" #include "geo.hpp" static PyObject * geocoord2string_py(PyObject *self, PyObject *args) { double angle = 0; if (!PyArg_ParseTuple(args, "d", &angle)) return NULL; string res = geocoord2string(angle); return Py_BuildValue("s", res.c_str()); } // La liste des fonctions qu'on expose en Python static PyMethodDef geoMethods[] = { { "geocoord2string", geocoord2string_py, METH_VARARGS, "Convert a latitude or a longitude as an angle in a string in the form : d° m' s''." }, { NULL, NULL, 0, NULL } /* Sentinel */ }; // La fonction initnomdumodule est appelée par l'interpréteur Python // à l'import du module PyMODINIT_FUNC initgeo(void) { (void) Py_InitModule("geo", geoMethods); }
  • 16. Avec Boost.Python ? geomudule.cpp #include <boost/python.hpp> #include <boost/python/module.hpp> #include "geo.hpp" using namespace boost::python; BOOST_PYTHON_MODULE(geo) { def("geocoord2string", geocoord2string); class_<GeoPoint>("GeoPoint", init<double, double>()) .def("distance", &GeoPoint::distance) … C’est tout ! ; }
  • 17. Avec Boost.Python, on peut – Exposer des fonctions C++ en Python – Exposer des classes C++ en Python – Choisir quelles méthodes exposer pour une classe – Utiliser Boost::optional pour gérer les paramètres optionnels
  • 18. Packager une extension Python Le fichier setup.py s’occupe de la compilation : from distutils.core import setup, Extension geo_module = Extension('geo', include_dirs = ['/usr/local/include',], library_dirs = ['/usr/local/lib',], extra_compile_args=['-std=c++11'], sources = ['geomodule.cpp', 'geo.cpp']) setup (name = 'Geo', version = '1.0', description = 'A geo package from Mappy', author = 'LBS team', author_email = 'lbs@mappy.com', url = 'http://github.com/mappy', long_description = ‘A demo package with geo functions', ext_modules = [geo_module]) Installer avec : python setup.py install Ou packager : python setup.py bdist
  • 19. Focus : Gestion de la mémoire – Un code C++ qui conserve une référence sur un objet Python doit appeler la macro Py_INCREF() pour s'assurer que l'objet ne sera pas détruit – Il faut appeler Py_DECREF() pour libérer l'objet
  • 20. Focus : Gestion des erreurs Le code suivant lève une exception C++ : import geo print geo.geocoord2string(181) Sans Boost.Python : terminate called after throwing an instance of 'std::invalid_argument' what(): Invalid argument : angle must be beetween -180° and 180° Avec Boost.Python : Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: Invalid argument : angle must be beetween -180° and 180° Boost.Python permet également d'affiner la gestion des erreurs en associant des erreurs spécifiques Python aux exceptions C++
  • 21. Un serveur de distance géographiques geoserveur.py from bottle import route, run, template from geo import GeoPoint @route('/distance/<lat1:float>,<lng1:float>/<lat2:float>,<lng2:float>') def index(lat1, lng1, lat2, lng2): dep = GeoPoint(lat1, lng1) arr = GeoPoint(lat2, lng2) return template("Distance = {{distance}}", distance=dep.distance(arr)) run(host='localhost', port=8888) A lancer par : python geoserver.py Tester l’url : http://localhost:8888/distance/48.85,2.35/43.30,5.38
  • 22. Une autre approche : Producteur / Consommateur – Le code python peut appeler des méthodes C++ à distance – Par exemple via un bus RabbitMQ ou bien des appels distants ZMQ – Au final, le code Python délègue l‘exécution des sections critiques à des workers C++
  • 23. Les difficultés en Python quand on vient du C++
  • 24. Typage dynamique – En C++ le typage statique offre une première validation du code – En Python, on ne détecte les erreurs de type qu'à l'exécution !  il faut exécuter le code pour le tester  les tests unitaires sont indispensables !
  • 25. Threads – Le Global Interpreter Lock (GIL) assure que les traitements concurrents ne se marchent pas dessus : https://docs.python.org/2/glossary.html#term-global-interpreter-lock http://dabeaz.blogspot.fr/2010/01/python-gil-visualized.html – Les modules thread / threading – encapsulent les primitives système de thread – fournissent des primitives de synchronisation : verrous, sémaphores, etc. – ... Mais à aucun moment deux instructions peuvent être exécutées en même temps à cause du GIL !  Mieux vaut utiliser multiprocessing
  • 26. Mémoire partagée – Le module mmap (Memory-mapped file) permet de partager de la mémoire entre plusieurs process – On peut accéder à cette mémoire comme un fichier en lecture / écriture – On accède à cette mémoire comme un tableau de char – Mais on ne peut pas utiliser de types complexes (listes, dictionnaires, objets définis sur mesures)  Pas aussi souple qu’en C++
  • 28. Où va Mappy ? – Amélioration continue de l’outillage – Nouveaux services asynchrones en Python – … Et bientôt un nouveau serveur d'itinéraire en Python / C++ ?
  • 29. Merci Enjoy : http://fr.mappy.com/ Pierre Marquis : pierre.marquis@mappy.com Alexandre Bonnasseau : https://github.com/abonnasseau