Skip to main content

App Framework

The Atlan App Framework is a Python framework for building durable, fault-tolerant applications on the Atlan platform. apps automatically recover from failures with checkpointed progress—when something crashes, execution resumes from the last checkpoint, not from scratch. Write normal Python code; the framework handles retries, state persistence, and observability.

Why durability matters: Network timeouts, service restarts, and transient failures are inevitable. Without durability, a 1-hour metadata extraction job that fails after 45 minutes must restart from the beginning. With the App Framework, it resumes from the last completed step — typically losing only minutes of work.

Think of it like rock climbing with anchors (the kind you secure the rope with).

  • Your app defines the route—which holds to grab, where to go next.
  • Tasks are the anchors you set along the way.

Each time you complete a task, you've clipped in—your progress is secured. If something fails (network error, service restart, whatever), you only fall back to the last anchor, not all the way down.

Completed anchors hold. Once a task is done, it stays done. The framework remembers. If something fails later, completed tasks don't need to run again.

Apps: Route

An app is a unit of execution. Each app has:

  • A typed Input and Output: the gear you bring to the climb and the photo from the summit when you're done
  • A run() method that defines the route

The run() method is the plan: it decides which tasks to run and in what order, but doesn't do the actual work itself. All side-effects (network calls, file I/O, database access) happen inside tasks.

Tasks: Anchors

A task (@task) is where the real work happens—network calls, file I/O, database access. Each completed task is a checkpoint—if the app restarts, completed tasks are skipped automatically.

Here's what this looks like in code:

from application_sdk.app import App, task
from application_sdk.contracts import Input, Output

class FetchInput(Input):
name: str = "World"

class FetchOutput(Output):
message: str = ""

class HelloWorldApp(App):
@task(timeout_seconds=10)
async def create_greeting(self, input: FetchInput) -> FetchOutput:
return FetchOutput(message=f"Hello, {input.name}!")

async def run(self, input: FetchInput) -> FetchOutput:
return await self.create_greeting(input)

The run() method composes tasks. The @task methods do the work. This separation is what makes the app durable.

What it gives you

🔄

Automatic fault tolerance

Completed tasks survive failures. Retry policies, timeouts, and progress reporting are declarative — no boilerplate required.

🔒

Type-safe contracts

Typed Input and Output models are validated at startup. Forbidden types are caught before your app runs, not after it fails in production.

🧪

Built-in testability

Test tasks directly without any external services using the framework's mock infrastructure utilities.

🚀

Platform integration

Prebuilt APIs, credential management, and deployment tooling make your app a first-class Atlan citizen.

Next steps

  • Apps and tasks: Deep dive into the App class, @task decorator, entry points, and lifecycle hooks.
  • Inputs and outputs: Typed contracts, payload safety, large data with FileReference, and evolution rules.
  • Handlers: Expose your app over HTTP with a typed handler that validates auth, runs preflights, and returns metadata.
  • Quickstart: Install the framework and run your first app in minutes.