> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pixeltable.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Working with OpenAI in Pixeltable

> Call GPT-4, embeddings, DALL-E, and Whisper from Pixeltable computed columns for chat, vision, image generation, and speech workflows.

<a href="https://kaggle.com/kernels/welcome?src=https://github.com/pixeltable/pixeltable/blob/release/docs/release/howto/providers/working-with-openai.ipynb" id="openKaggle" target="_blank" rel="noopener noreferrer"><img src="https://kaggle.com/static/images/open-in-kaggle.svg" alt="Open in Kaggle" style={{ display: 'inline', margin: '0px' }} noZoom /></a>  <a href="https://colab.research.google.com/github/pixeltable/pixeltable/blob/release/docs/release/howto/providers/working-with-openai.ipynb" id="openColab" target="_blank" rel="noopener noreferrer"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open in Colab" style={{ display: 'inline', margin: '0px' }} noZoom /></a>  <a href="https://raw.githubusercontent.com/pixeltable/pixeltable/refs/tags/release/docs/release/howto/providers/working-with-openai.ipynb" id="downloadNotebook" target="_blank" rel="noopener noreferrer"><img src="https://img.shields.io/badge/%E2%AC%87-Download%20Notebook-blue" alt="Download Notebook" style={{ display: 'inline', margin: '0px' }} noZoom /></a>

<Tip>This documentation page is also available as an interactive notebook. You can launch the notebook in
Kaggle or Colab, or download it for use with an IDE or local Jupyter installation, by clicking one of the
above links.</Tip>

export const quartoRawHtml = [`
<table class="dataframe" data-quarto-postprocess="true" data-border="1">
<thead>
<tr style="text-align: right;">
<th data-quarto-table-cell-role="th">input</th>
<th data-quarto-table-cell-role="th">response</th>
</tr>
</thead>
<tbody>
<tr>
<td style="vertical-align: middle;">How many islands are in the Aleutian island chain?</td>
<td style="vertical-align: middle;">The Aleutian Islands consist of approximately 300 islands,
stretching about 1,200 miles (1,900 kilometers) from the Alaska
Peninsula to the Kamchatka Peninsula in Russia. This chain includes a
variety of larger and smaller islands, many of which are part of the
Aleutian Islands National Wildlife Refuge.</td>
</tr>
</tbody>
</table>
`, `
<table class="dataframe" data-quarto-postprocess="true" data-border="1">
<thead>
<tr style="text-align: right;">
<th data-quarto-table-cell-role="th">input</th>
<th data-quarto-table-cell-role="th">response</th>
</tr>
</thead>
<tbody>
<tr>
<td style="vertical-align: middle;">What are the three largest moons of Jupiter?</td>
<td style="vertical-align: middle;">The three largest moons of Jupiter are: 1. **Ganymede** 2.
**Callisto** 3. **Io**</td>
</tr>
</tbody>
</table>
`, `
<table class="dataframe" data-quarto-postprocess="true" data-border="1">
<thead>
<tr style="text-align: right;">
<th data-quarto-table-cell-role="th">input</th>
<th data-quarto-table-cell-role="th">embedding</th>
</tr>
</thead>
<tbody>
<tr>
<td style="vertical-align: middle;">OpenAI provides a variety of embeddings models.</td>
<td style="vertical-align: middle;">[-0.023 -0.045 0.069 -0.017 -0.008 -0.027 ... 0.009 0.005 0.021
0.018 -0.012 -0.008]</td>
</tr>
</tbody>
</table>
`, `<style type="text/css">
#T_9da22_row0_col0 {
  white-space: pre-wrap;
  text-align: left;
  font-weight: bold;
}
</style>
`, `
<table id="T_9da22" data-quarto-postprocess="true">
<tbody>
<tr>
<td id="T_9da22_row0_col0" class="data row0 col0">table
'openai_demo/images'</td>
</tr>
</tbody>
</table>
`, `
<style type="text/css">
#T_05ebf th {
  text-align: left;
  border-bottom: 2px solid #666;
}
#T_05ebf_row0_col0, #T_05ebf_row0_col1, #T_05ebf_row0_col2, #T_05ebf_row0_col3, #T_05ebf_row0_col4, #T_05ebf_row1_col0, #T_05ebf_row1_col1, #T_05ebf_row1_col2, #T_05ebf_row1_col3, #T_05ebf_row1_col4 {
  white-space: pre-wrap;
  text-align: left;
}
</style>
`, `
<table id="T_05ebf" data-quarto-postprocess="true">
<thead>
<tr>
<th id="T_05ebf_level0_col0" class="col_heading level0 col0"
data-quarto-table-cell-role="th">Column Name</th>
<th id="T_05ebf_level0_col1" class="col_heading level0 col1"
data-quarto-table-cell-role="th">Type</th>
<th id="T_05ebf_level0_col2" class="col_heading level0 col2"
data-quarto-table-cell-role="th">Source</th>
<th id="T_05ebf_level0_col3" class="col_heading level0 col3"
data-quarto-table-cell-role="th">Computed With</th>
<th id="T_05ebf_level0_col4" class="col_heading level0 col4"
data-quarto-table-cell-role="th">Comment</th>
</tr>
</thead>
<tbody>
<tr>
<td id="T_05ebf_row0_col0" class="data row0 col0">input</td>
<td id="T_05ebf_row0_col1" class="data row0 col1">String</td>
<td id="T_05ebf_row0_col2" class="data row0 col2">images</td>
<td id="T_05ebf_row0_col3" class="data row0 col3"></td>
<td id="T_05ebf_row0_col4" class="data row0 col4"></td>
</tr>
<tr>
<td id="T_05ebf_row1_col0" class="data row1 col0">img</td>
<td id="T_05ebf_row1_col1" class="data row1 col1">Json</td>
<td id="T_05ebf_row1_col2" class="data row1 col2">images</td>
<td id="T_05ebf_row1_col3"
class="data row1 col3">image_generations(input,
model='gpt-image-2')</td>
<td id="T_05ebf_row1_col4" class="data row1 col4"></td>
</tr>
</tbody>
</table>
`, `
<table class="dataframe" data-quarto-postprocess="true" data-border="1">
<thead>
<tr style="text-align: right;">
<th data-quarto-table-cell-role="th">input</th>
<th data-quarto-table-cell-role="th">img</th>
</tr>
</thead>
<tbody>
<tr>
<td style="vertical-align: middle;">A giant Pixel floating in the open ocean in a sea of data</td>
<td style="vertical-align: middle;">{"data": [&lt;PIL.JpegImagePlugin.JpegImageFile image mode=RGB
size=1024x1024 at 0x385470C50&gt;], "size": null, "usage": null,
"created": 1775363018, "quality": null, "background": null,
"output_format": null}</td>
</tr>
</tbody>
</table>
`];

