Skip to main content

Python Client

Installation

pip install leapcell

Preparation

Leapcell uses an API Token for API access. Learn more about API Tokens here.

Quick Start

from leapcell import Leapcell
import os

# Get API token from env
api_token = os.environ.get("LEAPCELL_API_KEY")

# Initialize client with the token
leapclient = Leapcell(api_token)

# Initialize table instance
# Get table id from url, e.g., https://leapcell.io/issac/blog/table/12345678, then table id is 12345678
# Get project name from url, e.g., https://leapcell.io/issac/blog/table/12345678, then project name is issac/blog
table = leapclient.table("{{PROJECT_NAME}}", "{{TABLE_ID}}")

# Create a record
record = table.create({"title": "hello issac"})

# Update a record
record["title"] = "hello issac again"
record.save()

# Get a record by ID
record = table.get_by_id(record.id)

# Delete a record
record.delete()

# Get record if title is hello
records = table.select().where(table["title"] == "hello").limit(10).offset(0).first()

# Get record with sorting
records = table.select().where(table["title"] == "hello").order_by(table['title'].asc()).query()

# Update records
table.select().where(
{
"title": "hello issac again",
}
).update(
{
"title": "here is leapcell",
}
)

# Delete records
table.select().where(
{
"title": "hello issac again",
}
).delete()

# Bulk create
records = table.bulk_create(
[
{
"title": "hello issac",
},
{
"title": "hello jude",
},
]
)

# Search, like a search engine
records = table.search("hello jude")

# Search in the "title" field
records = table.search("hello", fields=["title"])

# Count records
count = table.select().where(table["title"] == "hello").count()

Usage

Initializing the Client

You can either place the API Token in the environment variables or pass it directly.

  • PROJECT_NAME: Your project name, e.g., if it's leapcell.io/issac/blog, then PROJECT_NAME is issac/blog.
  • TABLE_ID: Your table ID, e.g., if your table is leapcell.io/issac/blog/table/12345678, then TABLE_ID is 12345678.

By default, the table uses the table name. If you want to use the table ID, set name_type to id.

from leapcell import Leapcell
import os

# Get API token from env
api_token = os.environ.get("LEAPCELL_API_KEY")

# Initialize client with the token
leapclient = Leapcell(api_token)

# Initialize table instance
table = leapclient.table("{{PROJECT_NAME}}", "{{TABLE_ID}}")

# Initialize table instance with table id
# table = leapclient.table("{{PROJECT_NAME}}", "{{TABLE_ID}}", name_type="id")

Getting Table Meta Info

# Get table meta info
print(table.meta().toJSON())

# Output:
# {'resource': 'issac/blog', 'table_id': 'tbl1726117346872295424', 'fields': {'category': <field id: fld129608161 name: category, type: LABELS>, 'content': <field id: fld3419043789 name: content, type: LONG_TEXT>, 'cover': <field id: fld2448453439 name: cover, type: IMAGES>, 'summary': <field id: fld4203215423 name: summary, type: LONG_TEXT>, 'title': <field id: fld1188108910 name: title, type: STR>}}

Creating a Record

Leapcell automatically converts data based on the table's field types. If the conversion fails, an exception is raised.

# Create a record
record = table.create({"title": "hello issac"})

# Output:
# {'record_id': '60387060-6b27-47b4-b7e6-2770742654b8', 'data': {'title': 'hello issac'}, 'create_time': 1703150140, 'update_time': 1703150140}

Updating a Record

# Update a record
record["title"] = "hello issac again"
record.save()

# Output:
# {'record_id': '60387060-6b27-47b4-b7e6-2770742654b8', 'data': {'title': 'hello issac again'}, 'create_time': 1703150140, 'update_time': 1703150140}

Getting a Record By ID

# Get a record by ID
record = table.get_by_id(record.id)

# Output:
# {'record_id': '60387060-6b27-47b4-b7e6-2770742654b8', 'data': {'category': None, 'content': None, 'cover': None, 'summary': None, 'title': 'hello issac again'}, 'create_time': 1703150140, 'update_time': 1703150491}

Deleting a Record By ID

# Delete a record
record.delete()

# or

table.delete_by_id(record.id)

