minipy, un serveur Python dans son Android

Posté par  . Édité par palm123, BAud, Davy Defaud, Benoît Sibaud, Cyprien et gUI. Modéré par Davy Defaud. Licence CC By‑SA.
Étiquettes :
37
11
juil.
2019
Android

Minipy est une application Android dont les sources sont distribuées sous licence MIT. Cette application permet d’exécuter des petites commandes Python depuis son smartphone ou sa tablette Android. En elle‐même, cette application ne fait pas grand’chose et il faut bien reconnaître que son utilité est très limitée.

Toutefois, son intérêt n’est pas dans le pourquoi, mais plutôt dans le comment. Cette dépêche va donc expliquer comment cette application fonctionne et va détailler les différentes étapes nécessaires à la création de cette application jusqu’à son empaquetage plutôt non conventionnel.

Dans une seconde partie, cette dépêche va s’intéresser à l’architecture de Minipy qui permet de faire tourner « en local » un serveur Python Tornado qui dialogue avec une page HTML (rendue par un WebView) via des WebSockets.

minipy

Sommaire

Partie I : construire un APK from scratch avec Kivy et Buildozer

Il existe plusieurs solutions pour intégrer du Python dans une application Android. Parmi elles, le cadriciel Python Kivy a l’avantage de proposer des widgets. Ces widgets permettent de réaliser des interfaces graphiques avec une gestion multi‐plate‐forme : Windows, GNU/Linux, macOS et Android.

Une simple application « hello world! » avec Kivy

Sur la dernière Ubuntu 18.04 LTS, Kivy est disponible dans les paquets officiels de la distribution et s’installe très facilement avec un simple sudo apt install python3-kivy.

L’installation peut ensuite être testée en réalisant une application « hello world! » minimaliste telle que le montre le script suivant (script tiré du wiki officiel) :

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.label import Label

class Lesson1App(App):
    def build(self):
        lbl=Label(text='Hello World!')
        return lbl
if __name__ == '__main__': 
    Lesson1App().run()

Après avoir exécuté ce script, vous devriez voir une fenêtre graphique ressemblant à l’image suivante :
Hello World!

L’intérêt principal de Kivy est d’utiliser un code multi‐plate‐forme qui donnera le même rendu et le même comportement sur GNU/Linux, macOS et Android.

Créer son APK avec Buildozer

Une fois l’application réalisée, vient l’étape de création de l’Android application package (APK). Pour aider à cette tâche plutôt ingrate, Buildozer, un projet lui‐même basé sur Python-For-Android (souvent abrégé par p4a) permet de créer un APK sans trop de douleur. Buildozer est un script Python qui permet de :

  1. télécharger et d’installer les API et SDK Android ;
  2. télécharger les différentes sources des modules Python (ceux‐ci doivent être déclarés dans un fichier de configuration buildozer.spec) ;
  3. effectuer une compilation croisée de ces sources pour les terminaux Android (généralement pour les plates‐formes armeabi-v7a) ;
  4. rédiger le manifeste (manifest) Android pour, finalement, créer l’APK correspondant.

Essayons cela avec notre mini‐programme « hello world! ».

Installation de Buildozer

Tout d’abord, il faut installer Buildozer. Celui‐ci peut être installé via pip avec la commande (testé sur Ubuntu 18.04 LTS) :

sudo python3 -m pip install --upgrade buildozer

Pour la dernière Ubuntu LTS, la documentation recommande aussi de faire les manipulations suivantes :

sudo pip install --upgrade cython==0.28.6
sudo dpkg --add-architecture i386
sudo apt update
sudo apt install build-essential ccache git libncurses5:i386 libstdc++6:i386 libgtk2.0-0:i386 libpangox-1.0-0:i386 libpangoxft-1.0-0:i386 libidn11:i386 python2.7 python2.7-dev openjdk-8-jdk unzip zlib1g-dev zlib1g:i386

Attention, utiliser pip en mode "super utilisateur" n'est pas une pratique très recommandée, vous pouvez utiliser des méthodes plus sûres d'installation comme expliquées ici

