Skip to main content

Command Palette

Search for a command to run...

Getting Started with FastOpp using uv

Published
5 min read
Getting Started with FastOpp using uv

FastOpp is a student-friendly FastAPI starter for building AI web apps fast. It gives you admin, auth, database models, templates, and demo endpoints so you can focus on your idea instead of boilerplate. This guide gets you from zero to running locally with uv, sets up your .env variables safely, and shows how to switch the LLM used by the /ai-demo.

What you’ll install and why

  • PyPI is the central package index for Python. Open-source Python libraries publish releases there. Package managers pull your dependencies from PyPI.

  • uv is a fast Python package and project manager written in Rust. It installs Python, creates virtual environments, resolves dependencies, and runs your project. It’s a modern replacement for pip + venv + pip-tools workflows and is usually much faster.

FastOpp’s quick-start flow in the README defaults to uv. We’ll follow that so your setup matches the project’s expectations. GitHub

Prereqs

  • macOS, Linux, or Windows with shell access.

  • Python 3.12 is required for now. If you don’t have it, uv will install it. GitHub

Step 1: Install uv

Run the official installer:

curl -LsSf https://astral.sh/uv/install.sh | sh

Confirm:

uv --version

uv can also manage Python runtimes. You’ll use that next.

Step 2: Create a new FastOpp project with uv

  1. Ensure Python 3.12 is available:
uv python install 3.12
python --version
  1. Initialize a fresh project folder and add FastOpp:
mkdir my-project && cd my-project
uv init --python 3.12
uv add fastopp
  1. Scaffold the FastOpp app:
uv run fastopp-startproject

This command writes the starter files into your current directory.

  1. Start the dev server:
uv run python oppman.py runserver

Open a browser to http://localhost:8000.

Nice work! You should see this:

It’s running, but it’s not connected to anything yet…

Step 3: Configure .env correctly

The repo includes example.env. Copy it, then edit:

cp example.env .env

Open .env in your editor. You must set your OpenRouter API key:

OPENROUTER_API_KEY=...

How to get an API key without paying yourself

Oppkey provides keys for learners. Ask Oppkey for an OpenRouter key so usage is billed to Oppkey’s account during your learning and testing. We cap the usage at $2, which likely covers lots of testing. If you use up your cap, ask for another key.

You can use your own OpenRouter API key if you prefer, but then costs are yours.

Why .env protects sensitive values

The .env file lives only on your machine and is read by your app at runtime. You do not commit it to Git. It keeps secrets—API keys, DB URLs—out of source control and out of the codebase. The convention is simple:

  • .env stays local.

  • .gitignore blocks .env from commits.

  • Code reads values at runtime via environment variables.

This reduces accidental key exposure in pull requests and public repos. It does not make stolen machines safe and it is not a production secrets manager. For teaching and local development, it is the right default.

Step 4: Run locally and explore

Start the app:

uv run python oppman.py runserver

Then visit:

  • http://localhost:8000 for the app

  • API docs at http://localhost:8000/docs

  • Demo routes such as /ai-demo

If you copied example.env to .env and set OPENROUTER_API_KEY, the defaults will work locally.

Step 5: Resetting the LLM used by /ai-demo

The demo uses a model configured via environment variables in .env. The default free LLM is for easy setup. But we recommend that you switch to a paid model for better reliability and behavior.

There are two simple paths:

Option A: Uncomment and set the model in .env

Open .env and find the LLM models:

# OPENROUTER_LLM_MODEL=google/gemini-2.5-flash-lite-preview-09-2025
# Google model, detailed responses, great formatting
# OPENROUTER_LLM_MODEL=liquid/lfm2-8b-a1b
# Liquid AI model, startup spun out of MIT, fast, complete responses, good formatting, emojis.
# OPENROUTER_LLM_MODEL=meta-llama/llama-3.3-70b-instruct
# Meta model, complete responses, medium performance. Paid version of FastOpp default LLM.
# OPENROUTER_LLM_MODEL=qwen/qwen-2.5-72b-instruct
# Alibaba Cloud model, complete responses tend toward lists, medium performance.

Uncomment one line and pick the model you want:

OPENROUTER_LLM_MODEL=google/gemini-2.5-flash-lite-preview-09-2025

Restart your server so the change takes effect:

CTRL+C
uv run python oppman.py runserver

Option B: Choose a model from OpenRouter

OpenRouter exposes many models behind one API. Sign in to OpenRouter, pick a model, and paste its ID into your .env as OPENROUTER_LLM_MODEL=.... Use paid models for better consistency and throughput.

FastOpp’s README is explicit: the free default is fine to start, but the paid version of the same family—or other paid models—behaves more consistently, avoids free-tier rate limits, and is less confusing during testing. Use free only for quick smoke tests; use paid for steady classroom or demo use. GitHub

Quick Note on Python Versions

Use Python 3.12. The FastOpp README notes FastOpp will not work on 3.13 or 3.14 yet. If you’re on newer system Python, uv makes pinning 3.12 trivial:

  •   uv python install 3.12
      uv init --python 3.12
    

Recap: Quick list of the basic steps

# 1) install uv
curl -LsSf https://astral.sh/uv/install.sh | sh

# 2) create a clean project
mkdir my-project && cd my-project
uv init --python 3.12
uv add fastopp
uv run fastopp-startproject

# 3) configure secrets
cp example.env .env
# edit .env: set OPENROUTER_API_KEY to the key you got from Oppkey
# (or your own, but then you pay the charges)

# 4) run
uv run python oppman.py runserver
# open http://localhost:8000

# 5) switch models when ready
# in .env, set OPENROUTER_LLM_MODEL to a paid model ID for consistency
C
Craig Oda7mo ago

This is great. After changing one model, consider testing different models with the following criteria:

cost, speed of response, quality of response, match with intended use case.

For example, Qwen coder might be better at coding. Additionally, the example chat application may not be able to handle some models due to the differences in the response. It would be great to hear about these. For example, I tested some reasoning models and they didn't work.