How to build an AI Product (5) - FastAPI Backend Service: Return Similar Sentences
FastAPI is a modern web framework for building APIs with Python 3.6+ based on standard Python type hints. It's known for its speed and easy-to-use syntax.
Below, we showcase how to create a simple FastAPI backend service that accepts a sentence and returns similar sentences.
Setting up the environment: Start by installing FastAPI and an ASGI server, like uvicorn
.
pip install fastapi[all] uvicorn
Create a new FastAPI instance: Let's create a new Python file, main.py
from fastapi import FastAPI
from typing import List
from annoy import AnnoyIndex
import numpy as np
from sentence_transformers import SentenceTransformer
import os
from typing import Dict
# Initializing the model
model = SentenceTransformer('paraphrase-MiniLM-L6-v2')
app = FastAPI()
# Number of dimensions should be specific to the embeddings model used when creating the index.
t = AnnoyIndex(384, 'angular')
# Load the pre-built Annoy index
t.load('text_embeddings_index.ann')
# Create a function to convert text to embedding. This will be used to encode the input text.
def text_to_vector(text: str) -> np.array:
print(text)
return model.encode(text)
@app.get("/similar/")
def get_similar_sentences(sentence: str, num_results: int = 5) -> Dict[str, str]:
# Convert the input sentence to a vector
vector = text_to_vector(sentence)
# Query the Annoy index for the most similar vectors
indices = t.get_nns_by_vector(vector, num_results)
# For simplicity, we're returning the indices of the most similar sentences.
# In practice, you might want to map these indices back to the actual sentences or data.
return {"similar_indices": '|'.join([str(k) for k in indices])}
Please note, in the above code snippet we are loading the Annoy index created in previous tutorials.
We will go over various sections of the code and learn more about what each chunk of the code is doing.
Embedding Function: To use vector search, you will need to convert the input text into an embedding vector.
Create a function text_to_vector
that converts a sentence into the embedding vector. In practice, this could be a wrapper around a model like Word2Vec, FastText, or BERT. In our case we will use the sentence transformer model with the same embeddings model that was used to index the documents.
# Create a function to convert text to embedding. This will be used to encode the input text.
def text_to_vector(text: str) -> np.array:
print(text)
return model.encode(text)
Endpoint for Similar Sentences: Create an endpoint /similar
to process the text, convert it to a vector, and find the most similar vectors in the Annoy index.
@app.get("/similar/")
def get_similar_sentences(sentence: str, num_results: int = 5) -> Dict[str, str]:
# Convert the input sentence to a vector
vector = text_to_vector(sentence)
# Query the Annoy index for the most similar vectors
indices = t.get_nns_by_vector(vector, num_results)
# For simplicity, we're returning the indices of the most similar sentences.
# In practice, you might want to map these indices back to the actual sentences or data.
return {"similar_indices": '|'.join([str(k) for k in indices])}
The indices need to be used to look-up the actual sentences. This is left as an assignment to the reader.
Run the FastAPI app: Use uvicorn
to run the FastAPI application.
uvicorn main:app --host 0.0.0.0 --port 3000
Now lets query the above service.
We will use requests
library in Python.
Install the requests
library: If you haven't already installed it:
pip install requests
Querying the FastAPI service: Create a new Python script, query_service.py
, to make the request:
import requests
def query_similar_sentences(sentence: str, num_results: int = 5):
url = "http://127.0.0.1:3000/similar/"
params = {
"sentence": sentence,
"num_results": num_results
}
response = requests.get(url, params=params)
if response.status_code == 200:
return response.json()
else:
print(f"Error {response.status_code}: {response.text}")
if __name__ == "__main__":
sentence = "Your sample sentence"
results = query_similar_sentences(sentence)
print(results)
Run the script: Execute the query_service.py
script:
python query_service.py
With this query_service.py
script, you're using Python's requests
library to make an HTTP GET request to your FastAPI service, sending the desired sentence as a query parameter and receiving the indices of similar sentences from the Annoy index in response.
🤖 Want to Build the Next Big AI Product?
Join our hands-on, real-life bootcamp and transform your ideas into groundbreaking AI solutions.
Sign Up Now