Подключение внешнего приложения к Lakebase с помощью API

В этом руководстве показано, как подключить внешние приложения к Автомасштабированию Lakebase с помощью прямых вызовов REST API. Используйте этот подход, если пакет SDK Databricks недоступен для вашего языка (Node.js, Ruby, PHP, Elixir, Rust и т. д.).

Если язык поддерживает пакет SDK (Python, Java или Go), используйте подключение внешнего приложения к Lakebase с помощью пакета SDK для более простого управления маркерами.

Вы выполняете два вызова API для получения учетных данных базы данных с помощью смены маркера OAuth. Примеры приведены для curl и Node.js.

Замечание

Двухэтапная аутентификация: Этот подход требует двух вызовов API для каждой учетной записи базы данных: (1) обменять секрет учетной записи служебного принципала на токен OAuth рабочей области; (2) обменять токен OAuth на учетные данные базы данных. Срок действия обоих токенов истекает через 60 минут. Пакет SDK автоматически обрабатывает шаг 1.

Предпосылки

Вам нужна та же настройка, что и подход пакета SDK: субъект-служба, роль Postgres и сведения о подключении.

Предпосылка Основные сведения Дополнительная информация
Управляющий службой Секрет OAuth с 730-дневным максимальным временем существования; включите доступ к рабочей области. Обратите внимание на идентификатор клиента (UUID) для роли Postgres и переменных окружения. Создание субъекта-службы
Роль Postgres Создайте роль OAuth в редакторе SQL Lakebase: databricks_create_role('{client-id}', 'SERVICE_PRINCIPAL') и предоставьте CONNECT, USAGE, SELECT/INSERT/UPDATE/DELETE. Используйте идентификатор клиента из шага 1. Создать роль Postgres
Сведения о подключении Из консоли Lakebase Connect: имя конечной точки (projects/.../branches/.../endpoints/...), узел, база данных (обычно databricks_postgres). Получение сведений о подключении

Принцип работы

Для подхода API вручную требуется два обмена токенами:

Ручной поток обмена токенами API

Время существования токена:

  • Секрет служебного пользователя: До 730 дней (устанавливается во время создания)
  • Маркер OAuth рабочей области: 60 минут (шаг 1)
  • Учетные данные базы данных: 60 минут (шаг 2)

Область применения токенов: Учетные данные базы данных привязаны к рабочей области. endpoint Хотя параметр является обязательным, возвращенный маркер может получить доступ к любой базе данных или проекту в рабочем пространстве, для которой служебный принципал имеет разрешения на доступ.

Установка переменных среды

Задайте эти переменные среды перед запуском приложения:

# Databricks workspace authentication
export DATABRICKS_HOST="https://your-workspace.databricks.com"
export DATABRICKS_CLIENT_ID="<service-principal-client-id>"
export DATABRICKS_CLIENT_SECRET="<your-oauth-secret>"

# Lakebase connection details (from prerequisites)
export ENDPOINT_NAME="projects/<project-id>/branches/<branch-id>/endpoints/<endpoint-id>"
export PGHOST="<endpoint-id>.database.<region>.cloud.databricks.com"
export PGDATABASE="databricks_postgres"
export PGUSER="<service-principal-client-id>"   # Same UUID as client ID
export PGPORT="5432"

Добавление кода подключения

завиток

В этом примере показаны необработанные вызовы API. Для рабочих приложений реализуйте кэширование маркеров и логику обновления.

# Step 1: Get workspace OAuth token
OAUTH_TOKEN=$(curl -s -X POST "${DATABRICKS_HOST}/oidc/v1/token" \
  -u "${DATABRICKS_CLIENT_ID}:${DATABRICKS_CLIENT_SECRET}" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials&scope=all-apis" \
  | jq -r '.access_token')

echo "Got workspace OAuth token (60-min lifetime)"

# Step 2: Get database credential
PG_TOKEN=$(curl -s -X POST "${DATABRICKS_HOST}/api/2.0/postgres/credentials" \
  -H "Authorization: Bearer ${OAUTH_TOKEN}" \
  -H "Content-Type: application/json" \
  -d "{\"endpoint\": \"${ENDPOINT_NAME}\"}" \
  | jq -r '.token')

echo "Got database credential (60-min lifetime)"

# Step 3: Connect to Postgres
PGPASSWORD="${PG_TOKEN}" psql \
  -h "${PGHOST}" \
  -p "${PGPORT}" \
  -U "${PGUSER}" \
  -d "${PGDATABASE}" \
  -c "SELECT current_user, current_database()"

Node.js

В этом примере используется node-postgres с асинхронной функцией для работы с паролями, которая обрабатывает получение и кэширование токенов.

import pg from 'pg';

// Step 1: Fetch workspace OAuth token
async function getWorkspaceToken(host, clientId, clientSecret) {
  const auth = Buffer.from(`${clientId}:${clientSecret}`).toString('base64');
  const response = await fetch(`${host}/oidc/v1/token`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded',
      Authorization: `Basic ${auth}`,
    },
    body: 'grant_type=client_credentials&scope=all-apis',
  });

  if (!response.ok) {
    throw new Error(`OAuth failed: ${response.status}`);
  }

  const data = await response.json();
  return {
    token: data.access_token,
    expires: Date.now() + data.expires_in * 1000,
  };
}