Création du fichier de config Buildozer

Une fois l’installation de buildozer réalisée, vous devez vous placer dans le répertoire de votre script Python et lancer la commande buildozer init. Celle‐ci crée un fichier de configuration par défaut qui se nomme buildozer.spec. Votre répertoire courant doit donc maintenant contenir deux fichiers :

.
├── buildozer.spec
└── main.py

Notez que le script Python doit se nommer main.py.

Maintenant, il ne vous reste plus qu’à brancher votre appareil Android sur votre PC en activant le mode de débogage Android, puis exécuter la commande :

buildozer android debug deploy run

La première fois que vous exécutez cette commande, cela peut être assez long… Soyez patient !

Cette commande va :

  1. créer un APK Android en mode débogage (option android debug) ;
  2. la déployer sur le téléphone/tablette Android (option deploy) ;
  3. exécuter cet APK sur votre téléphone/tablette (option run).

À l’issue de cette commande, vous devriez voir votre application s’exécuter sur votre appareil Android. De plus, votre répertoire courant doit maintenant contenir :

.
├── .buildozer
├── bin
│   └── myapp-0.1-debug.apk
├── buildozer.spec
└── main.py

Aux deux précédents fichiers buildozer.spec et main.py, ce sont rajoutés un dossier caché .buildozer qui contient tout un tas de fichiers (notamment, les sources des modules Python utilisés par main.py) et un nouveau dossier bin dans lequel se trouve votre APK.

Maintenant, si vous souhaitez que Monsieur et Madame Michu puissent utiliser votre application, vous voulez sans doute la distribuer sur Google Play. Or, en l’état, cet APK ne peut pas y être déposée. La partie suivante montre comment rendre l’APK compatible avec ggplay.

Rendre l’APK compatible avec Google Play

Cette partie traite d’un service privateur. Pour distribuer votre application, vous pouvez vous tourner aussi vers des magasins d’applications alternatifs ouverts et respectueux de votre vie privée, tels que F‑Droid.

Tout d’abord, il va falloir créer un APK en mode release. Pour cela, il faut d’abord changer la valeur par défaut du champ package.domain du fichier buildozer.spec, puis lancer buildozer avec la commande :

buildozer android release

À ce stade, il semble y avoir une erreur ! Buildozer cherche à copier l’APK depuis un sous‐dossier release-unsigned alors que celui-ci se trouve dans un dossier nommé release. Nous allons donc copier à la main ce fichier dans le répertoire bin avec la commande :

cp .buildozer/android/platform/build/dists/myapp/build/outputs/apk/release/myapp-release-unsigned.apk ./bin

L’APK myapp-release-unsigned.apk se trouve maintenant dans le répertoire bin. À présent, nous allons créer une clé pour signer cette application grâce à keytool, disponible dans les security tools d’OpenJDK avec la commande :

keytool -genkey -v -keystore my-app.keystore -alias cb-play -keyalg RSA -keysize 2048 -validity 10000

Aprés avoir répondu à différentes questions, cette commande crée un fichier my-app.keystore qui contient votre clé de chiffrement. Le programme jarsigner, disponible également dans les security tools d’OpenJDK, va nous servir à signer l’APK avec la commande :

jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore ./my-app.keystore ./bin/myapp-release-unsigned.apk  cb-play

Une dernière étape consiste maintenant à « zipaligner » votre application. Pour trouver l’exécutable zipalign, il faut un peu fouiner dans les entrailles de buildozer. Chez moi, celui‐ci se trouve dans le dossier ~/.buildozer/android/platform/android-sdk/build-tools/29.0.0. Pour « zipaligner » l’APK, il suffit de lancer la commande :

~/.buildozer/android/platform/android-sdk/build-tools/29.0.0/zipalign -v 4 ./bin/myapp-release-unsigned.apk ./bin/myapp.apk

Et Voilà ! Le fichier myapp.apk se trouvant dans le répertoire bin peut être déposé sur Google Play.

