はじめに
Daytona SDKはDaytonaと連携するための公式PythonおよびTypeScriptインターフェースを提供し、開発環境をプログラムで管理し、コードを実行できます。Python SDKは同期・非同期の両方のプログラミングモデルをサポートしており、非同期クラスにはAsync
の接頭辞が付きます。
手順に従って、AIエージェント向けの最初のDaytona サンドボックス(Daytonaが管理する隔離された一時的な実行環境)を作成・実行しましょう。
環境変数の設定やステージング環境での実験的機能へのアクセスなど、追加の設定手順についてはConfigurationを参照してください。
Daytona SDK をインストールする
Daytona は、Daytona プラットフォームと連携するための公式 Python および TypeScript の SDK を提供しています。お好みの方法で SDK をインストールしてください。
pip install daytona
# npm を使用npm install @daytonaio/sdk
# yarn を使用yarn add @daytonaio/sdk
# pnpm を使用pnpm add @daytonaio/sdk
サンドボックス内でコードを実行する
次のコードを実行して、Daytona のサンドボックスを作成し、コマンドを実行します。
from daytona import Daytona, DaytonaConfig
# Daytona クライアントを初期化daytona = Daytona(DaytonaConfig(api_key="YOUR_API_KEY"))
# サンドボックスのインスタンスを作成sandbox = daytona.create()
# サンドボックス内で安全にコードを実行response = sandbox.process.code_run('print("Sum of 3 and 4 is " + str(3 + 4))')if response.exit_code != 0: print(f"Error running code: {response.exit_code} {response.result}")else: print(response.result)
# サンドボックスをクリーンアップsandbox.delete()
import { Daytona } from '@daytonaio/sdk'
async function main() { // Daytona クライアントを初期化 const daytona = new Daytona({ apiKey: 'YOUR_API_KEY', })
let sandbox; try { // サンドボックスのインスタンスを作成 sandbox = await daytona.create({ language: "python", }); // サンドボックス内で安全にコードを実行 const response = await sandbox.process.codeRun( 'print("Sum of 3 and 4 is " + str(3 + 4))' ); if (response.exitCode !== 0) { console.error("Error running code:", response.exitCode, response.result); } else { console.log(response.result); } } catch (error) { console.error("Sandbox flow error:", error); } finally { // サンドボックスをクリーンアップ if (sandbox) { await sandbox.delete(); } }}
main().catch(console.error)
python main.py
npx tsx ./index.ts
アプリをプレビュー
次のスニペットは、シンプルな Flask アプリを含むファイルを Daytona のサンドボックスにアップロードします。Web サーバーはポート 3000
で起動し、提供されたプレビューURLからアクセスできます。
from daytona import Daytona, DaytonaConfig, SessionExecuteRequest
daytona = Daytona(DaytonaConfig(api_key="YOUR_API_KEY"))
sandbox = daytona.create()
app_code = b'''from flask import Flask
app = Flask(__name__)
@app.route('/')def hello(): return """ <!DOCTYPE html> <html> <head> <title>Hello World</title> <link rel="icon" href="https://www.daytona.io/favicon.ico"> </head> <body style="display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; background-color: #0a0a0a; font-family: Arial, sans-serif;"> <div style="text-align: center; padding: 2rem; border-radius: 10px; background-color: white; box-shadow: 0 4px 8px rgba(0,0,0,0.1);"> <img src="https://raw.githubusercontent.com/daytonaio/daytona/main/assets/images/Daytona-logotype-black.png" alt="Daytona Logo" style="width: 180px; margin: 10px 0px;"> <p>This web app is running in a Daytona sandbox!</p> </div> </body> </html> """
if __name__ == '__main__': app.run(host='0.0.0.0', port=3000)'''
# Save the Flask app to a file
sandbox.fs.upload_file(app_code, "app.py")
# Create a new session and execute a command
exec_session_id = "python-app-session"sandbox.process.create_session(exec_session_id)
sandbox.process.execute_session_command(exec_session_id, SessionExecuteRequest( command="python /app.py", var_async=True))
# Get the preview link for the Flask app
preview_info = sandbox.get_preview_link(3000)print(f"Flask app is available at: {preview_info.url}")
import { Daytona } from '@daytonaio/sdk';
const daytona = new Daytona(({ apiKey: "YOUR_API_KEY"}));
async function main() { const sandbox = await daytona.create();
const appCode = Buffer.from(`from flask import Flask
app = Flask(__name__)
@app.route('/')def hello(): return """ <!DOCTYPE html> <html> <head> <title>Hello World</title> <link rel="icon" href="https://www.daytona.io/favicon.ico"> </head> <body style="display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; background-color: #0a0a0a; font-family: Arial, sans-serif;"> <div style="text-align: center; padding: 2rem; border-radius: 10px; background-color: white; box-shadow: 0 4px 8px rgba(0,0,0,0.1);"> <img src="https://raw.githubusercontent.com/daytonaio/daytona/main/assets/images/Daytona-logotype-black.png" alt="Daytona Logo" style="width: 180px; margin: 10px 0px;"> <p>This web app is running in a Daytona sandbox!</p> </div> </body> </html> """
if __name__ == '__main__': app.run(host='0.0.0.0', port=3000) `);
// Save the Flask app to a file await sandbox.fs.uploadFile(appCode, "app.py");
// Create a new session and execute a command const execSessionId = "python-app-session"; await sandbox.process.createSession(execSessionId);
await sandbox.process.executeSessionCommand(execSessionId, ({ command: `python app.py`, async: true, }));
// Get the preview link for the Flask app const previewInfo = await sandbox.getPreviewLink(3000); console.log(`Flask app is available at: ${previewInfo.url}`);}
main().catch(error => console.error("Error:", error));
このエンドポイントにプログラムからアクセスする必要がありますか?プレビューと認証をご覧ください。
LLM に接続する
次のスニペットは、Anthropic API を用いて LLM に接続し、Claude に 25 の階乗を求めるコードの生成を依頼し、そのコードを Daytona のサンドボックス(Daytonaが管理する隔離された一時的な実行環境)内で実行します。
import osimport reimport requestsfrom daytona import Daytona, DaytonaConfigfrom dotenv import load_dotenv
load_dotenv()
daytona = Daytona(DaytonaConfig())
sandbox = daytona.create()
def get_claude_response(api_key, prompt): url = "https://api.anthropic.com/v1/messages" headers = { "x-api-key": api_key, "anthropic-version": "2023-06-01", "Content-Type": "application/json" } data = { "model": "claude-3-7-sonnet-latest", "max_tokens": 256, "messages": [{"role": "user", "content": prompt}] } response = requests.post(url, json=data, headers=headers) if response.status_code == 200: content = response.json().get("content", []) return "".join([item["text"] for item in content if item["type"] == "text"]) else: return f"Error {response.status_code}: {response.text}"
prompt = "25 の階乗を返す Python コード。出力はコードのみ。説明なし。前置きなし。コメントなし。単一のコードブロックで生のコードのみ。"
result = get_claude_response(os.environ["ANTHROPIC_API_KEY"], prompt)
code_match = re.search(r"```python\n(.*?)```", result, re.DOTALL)
code = code_match.group(1) if code_match else resultcode = code.replace('\\', '\\\\')
# サンドボックス内で Python コードを実行し、結果を取得
response = sandbox.process.code_run(code)print("The factorial of 25 is", response.result)
スニペットを実行する:
ANTHROPIC_API_KEY="your-anthropic-api-key"DAYTONA_API_KEY="your-daytona-api-key"DAYTONA_TARGET=uspython claude-example.py
> 25 の階乗は 15511210043330985984000000 です
import { Daytona } from '@daytonaio/sdk'import * as dotenv from 'dotenv'import axios from 'axios'
dotenv.config()
const daytona = new Daytona()
async function getClaudeResponse(apiKey: string, prompt: string): Promise<string> { const url = "https://api.anthropic.com/v1/messages" const headers = { "x-api-key": apiKey, "anthropic-version": "2023-06-01", "Content-Type": "application/json" } const data = { "model": "claude-3-7-sonnet-latest", "max_tokens": 256, "messages": [{"role": "user", "content": prompt}] }
try { const response = await axios.post(url, data, { headers }) if (response.status === 200) { const content = response.data.content || [] return content .filter((item: any) => item.type === "text") .map((item: any) => item.text) .join("") } else { return `Error ${response.status}: ${response.statusText}` } } catch (error: any) { return `Error: ${error.message}` }}
async function main() { const sandbox = await daytona.create()
const prompt = "25 の階乗を返す Python コード。コードのみを出力。説明なし。前置きなし。コメントなし。単一のコードブロックに生のコードのみ。"
const result = await getClaudeResponse(process.env.ANTHROPIC_API_KEY || "", prompt)
// レスポンスから正規表現でコードを抽出 const codeMatch = result.match(/```python\n(.*?)```/s)
let code = codeMatch ? codeMatch[1] : result code = code.replace(/\\/g, '\\\\')
// 抽出したコードをサンドボックスで実行 const response = await sandbox.process.codeRun(code) console.log("The factorial of 25 is", response.result)}
main().catch(console.error)
スニペットを実行する:
ANTHROPIC_API_KEY="your-anthropic-api-key"DAYTONA_API_KEY="your-daytona-api-key"DAYTONA_TARGET=usnpx ts-node claude-example.ts
> 25の階乗は 15511210043330985984000000 です
追加の例
Daytona SDK の Python の例 または TypeScript/JavaScript の例 を使ってサンドボックス(Daytonaが管理する隔離された一時的な実行環境)を作成し、コードを実行しましょう。
LLM を活用して Daytona 上での開発を加速できます。/llms.txt ファイルをコピーし、プロジェクトやチャットのコンテキストに含めてください: llms-full.txt または llms.txt
GitHub 上の Daytona SDK リポジトリを参照して、さらに詳しく学びましょう。
ViteプロジェクトでのDaytona
ViteベースのプロジェクトでDaytona SDKを使用する場合、互換性を確保するためにNodeのポリフィルを設定する必要があります。vite.config.ts
のplugins配列に以下の設定を追加してください:
import { nodePolyfills } from 'vite-plugin-node-polyfills'
export default defineConfig({ plugins: [ // ... other plugins nodePolyfills({ globals: { global: true, process: true, Buffer: true }, overrides: { path: 'path-browserify-win32', }, }), ], // ... rest of your config})
Next.js プロジェクトにおける Daytona
Next.js プロジェクトで Daytona SDK を使用する場合、利用中のバンドラーに応じて Webpack や Turbopack との互換性を保つため、Node のポリフィルを設定する必要があります。次の設定を next.config.ts
に追加してください:
import type { NextConfig } from 'next'import NodePolyfillPlugin from 'node-polyfill-webpack-plugin'import { env, nodeless } from 'unenv'
const { alias: turbopackAlias } = env(nodeless, {})
const nextConfig: NextConfig = { // Turbopack experimental: { turbo: { resolveAlias: { ...turbopackAlias, }, }, }, // Webpack webpack: (config, { isServer }) => { if (!isServer) { config.plugins.push(new NodePolyfillPlugin()) } return config },}
export default nextConfig
Daytona CLI のセットアップ
ローカルデバイス上のイメージを使用する場合、またはコマンドラインインターフェースでサンドボックスを管理したい場合は、次のコマンドで Daytona CLI をインストールしてください:
brew install daytonaio/cli/daytona
powershell -Command "irm https://get.daytona.io/windows | iex"