Skill Tracer
Skills › Scientific Agent Skills › modal › getting-started.md

getting-started.md

179 lines · skills/modal/references/getting-started.md at 5f2bc03

Open on GitHub
1# Modal Getting Started Guide
2
3Reviewed against Modal 1.6.0, the [getting started guide](https://modal.com/docs/guide/getting-started)
4and [SDK release notes](https://modal.com/docs/sdk/py/releases). The hello-world handler
5was run locally; cloud execution and the third-party examples remain illustrative.
6

Modal Getting Started Guide

Reviewed against Modal 1.6.0, the getting started guide and SDK release notes. The hello-world handler was run locally; cloud execution and the third-party examples remain illustrative.

Raw lines 1 to 6
7## Installation
8
9Install Modal with uv (recommended). The SDK supports Python 3.10–3.14:
11```bash
12uv pip install "modal==1.6.0"
13```

Installation

Install Modal with uv (recommended). The SDK supports Python 3.10–3.14:

uv pip install "modal==1.6.0"
Raw lines 7 to 14
15## Authentication

Authentication

Raw lines 15 to 16
17### Interactive Setup
19```bash
20modal setup
21```
23This opens a browser and stores a profile in `.modal.toml`. Reuse an existing profile
24or `MODAL_TOKEN_ID`/`MODAL_TOKEN_SECRET` pair before running setup. Check credential
25presence without printing values; do not dump environment variables or credential files.

Interactive Setup

modal setup

This opens a browser and stores a profile in .modal.toml. Reuse an existing profile or MODAL_TOKEN_ID/MODAL_TOKEN_SECRET pair before running setup. Check credential presence without printing values; do not dump environment variables or credential files.

Raw lines 17 to 26
27### Headless / CI/CD Setup
29For environments without a browser, use token-based authentication:
311. Generate tokens at https://modal.com/settings
322. Set environment variables:
34```bash
35export MODAL_TOKEN_ID=<your-token-id>
36export MODAL_TOKEN_SECRET=<your-token-secret>
37```
39Or use the CLI:
41```bash
42modal token set --token-id <id> --token-secret <secret>
43```

Headless / CI/CD Setup

For environments without a browser, use token-based authentication:

  1. Generate tokens at https://modal.com/settings
  2. Set environment variables:
export MODAL_TOKEN_ID=<your-token-id>
export MODAL_TOKEN_SECRET=<your-token-secret>

Or use the CLI:

modal token set --token-id <id> --token-secret <secret>
Raw lines 27 to 44
45### Free Tier
47Check the [pricing page](https://modal.com/pricing) for current credits and plan limits.
48GPU use requires a payment method; credits do not imply every workload is free.

Free Tier

Check the pricing page for current credits and plan limits. GPU use requires a payment method; credits do not imply every workload is free.

Raw lines 45 to 49
50## Your First App

Your First App

Raw lines 50 to 51
52### Hello World
54Create a file `hello.py`:
56```python
57import modal
59app = modal.App("hello-world")
61@app.function()
62def greet(name: str) -> str:
63 return f"Hello, {name}! This ran in the cloud."
65@app.local_entrypoint()
66def main():
67 result = greet.remote("World")
68 print(result)
69```
71Run it:
73```bash
74modal run hello.py
75```
77What happens:
781. Modal packages your code
792. Creates a container in the cloud
803. Executes `greet()` remotely
814. Returns the result to your local machine

Hello World

Create a file hello.py:

import modal

app = modal.App("hello-world")

@app.function()
def greet(name: str) -> str:
    return f"Hello, {name}! This ran in the cloud."

@app.local_entrypoint()
def main():
    result = greet.remote("World")
    print(result)

Run it:

modal run hello.py

What happens:

  1. Modal packages your code
  2. Creates a container in the cloud
  3. Executes greet() remotely
  4. Returns the result to your local machine
Raw lines 52 to 82
83### Understanding the Flow
85- `modal.App("name")` — Creates a named application
86- `@app.function()` — Marks a function for remote execution
87- `@app.local_entrypoint()` — Defines the local entry point (runs on your machine)
88- `.remote()` — Calls the function in the cloud
89- `.local()` — Calls locally without applying the Image, resource, Secret or Volume configuration

Understanding the Flow

  • modal.App("name") — Creates a named application
  • @app.function() — Marks a function for remote execution
  • @app.local_entrypoint() — Defines the local entry point (runs on your machine)
  • .remote() — Calls the function in the cloud
  • .local() — Calls locally without applying the Image, resource, Secret or Volume configuration
Raw lines 83 to 90
91### Running Modes
93| Command | Description |
94|---------|-------------|
95| `modal run script.py` | Run an entrypoint or selected Function in an ephemeral App |
96| `modal serve script.py` | Start a dev server with hot reload (for web endpoints) |
97| `modal deploy script.py` | Persist the App definition; containers still scale to zero |

Running Modes

CommandDescription
modal run script.pyRun an entrypoint or selected Function in an ephemeral App
modal serve script.pyStart a dev server with hot reload (for web endpoints)
modal deploy script.pyPersist the App definition; containers still scale to zero
Raw lines 91 to 98
99### A Simple Web Scraper
101```python
102import modal
104app = modal.App("web-scraper")
106image = modal.Image.debian_slim().uv_pip_install("httpx", "beautifulsoup4")
108@app.function(image=image)
109def scrape(url: str) -> str:
110 import httpx
111 from bs4 import BeautifulSoup
113 response = httpx.get(url, follow_redirects=True, timeout=30)
114 response.raise_for_status()
115 soup = BeautifulSoup(response.text, "html.parser")
116 return soup.get_text()[:1000]
118@app.local_entrypoint()
119def main():
120 result = scrape.remote("https://example.com")
121 print(result)
122```

A Simple Web Scraper

import modal

app = modal.App("web-scraper")

image = modal.Image.debian_slim().uv_pip_install("httpx", "beautifulsoup4")

@app.function(image=image)
def scrape(url: str) -> str:
    import httpx
    from bs4 import BeautifulSoup

    response = httpx.get(url, follow_redirects=True, timeout=30)
    response.raise_for_status()
    soup = BeautifulSoup(response.text, "html.parser")
    return soup.get_text()[:1000]

@app.local_entrypoint()
def main():
    result = scrape.remote("https://example.com")
    print(result)
Raw lines 99 to 123
124### GPU-Accelerated Inference
126```python
127import modal
129app = modal.App("gpu-inference")
131image = (
132 modal.Image.debian_slim(python_version="3.11")
133 .uv_pip_install("torch", "transformers", "accelerate")
136@app.function(gpu="L40S", image=image)
137def generate(prompt: str) -> str:
138 from transformers import pipeline
139 pipe = pipeline("text-generation", model="openai-community/gpt2", device=0)
140 result = pipe(prompt, max_new_tokens=100)
141 return result[0]["generated_text"]
143@app.local_entrypoint()
144def main():
145 print(generate.remote("The future of AI is"))
146```

GPU-Accelerated Inference

import modal

app = modal.App("gpu-inference")

image = (
    modal.Image.debian_slim(python_version="3.11")
    .uv_pip_install("torch", "transformers", "accelerate")
)

@app.function(gpu="L40S", image=image)
def generate(prompt: str) -> str:
    from transformers import pipeline
    pipe = pipeline("text-generation", model="openai-community/gpt2", device=0)
    result = pipe(prompt, max_new_tokens=100)
    return result[0]["generated_text"]

@app.local_entrypoint()
def main():
    print(generate.remote("The future of AI is"))
Raw lines 124 to 147
148## Project Structure
150Modal apps are typically single Python files, but can be organized into modules:
152```
153my-project/
154├── app.py # Main app with @app.local_entrypoint()
155├── inference.py # Inference functions
156├── training.py # Training functions
157└── common.py # Shared utilities
158```
160Use `modal.Image.add_local_python_source()` to include local modules in the container image.

Project Structure

Modal apps are typically single Python files, but can be organized into modules:

my-project/
├── app.py           # Main app with @app.local_entrypoint()
├── inference.py     # Inference functions
├── training.py      # Training functions
└── common.py        # Shared utilities

Use modal.Image.add_local_python_source() to include local modules in the container image.

Raw lines 148 to 161
162## Key Concepts Summary
164| Concept | What It Does |
165|---------|-------------|
166| `App` | Groups related functions into a deployable unit |
167| `Function` | A serverless function backed by autoscaling containers |
168| `Image` | Defines the container environment (packages, files) |
169| `Volume` | Persistent distributed file storage |
170| `Secret` | Secure credential injection |
171| `Schedule` | Cron or periodic job scheduling |
172| `gpu` | GPU type/count for the function |

Key Concepts Summary

ConceptWhat It Does
AppGroups related functions into a deployable unit
FunctionA serverless function backed by autoscaling containers
ImageDefines the container environment (packages, files)
VolumePersistent distributed file storage
SecretSecure credential injection
ScheduleCron or periodic job scheduling
gpuGPU type/count for the function
Raw lines 162 to 173
174## Next Steps
176- See `functions.md` for advanced function patterns
177- See `images.md` for custom container environments
178- See `gpu.md` for GPU selection and configuration
179- See `web-endpoints.md` for serving APIs

Next Steps

  • See functions.md for advanced function patterns
  • See images.md for custom container environments
  • See gpu.md for GPU selection and configuration
  • See web-endpoints.md for serving APIs
Raw lines 174 to 179