Skip to main content

External Data

These examples show how to send and receive data from external sources, such as APIs or databases. You can use these techniques to pre-fill forms, validate inputs, or save data dynamically.

Before or after the user fills the form

You can perform API calls or other operations before or after the form is displayed to the user.

from abstra.forms import NumberInput, run
import my_api # Example API module

# Fetch data before showing the form
username = my_api.get_username()

# Define the form
personal_details = [NumberInput(f"How old are you, {username}?", key="age")]

# Run the form
state = run([personal_details])

# Save data after the form is submitted
my_api.set_age(state["age"])

After a page is advanced

You can also load or save data dynamically as the user progresses through the form. Use functions to perform these operations and pass them to run.

from abstra.forms import NumberInput, TextInput, run
import my_api # Example API module

def email_page(state):
return [TextInput("Enter email", key="email")]

def load_user_data(state):
# Use previous page data to load the user
state["user"] = my_api.load_user(state["email"])
return # This function won't be shown as a form step

def age_page(state):
username = state["user"].get("name", "User")
return [NumberInput(f"How old are you, {username}?", key="age")]

def save_user_data(state):
# Save the age answer from previous page
my_api.save_age(state["email"], state["age"])
return # This function won't be shown as a form step

# Run the form with dynamic data handling
run([email_page, load_user_data, age_page, save_user_data])

While a page is being filled

You can also load data dynamically while the user is filling out a page. This is useful for pre-filling fields or validating inputs.

from abstra.forms import NumberInput, TextInput, run
import my_api # Example API module

def reactive_page(state):
company_id = state.get("company_id")
if company_id and len(company_id) == 10:
# Fetch company name only once for each company_id
state["company_name"] = reuse(my_api.fetch, company_id)

return [
TextInput("Company ID", key="company_id"),
TextInput("Company Name", key="company_name"),
]

# Run the reactive form
run([reactive_page])

In this example, “company name” field is automatically filled based on API data when “company id” is filled by the user.

Note the use of reuse wrapping this the API call. Without it, each time the user pressed a key (and the corresponding state changed) an API call would be made slowing things down. This guarantees that my_api.fetch is only called once for each company_id .