Pixeltable’s OpenAI integration enables you to access OpenAI models via
the OpenAI API.

### Prerequisites

* An OpenAI account with an API key
  ([https://openai.com/index/openai-api/](https://openai.com/index/openai-api/))

### Important notes

* OpenAI usage may incur costs based on your OpenAI plan.
* Be mindful of sensitive data and consider security measures when
  integrating with external services.

First you’ll need to install required libraries and enter your OpenAI
API key.

```python theme={"theme":{"light":"light-plus","dark":"dark-plus"}}
%pip install -qU pixeltable openai
```

```python theme={"theme":{"light":"light-plus","dark":"dark-plus"}}
import getpass
import os

if 'OPENAI_API_KEY' not in os.environ:
    os.environ['OPENAI_API_KEY'] = getpass.getpass(
        'Enter your OpenAI API key:'
    )
```

Now let’s create a Pixeltable directory to hold the tables for our demo.

```python theme={"theme":{"light":"light-plus","dark":"dark-plus"}}
import pixeltable as pxt

# Remove the 'openai_demo' directory and its contents, if it exists
pxt.drop_dir('openai_demo', force=True)
pxt.create_dir('openai_demo')
```

<pre style={{ 'margin': '-20px 20px 0px 20px', 'padding': '0px', 'background-color': 'transparent', 'color': 'black' }}>
  Connected to Pixeltable database at: postgresql+psycopg://postgres:@/pixeltable?host=/Users/asiegel/.pixeltable/pgdata
  Pixeltable dashboard available at: [http://localhost:22089](http://localhost:22089)
  Created directory 'openai\_demo'.
  \<pixeltable.catalog.dir.Dir at 0x136db16c0>
</pre>

## Chat completions

Create a Table: In Pixeltable, create a table with columns to represent
your input data and the columns where you want to store the results from
OpenAI.

```python theme={"theme":{"light":"light-plus","dark":"dark-plus"}}
from pixeltable.functions import openai

# Create a table in Pixeltable and add a computed column that calls OpenAI

t = pxt.create_table('openai_demo/chat', {'input': pxt.String})

messages = [{'role': 'user', 'content': t.input}]
t.add_computed_column(
    output=openai.chat_completions(
        messages=messages,
        model='gpt-4o-mini',
        model_kwargs={
            # Optional dict with parameters for the OpenAI API
            'max_tokens': 300,
            'top_p': 0.9,
            'temperature': 0.7,
        },
    )
)
```

<pre style={{ 'margin': '-20px 20px 0px 20px', 'padding': '0px', 'background-color': 'transparent', 'color': 'black' }}>
  Created table 'chat'.
  Added 0 column values with 0 errors in 0.01 s
  No rows affected.
</pre>

```python theme={"theme":{"light":"light-plus","dark":"dark-plus"}}
# Parse the response into a new column
t.add_computed_column(response=t.output.choices[0].message.content)
```

<pre style={{ 'margin': '-20px 20px 0px 20px', 'padding': '0px', 'background-color': 'transparent', 'color': 'black' }}>
  Added 0 column values with 0 errors in 0.02 s
  No rows affected.
</pre>

```python theme={"theme":{"light":"light-plus","dark":"dark-plus"}}
# Start a conversation
t.insert(
    [{'input': 'How many islands are in the Aleutian island chain?'}]
)
t.select(t.input, t.response).head()
```

<pre style={{ 'margin': '-20px 20px 0px 20px', 'padding': '0px', 'background-color': 'transparent', 'color': 'black' }}>
  Inserted 1 row with 0 errors in 2.17 s (0.46 rows/s)
</pre>

<div style={{ 'margin': '0px 20px 0px 20px' }} dangerouslySetInnerHTML={{ __html: quartoRawHtml[0] }} />

## Responses API

The [Responses
API](https://developers.openai.com/api/docs/api-reference/responses) is
OpenAI’s recommended API for new projects. It offers built-in tools (web
search, file search, code interpreter), improved reasoning model
performance, lower costs, and cleaner semantics compared to Chat
Completions.

Key benefits:

* **`instructions` parameter**: Cleanly separates system-level guidance
  from user input
* **`output_text` field**: Convenient access to the response text
* **Built-in tools**: Use `web_search`, `file_search`,
  `code_interpreter` natively
* **Multi-turn via `previous_response_id`**: Simpler conversation state
  management

```python theme={"theme":{"light":"light-plus","dark":"dark-plus"}}
# Create a table and add a computed column using the Responses API

resp_t = pxt.create_table('openai_demo/responses', {'input': pxt.String})

messages = [{'role': 'user', 'content': resp_t.input}]
resp_t.add_computed_column(
    output=openai.responses(
        input=messages,
        model='gpt-4o-mini',
        model_kwargs={
            'instructions': 'You are a helpful assistant. Be concise.',
            'temperature': 0.7,
            'max_output_tokens': 300,
        },
    )
)

# The Responses API provides a convenient 'output_text' field
resp_t.add_computed_column(response=resp_t.output.output_text)
```

<pre style={{ 'margin': '-20px 20px 0px 20px', 'padding': '0px', 'background-color': 'transparent', 'color': 'black' }}>
  Created table 'responses'.
  Added 0 column values with 0 errors in 0.01 s
  Added 0 column values with 0 errors in 0.01 s
  No rows affected.
</pre>

```python theme={"theme":{"light":"light-plus","dark":"dark-plus"}}
# Insert data and view results
resp_t.insert([{'input': 'What are the three largest moons of Jupiter?'}])
resp_t.select(resp_t.input, resp_t.response).head()
```

<pre style={{ 'margin': '-20px 20px 0px 20px', 'padding': '0px', 'background-color': 'transparent', 'color': 'black' }}>
  Inserted 1 row with 0 errors in 1.22 s (0.82 rows/s)
</pre>

<div style={{ 'margin': '0px 20px 0px 20px' }} dangerouslySetInnerHTML={{ __html: quartoRawHtml[1] }} />

## Embeddings

Note: OpenAI Embeddings API is not available with free tier API keys

```python theme={"theme":{"light":"light-plus","dark":"dark-plus"}}
emb_t = pxt.create_table('openai_demo/embeddings', {'input': pxt.String})
emb_t.add_computed_column(
    embedding=openai.embeddings(
        input=emb_t.input, model='text-embedding-3-small'
    )
)
```

<pre style={{ 'margin': '-20px 20px 0px 20px', 'padding': '0px', 'background-color': 'transparent', 'color': 'black' }}>
  Created table 'embeddings'.
  Added 0 column values with 0 errors in 0.00 s
  No rows affected.
</pre>

```python theme={"theme":{"light":"light-plus","dark":"dark-plus"}}
emb_t.insert(
    [{'input': 'OpenAI provides a variety of embeddings models.'}]
)
```

<pre style={{ 'margin': '-20px 20px 0px 20px', 'padding': '0px', 'background-color': 'transparent', 'color': 'black' }}>
  Inserted 1 row with 0 errors in 1.03 s (0.97 rows/s)
  1 row inserted.
</pre>

```python theme={"theme":{"light":"light-plus","dark":"dark-plus"}}
emb_t.head()
```

<div style={{ 'margin': '0px 20px 0px 20px' }} dangerouslySetInnerHTML={{ __html: quartoRawHtml[2] }} />

## Image generations

```python theme={"theme":{"light":"light-plus","dark":"dark-plus"}}
image_t = pxt.create_table('openai_demo/images', {'input': pxt.String})
image_t.add_computed_column(
    img=openai.image_generations(image_t.input, model='gpt-image-2')
)
```

<pre style={{ 'margin': '-20px 20px 0px 20px', 'padding': '0px', 'background-color': 'transparent', 'color': 'black' }}>
  Created table 'images'.
  Added 0 column values with 0 errors in 0.01 s
  No rows affected.
</pre>

```python theme={"theme":{"light":"light-plus","dark":"dark-plus"}}
image_t.insert(
    [
        {
            'input': 'A giant Pixel floating in the open ocean in a sea of data'
        }
    ]
)
```

<pre style={{ 'margin': '-20px 20px 0px 20px', 'padding': '0px', 'background-color': 'transparent', 'color': 'black' }}>
  Inserted 1 row with 0 errors in 12.21 s (0.08 rows/s)
  1 row inserted.
</pre>

```python theme={"theme":{"light":"light-plus","dark":"dark-plus"}}
image_t
```

<div style={{ 'margin': '0px 20px 0px 20px' }} dangerouslySetInnerHTML={{ __html: quartoRawHtml[3] }} />

<div style={{ 'margin': '0px 20px 0px 20px' }} dangerouslySetInnerHTML={{ __html: quartoRawHtml[4] }} />

<div style={{ 'margin': '0px 20px 0px 20px' }} dangerouslySetInnerHTML={{ __html: quartoRawHtml[5] }} />

<div style={{ 'margin': '0px 20px 0px 20px' }} dangerouslySetInnerHTML={{ __html: quartoRawHtml[6] }} />

```python theme={"theme":{"light":"light-plus","dark":"dark-plus"}}
image_t.head()
```

<div style={{ 'margin': '0px 20px 0px 20px' }} dangerouslySetInnerHTML={{ __html: quartoRawHtml[7] }} />

## Audio Transcription

```python theme={"theme":{"light":"light-plus","dark":"dark-plus"}}
audio_t = pxt.create_table('openai_demo/audio', {'input': pxt.Audio})
audio_t.add_computed_column(
    result=openai.transcriptions(
        audio_t.input,
        model='whisper-1',
        model_kwargs={
            'language': 'en',
            'prompt': 'Transcribe the contents of this recording.',
        },
    )
)
```

<pre style={{ 'margin': '-20px 20px 0px 20px', 'padding': '0px', 'background-color': 'transparent', 'color': 'black' }}>
  Created table 'audio'.
  Added 0 column values with 0 errors in 0.00 s
  No rows affected.
</pre>

```python theme={"theme":{"light":"light-plus","dark":"dark-plus"}}
url = (
    'https://github.com/pixeltable/pixeltable/raw/release/tests/data/audio/'
    'jfk_1961_0109_cityuponahill-excerpt.flac'
)
audio_t.insert([{'input': url}])
```

<pre style={{ 'margin': '-20px 20px 0px 20px', 'padding': '0px', 'background-color': 'transparent', 'color': 'black' }}>
  Inserted 1 row with 0 errors in 2.66 s (0.38 rows/s)
  1 row inserted.
</pre>

```python theme={"theme":{"light":"light-plus","dark":"dark-plus"}}
audio_t.head()
```

```python theme={"theme":{"light":"light-plus","dark":"dark-plus"}}
audio_t.head()[0]['result']['text']
```

<pre style={{ 'margin': '-20px 20px 0px 20px', 'padding': '0px', 'background-color': 'transparent', 'color': 'black' }}>
  'Allow me to illustrate. During the last 60 days, I have been at the task of constructing an administration. It has been a long and deliberate process. Some have counseled greater speed. Others have counseled more expedient tests. But I have been guided by the standard John Winthrop set before his shipmates on the flagship Arabella 331 years ago, as they too faced the task of building a new government on a perilous frontier. We must always consider, he said, that we shall be as a city upon a hill. The eyes of all peoples are upon us. Today the eyes of all people are truly upon us. And our governments, in every branch, at every level,'
</pre>

### Learn more

To learn more about advanced techniques like RAG operations in
Pixeltable, check out the [RAG Operations in
Pixeltable](/howto/use-cases/rag-operations)
tutorial.

If you have any questions, don’t hesitate to reach out.
