Spaces:
Sleeping
Sleeping
Lazar Radojevic
commited on
Commit
·
3556e6f
1
Parent(s):
45462fb
update README
Browse files- README.md +81 -1
- frontend/app_ui.py +25 -8
- main.py +4 -2
- poe/common-tasks.toml +2 -11
- pyproject.toml +1 -1
- src/prompt_loader.py +3 -2
- src/search_engine.py +1 -1
README.md
CHANGED
@@ -9,4 +9,84 @@ license: apache-2.0
|
|
9 |
app_port: 8000
|
10 |
---
|
11 |
|
12 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
app_port: 8000
|
10 |
---
|
11 |
|
12 |
+
## Overview
|
13 |
+
|
14 |
+
The **Prompt Engine** project is a take-home assignment for the SmartCat recruitment process. This project comprises two main components:
|
15 |
+
|
16 |
+
- **Backend**: A REST API that provides functionality to find similar prompts.
|
17 |
+
- **Frontend**: A user interface for interacting with the backend service.
|
18 |
+
|
19 |
+
### Service Description
|
20 |
+
|
21 |
+
The service retrieves and displays the 5 most similar prompts to a user’s query. This helps improve user queries by showing related examples from a database of well-curated prompts.
|
22 |
+
|
23 |
+
## Setup Instructions
|
24 |
+
|
25 |
+
### Prerequisites
|
26 |
+
|
27 |
+
Before you start, ensure you have the following tools installed:
|
28 |
+
|
29 |
+
- `Poetry`
|
30 |
+
- `Docker`
|
31 |
+
|
32 |
+
### Installation
|
33 |
+
|
34 |
+
1. **Install Dependencies**:
|
35 |
+
|
36 |
+
```bash
|
37 |
+
poetry install
|
38 |
+
```
|
39 |
+
|
40 |
+
2. **Activate the Virtual Environment**:
|
41 |
+
|
42 |
+
```bash
|
43 |
+
poetry shell
|
44 |
+
```
|
45 |
+
|
46 |
+
### Backend Details
|
47 |
+
|
48 |
+
The backend API provides the following endpoint:
|
49 |
+
|
50 |
+
- **Endpoint**: POST /most_similar
|
51 |
+
- **Description**: Accepts a user query and the number of similar prompts to return.
|
52 |
+
|
53 |
+
### Docker
|
54 |
+
|
55 |
+
The repository includes a Dockerfile to build and run the backend service. To build the image:
|
56 |
+
|
57 |
+
```bash
|
58 |
+
docker build -t prompt-search-engine .
|
59 |
+
```
|
60 |
+
|
61 |
+
To start the backend service, run:
|
62 |
+
|
63 |
+
```bash
|
64 |
+
docker run -d -p 8000:8000 prompt-serach-engine
|
65 |
+
```
|
66 |
+
|
67 |
+
This command will build the Docker image and start the service.
|
68 |
+
|
69 |
+
### Deployment
|
70 |
+
|
71 |
+
The project is integrated with HuggingFace Spaces. The solution is automatically deployed to HuggingFace with every push to the repository.
|
72 |
+
|
73 |
+
In case you want to set up your own HuggingFace Space, you must create a HF token and add it with:
|
74 |
+
|
75 |
+
```
|
76 |
+
git remote set-url origin https://USERNAME:[email protected]/spaces/USERNAME/REPO_NAME.git
|
77 |
+
```
|
78 |
+
|
79 |
+
### User Interface
|
80 |
+
|
81 |
+
The frontend UI is simple and includes:
|
82 |
+
|
83 |
+
- A text field for entering the user query.
|
84 |
+
- A slider to specify the number of similar prompts to retrieve
|
85 |
+
|
86 |
+
To start only the UI service you can run:
|
87 |
+
|
88 |
+
```bash
|
89 |
+
poe frontend --api_url http://localhost:8000
|
90 |
+
```
|
91 |
+
|
92 |
+
The default api points to HF Space of this repository.
|
frontend/app_ui.py
CHANGED
@@ -1,13 +1,27 @@
|
|
1 |
-
import
|
|
|
2 |
import requests
|
|
|
3 |
|
4 |
-
|
5 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6 |
|
7 |
|
8 |
-
def get_similar_prompts(query, n):
|
|
|
9 |
try:
|
10 |
-
response = requests.post(
|
|
|
|
|
11 |
response.raise_for_status() # Raise an exception for HTTP errors
|
12 |
return response.json()
|
13 |
except requests.RequestException as e:
|
@@ -16,6 +30,7 @@ def get_similar_prompts(query, n):
|
|
16 |
|
17 |
|
18 |
def get_color(score):
|
|
|
19 |
if score >= 0.8:
|
20 |
return "green"
|
21 |
elif score >= 0.5:
|
@@ -24,7 +39,8 @@ def get_color(score):
|
|
24 |
return "red"
|
25 |
|
26 |
|
27 |
-
def main():
|
|
|
28 |
st.title("Prompt Similarity Finder")
|
29 |
|
30 |
# User input for query
|
@@ -36,7 +52,7 @@ def main():
|
|
36 |
if st.button("Find Similar Prompts"):
|
37 |
if query:
|
38 |
with st.spinner("Fetching similar prompts..."):
|
39 |
-
result = get_similar_prompts(query, n)
|
40 |
if result:
|
41 |
similar_prompts = result.get("similar_prompts", [])
|
42 |
if similar_prompts:
|
@@ -57,4 +73,5 @@ def main():
|
|
57 |
|
58 |
|
59 |
if __name__ == "__main__":
|
60 |
-
|
|
|
|
1 |
+
import argparse
|
2 |
+
|
3 |
import requests
|
4 |
+
import streamlit as st
|
5 |
|
6 |
+
|
7 |
+
def parse_arguments():
|
8 |
+
"""Parse command-line arguments."""
|
9 |
+
parser = argparse.ArgumentParser(description="Prompt Similarity Finder")
|
10 |
+
parser.add_argument(
|
11 |
+
"--api_url",
|
12 |
+
type=str,
|
13 |
+
default="https://lazarr19-prompt-engine.hf.space",
|
14 |
+
help="The URL of the FastAPI service",
|
15 |
+
)
|
16 |
+
return parser.parse_args()
|
17 |
|
18 |
|
19 |
+
def get_similar_prompts(api_url, query, n):
|
20 |
+
"""Fetch similar prompts from the FastAPI service."""
|
21 |
try:
|
22 |
+
response = requests.post(
|
23 |
+
f"{api_url}/most_similar", json={"query": query, "n": n}
|
24 |
+
)
|
25 |
response.raise_for_status() # Raise an exception for HTTP errors
|
26 |
return response.json()
|
27 |
except requests.RequestException as e:
|
|
|
30 |
|
31 |
|
32 |
def get_color(score):
|
33 |
+
"""Determine the color based on the score."""
|
34 |
if score >= 0.8:
|
35 |
return "green"
|
36 |
elif score >= 0.5:
|
|
|
39 |
return "red"
|
40 |
|
41 |
|
42 |
+
def main(api_url):
|
43 |
+
"""Main function to run the Streamlit app."""
|
44 |
st.title("Prompt Similarity Finder")
|
45 |
|
46 |
# User input for query
|
|
|
52 |
if st.button("Find Similar Prompts"):
|
53 |
if query:
|
54 |
with st.spinner("Fetching similar prompts..."):
|
55 |
+
result = get_similar_prompts(api_url, query, n)
|
56 |
if result:
|
57 |
similar_prompts = result.get("similar_prompts", [])
|
58 |
if similar_prompts:
|
|
|
73 |
|
74 |
|
75 |
if __name__ == "__main__":
|
76 |
+
args = parse_arguments()
|
77 |
+
main(args.api_url)
|
main.py
CHANGED
@@ -1,9 +1,11 @@
|
|
|
|
|
|
1 |
from fastapi import FastAPI, HTTPException
|
2 |
from fastapi.responses import HTMLResponse
|
3 |
from pydantic import BaseModel
|
4 |
-
|
5 |
-
from src.search_engine import PromptSearchEngine
|
6 |
from src.prompt_loader import PromptLoader
|
|
|
7 |
|
8 |
# Constants
|
9 |
SEED = 42
|
|
|
1 |
+
from typing import List
|
2 |
+
|
3 |
from fastapi import FastAPI, HTTPException
|
4 |
from fastapi.responses import HTMLResponse
|
5 |
from pydantic import BaseModel
|
6 |
+
|
|
|
7 |
from src.prompt_loader import PromptLoader
|
8 |
+
from src.search_engine import PromptSearchEngine
|
9 |
|
10 |
# Constants
|
11 |
SEED = 42
|
poe/common-tasks.toml
CHANGED
@@ -51,15 +51,6 @@ cmd = """
|
|
51 |
help = "Run all checks on the code base"
|
52 |
sequence = ["style", "types", "lint", "clean"]
|
53 |
|
54 |
-
[tool.poe.tasks.
|
55 |
help = "Start the UI"
|
56 |
-
cmd = "streamlit run ./frontend/app_ui.py"
|
57 |
-
|
58 |
-
[tool.poe.tasks.build]
|
59 |
-
help = "Build the Docker image"
|
60 |
-
cmd = "docker build -t prompt-search-engine ."
|
61 |
-
|
62 |
-
[tool.poe.tasks.start]
|
63 |
-
help = "Run the Docker container"
|
64 |
-
cmd = "docker run -d -p 8000:8000 prompt-serach-engine"
|
65 |
-
|
|
|
51 |
help = "Run all checks on the code base"
|
52 |
sequence = ["style", "types", "lint", "clean"]
|
53 |
|
54 |
+
[tool.poe.tasks.frontend]
|
55 |
help = "Start the UI"
|
56 |
+
cmd = "streamlit run ./frontend/app_ui.py"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pyproject.toml
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
[tool.poetry]
|
2 |
-
name = "smart-cat-assignment
|
3 |
version = "0.0.1"
|
4 |
description = "SmartCat Assignment"
|
5 |
authors = ["Lazar Radojevic <[email protected]>"]
|
|
|
1 |
[tool.poetry]
|
2 |
+
name = "smart-cat-assignment"
|
3 |
version = "0.0.1"
|
4 |
description = "SmartCat Assignment"
|
5 |
authors = ["Lazar Radojevic <[email protected]>"]
|
src/prompt_loader.py
CHANGED
@@ -1,6 +1,7 @@
|
|
1 |
-
from typing import Optional, List
|
2 |
-
from datasets import load_dataset
|
3 |
import random
|
|
|
|
|
|
|
4 |
|
5 |
|
6 |
class PromptLoader:
|
|
|
|
|
|
|
1 |
import random
|
2 |
+
from typing import List, Optional
|
3 |
+
|
4 |
+
from datasets import load_dataset
|
5 |
|
6 |
|
7 |
class PromptLoader:
|
src/search_engine.py
CHANGED
@@ -2,8 +2,8 @@ from typing import List, Sequence, Tuple
|
|
2 |
|
3 |
from sentence_transformers import SentenceTransformer
|
4 |
|
5 |
-
from src.vectorizer import Vectorizer
|
6 |
from src.similarity_scorer import SimilarityScorer
|
|
|
7 |
|
8 |
|
9 |
class PromptSearchEngine:
|
|
|
2 |
|
3 |
from sentence_transformers import SentenceTransformer
|
4 |
|
|
|
5 |
from src.similarity_scorer import SimilarityScorer
|
6 |
+
from src.vectorizer import Vectorizer
|
7 |
|
8 |
|
9 |
class PromptSearchEngine:
|