import { Tabs } from "nextra/components";

export const providers = [
  "OpenAI",
  "Anthropic",
  "Gemini",
  "Mistral",
  "OpenRouter",
];
export const os = ["macOS and Linux", "Windows"];

# Quickstart

Integrate your LLM application with Lilypad to get automatic versioning and tracing.

## Setup

Install `uv` and create a new project:

<Tabs items={os} storageKey="os">
  <Tabs.Tab>
    ```bash
    curl -LsSf https://astral.sh/uv/install.sh | sh 
    uv init quickstart-project
    ```
  </Tabs.Tab>
  <Tabs.Tab>
    ```bash
    powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex" 
    uv init quickstart-project
    ```
  </Tabs.Tab>
</Tabs>

Install Lilypad, specifying the provider(s) you intend to use, and set your API key:

<Tabs items={os} storageKey="os">
  <Tabs.Tab>
    <Tabs items={providers} storageKey="provider">
      <Tabs.Tab>
        ```bash
        uv add "python-lilypad[openai]"
        export OPENAI_API_KEY=XXXXX
        ```
      </Tabs.Tab>
      <Tabs.Tab>
        ```bash
        uv add "python-lilypad[anthropic]"
        export ANTHROPIC_API_KEY=XXXXX
        ```
      </Tabs.Tab>
      <Tabs.Tab>
        ```bash
        uv add "python-lilypad[gemini]"
        export GOOGLE_API_KEY=XXXXX
        ```
      </Tabs.Tab>
      <Tabs.Tab>
        ```bash
        uv add "python-lilypad[mistral]"
        export MISTRAL_API_KEY=XXXXX
        ```
      </Tabs.Tab>
      <Tabs.Tab>
        ```bash
        uv add "python-lilypad[openai]"
        export OPENROUTER_API_KEY=XXXXX
        ```
      </Tabs.Tab>
    </Tabs>
  </Tabs.Tab>
  <Tabs.Tab>
    <Tabs items={providers} storageKey="provider">
      <Tabs.Tab>
        ```bash
        uv add "python-lilypad[openai]"
        set OPENAI_API_KEY=XXXXX
        ```
      </Tabs.Tab>
      <Tabs.Tab>
        ```bash
        uv add "python-lilypad[anthropic]"
        set ANTHROPIC_API_KEY=XXXXX
        ```
      </Tabs.Tab>
      <Tabs.Tab>
        ```bash
        uv add "python-lilypad[gemini]"
        set GOOGLE_API_KEY=XXXXX
        ```
      </Tabs.Tab>
      <Tabs.Tab>
        ```bash
        uv add "python-lilypad[mistral]"
        set MISTRAL_API_KEY=XXXXX
        ```
      </Tabs.Tab>
      <Tabs.Tab>
        ```bash
        uv add "python-lilypad[openai]"
        set OPENROUTER_API_KEY=XXXXX
        ```
      </Tabs.Tab>
    </Tabs>
  </Tabs.Tab>
</Tabs>

## Create a new project

1. Navigate to [Lilypad App](https://app.lilypad.so)

2. Create an account by signing in with your GitHub.

3. Navigate to [Your Organization Settings](https://app.lilypad.so/settings/org) to create a project and API key.

4. Copy the project ID and API key and place them in your environment

```bash
LILYPAD_PROJECT_ID=XXXXX
LILYPAD_API_KEY=XXXXX
```

You are now ready to start tracing your generations.

## Run a generation

Copy-paste this generation into a new Python file (`main.py`):

<Tabs items={providers} storageKey="provider">
  <Tabs.Tab>
  ```python
  import lilypad
  from openai import OpenAI

  client = OpenAI()

  @lilypad.generation()
  def answer_question(question: str) -> str:
      completion = client.chat.completions.create(
          model="gpt-4o-mini",
          messages=[{"role": "user", "content": question}],
      )
      return str(completion.choices[0].message.content)

  if __name__ == "__main__":
      lilypad.configure()
      answer = answer_question("What is the meaning of life?")
      print(answer)
  ```
  </Tabs.Tab>
  <Tabs.Tab>
  ```python
  import lilypad
  from anthropic import Anthropic

  client = Anthropic()

  @lilypad.generation()
  def answer_question(question: str) -> str:
      message = client.messages.create(
          model="claude-3-5-sonnet-20240620",
          messages=[{"role": "user", "content": question}],
          max_tokens=1024,
      )
      block = message.content[0]
      return block.text if block.type == "text" else ""


  if __name__ == "__main__":
      lilypad.configure()
      answer = answer_question("What is the meaning of life?")
      print(answer)
  ```
  </Tabs.Tab>
  <Tabs.Tab>
  ```python
  from google.generativeai import GenerativeModel
  import lilypad

  client = GenerativeModel("gemini-1.5-flash")

  @lilypad.generation()
  def answer_question(question: str) -> str:
      generation = client.generate_content(
          contents=[{"role": "user", "parts": question}]
      )
      return generation.candidates[0].content.parts[0].text

  if __name__ == "__main__":
      lilypad.configure()
      answer = answer_question("What is the meaning of life?")
      print(answer)
  ```
  </Tabs.Tab>
  <Tabs.Tab>
  ```python
  import os

  import lilypad
  from typing import cast

  from mistralai import Mistral

  client = Mistral(api_key=os.environ["MISTRAL_API_KEY"])

  @lilypad.generation()
  def answer_question(question: str) -> str | None:
      completion = client.chat.complete(
          model="mistral-large-latest",
          messages=[{"role": "user", "content": question}],
      )
      if completion and (choices := completion.choices):
          return cast(str, choices[0].message.content)


  if __name__ == "__main__":
      lilypad.configure()
      answer = answer_question("What is the meaning of life?")
      print(answer)
  ```
  </Tabs.Tab>
  <Tabs.Tab>
  ```python
  import os

  import lilypad
  from openai import OpenAI

  client = OpenAI(
      base_url="https://openrouter.ai/api/v1",
      api_key=os.getenv("OPENROUTER_API_KEY"),
  )

  @lilypad.generation()
  def answer_question(question: str) -> str:
      completion = client.chat.completions.create(
          model="gpt-4o-mini",
          messages=[{"role": "user", "content": question}],
      )
      return str(completion.choices[0].message.content)


  if __name__ == "__main__":
      lilypad.configure()
      answer = answer_question("What is the meaning of life?")
      print(answer)
  ```
  </Tabs.Tab>
</Tabs>

Run the Python file

```bash
uv run main.py
```

Follow the link output by the command to view the trace in the Lilypad app.

The `@lilypad.generation` decorator will automatically version the `answer_question` function and collect a trace against that version. This ensures that you can always trace back to the exact code that generated a particular output.

This means that you can code as you always have, and Lilypad will take care of the rest.
