# FastAPI Quick-Start

This quick-start will guide you through packaging your python app with FastAPI and deploying it to Health Universe, the open-source health research cloud for ML/AI.

## Step 1: Create a GitHub repository

1. Create a new repository on GitHub to host your project. You can make the repository either public or private, and it is a good idea to have a readme.md file in the repository and use a .gitignore template so that you can ignore the .env. This is important when you're linking a local development environment to a github repository.

   * [x] **Repo contains main.py and requirements.txt**
   * [x] **Repo has a readme.md**
   * [x] **Use the "python" .gitignore template (to ignore .env)**

   Note: If you're using a local development environment, link your local environment to your GitHub repository<br>
2. Clone the repository to your local machine or use our [FastAPI Template](https://github.com/Health-Universe/fastapi-template-demo):

   `git clone https://github.com/<your_account>/<your_repo_name>.git`<br>
3. Change to your project directory:

   `cd <your_repo>`<br>
4. Create a virtual environment using:\
   `python -m venv .env`<br>
5. Activate your virtual environment with:

   `source .env/bin/activate`<br>
6. Upgrade pip to make sure things go smoothly:\
   `python -m pip install --upgrade pip`<br>
7. Install the FastAPI, Uvicorn, & Pydantic libraries with:

   `pip install fastapi uvicorn pydantic`

## Step 2: Create your python app

In your local repository, create the following files:

* **main.py**: This file should contain your Python model.
* **requirements.txt**: This file will list your project dependencies.

Next, learn a little bit about how FastAPI works.

* [Overview of the main concepts](https://fastapi.tiangolo.com/tutorial/) for creating UI with FastAPI.
* [Here's a nifty cheat sheet](https://fastapi.tiangolo.com/tutorial/query-params/) for all the parameters you can create.

### main.py

For FastAPI apps, it is best to work from a [template](https://github.com/Health-Universe/fastapi-template-demo) so that Navigator knowns how to interact with your app. The template is listed below:

```python
from typing import Annotated, Any
import httpx
from fastapi import FastAPI, Form
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from pydantic import BaseModel, Field


# Input and Output Schemas
class Input(BaseModel):
    """
    Form-based input schema for template.
    """
    data: Any = Field(
        ...,
        title="An applicable title is helpful for the navigator.",
        examples=["Examples are helpful for navigator to understand the data."],
        description="Always provide verbose description for the data.",
    )


class Output(BaseModel):
    """
    Form-based output schema for template.
    """
    data: Any = Field(
        ...,
        title="An applicable title is helpful for the navigator.",
        examples=["Examples are helpful for navigator to understand the data."],
        description="Always provide verbose description for the data.",
    )


# FastAPI app initialization
app = FastAPI(
    title="Navigator Tool Template",
    description=(
        "The Navigator tool template provides a starting point for creating new Navigator tools. "
    ),
    version="1.0.0",
)

# CORS middleware configuration
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# Tool endpoint
@app.post("/call/", response_model=Output)
async def call(data: Annotated[Input, Form()]) -> Output | JSONResponse:
    """
    Process the input data and return the output.

    Args:
        data: The input data.

    Returns:
        The output data.
    """
    async with httpx.AsyncClient() as client:
        try:
            return Output(**data.model_dump())
        except (httpx.RequestError, httpx.HTTPStatusError) as e:
            return JSONResponse(
                {"error": f"Request failed: {e}"}, status_code=500
            )


# Health check endpoint
@app.get("/health", response_class=JSONResponse)
async def health_check():
    """
    Health check endpoint.
    """
    return {"status": "Application is running."}

```

### requirements.txt

For FastAPI apps, at a minimum you should include the requirements listed below. You may have additional requirements specific to your app, so be sure to include those as well.

```txt
fastapi
python-multipart
uvicorn
httpx
pydantic
# Include any other libraries required by your app.
```

**Test out your app by running it locally:**

1. Run your app locally using:

   `uvicorn main:app --reload`
2. Use the auto-generated Swagger UI at: <http://127.0.0.1:8000/docs>

## Step 3: Deploy to Health Universe

1. Push your local repo to GitHub.
2. Log in or create a Health Universe account if you haven't already.
3. Go to [https://healthuniverse.com](https://www.healthuniverse.com) and navigate to "Apps."
4. Click "Add App" to create a new app.
5. Fill out the following fields:
   * App Name: Name of your app
   * Description: A brief description of your app
   * Github Account: Your GitHub username
   * Github Repo: The exact name of your GitHub repository
   * Main File: The name of your python file (usually `main.py`)
6. Click "Add App" to deploy your app. This process may take a few minutes.

Once you've completed these steps, your app will be published on Health Universe!


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.healthuniverse.com/overview/core-concepts/15-second-quick-start/fastapi-quick-start.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
