1. YouTube Summaries
  2. Build a Free Local Typing Assistant with Python and Ollama

Build a Free Local Typing Assistant with Python and Ollama

By scribe 7 minute read

Create articles from any YouTube video or use our API to get YouTube transcriptions

Start for free
or, create a free article to see how easy it is.

Introduction

In today's fast-paced digital world, typing quickly and accurately is a valuable skill. However, even the most proficient typists make mistakes. What if you could type at lightning speed without worrying about typos, knowing that an intelligent assistant would correct them instantly? This tutorial will guide you through creating your own free typing assistant using Python and Ollama, allowing you to fix typos with a large language model running locally on your machine.

Project Overview

Our typing assistant will have two main functions:

  1. Fix typos in the current line (triggered by pressing F9)
  2. Fix typos in a selected block of text (triggered by pressing F10)

The assistant will use a locally-run large language model to correct spelling, grammar, and punctuation while preserving the original meaning and structure of the text.

Prerequisites

Before we begin, make sure you have the following installed on your system:

  • Python 3.x
  • pip (Python package manager)
  • Ollama (for running the local language model)

Setting Up the Environment

Let's start by creating a new project and setting up a virtual environment:

python -m venv typing_assistant_env
source typing_assistant_env/bin/activate  # On Windows, use `typing_assistant_env\Scripts\activate`

Next, we'll install the necessary libraries:

pip install pynput pyperclip httpx

Implementing Hotkey Listeners

We'll use the pynput library to listen for global hotkeys. Create a new file called main.py and add the following code:

from pynput import keyboard
from pynput.keyboard import Key, Controller

def on_f9():
    print("F9 pressed")

def on_f10():
    print("F10 pressed")

with keyboard.GlobalHotKeys({
    '<101>': on_f9,  # F9
    '<109>': on_f10  # F10
}) as h:
    h.join()

This code sets up listeners for the F9 and F10 keys. When pressed, they will trigger the respective functions.

Implementing Text Selection and Clipboard Manipulation

Next, we'll implement functions to select text and interact with the clipboard. Add the following imports and functions to your main.py file:

import pyperclip
import time

controller = Controller()

def fix_current_line():
    with controller.pressed(Key.cmd, Key.shift):
        controller.press(Key.left)
        controller.release(Key.left)
    time.sleep(0.1)
    fix_selection()

def fix_selection():
    # Copy selected text to clipboard
    with controller.pressed(Key.cmd):
        controller.tap('c')
    time.sleep(0.1)
    
    # Get text from clipboard
    text = pyperclip.paste()
    
    # Fix the text (we'll implement this later)
    fixed_text = fix_text(text)
    
    # Copy fixed text back to clipboard
    pyperclip.copy(fixed_text)
    time.sleep(0.1)
    
    # Paste fixed text
    with controller.pressed(Key.cmd):
        controller.tap('v')

Update the on_f9 and on_f10 functions to call these new functions:

def on_f9():
    fix_current_line()

def on_f10():
    fix_selection()

Integrating Ollama for Text Correction

Now, let's implement the fix_text function using Ollama. First, make sure you have Ollama installed and running on your system. We'll use the Mistral 7B model with the instruct tag for this project.

Add the following code to your main.py file:

import httpx
from string import Template

OLLAMA_ENDPOINT = "http://localhost:11434/api/generate"
OLLAMA_CONFIG = {
    "model": "mistral:instruct-v0.2-q4_K_S",
    "stream": False,
    "keep_alive": "5m"
}

PROMPT_TEMPLATE = Template("""
Fix all typos and the casing and also the punctuation in this text but preserve all new line characters:
$text

Return only the corrected text. Don't include a preamble.
""")

def fix_text(text):
    prompt = PROMPT_TEMPLATE.substitute(text=text)
    
    response = httpx.post(
        OLLAMA_ENDPOINT,
        json={"prompt": prompt, **OLLAMA_CONFIG},
        headers={"Content-Type": "application/json"},
        timeout=10
    )
    
    if response.status_code != 200:
        return None
    
    return response.json()["response"].strip()

This code sets up the Ollama API endpoint, configures the model, and creates a function to send the text to Ollama for correction.

Putting It All Together

Now that we have all the pieces in place, let's update our main script to run the typing assistant:

from pynput import keyboard
from pynput.keyboard import Key, Controller
import pyperclip
import time
import httpx
from string import Template

# ... (keep all the previously defined functions and constants)

def main():
    with keyboard.GlobalHotKeys({
        '<101>': on_f9,  # F9
        '<109>': on_f10  # F10
    }) as h:
        print("Typing assistant is running. Press F9 to fix the current line or F10 to fix the selected text.")
        print("Press Ctrl+C to exit.")
        h.join()

if __name__ == "__main__":
    main()

Running the Typing Assistant

To run your typing assistant, make sure Ollama is running in the background, then execute the following command in your terminal:

python main.py

