Skip to content

Commit

Permalink
Make Postgres credentials optionnal when set on env variables
Browse files Browse the repository at this point in the history
  • Loading branch information
JJK801 committed Oct 26, 2024
1 parent 0b23189 commit 4e1f4c4
Show file tree
Hide file tree
Showing 10 changed files with 177 additions and 50 deletions.
14 changes: 13 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,19 @@ Flowise support different environment variables to configure your instance. You
| S3_ENDPOINT_URL | Custom Endpoint for S3 | String | |
| S3_FORCE_PATH_STYLE | Set this to true to force the request to use path-style addressing | Boolean | false |
| SHOW_COMMUNITY_NODES | Show nodes created by community | Boolean | |

| POSTGRES_VECTORSTORE_HOST | Default `host` for Postgres Vector Store | String | |
| POSTGRES_VECTORSTORE_PORT | Default `port` for Postgres Vector Store | Number | 5432 |
| POSTGRES_VECTORSTORE_USER | Default `user` for Postgres Vector Store | String | |
| POSTGRES_VECTORSTORE_PASSWORD | Default `password` for Postgres Vector Store | String | |
| POSTGRES_VECTORSTORE_DATABASE | Default `database` for Postgres Vector Store | String | |
| POSTGRES_VECTORSTORE_TABLE_NAME | Default `tableName` for Postgres Vector Store | String | documents |
| POSTGRES_VECTORSTORE_CONTENT_COLUMN_NAME | Default `contentColumnName` for Postgres Vector Store | String | pageContent |
| POSTGRES_RECORDMANAGER_HOST | Default `host` for Postgres Record Manager | String | |
| POSTGRES_RECORDMANAGER_PORT | Default `port` for Postgres Record Manager | Number | 5432 |
| POSTGRES_RECORDMANAGER_USER | Default `user` for Postgres Record Manager | String | |
| POSTGRES_RECORDMANAGER_PASSWORD | Default `password` for Postgres Record Manager | String | |
| POSTGRES_RECORDMANAGER_DATABASE | Default `database` for Postgres Record Manager | String | |
| POSTGRES_RECORDMANAGER_TABLE_NAME | Default `tableName` for Postgres Record Manager | String | upsertion_records |
You can also specify the env variables when using `npx`. For example:

```
Expand Down
36 changes: 35 additions & 1 deletion docker/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,38 @@ BLOB_STORAGE_PATH=/root/.flowise/storage
# S3_FORCE_PATH_STYLE=false

# APIKEY_STORAGE_TYPE=json (json | db)
# SHOW_COMMUNITY_NODES=true
# SHOW_COMMUNITY_NODES=true

############################################
# Default postgres vectorstore credentials #
############################################

# POSTGRES_VECTORSTORE_USER=
# POSTGRES_VECTORSTORE_PASSWORD=

#######################################
# Default postgres vectorstore config #
#######################################

# POSTGRES_VECTORSTORE_HOST=
# POSTGRES_VECTORSTORE_DATABASE=
# POSTGRES_VECTORSTORE_PORT=
# POSTGRES_VECTORSTORE_TABLE_NAME=
# POSTGRES_VECTORSTORE_CONTENT_COLUMN_NAME=

###############################################
# Default postgres record manager credentials #
###############################################

# POSTGRES_RECORDMANAGER_USER=
# POSTGRES_RECORDMANAGER_PASSWORD=

##########################################
# Default postgres record manager config #
##########################################

# POSTGRES_RECORDMANAGER_HOST=
# POSTGRES_RECORDMANAGER_DATABASE=
# POSTGRES_RECORDMANAGER_PORT=
# POSTGRES_RECORDMANAGER_TABLE_NAME=
# POSTGRES_RECORDMANAGER_CONTENT_COLUMN_NAME=
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ import { ICommonObject, INode, INodeData, INodeParams } from '../../../src/Inter
import { getBaseClasses, getCredentialData, getCredentialParam } from '../../../src/utils'
import { ListKeyOptions, RecordManagerInterface, UpdateOptions } from '@langchain/community/indexes/base'
import { DataSource, QueryRunner } from 'typeorm'
import { getHost } from '../../vectorstores/Postgres/utils'
import { getDatabase, getPort, getTableName } from './utils'

const serverCredentialsExists = !!process.env.POSTGRES_RECORDMANAGER_USER && !!process.env.POSTGRES_RECORDMANAGER_PASSWORD

class PostgresRecordManager_RecordManager implements INode {
label: string
Expand Down Expand Up @@ -29,18 +33,22 @@ class PostgresRecordManager_RecordManager implements INode {
{
label: 'Host',
name: 'host',
type: 'string'
type: 'string',
placeholder: getHost(),
optional: !!getHost()
},
{
label: 'Database',
name: 'database',
type: 'string'
type: 'string',
placeholder: getDatabase(),
optional: !!getDatabase()
},
{
label: 'Port',
name: 'port',
type: 'number',
placeholder: '5432',
placeholder: getPort(),
optional: true
},
{
Expand All @@ -54,7 +62,7 @@ class PostgresRecordManager_RecordManager implements INode {
label: 'Table Name',
name: 'tableName',
type: 'string',
placeholder: 'upsertion_records',
placeholder: getTableName(),
additionalParams: true,
optional: true
},
Expand Down Expand Up @@ -110,16 +118,16 @@ class PostgresRecordManager_RecordManager implements INode {
label: 'Connect Credential',
name: 'credential',
type: 'credential',
credentialNames: ['PostgresApi']
credentialNames: ['PostgresApi'],
optional: serverCredentialsExists
}
}

async init(nodeData: INodeData, _: string, options: ICommonObject): Promise<any> {
const credentialData = await getCredentialData(nodeData.credential ?? '', options)
const user = getCredentialParam('user', credentialData, nodeData)
const password = getCredentialParam('password', credentialData, nodeData)
const _tableName = nodeData.inputs?.tableName as string
const tableName = _tableName ? _tableName : 'upsertion_records'
const user = getCredentialParam('user', credentialData, nodeData, process.env.POSTGRES_RECORDMANAGER_USER)
const password = getCredentialParam('password', credentialData, nodeData, process.env.POSTGRES_RECORDMANAGER_PASSWORD)
const tableName = getTableName(nodeData)
const additionalConfig = nodeData.inputs?.additionalConfig as string
const _namespace = nodeData.inputs?.namespace as string
const namespace = _namespace ? _namespace : options.chatflowid
Expand All @@ -139,11 +147,11 @@ class PostgresRecordManager_RecordManager implements INode {
const postgresConnectionOptions = {
...additionalConfiguration,
type: 'postgres',
host: nodeData.inputs?.host as string,
port: nodeData.inputs?.port as number,
host: getHost(nodeData),
port: getPort(nodeData),
username: user,
password: password,
database: nodeData.inputs?.database as string
database: getDatabase(nodeData)
}

const args = {
Expand All @@ -162,7 +170,7 @@ class PostgresRecordManager_RecordManager implements INode {

type PostgresRecordManagerOptions = {
postgresConnectionOptions: any
tableName?: string
tableName: string
}

class PostgresRecordManager implements RecordManagerInterface {
Expand All @@ -180,7 +188,7 @@ class PostgresRecordManager implements RecordManagerInterface {
const { postgresConnectionOptions, tableName } = config
this.namespace = namespace
this.datasource = new DataSource(postgresConnectionOptions)
this.tableName = tableName || 'upsertion_records'
this.tableName = tableName
}

async createSchema(): Promise<void> {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { defaultChain, INodeData } from '../../../src'

export function getHost(nodeData?: INodeData) {
return defaultChain(nodeData?.inputs?.host, process.env.POSTGRES_RECORDMANAGER_HOST)
}

export function getDatabase(nodeData?: INodeData) {
return defaultChain(nodeData?.inputs?.database, process.env.POSTGRES_RECORDMANAGER_DATABASE)
}

export function getPort(nodeData?: INodeData) {
return defaultChain(nodeData?.inputs?.port, process.env.POSTGRES_RECORDMANAGER_PORT, '5432')
}

export function getTableName(nodeData?: INodeData) {
return defaultChain(nodeData?.inputs?.tableName, process.env.POSTGRES_RECORDMANAGER_TABLE_NAME, 'upsertion_records')
}
28 changes: 17 additions & 11 deletions packages/components/nodes/vectorstores/Postgres/Postgres.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import { VectorStore } from '@langchain/core/vectorstores'
import { VectorStoreDriver } from './driver/Base'
import { TypeORMDriver } from './driver/TypeORM'
import { PGVectorDriver } from './driver/PGVector'
import { getContentColumnName, getDatabase, getHost, getPort, getTableName } from './utils'

const serverCredentialsExists = !!process.env.POSTGRES_VECTORSTORE_USER && !!process.env.POSTGRES_VECTORSTORE_PASSWORD

class Postgres_VectorStores implements INode {
label: string
Expand Down Expand Up @@ -36,7 +39,8 @@ class Postgres_VectorStores implements INode {
label: 'Connect Credential',
name: 'credential',
type: 'credential',
credentialNames: ['PostgresApi']
credentialNames: ['PostgresApi'],
optional: serverCredentialsExists
}
this.inputs = [
{
Expand Down Expand Up @@ -77,34 +81,38 @@ class Postgres_VectorStores implements INode {
{
label: 'Host',
name: 'host',
type: 'string'
type: 'string',
placeholder: getHost(),
optional: !!getHost()
},
{
label: 'Database',
name: 'database',
type: 'string'
type: 'string',
placeholder: getDatabase(),
optional: !!getDatabase()
},
{
label: 'Port',
name: 'port',
type: 'number',
placeholder: '5432',
placeholder: getPort(),
optional: true
},
{
label: 'Table Name',
name: 'tableName',
type: 'string',
placeholder: 'documents',
placeholder: getTableName(),
additionalParams: true,
optional: true
},
{
label: 'Content Column Name',
name: 'contentColumnName',
description: 'Column name to store the text content (PGVector Driver only)',
description: 'Column name to store the text content (PGVector Driver only, others use pageContent)',
type: 'string',
placeholder: PGVectorDriver.CONTENT_COLUMN_NAME_DEFAULT,
placeholder: getContentColumnName(),
additionalParams: true,
optional: true
},
Expand Down Expand Up @@ -184,8 +192,7 @@ class Postgres_VectorStores implements INode {
//@ts-ignore
vectorStoreMethods = {
async upsert(nodeData: INodeData, options: ICommonObject): Promise<Partial<IndexingResult>> {
const _tableName = nodeData.inputs?.tableName as string
const tableName = _tableName ? _tableName : 'documents'
const tableName = getTableName(nodeData)
const docs = nodeData.inputs?.document as Document[]
const recordManager = nodeData.inputs?.recordManager
const isFileUploadEnabled = nodeData.inputs?.fileUpload as boolean
Expand Down Expand Up @@ -232,8 +239,7 @@ class Postgres_VectorStores implements INode {
},
async delete(nodeData: INodeData, ids: string[], options: ICommonObject): Promise<void> {
const vectorStoreDriver: VectorStoreDriver = Postgres_VectorStores.getDriverFromConfig(nodeData, options)
const _tableName = nodeData.inputs?.tableName as string
const tableName = _tableName ? _tableName : 'documents'
const tableName = getTableName(nodeData)
const recordManager = nodeData.inputs?.recordManager

const vectorStore = await vectorStoreDriver.instanciate()
Expand Down
30 changes: 26 additions & 4 deletions packages/components/nodes/vectorstores/Postgres/driver/Base.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { VectorStore } from '@langchain/core/vectorstores'
import { ICommonObject, INodeData } from '../../../../src'
import { getCredentialData, getCredentialParam, ICommonObject, INodeData } from '../../../../src'
import { Document } from '@langchain/core/documents'
import { Embeddings } from '@langchain/core/embeddings'
import { getDatabase, getHost, getPort, getTableName } from '../utils'

export abstract class VectorStoreDriver {
constructor(protected nodeData: INodeData, protected options: ICommonObject) {}
Expand All @@ -14,13 +15,34 @@ export abstract class VectorStoreDriver {
return instance
}

getTableName() {
const _tableName = this.nodeData.inputs?.tableName as string
getHost() {
return getHost(this.nodeData) as string
}

getPort() {
return getPort(this.nodeData) as number
}

getDatabase() {
return getDatabase(this.nodeData) as string
}

return _tableName ? _tableName : 'documents'
getTableName() {
return getTableName(this.nodeData)
}

getEmbeddings() {
return this.nodeData.inputs?.embeddings as Embeddings
}

async getCredentials() {
const credentialData = await getCredentialData(this.nodeData.credential ?? '', this.options)
const user = getCredentialParam('user', credentialData, this.nodeData, process.env.POSTGRES_VECTORSTORE_USER)
const password = getCredentialParam('password', credentialData, this.nodeData, process.env.POSTGRES_VECTORSTORE_PASSWORD)

return {
user,
password
}
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { VectorStoreDriver } from './Base'
import { FLOWISE_CHATID, getCredentialData, getCredentialParam } from '../../../../src'
import { FLOWISE_CHATID } from '../../../../src'
import { DistanceStrategy, PGVectorStore, PGVectorStoreArgs } from '@langchain/community/vectorstores/pgvector'
import { Document } from '@langchain/core/documents'
import { PoolConfig } from 'pg'
import { getContentColumnName } from '../utils'

export class PGVectorDriver extends VectorStoreDriver {
static CONTENT_COLUMN_NAME_DEFAULT: string = 'pageContent'
Expand All @@ -11,9 +12,7 @@ export class PGVectorDriver extends VectorStoreDriver {

protected async getPostgresConnectionOptions() {
if (!this._postgresConnectionOptions) {
const credentialData = await getCredentialData(this.nodeData.credential ?? '', this.options)
const user = getCredentialParam('user', credentialData, this.nodeData)
const password = getCredentialParam('password', credentialData, this.nodeData)
const { user, password } = await this.getCredentials()
const additionalConfig = this.nodeData.inputs?.additionalConfig as string

let additionalConfiguration = {}
Expand All @@ -28,11 +27,11 @@ export class PGVectorDriver extends VectorStoreDriver {

this._postgresConnectionOptions = {
...additionalConfiguration,
host: this.nodeData.inputs?.host as string,
port: this.nodeData.inputs?.port as number,
host: this.getHost(),
port: this.getPort(),
user: user,
password: password,
database: this.nodeData.inputs?.database as string
database: this.getDatabase()
}
}

Expand All @@ -44,7 +43,7 @@ export class PGVectorDriver extends VectorStoreDriver {
postgresConnectionOptions: await this.getPostgresConnectionOptions(),
tableName: this.getTableName(),
columns: {
contentColumnName: (this.nodeData.inputs?.contentColumnName || PGVectorDriver.CONTENT_COLUMN_NAME_DEFAULT) as string
contentColumnName: getContentColumnName(this.nodeData)
},
distanceStrategy: (this.nodeData.inputs?.distanceStrategy || 'cosine') as DistanceStrategy
}
Expand Down
Loading

0 comments on commit 4e1f4c4

Please sign in to comment.