Cette première partie a permis d’introduire très brièvement Kivy et le cycle de création d’un APK grâce à Buildozer et aux security tools d’OpenJDK. La partie suivante propose de revenir sur minipy en détaillant son architecture particulière client Web / serveur Python.

Partie II : retour sur minipy

Un défaut majeur de Kivy est son rendu plutôt simpliste, peu compatible avec les critères esthétiques des applications d’aujourd’hui. Par exemple, l’image suivante (issue de la doc de Kivy) montre une fenêtre de connexion. Vous en conviendrez, c’est plutôt moche minimaliste :

snapshot kivy

L’idée est donc de transformer notre application en WebApp, c’est‐à‐dire une application dont la partie graphique sera rendue par des pages Web via des WebView. En effet, les technologies HTML5, CSS et JavaScript disposent de bibliothèques comme Bootstrap qui permettent des rendus de grande qualité graphique avec un minimum d’effort.

Aussi, la communication entre Python et les pages Web sera assurée par un serveur Python léger du nom de Tornado qui permet de prendre en charge le protocole standard WebSocket largement utilisé dans les technologies Web.

Voici un petit schéma qui synthétise l’architecture retenue :

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!               APK ANDROID               !
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!     PYTHON                   WEBVIEW    !
! ##############           ############## !
! # tornado    # websocket # html       # !
! # numpy      # <-------> # css        # ! 
! # etc.       #           # javascript # !
! ##############           ############## !
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Une WebApp pour s’affranchir des widgets Kivy

Minipy montre comment implémenter cette architecture « serveur Python‐client Web". À ce titre, c’est un simple « démonstrateur » qui se contente d’illustrer cette solution et rien de plus ! Aussi, l’utilisation de minipy consiste simplement à :

  1. entrer des commandes Python dans le client HTML ;
  2. ces commandes sont ensuite envoyées au serveur Tornado via des WebSocket du client vers le serveur ;
  3. le serveur Python interprète ces commandes puis retourne le résultat via (encore) des WebSockets, mais cette fois du serveur vers le client ;
  4. le client Web reçoit le résultat (via un événement JavaScript) et affiche ce résultat dans une fenêtre modale.

Les deux captures d’écran suivantes montrent minipy en action :
snap1

Exécuter minipy sur GNU/Linux

Si vous clonez minipy, avec la commande git clone https://gitlab.com/damien.andre/minipy.git, vous verrez apparaître l’arborescence de fichiers :

├── apk
│   └── minipy-0.102.apk
├── LICENSE
├── README.md
└── src
    ├── buildozer.spec   # fichier de config buildozer
    ├── data             # dossier contenant quelques fichiers pour Android dont :
    │   ├── logo.png     # l’icône de l’app dans le menu Android
    │   ├── logo.svg     # le source SVG
    │   ├── splash.png   # l’image « splash screen » affichée au lancement de l’app
    │   └── splash.svg   # le source SVG
    ├── html             # dossier contenant les sources pour le client HTML dont :
    │   ├── favicon.png  # l’image favicon
    │   ├── header.png   # l’image d’en‐tête
    │   ├── header.svg   # le source SVG
    │   ├── minipy.css   # le fichier CSS
    │   ├── minipy.html  # le fichier HTML
    │   ├── minipy.js    # le fichier JavaScript
    │   └── vendor       # le dossier contenant des bibliothèques tierces dont :
    │       ├── jquery-ui.min.js # jQuery
    │       └── waitingfor.js    # bibliothèque pour la boîte de dialogue « patientez »
    └── main.py          # le serveur Python

Le démarrage de minipy consiste simplement à exécuter le script main.py. Aussi, il suffit de faire :

cd src
python3 ./main.py

Dans le cas d’Android, notez que le script main.py est exécuté automatiquement.

Autopsie de la partie serveur main.py

Le script main.py doit assurer les fonctions suivantes :

  1. implémenter le serveur Tornado (c’est‐à‐dire paramétrer son comportement) ;
  2. exécuter le serveur Tornado dans un fil d’exécution séparé ;
  3. exécuter le client Web dans un fil d’exécution séparé.

