pyfzf : Python Fuzzy Finder
Tags: python, vim, bash, tooling
Published: 2024-03-10 15:08:12

<!-- FIXME:cover image -->

## Introduction 📪

Programmers understand how much easier their work is when they use a tool like `fzf` to pick data on data pathways in mixed file systems. If you do a quick YouTube video searching, you may get a ton of information on this topic. If I told you that you could utilize this tool without ever leaving your Python coding screen while creating code, how would you react?

Especially in large-scale projects, sometimes you have to search for hours with regex etc. to select data from the texts. Using a fuzzy finder would be a smart solution to eliminate this burden. We will do this with `pyfzf` in the codes we wrote in Python.

Let's continue the explanation without further ado. 


## Requirements 🟥
### Basic Requirements 

![fzf](https://raw.githubusercontent.com/junegunn/i/master/fzf.png)

The basic libraries and tools we will need are given below.

- fzf  :  [https://github.com/junegunn/fzf](https://github.com/junegunn/fzf) 
- pyfzf : [https://github.com/nk412/pyfzf](https://github.com/nk412/pyfzf) 

Here you see a working example of pyfzf:

![fzf](https://raw.githubusercontent.com/nk412/pyfzf/master/pyfzf.gif) 

## Setup ✅

### fzf Setup 

The address provided here has all the information you need to install `fzf`: 

[https://github.com/junegunn/fzf?tab=readme-ov-file#installation](https://github.com/junegunn/fzf?tab=readme-ov-file#installation)

### pyfzf Setup

Using `pip`, we will first need to install our library, `pyfzf`.

```bash 
pip install pyfzf 
```

### Usage 🧰

Workflow and module usage are quite straightforward. Importing the `pyfzf` library comes first. The imported library gets utilized to call the `FzfPrompt` module.
 
```python 
from pyfzf.pyfzf import FzfPrompt
```
Your `fzf` application on your system will be automatically found.

```python
fzf = FzfPrompt()
```
If `fzf` cannot be found automatically, the `fzf` file path must be defined manually.

```python 
# example 
fzf = FzfPrompt("/usr/bin/fzf")
```

## Sample Project: User Agent Selector 📽️
 
Let's create a new project folder. Let's start our project by creating a file named `user_agents.txt` and creating a **.txt** file containing hundreds of `User-Agents`. After saving and closing the file, we create a file named `fzf_choicer.py` and start writing our codes. The Foldertree of our project will be as follows.

```bash 
├── fzf_choicer.py
└── user_agents.txt
```

The content of our `user_agents.txt` file should be like this. Our User-Agent list
We will provide it via [this gist](https://gist.githubusercontent.com/pzb/b4b6f57144aea7827ae4/raw/cf847b76a142955b1410c8bcef3aabe221a63db1/user-agents.txt). 

Here are a few lines of the file content:

```plaintext 

Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/37.0.2062.94 Chrome/37.0.2062.94 Safari/537.36
Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36
Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/600.8.9 (KHTML, like Gecko) Version/8.0.8 Safari/600.8.9
Mozilla/5.0 (iPad; CPU OS 8_4_1 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12H321 Safari/600.1.4
Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36
Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.10240
Mozilla/5.0 (Windows NT 6.3; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0
Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko
Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36
Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0) like Gecko
Mozilla/5.0 (Windows NT 10.0; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0
...

```
First of all, we start by calling our library. 

```python 
from pyfzf.pyfzf import fzfprompt
# fzf = fzfprompt('/usr/bin/fzf')
fzf = fzfprompt()

```

Now let's write the module where we will read the data together.

```python 

def ReadItems(filepath=''):
    with open(f'{filepath}', 'r') as rf:
        rawdata = rf.readlines()
        rawdata = [r.strip() for r in rawdata]
    return rawdata

```

Here, we used the module named `.strip()` to delete the line spaces since the data will come with the expression `\n` during the reading process.

Now, let's write our module that will read from the file and select the data from the stored values:

```python 
def ItemChooser(rawdata):
    data = fzf.prompt(rawdata, fzf_options='--reverse')
    choice = data[0]
    return choice
```
To run these functions, let's call our starter function named `__main__`. Those who are familiar with languages such as GO will know that this function named __main__ is the basic initializer function. When a script runs, the function named __main__ will always run in the background. When you run your codes within this function, you can perform optimization activities more easily. This is one way to run your programs more efficiently.

```python 

if __name__ == "__main__":
    rawdata = ReadItems('user_agents.txt')
    choice = ItemChooser(rawdata)
    print(choice)

```

Let's see our code in its entirety:


![carboncode](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gp3fpj27gq4x5wf7hqee.png)

Now let's examine the visual of how it works:




<img src="https://i.ibb.co/PxgM7Wy/pyfzf.gif" alt="pyfzf" border="0">


## Conlusion 🎙️

We worked to create an application using a library named `pyfzf`. This application allows you to import phrases into your scripts selectively from text files and big lists.


## Contact 📞

You can contact me using the biolink given below: 
[https://linktr.ee/gokayburuc](https://linktr.ee/gokayburuc)

<!-- FIXME: contact info -->