Pythonesse : La prêtresse de l'oracle d'Apollon à Delphes.
Pythonesse d'Emery Berger, extension de Kyle Gwilt et Stephen Freund
Pythoness génère automatiquement du code Python à partir de descriptions et de tests en langage naturel.
Remarque Pythoness doit être connecté à un LLM pour fonctionner. Vous trouverez ci-dessous un exemple montrant comment connecter Pythoness à un compte OpenAI. Pour les autres LLM, consultez leur documentation.
Compte OpenAI. Votre compte devra avoir un solde positif pour que cela fonctionne (vérifiez votre solde). Si vous n'avez jamais acheté de crédits, vous devrez acheter au moins 1 $ de crédits (si votre compte API a été créé avant le 13 août 2023) ou 0,50 $ (si vous avez un compte API plus récent). Obtenez une clé ici.
Une fois que vous disposez d'une clé API, définissez-la comme variable d'environnement appelée
OPENAI_API_KEY
.export OPENAI_API_KEY= < your-api-key >
Le moyen le plus simple d'installer Pythoness consiste à utiliser pip :
python3 -m pip install pythoness
Pour utiliser Pythoness, il vous suffit d'importer le module pythoness
puis d'utiliser le décorateur @pythoness.spec
pour spécifier la fonctionnalité souhaitée :
import pythoness
@ pythoness . spec ( "Compute the nth number in the Fibonacci series." )
def myfib ( n : int ) -> int :
""
Ce code générera en interne une fonction Python nommée myfib
qui calcule le nième nombre de la série de Fibonacci. Pour exécuter réellement la fonction, vous pouvez l'appeler comme n'importe quelle autre fonction Python :
for i in range ( 20 ):
print ( myfib ( i ))
Pythoness met en cache les résultats de la traduction du langage naturel en Python, de sorte que les exécutions ultérieures dans le même répertoire s'exécuteront beaucoup plus rapidement (Pythoness crée une base de données appelée pythoness-cache.db
qui enregistre ces traductions).
Pour désactiver tous les messages de journalisation, utilisez la variable d'environnement PYNS_QUIET
:
env PYNS_QUIET=1 python3 myfib.py
Vous pouvez guider Pythoness en fournissant quelques tests. Pythoness utilisera des tests à la fois pour générer le code Python et pour le valider. Les tests ne sont qu'une liste de chaînes contenant du code ou des fonctions Python qui doivent toutes être évaluées à True
.
@ pythoness . spec ( "Compute the nth number in the Fibonacci series." ,
tests = [ "myfib(1) == 1" , "myfib(2) == 1" ])
def myfib ( n : int ) -> int :
""
Vous pouvez également guider Pythoness avec des tests basés sur les propriétés . Pour ce faire, décrivez les propriétés que vous souhaitez que votre programme présente. Pythoness exécutera un testeur basé sur les propriétés (hypothèse), qui effectuera des tests plusieurs fois pour garantir que la fonction générée répond aux propriétés spécifiées. Cette approche est beaucoup plus puissante que les tests unitaires décrits ci-dessus.
@ pythoness . spec ( "Compute the nth number in the Fibonacci series." , tests = [({ 'n' : 'integers(1,20)' }, "myfib(n+2) == myfib(n+1)+myfib(n)" )])
def myfib ( n : int ) -> int :
""
Les TestCases du framework unittest intégré sont la dernière option de test et peuvent être utilisés en donnant à Pythoness TestCases ou un module de TestCases :
@ pythoness . spec ( "Compute the nth number in the Fibonacci series." , tests = [ testmodule . TestFib ])
def myfib ( n : int ) -> int :
""
Vous pouvez guider davantage Pythoness en lui donnant des fonctions et des classes liées au code qu'il générera. Il utilise la docstring des fonctions et classes fournies pour comprendre leur objectif. Pythoness peut utiliser des fonctions qui seront générées par lui-même de cette manière, où la docstring est spécifiée dans spec
.
related_objs
est une liste qui peut inclure des fonctions, des classes ou des chaînes spéciales :
'cls'
qui représente tout ce qui se trouve dans la classe dans laquelle la fonction générée est contenue, en plus d'elle-même'*'
qui représente tout ce qui se trouve dans le fichier dans lequel la fonction générée est contenue, en plus d'elle-même @ pythoness . spec ( "Encodes a string using a single-shift Caesar cipher" )
def encode ( s : str ) -> str :
""
@ pythoness . spec ( "Decodes a string given to encode()" , related_objs = [ encode ])
def decode ( s : str ) -> str :
""
Lorsque vous travaillez avec des classes, il est préférable d'utiliser la fonctionnalité __slots__
de Python. Bien que Pythoness puisse fonctionner sans lui, cela augmente la cohérence de Pythoness.
Vous pouvez demander à Pythoness de remplacer la spécification directement dans votre fichier par la fonction générée : ajoutez simplement `replace=True' :
@ pythoness . spec ( "Compute the nth number in the Fibonacci series." ,
tests = [ "myfib(1) == 1" , "myfib(2) == 1" ],
replace = True )
def myfib ( n : int ) -> int :
""
Par exemple, Pythoness a produit ce code :
def myfib(n: int) -> int:
"""
Compute the nth number in the Fibonacci series.
:param n: The position of the desired number in the Fibonacci series
:type n: int
:return: The nth number in the Fibonacci series
:rtype: int
"""
if n <= 0:
raise ValueError("n must be a positive integer")
elif n == 1 or n == 2:
return 1
else:
fib1, fib2 = 1, 1
for _ in range(3, n + 1):
fib1, fib2 = fib2, fib1 + fib2
return fib2
Vous pouvez également remplacer chaque fonction générée à l'aide de la variable d'environnement 'PYNS_REPLACE' :
env ' PYNS_REPLACE ' =1
Pythoness propose quelques autres moyens de contrôler son comportement. Ce sont tous des arguments à spec
. Les valeurs fournies indiquent la valeur par défaut.
max_retries=3
: contrôle le nombre maximum de tentatives dues à des échecs (par exemple, une fonction qui échoue à l'un des tests fournis).
model='gpt-4o'
: contrôle quel modèle LLM interroger
timeout_seconds=0
: définit la durée d'expiration d'une seule tentative Pythoness. Par défaut, il n'y a pas de délai d'attente.
verbose=False
: définissez ceci sur True
pour que Pythoness affiche les détails lors de la génération et de la validation du code. Surtout utile pour les développeurs et pour garder un œil sur les progrès. Peut être défini pour chaque fonction à la fois à l'aide de la variable d'environnement 'PYNS_VERBOSE'.
regenerate=False
: définissez ceci sur True
pour générer un nouveau code à chaque fois qu'une fonction est appelée, plutôt que de le stocker et de le réutiliser.
output=False
: définissez ceci sur True
pour que Pythoness génère le code généré la première fois que la fonction est appelée.