L’objet de cette dépêche n’est pas l’implémentation d’un serveur Tornado. Aussi, il ne sera pas abordé en détail le point no 1. En revanche, les points nos 2 et 3 nécessitent quelques astuces qui vont être détaillées ici.

Tout se passe dans le constructeur Wv invoqué au démarrage du script. Wv est une classe qui dérive de Kivy.Widget. C’est une astuce car, en fait, le widget n’affiche rien. Aussi, le constructeur donne :

class Wv(Widget):                                                                               
    def __init__(self, **kwargs):
        self.f2 = self.create_webview       # sans ça… c’est le bogue !
        super(Wv, self).__init__(**kwargs)  # invoque le constructeur parent
        self.visible = False                # le widget n’affiche rien
        WebServer().start()                 # serveur tornado (voir plus loin)
        if platform == 'android':           # on démarre les clients… 
            Clock.schedule_once(self.create_webview, 0)   # … Android 
        else:
            Clock.schedule_once(self.open_web_browser, 0) # … autres qu’Android

Démarrage automatique du client Web

Ici, il est nécessaire de traiter à part le cas d’Android, car le client WebView doit être démarré dans le fil d’exécution graphique principal :

## class Wv(Widget):    
## ... ... ... ...
    @run_on_ui_thread                                                                           
    def create_webview(self, *args):
        webview = webView(activity)
        webview.getSettings().setJavaScriptEnabled(True)
        wvc = webViewClient();
        webview.setWebViewClient(wvc);
        activity.setContentView(webview)
        file_path = "file:///" + getcwd() + "/html/minipy.html"
        webview.loadUrl(file_path)

Ici, le décorateur @run_on_ui_thread est utilisé afin de créer un objet WebView de l’API d’Android qui pointe vers le fichier minipy.html. Le WebView est créé grâce à PyJnius, une bibliothèque Python qui sert de passerelle pour manipuler des classes et objets Java. Ce sera ici la seule compromission avec utilisation du langage Java.

En revanche, si minipy est exécutée sur une plate‐forme autre qu’Android, le démarrage du client Web est réalisé simplement grâce au module webbrowser selon :

## class Wv(Widget):    
## ... ... ... ...
    def open_web_browser(self, *args):
        import webbrowser
        webbrowser.open_new_tab('./html/minipy.html')

Implémentation du serveur Tornado

La ligne WebServer().start() du constructeur de Wv permet de créer et d’exécuter le serveur Tornado dans un nouveau fil d’exécution (non graphique, cette fois). Pour cela, la classe WebServer dérive de la classe Thread et implémente la méthode run(self). Cette méthode démarre le serveur Tornado qui écoute des WebSockets sur le port 9999 :

class WebServer(Thread):
    def __init__(self):
        super(WebServer, self).__init__()

    def run(self):
        Logger.info("Awaiting connection on port 9999")
        asyncio.set_event_loop(asyncio.new_event_loop())
        application = tornado.web.Application([(r'/ws', EchoWebSocket),])
        application.listen(9999)
        tornado.ioloop.IOLoop.instance().start()

Le comportement du serveur Tornado est défini au travers de la classe EchoWebSocket, qui dérive de websocket.WebSocketHandler. Cette classe surcharge les méthodes open(self), on_message(self, message), on_close(self) et check_origin(self, origin) :

class (websocket.WebSocketHandler):
    def open(self): # lorsqu’une connexion s’ouvre
        ...
    def on_message(self, message): # lorsqu’un message du client arrive
        ...
    def on_close(self): # lorsque la connexion s’arrête
        ...
    def check_origin(self, origin): # pour certifier l’origine de la connexion
        return True # toujours vrai car tout se passe en local

Ces méthodes sont exécutées lors des différents événements énumérés ci‐dessus. Il suffit donc de surcharger ces méthodes pour obtenir les comportements souhaités. Dans le cas de minipy, le plus intéressant se passe dans la méthode on_message(self, message), dont voici un aperçu :