You should see a message indicating that the typing assistant is running. You can now use F9 to fix the current line or F10 to fix selected text in any application.

Customizing and Extending the Typing Assistant

Now that you have a working typing assistant, there are several ways you can customize and extend its functionality:

1. Try Different Language Models

Ollama supports various language models. You can experiment with different models to find the one that works best for your needs. To change the model, simply update the OLLAMA_CONFIG dictionary in your script:

OLLAMA_CONFIG = {
    "model": "llama2:13b",  # Change to a different model
    "stream": False,
    "keep_alive": "5m"
}

2. Adjust the Prompt Template

You can modify the PROMPT_TEMPLATE to give more specific instructions to the language model. For example, you might want to preserve certain formatting or handle specific types of text differently:

PROMPT_TEMPLATE = Template("""
Fix all typos, casing, and punctuation in this text. Preserve all new line characters and markdown formatting:
$text

Return only the corrected text. Don't include a preamble.
""")

3. Add Support for Different Keyboard Layouts

The current implementation assumes a standard keyboard layout. If you're using a different layout, you may need to adjust the key combinations in the fix_current_line function:

def fix_current_line():
    with controller.pressed(Key.ctrl, Key.shift):  # Change Key.cmd to Key.ctrl for Windows/Linux
        controller.press(Key.home)  # Use Key.home instead of Key.left for some layouts
        controller.release(Key.home)
    time.sleep(0.1)
    fix_selection()

4. Implement Text Formatting Options

You could add additional hotkeys to apply specific formatting options. For example, you might want to add a hotkey to convert text to title case or to remove all formatting:

def to_title_case():
    fix_selection()
    text = pyperclip.paste()
    titled_text = text.title()
    pyperclip.copy(titled_text)
    with controller.pressed(Key.cmd):
        controller.tap('v')

# Add this to your GlobalHotKeys
'<110>': to_title_case,  # F11 for title case

5. Add a GUI for Configuration

To make your typing assistant more user-friendly, you could create a simple GUI using a library like tkinter or PyQt. This GUI could allow users to change settings, select different language models, or customize hotkeys without modifying the code.

6. Implement Context-Aware Corrections

You could enhance the fix_text function to consider the context of the application or document type. For example, you might want to apply different correction rules for code snippets versus natural language text:

def fix_text(text, context="general"):
    if context == "code":
        prompt = "Fix typos in this code snippet, but preserve all syntax and indentation:"
    else:
        prompt = "Fix all typos and improve the grammar of this text:"
    
    full_prompt = f"{prompt}\n{text}\n\nReturn only the corrected text."
    
    # ... (rest of the function remains the same)

7. Add Support for Multiple Languages

If you work with multiple languages, you could implement language detection and use language-specific models or prompts:

from langdetect import detect

def fix_text(text):
    lang = detect(text)
    if lang == 'es':
        prompt = "Corrige todos los errores ortográficos y gramaticales en este texto en español:"
    elif lang == 'fr':
        prompt = "Corrigez toutes les fautes d'orthographe et de grammaire dans ce texte en français :"
    else:
        prompt = "Fix all typos and grammatical errors in this text:"
    
    full_prompt = f"{prompt}\n{text}\n\nReturn only the corrected text."
    
    # ... (rest of the function remains the same)

8. Implement Undo Functionality

Add an undo feature to revert the last correction if the user is not satisfied with the result:

last_original_text = ""

def fix_selection():
    global last_original_text
    # Copy selected text to clipboard
    with controller.pressed(Key.cmd):
        controller.tap('c')
    time.sleep(0.1)
    
    # Get text from clipboard
    text = pyperclip.paste()
    last_original_text = text
    
    # ... (rest of the function remains the same)

def undo_last_correction():
    global last_original_text
    pyperclip.copy(last_original_text)
    with controller.pressed(Key.cmd):
        controller.tap('v')

# Add this to your GlobalHotKeys
'<111>': undo_last_correction,  # F12 for undo

Conclusion

Congratulations! You've successfully built a free, local typing assistant using Python and Ollama. This powerful tool can significantly improve your typing efficiency by automatically correcting typos and grammatical errors as you write.

By leveraging the power of large language models running locally on your machine, you've created a privacy-friendly solution that doesn't rely on external services. This approach ensures that your text remains confidential and allows you to work offline.

Remember that the effectiveness of your typing assistant largely depends on the quality and capabilities of the language model you're using. Experiment with different models available through Ollama to find the one that best suits your needs.

As you continue to use and refine your typing assistant, consider implementing some of the customizations and extensions discussed earlier. These enhancements can tailor the tool to your specific workflow and preferences, making it an even more valuable asset in your daily tasks.

Happy typing, and may your words flow smoothly and error-free with your new AI-powered assistant!

Article created from: https://www.youtube.com/watch?app=desktop&v=IUTFrexghsQ&feature=emb_imp_woyt

Ready to automate your
LinkedIn, Twitter and blog posts with AI?

Start for free