mirror of
https://github.com/hwchase17/langchain.git
synced 2025-09-01 19:12:42 +00:00
Templates (#12294)
Co-authored-by: Harrison Chase <hw.chase.17@gmail.com> Co-authored-by: Lance Martin <lance@langchain.dev> Co-authored-by: Jacob Lee <jacoblee93@gmail.com>
This commit is contained in:
1
templates/self-query-supabase/.gitignore
vendored
Normal file
1
templates/self-query-supabase/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.env
|
103
templates/self-query-supabase/README.md
Normal file
103
templates/self-query-supabase/README.md
Normal file
@@ -0,0 +1,103 @@
|
||||
# Self-querying with Supabase
|
||||
|
||||
> [Supabase](https://supabase.com/docs) is an open-source Firebase alternative. It is built on top of [PostgreSQL](https://en.wikipedia.org/wiki/PostgreSQL), a free and open-source relational database management system (RDBMS) and uses [pgvector](https://github.com/pgvector/pgvector) to store embeddings within your tables.
|
||||
|
||||
Use this package to host a LangServe API that can [self-query](https://python.langchain.com/docs/modules/data_connection/retrievers/self_query) Supabase. You'll be able to use natural language to generate a structured query against the database.
|
||||
|
||||
## Install Package
|
||||
|
||||
From within your `langservehub` project run:
|
||||
|
||||
```shell
|
||||
poetry run poe add self-query-supabase
|
||||
```
|
||||
|
||||
## Setup Supabase Database
|
||||
|
||||
Use these steps to setup your Supabase database if you haven't already.
|
||||
|
||||
1. Head over to https://database.new to provision your Supabase database.
|
||||
2. In the studio, jump to the [SQL editor](https://supabase.com/dashboard/project/_/sql/new) and run the following script to enable `pgvector` and setup your database as a vector store:
|
||||
|
||||
```sql
|
||||
-- Enable the pgvector extension to work with embedding vectors
|
||||
create extension if not exists vector;
|
||||
|
||||
-- Create a table to store your documents
|
||||
create table
|
||||
documents (
|
||||
id uuid primary key,
|
||||
content text, -- corresponds to Document.pageContent
|
||||
metadata jsonb, -- corresponds to Document.metadata
|
||||
embedding vector (1536) -- 1536 works for OpenAI embeddings, change as needed
|
||||
);
|
||||
|
||||
-- Create a function to search for documents
|
||||
create function match_documents (
|
||||
query_embedding vector (1536),
|
||||
filter jsonb default '{}'
|
||||
) returns table (
|
||||
id uuid,
|
||||
content text,
|
||||
metadata jsonb,
|
||||
similarity float
|
||||
) language plpgsql as $$
|
||||
#variable_conflict use_column
|
||||
begin
|
||||
return query
|
||||
select
|
||||
id,
|
||||
content,
|
||||
metadata,
|
||||
1 - (documents.embedding <=> query_embedding) as similarity
|
||||
from documents
|
||||
where metadata @> filter
|
||||
order by documents.embedding <=> query_embedding;
|
||||
end;
|
||||
$$;
|
||||
```
|
||||
|
||||
## Setup Environment Variables
|
||||
|
||||
Since we are using [`SupabaseVectorStore`](https://python.langchain.com/docs/integrations/vectorstores/supabase) and [`OpenAIEmbeddings`](https://python.langchain.com/docs/integrations/text_embedding/openai), we need to load their API keys.
|
||||
|
||||
Create a `.env` file in the root of your project:
|
||||
|
||||
_.env_
|
||||
|
||||
```shell
|
||||
SUPABASE_URL=
|
||||
SUPABASE_SERVICE_KEY=
|
||||
OPENAI_API_KEY=
|
||||
```
|
||||
|
||||
To find your `SUPABASE_URL` and `SUPABASE_SERVICE_KEY`, head to your Supabase project's [API settings](https://supabase.com/dashboard/project/_/settings/api).
|
||||
|
||||
- `SUPABASE_URL` corresponds to the Project URL
|
||||
- `SUPABASE_SERVICE_KEY` corresponds to the `service_role` API key
|
||||
|
||||
To get your `OPENAI_API_KEY`, navigate to [API keys](https://platform.openai.com/account/api-keys) on your OpenAI account and create a new secret key.
|
||||
|
||||
Add this file to your `.gitignore` if it isn't already there (so that we don't commit secrets):
|
||||
|
||||
_.gitignore_
|
||||
|
||||
```
|
||||
.env
|
||||
```
|
||||
|
||||
Install [`python-dotenv`](https://github.com/theskumar/python-dotenv) which we will use to load the environment variables into the app:
|
||||
|
||||
```shell
|
||||
poetry add python-dotenv
|
||||
```
|
||||
|
||||
Finally, call `load_dotenv()` in `server.py`.
|
||||
|
||||
_app/server.py_
|
||||
|
||||
```python
|
||||
from dotenv import load_dotenv
|
||||
|
||||
load_dotenv()
|
||||
```
|
1710
templates/self-query-supabase/poetry.lock
generated
Normal file
1710
templates/self-query-supabase/poetry.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
26
templates/self-query-supabase/pyproject.toml
Normal file
26
templates/self-query-supabase/pyproject.toml
Normal file
@@ -0,0 +1,26 @@
|
||||
[tool.poetry]
|
||||
name = "self_query_supabase"
|
||||
version = "0.1.0"
|
||||
description = ""
|
||||
authors = ["Greg Richardson <greg@supabase.io>"]
|
||||
readme = "README.md"
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = ">=3.8.1,<4.0"
|
||||
langchain = ">=0.0.313"
|
||||
openai = "^0.28.1"
|
||||
tiktoken = "^0.5.1"
|
||||
supabase = "^1.2.0"
|
||||
lark = "^1.1.8"
|
||||
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
python-dotenv = { extras = ["cli"], version = "^1.0.0" }
|
||||
|
||||
[tool.langserve]
|
||||
export_module = "self_query_supabase.chain"
|
||||
export_attr = "chain"
|
||||
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core"]
|
||||
build-backend = "poetry.core.masonry.api"
|
64
templates/self-query-supabase/self_query_supabase/chain.py
Normal file
64
templates/self-query-supabase/self_query_supabase/chain.py
Normal file
@@ -0,0 +1,64 @@
|
||||
import os
|
||||
from langchain.llms.openai import OpenAI
|
||||
from langchain.retrievers.self_query.base import SelfQueryRetriever
|
||||
from langchain.chat_models import ChatOpenAI
|
||||
from langchain.embeddings import OpenAIEmbeddings
|
||||
from langchain.schema.output_parser import StrOutputParser
|
||||
from langchain.schema.runnable import RunnablePassthrough, RunnableParallel
|
||||
from langchain.chains.query_constructor.base import AttributeInfo
|
||||
|
||||
from supabase.client import create_client
|
||||
from langchain.embeddings.openai import OpenAIEmbeddings
|
||||
from langchain.vectorstores.supabase import SupabaseVectorStore
|
||||
|
||||
supabase_url = os.environ.get("SUPABASE_URL")
|
||||
supabase_key = os.environ.get("SUPABASE_SERVICE_KEY")
|
||||
supabase = create_client(supabase_url, supabase_key)
|
||||
|
||||
embeddings = OpenAIEmbeddings()
|
||||
|
||||
vectorstore = SupabaseVectorStore(
|
||||
client=supabase,
|
||||
embedding=embeddings,
|
||||
table_name="documents",
|
||||
query_name="match_documents"
|
||||
)
|
||||
|
||||
# Adjust this based on the metadata you store in the `metadata` JSON column
|
||||
metadata_field_info = [
|
||||
AttributeInfo(
|
||||
name="genre",
|
||||
description="The genre of the movie",
|
||||
type="string or list[string]",
|
||||
),
|
||||
AttributeInfo(
|
||||
name="year",
|
||||
description="The year the movie was released",
|
||||
type="integer",
|
||||
),
|
||||
AttributeInfo(
|
||||
name="director",
|
||||
description="The name of the movie director",
|
||||
type="string",
|
||||
),
|
||||
AttributeInfo(
|
||||
name="rating", description="A 1-10 rating for the movie", type="float"
|
||||
),
|
||||
]
|
||||
|
||||
# Adjust this based on the type of documents you store
|
||||
document_content_description = "Brief summary of a movie"
|
||||
llm = OpenAI(temperature=0)
|
||||
|
||||
retriever = SelfQueryRetriever.from_llm(
|
||||
llm,
|
||||
vectorstore,
|
||||
document_content_description,
|
||||
metadata_field_info,
|
||||
verbose=True
|
||||
)
|
||||
|
||||
chain = (
|
||||
RunnableParallel({"query": RunnablePassthrough()})
|
||||
| retriever
|
||||
)
|
0
templates/self-query-supabase/tests/__init__.py
Normal file
0
templates/self-query-supabase/tests/__init__.py
Normal file
Reference in New Issue
Block a user