Getting a Record By Filter

Leapcell supports various query methods. Use where to perform queries, and fields are represented by table["field_name"].

Get a record if the title is "hello":

# Get record if title is hello
records = table.select().where(table["title"] == "hello").limit(10).offset(0).first()

AND

Get a record if the title is "hello" and the category is "tutorial":

records = table.select().where(
(table["title"] == "hello" & table["category"] == "tutorial")
).limit(10).offset(0).first()

OR

Get a record if the title is "hello" or the category is "tutorial":

records = table.select().where(
(table["title"] == "hello" | table["category"] == "tutorial")
).limit(10).offset(0).first()

Field Operators

For information about the operators supported by fields, refer to Field Operators.

The mapping between op and Python operators is as follows:

# op: eq
table["title"] == "hello"

# op: gt
table["title"] > "hello"

# op: gte
table["title"] >= "hello"

# op: lt
table["title"] < "hello"

# op: lte
table["title"] <= "hello"

# op: neq
table["title"] != "hello"

# op: contain
table["title"].contain("hello")

# "hello" in table["title"]

# op: in
table["title"].in_(["hello", "world"])

# op: not_in
table["title"].not_in(["hello", "world"])

# op: is_null
table["title"].is_null()

# op: is_not_null
table["title"].is_not_null()

Getting Records and Sorting

records = table.select().where(table["title"] == "hello").order_by(table['title'].asc()).query()

records = table.select().where(table["title"] == "hello").order_by(table['title'].desc()).query()

Get Records and Pagination

Retrieve records with a limit of 10 and an offset of 0.

records = table.select().where(table["title"] == "hello").limit(10).offset(0).query()

Update Record By Filter

Update records where the title is "hello issac again."

# Update records
table.select().where(
{
"title": "hello issac again",
}
).update(
{
"title": "here is leapcell",
}
)

Delete Record By Filter

Delete records where the title is "hello issac again."

# Delete records
table.select().where(
{
"title": "hello issac again",
}
).delete()

Bulk Create

Bulk create records.

# Bulk create
records = table.bulk_create(
[
{
"title": "hello issac",
},
{
"title": "hello jude",
},
]
)

By default, the search is performed on all fields. If you want to specify fields, use the fields parameter.

Similar to a search engine, Leapcell tokenizes search keywords and performs searches. When you search for "hello issac," Leapcell searches for "hello" and then "issac," finally merging the results.

# Search
records = table.search("hello")

# Search for "hello" and "jude"
records = table.search("hello jude")

# Search in the "title" field
records = table.search("hello", fields=["title"])

# Pagination
records = table.select().limit(10).offset(0).search("hello")

Image Upload

Leapcell supports image uploads. You can upload images to Leapcell and save the image URL to the table.

Images will be uploaded to the CDN.

import requests

# Fetch image
image_req = requests.get(
"https://leapcell-dev-bucket.s3.amazonaws.com/920417ee6a70435084fe6b40d58dad4e.jpeg"
)

image = image_req.content
resp = table.upload_file(image)
# Output:
# LeapcellFile(id=img07201ffc5ce24f85abb6fabc9e63fa80-file.jpeg, link=https://cdn1.leapcell.io/img07201ffc5ce24f85abb6fabc9e63fa80-file.jpeg, width=0, height=0)

# Save image ID to the table
record["cover"] = resp.id
record.save()

Upload multiple images.

import requests

# Fetch image
image_req = requests.get(
"https://leapcell-dev-bucket.s3.amazonaws.com/920417ee6a70435084fe6b40d58dad4e.jpeg"
)

resp = table.upload_files([image, image])
# Output:
# [{"id": "imge8ba2e9ba6b64afaab953239869fb564-files.jpeg", "link": "https://cdn1.leapcell.io/imge8ba2e9ba6b64afaab953239869fb564-files.jpeg", "meta": {"width": 0, "height": 0}}, {"id": "img31277a9417044d2c80fee16f42e6b654-files.jpeg", "link": "https://cdn1.leapcell.io/img31277a9417044d2c80fee16f42e6b654-files.jpeg", "meta": {"width": 0, "height": 0}}]

record["cover"] = [resp[0].id, resp[1].id]
record.save()