def on_message(self, message):
        json_data = json.loads(message)
        if (json_data['cmd'] == 'interpret'):
             res = str(eval(json_data['content'], self.global_env, self.local_env))
             msg = "your cmd '{}' gives '{}'".format(json_data['content'], res)
             self.send_msg(msg)

def send_msg(self, msg):
        json_data = {}
        json_data['cmd'] = 'msg'
        json_data['content'] = msg
        self.write_message(json.dumps(json_data))

Dans le cas de minipy, les messages venant des WebSockets sont encodés et décodés via JSON, un format qui a l’avantage d’être très bien géré par Python et JavaScript.

Dans minipy, le choix a été fait d’utiliser la clé cmd pour spécifier le type de comportement voulu par le client. Si le champ associé à la clé cmd est la chaîne de caractères interpret, alors :

  1. minipy va interpréter en Python (avec la fonction interne eval()) le message envoyé par le client (champ associé à la clé content) ;
  2. puis le résultat res est renvoyé au client (toujours au format JSON) grâce à la méthode write_message héritée de la classe parente websocket.WebSocketHandler.

Voici donc un bref aperçu de la partie serveur, la suite concerne maintenant le client Web et plus particulièrement le code JavaScript permettant d’implémenter les WebSockets.

Le client JavaScript minipy.js

Lors du chargement de la page Web minipy.html, le fichier JavaScript minipy.js est automatiquement exécuté. Celui‐ci tient en quelques lignes dont voici un aperçu :

// création d’un websocket lors du chargement de la page
var ws = new WebSocket("ws://127.0.0.1:9999/ws"); 

// lorsqu’un message arrive
ws.onmessage = function(e){    
    json = JSON.parse(e.data);
    if(json["cmd"]=="msg") {
    $('#modal-msg-content').html(json["content"]);
    $('#modal-msg').modal('show');
    }
}

Ici, le traitement des messages suit la même procédure que pour Python. Le message encodé en JSON doit contenir la clé cmd. Si le champ associé à cette clé est msg alors une fenêtre modale Bootstrap apparaît. Finalement, le contenu de cette fenêtre modale a été préalablement défini par le champ associé à la clé content du message JSON (voir partie serveur).

Conclusion

Si vous êtes un « fanatique enthousiaste de Python » et que vous voulez tout faire avec ce langage, alors cette dépêche vous donne quelques clés pour développer et déployer votre application Android codée en Python grâce à Kivy et Buildozer.

Toutefois, le cadriciel Kivy pêche un peu par son rendu graphique. Aussi, minipy propose une solution originale pour contrecarrer ce problème : le rendu graphique est déporté grâce à un client Web, tout en conservant Python pour la partie serveur.

En résumé, cette dépêche montre et détaille les quelques étapes clés permettant de coder des applications Android au design sympa grâce aux technologies Web et avec votre langage préféré… a.k.a Python !

