Run background task to grab data

What I’m trying to do:
I am trying to get data from an API using a background server call. I was originally using a standard server call but it kept timing out because the dataset is so large. I want the client side function to return the data which is currently in a listed dictionary. I cannot append or bind the data because it will be frequently updated based on user input.

What I’ve tried and what’s not working:
On the server side, I have created a background task to get the data from the API. Then I created a callable server function to start that background task. On the client side, I have created a function to call the server function. However, my data does not return and no errors are appearing. I really have no idea how the get_state() works because it is not clear in the documentation when you are returning dictionaries.

Server Code Sample:


import anvil.server
import anvil.secrets
import requests
from datetime import date

@anvil.server.background_task
def call_api_endpoint(start_date: date, end_date: date):
    url = "XXXXXXXXXhiddeninformationXXXXXXXXX"
    headers = {'x-apikey': anvil.secrets.get_secret('API_KEY')}
    params = {
        "from": start_date.isoformat(),
        "to": end_date.isoformat()
    }

    # Making the API request
    response = requests.get(url, params=params, headers=headers)
    response.raise_for_status()
    
    # Communicating the result back to the client
    anvil.server.task_state['data'] = response.json()  # Save the API response into task_state
    
    return response.json()


# This function will be called by the client to start the background task
@anvil.server.callable
def start_data_insights_task(start_date, end_date):
    # Launch the background task and pass the dates to it
    task = anvil.server.launch_background_task('call_api_endpoint', start_date, end_date)
    return task  # Return the task object to the client

Client Code Sample:

from ._anvil_designer import heat_map_copyTemplate
from anvil import *
import anvil.server
from datetime import date
import plotly.graph_objects as go
import json

class heat_map_copy(heat_map_copyTemplate):
    def __init__(self, **properties):
        """Initialize form components and set up default values."""
        self.init_components(**properties)
        self.date_picker_start.date = date(2025, 1, 1)
        self.date_picker_end.date = date(2025, 1, 31)

    def collect_data_button_click(self, **event_args):
        """Triggered when the user clicks the 'Collect Data' button."""
        
        # Start the background task
        self.bg_task = anvil.server.call('start_data_insights_task', self.date_picker_start.date, self.date_picker_end.date)
        
        # Polling the task completion status
        self.timer_1.enabled = True  # Start a timer to check the task status

    def timer_1_tick(self, **event_args):
        """Check if background task is completed."""
        
        if self.bg_task.is_completed():  # Check if the task is done
            self.timer_1.enabled = False  # Stop the timer
            
            # Fetch the result from the background task
            result = self.bg_task.get_return_value()
            print("Fetched data:", result)  # Print the result to console

            if result:
                # Process and clean the data if available
                self.raw_contributions = result
                print("Cleaned data:", self.raw_contributions)

Hey @pkemp, Welcome to the community.

The one thing I did see is the self.timer_1.enabled = True.
The way to handle the timers is using their interval attribute
Disable a timer by: self.timer.interval = 0

Here is a quick little demo that gives you somewhere to start that I think includes all the elements you were looking for:
Background Task Demo