// Step 2: Fetch database credential
async function getPostgresCredential(host, workspaceToken, endpoint) {
  const response = await fetch(`${host}/api/2.0/postgres/credentials`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${workspaceToken}`,
    },
    body: JSON.stringify({ endpoint }),
  });

  if (!response.ok) {
    throw new Error(`Database credential failed: ${response.status}`);
  }

  const data = await response.json();
  return {
    token: data.token,
    expires: new Date(data.expire_time).getTime(),
  };
}

// Simple caching wrapper (production: use more sophisticated caching)
function cached(fetchFn) {
  let cache = null;
  return async (...args) => {
    const now = Date.now();
    if (!cache || now >= cache.expires - 5 * 60 * 1000) {
      // Refresh 5 min early
      const result = await fetchFn(...args);
      cache = result;
    }
    return cache.token;
  };
}

// Create connection pool with async password function
function createPool() {
  const host = process.env.DATABRICKS_HOST;
  const clientId = process.env.DATABRICKS_CLIENT_ID;
  const clientSecret = process.env.DATABRICKS_CLIENT_SECRET;
  const endpoint = process.env.ENDPOINT_NAME;

  const cachedWorkspaceToken = cached(() => getWorkspaceToken(host, clientId, clientSecret));
  const cachedPostgresToken = cached(async () => {
    const workspaceToken = await cachedWorkspaceToken();
    return getPostgresCredential(host, workspaceToken, endpoint);
  });

  return new pg.Pool({
    host: process.env.PGHOST,
    port: process.env.PGPORT,
    database: process.env.PGDATABASE,
    user: process.env.PGUSER,
    password: cachedPostgresToken, // Async function: () => Promise<string>
    ssl: { rejectUnauthorized: true },
    min: 1,
    max: 10,
    idleTimeoutMillis: 900000, // Example: 15 minutes
    connectionTimeoutMillis: 60000, // Example: 60 seconds
  });
}

// Use the pool
const pool = createPool();
const result = await pool.query('SELECT current_user, current_database()');
console.log('Connected as:', result.rows[0].current_user);

Зависимости:pg (node-postgres)

Примечание: Node-postgres (pg) принимает асинхронную функцию в качестве пароля. Функция вызывается каждый раз при создании нового подключения, обеспечивая свежие токены.

Запуск и проверка подключения

завиток

Запустите скрипт Bash с загруженными переменными среды:

export $(cat .env | xargs)
bash connect.sh

Ожидаемые выходные данные:

Got workspace OAuth token (60-min lifetime)
Got database credential (60-min lifetime)
     current_user      | current_database
-----------------------+------------------
 c00f575e-d706-4f6b... | databricks_postgres

Если current_user соответствует идентификатору клиента сервисного принципала, значит, OAuth работает правильно.

Node.js

Установите зависимости:

npm install pg

Запустить:

node app.js

Ожидаемые выходные данные:

Connected as: c00f575e-d706-4f6b-b62c-e7a14850571b

Примечание: Первое подключение после простоя может занять больше времени, так как автомасштабирование Lakebase начинает вычисление с нуля.

Устранение неполадок

Ошибка Исправить
"invalid_client" или "Отсутствует проверка подлинности клиента" Проверьте, что DATABRICKS_CLIENT_ID и DATABRICKS_CLIENT_SECRET корректны. Используйте базовую проверку подлинности (в кодировке Base64).
"API отключен для пользователей без прав доступа к рабочей области" Включите "Доступ к рабочей области" для субъекта-службы (предварительные требования).
"INVALID_PARAMETER_VALUE" / "Поле "конечная точка" является обязательным" Убедитесь, что параметр endpoint включен в тело POST-запроса на шаге 2 с форматом projects/<id>/branches/<id>/endpoints/<id>.
Роль не существует или проверка подлинности завершается ошибкой Создайте роль OAuth с помощью SQL (предварительные требования).
"Отклонено подключение" или время ожидания Первое подключение после масштабирования до нуля может занять больше времени. Реализуйте логику повторных попыток.
Истек срок действия токена / "Сбой проверки подлинности пароля" Срок действия маркеров рабочей области и базы данных истекает через 60 минут. Реализуйте кэширование с проверками срока действия.