Aller plus loin

  • # Kivy est un excellent cadriciel graphique

    Posté par  (site web personnel, Mastodon) . Évalué à 10. Dernière modification le 12 juillet 2019 à 07:22.

    Salut et merci pour ton article qui fait un peu connaître Kivy, p4a et buildozer.

    Par contre je pense que tu sous-estimes Kivy, le thème sombre par défaut ne plaît sans doute pas à tout le monde, mais un des intérêts de ce cadriciel c'est qu'il est très facile de l'adapter et de faire rapidement des choses très jolies. Si tu n'aimes pas les widgets de base, tu as KivyMD qui est une collections de widgets inspirés de Material Design, tu as une démo en vidéo sur la page que je viens de lier, et sinon ça ressemble à ça :

    image de démo de KivyMD

    Il est aussi très facile d'adapter toi même les widgets, grâce notamment à Kv, le langage descriptif utilisé en complément de Python pour gérer les widgets. Voici par exemple la capture de Cagou (SàT), le client XMPP sur lequel je travaille, dans sa version Android:

    Cagou (SàT) sur Android

    Alors oui tu as la possibilité d'utiliser Python-for-Android avec des cadriciels web, mais c'est dommage de passer à côté de Kivy qui est excellent est bien maintenu (et avec une communauté sympa en prime, leur seul défaut est d'utiliser une messagerie proprio et centralisée, mais peut-être qu'un jour j'arriverai à les faire passer sur XMPP :) ).

    Le reste de l'écosystème est tout aussi bon, et Pyjnius que tu as cité permet d'accéder à l'API Java. Il y a également Plyer qui est un module multi-plateformes pour utiliser facilement les fonctions comme l'appareil photo, le GPS, ou l'état de la batterie.

    Aussi Kivy fonctionne bien sur Windows (il faudrait sans doute le préciser dans la dépêche), et même sur iOS qui n'a pas été cité.

    Bref, c'est un écosystème super et le résultat d'un énorme travail collectif, c'est vraiment dommage qu'il ne soit pas plus connu, espérons que ce genre de dépêche aide à sa démocratisation.

    • [^] # Re: Kivy est un excellent cadriciel graphique

      Posté par  (Mastodon) . Évalué à 2. Dernière modification le 12 juillet 2019 à 07:29.

      Aussi Kivy fonctionne bien sur Windows (il faudrait sans doute le préciser dans la dépêche), et même sur iOS qui n'a pas été cité.

      Corrigé, merci.

      En théorie, la théorie et la pratique c'est pareil. En pratique c'est pas vrai.

    • [^] # Re: Kivy est un excellent cadriciel graphique

      Posté par  . Évalué à 4.

      Concernant le design, j'ai vraiment eu du mal à obtenir quelque chose qui me satisfasse en n'utilisant que les widgets Kivy. C'est pour cela que je me suis tourné vers une techno que je connaissais un peu mieux (HTML5/CSS/JavaScript).

      Par contre, je dois dire que je suis carrément passé à coté des exemples que tu montres. Si j'avais eu à l'esprit que l'on pouvait obtenir ce genre de rendu, j'aurais un peu plus insisté avec Kivy.

      Enfin, mea culpa pour Windows !

  • # sudo pip?

    Posté par  (site web personnel) . Évalué à 6.

    Merci pour l'article intéressant.

    Par contre je pense qu'utiliser pip en tant que root n'est pas une super idée. De mon expérience il est préférable de laisser le gestionnaire de paquets de sa distrib gérer les paquets python dans les répertoires dédiés, et d'utiliser virtualenv (ou conda), voire pip --user pour ce que la distrib ne package pas.

    Mais peut-être que quelqu'un va me contredire ?

    • [^] # Re: sudo pip?

      Posté par  . Évalué à 1.

      Bonjour, c'est vrai que le sudo pip est un peu brutal. Je propose de faire comme cela dans la dépêche car je suis une machine perso de développement et que Builodzer n'est pas présent dans les paquets de ma distrib.

      Si un modo passe par là, peut-il rajouter SVP la petite phrase suivante : Attention, utiliser pip en mode "super utilisateur" n'est pas une pratique très recommandée, vous pouvez utiliser des méthodes plus sûres d'installation comme expliquées ici

  • # responsive et compatibilité

    Posté par  . Évalué à 4.

    Merci pour cet article.

    J'ai développé une application avec Kivy.
    Mais dès que j'ai voulu faire un truc un peu joli, je me suis confronté au problème : c'est beau sur mon téléphone mais dès que je passe sur un autre téléphone c'est moche. Est-ce qu'il y a un moyen simple pour ça ou il faut tester chaque résolution de téléphone ?

    Sinon comme autre problème que j'ai eu : impossibilité de l'installer sur certains téléphones. Comment ça marche la compatibilité sur Android ?

    • [^] # Re: responsive et compatibilité

      Posté par  (site web personnel, Mastodon) . Évalué à 4.

      Mais dès que j'ai voulu faire un truc un peu joli, je me suis confronté au problème : c'est beau sur mon téléphone mais dès que je passe sur un autre téléphone c'est moche. Est-ce qu'il y a un moyen simple pour ça ou il faut tester chaque résolution de téléphone ?

      Tu as les mesures indépendantes de la densité en pixels (dp) qui sont gérées par Kivy, cf. https://kivy.org/doc/stable/api-kivy.metrics.html

      Sinon comme autre problème que j'ai eu : impossibilité de l'installer sur certains téléphones. Comment ça marche la compatibilité sur Android ?

      Je n'ai pas la possibilité de tester sur des centaines de téléphones, mais de mon expérience ça marche plutôt bien. Je pense que c'est surtout l'API minimale que tu déclares dans Python-for-Android qui détermine si tu peux l'installer ou pas. À voir avec les équipes derrière Kivy si ça marche sur un téléphone et pas un autre, peut-être qu'il y a un bogue à remonter.

      • [^] # Re: responsive et compatibilité

        Posté par  (site web personnel) . Évalué à 2.

        Quand on veut réellement gérer la diversité des affichages qu'on peut trouver sur Android, utiliser les dps ne suffit pas. L'idéal est :

        • de ne rien mettre en dimension, sauf les marges / paddings, mais utiliser des layouts plus adaptatives à base de contraintes
        • d'avoir des layouts séparés pour les situations très différentes (portrait/paysage, plein de dp/pas beaucoup de dp, etc), le plus dur étant de gérer tous ces cas sans trop alourdir le code

        Après, je ne sais pas si Kivy permet de faire ce genre de choses, mais c'est déjà un sujet loin d'être trivial avec les outils de dev Android ^

  • # ça me semble parfait pour wuy

    Posté par  (site web personnel) . Évalué à 1.

    Merci pour ce post assez clair.

    J'édite une couche (https://github.com/manatlan/wuy) qui permet de réaliser "facilement" des GUI sur n'importe quelle plateforme. En utilisant principalement chrome, en mode "app" (un peu comme python-eel, mais en moins buggé).
    Le GUI se fait "facilement", en html/js/css … et wuy propose une couche JS qui permet de discuter facilement avec la partie serveur, via des websockets. Côté serveur, une couche python permet de discuter facilement avec le GUI. Accessoirement, c'est très facile de générer un "exe" pour chaque OS. Mais ça necessite d'avoir chrome sur l'os hôté.
    Alternativement, j'ai fait des tests avec cefpython3, pour embbeded chrome dans l'exe : ça marche à l'identique. (et permet de passer outre la necessité d'avoir chrome sur l'os hôte)

    (accessoirement, avec une couche comme vbuild (https://github.com/manatlan/vbuild), il est très simple d'embedder une appli vuejs en python only)

    J'aimerai porter cette solution sur android. J'ai un peu testé avec buildozer, mais je ne suis pas arrivé à mes fins. (Côté serveur python, j'utilise aiohttp).

    Si je comprends bien, j'aurai 2 options :
    - soit je fais, comme toi, j'utilise kivy, pour réutiliser la webview/android. et je devrai arrivé à m'en sortir avec tes infos . (en remplaçant tornado par aiohttp)
    - soit je persiste et j'essai de buildozer avec cefpython3. (mais ce dernier n'est pas encore compatible android, je crois)

    la soluce 1 me paraît plus simple maintenant …
    SI j'ai des soucis : tu peux m'aider ?

    • [^] # Re: ça me semble parfait pour wuy

      Posté par  (site web personnel) . Évalué à 1.

      bon, j'ai réussi, après 3/4h de galères, à faire le tuto pour tester la compilation/installation de l'apk sur l'android.
      Globalement, ça marche …
      (ma plus grosse galère : j'ai du récupérer le répertoire "sources" pour le mettre dans le NDK android (sinon erreur cxx-stl/system) du buildozer)

      mais à l'execution, la webview n'arrive pas à se connecter à la socket (sur xiaomi mi9 uptodate).

      mais c'est le même résultat que l'apk du playstore.
      (est-ce que ça marche chez qqu'un ?)

      Donc, c'est ISO ;-)

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.