KeiruaProd

I help my clients acquire new users and make more money with their web businesses. I have ten years of experience with SaaS projects. If that’s something you need help with, we should get in touch!
< Back to article list

Un REPL avec readline

Quand on ouvre un interpreteur python (avec… python) ou ruby (avec irb), on est face à un REPL, c’est à dire un programme qui boucle en :

Read, Eval, Print, Loop. REPL.

On peut implémenter la base assez facilement, mais il y a 2-3 outils assez intéressants, comme la gestion de l’historique, la complétion, etc. que l’on retrouve avec un simple import readline python:

import os
import readline
import atexit
import getpass

def run_repl(eval_func):
    # Load history, if any
    HISTORY_FILE = os.path.join(os.path.expanduser("~"), ".gpt3_repl_history")
    if os.path.exists(HISTORY_FILE):
        readline.read_history_file(HISTORY_FILE)
        # default history len is -1 (infinite), which may grow unruly
        readline.set_history_length(1000)

    atexit.register(readline.write_history_file, HISTORY_FILE)

    current_user = getpass.getuser()

    # our REPL
    while True:
        try:
            line = input(f"{current_user} > ")
            if len(line.strip()) > 0:
                readline.write_history_file(HISTORY_FILE)
                answer = eval_func(line)
                print(answer)
        except ValueError as e:
            print("error:", e)
        except (KeyboardInterrupt, EOFError):
            break

if __name__ == "__main__":
    run_repl(eval)

Si on croise ce bout de code avec la fonction ask_openai vue un post précédent, on a un REPL pour échanger avec l’IA d’openAI. J’ai appelé le mien Jarvis

#!/usr/bin/env python3
# coding=utf-8

import openai, os, time
import readline
from dotenv import load_dotenv
import getpass

def ask_openai(prompt: str) -> str:
    """
    Send the 'prompt' to ChatGPT.
    Return the answer (that may span multiple seconds)
    """
    response = openai.Completion.create(
        model="text-davinci-003",
        prompt=prompt,
        max_tokens=4000,  # tune how many tokens you want
        temperature=0,
        stream=True,
    )

    pieces = [e["choices"][0]["text"] for e in response]
    return "".join(pieces)

def run_repl(eval_func):
	current_user = getpass.getuser()

    # Load history, if any
    HISTORY_FILE = os.path.expanduser("~/.gpt3_repl_history")
    if os.path.exists(HISTORY_FILE):
        readline.read_history_file(HISTORY_FILE)

    # our REPL
    while True:
        try:
            line = input(f"{current_user} > ")
            if len(line.strip()) > 0:
                readline.write_history_file(HISTORY_FILE)
                print(eval_func(line))
        except ValueError as e:
            print("error:", e)
        except (KeyboardInterrupt, EOFError):
            break


def main():
    # Load the environment variables from .env
    load_dotenv()
    openai.api_key = os.getenv("OPENAI_API_KEY")

    run_repl(ask_openai)

if __name__ == "__main__":
    main()