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.
Pixeltable’s fal.ai integration enables you to access fal.ai’s fast
inference models via the fal.ai API.
fal.ai usage may incur costs based on your fal.ai 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 a fal.ai API
key.
%pip install -qU fal-client
import getpassimport osif 'FAL_API_KEY' not in os.environ: os.environ['FAL_API_KEY'] = getpass.getpass('fal.ai API Key: ')
Now let’s create a Pixeltable directory to hold the tables for our demo.
import pixeltable as pxt# Remove the 'fal_demo' directory and its contents, if it existspxt.drop_dir('fal_demo', force=True)pxt.create_dir('fal_demo')
Connected to Pixeltable database at: postgresql+psycopg://postgres:@/pixeltable?host=/Users/pjlb/.pixeltable/pgdata
Created directory ‘fal_demo’.
<pixeltable.catalog.dir.Dir at 0x13c533650>
Let’s start by using fal.ai’s FLUX Schnell model, which is optimized for
fast image generation. We’ll create a table to store prompts and
generated images.
from pixeltable.functions import fal# Create a table for image generationt = pxt.create_table('fal_demo/images', {'prompt': pxt.String})# Add a computed column that calls the FLUX Schnell modelt.add_computed_column( response=fal.run( input={'prompt': t.prompt}, app='fal-ai/flux/schnell' ))
Created table ‘images’.
Added 0 column values with 0 errors in 0.01 s
No rows affected.
Now let’s insert some prompts and see the results:
# Insert a few promptst.insert( [ { 'prompt': 'A serene mountain landscape at sunset with a crystal clear lake' }, { 'prompt': 'A friendly robot teaching a class of kittens to code' }, {'prompt': 'An underwater city with bioluminescent architecture'}, ])
Inserted 3 rows with 0 errors in 1.77 s (1.70 rows/s)
3 rows inserted.
Let’s examine the structure of the response:
t.select(t.prompt, t.response).head(1)
We can see that fal.ai returns a JSON response with an images array.
Each image has a url field. Let’s extract and display the images:
# Add a computed column to extract the image URL and convert it to an Image typet.add_computed_column( image=t.response['images'][0]['url'].astype(pxt.Image))# Display the prompts and imagest.select(t.prompt, t.image).head()
Added 3 column values with 0 errors in 0.04 s (85.38 rows/s)
fal.ai also offers Fast SDXL, which provides more control over image
generation parameters. Let’s create a new table to explore these
capabilities.
# Create a table with more parameterssdxl_t = pxt.create_table( 'fal_demo/sdxl_images', { 'prompt': pxt.String, 'negative_prompt': pxt.String, 'steps': pxt.Int, },)# Add a computed column with more parameterssdxl_t.add_computed_column( response=fal.run( input={ 'prompt': sdxl_t.prompt, 'negative_prompt': sdxl_t.negative_prompt, 'image_size': 'square_hd', # 1024x1024 'num_inference_steps': sdxl_t.steps, }, app='fal-ai/fast-sdxl', ))# Extract the imagesdxl_t.add_computed_column( image=sdxl_t.response['images'][0]['url'].astype(pxt.Image))
Created table ‘sdxl_images’.
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.
# Insert prompts with different parameterssdxl_t.insert( [ { 'prompt': 'A majestic lion in a savanna at golden hour, photorealistic', 'negative_prompt': 'cartoon, illustration, drawing', 'steps': 25, }, { 'prompt': 'A futuristic cityscape with flying cars and neon lights', 'negative_prompt': 'blurry, low quality', 'steps': 30, }, ])
Inserted 2 rows with 0 errors in 5.23 s (0.38 rows/s)
2 rows inserted.
# Display the resultssdxl_t.select(sdxl_t.prompt, sdxl_t.image).head()
You can also generate multiple variations of the same prompt in a single
request:
# Create a table for multiple image generationmulti_t = pxt.create_table( 'fal_demo/multi_images', {'prompt': pxt.String})# Generate 3 variations of each promptmulti_t.add_computed_column( response=fal.run( input={'prompt': multi_t.prompt, 'num_images': 3}, app='fal-ai/flux/schnell', ))# Extract the first image (you could create columns for all three)multi_t.add_computed_column( image_1=multi_t.response['images'][0]['url'].astype(pxt.Image))multi_t.add_computed_column( image_2=multi_t.response['images'][1]['url'].astype(pxt.Image))multi_t.add_computed_column( image_3=multi_t.response['images'][2]['url'].astype(pxt.Image))
Created table ‘multi_images’.
Added 0 column values with 0 errors in 0.01 s
Added 0 column values with 0 errors in 0.01 s
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.
# Insert a promptmulti_t.insert( [{'prompt': 'A steampunk mechanical butterfly on a brass flower'}])
Inserted 1 row with 0 errors in 1.14 s (0.88 rows/s)
1 row inserted.
# Display all three variationsmulti_t.select(multi_t.image_1, multi_t.image_2, multi_t.image_3).head()
For higher quality generation, you can use models like fal-ai/flux/dev
which produce better results but take more time:
# Create a table using FLUX Devdev_t = pxt.create_table('fal_demo/flux_dev', {'prompt': pxt.String})# Use FLUX Dev model for higher qualitydev_t.add_computed_column( response=fal.run( input={'prompt': dev_t.prompt}, app='fal-ai/flux/dev' ))dev_t.add_computed_column( image=dev_t.response['images'][0]['url'].astype(pxt.Image))
Created table ‘flux_dev’.
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.
# Insert a prompt (note: FLUX Dev may take longer but produces higher quality results)dev_t.insert( [ { 'prompt': 'A highly detailed oil painting of a wizard casting a spell in an ancient library' } ])
Inserted 1 row with 0 errors in 1.74 s (0.58 rows/s)
1 row inserted.
# Display the resultdev_t.select(dev_t.prompt, dev_t.image).head()
Pixeltable’s computed columns make it easy to process multiple images in
batch. Let’s create a larger dataset:
# Create a batch processing tablebatch_t = pxt.create_table( 'fal_demo/batch', {'category': pxt.String, 'description': pxt.String})# Create a prompt by combining category and descriptionbatch_t.add_computed_column( prompt=pxt.functions.string.format( 'A {} that is {}', batch_t.category, batch_t.description ))# Generate imagesbatch_t.add_computed_column( response=fal.run( input={'prompt': batch_t.prompt}, app='fal-ai/flux/schnell' ))batch_t.add_computed_column( image=batch_t.response['images'][0]['url'].astype(pxt.Image))
Created table ‘batch’.
Added 0 column values with 0 errors in 0.02 s
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.
# Insert a batch of promptsbatch_t.insert( [ {'category': 'landscape', 'description': 'peaceful and zen-like'}, { 'category': 'portrait', 'description': 'mysterious and ethereal', }, { 'category': 'abstract art', 'description': 'colorful and energetic', }, { 'category': 'architecture', 'description': 'modern and minimalist', }, {'category': 'animal', 'description': 'cute and fluffy'}, ])
Inserted 5 rows with 0 errors in 1.69 s (2.96 rows/s)
5 rows inserted.
# View all resultsbatch_t.select( batch_t.category, batch_t.description, batch_t.image).show()