> ## Documentation Index
> Fetch the complete documentation index at: https://docs.synthefy.com/llms.txt
> Use this file to discover all available pages before exploring further.

# On-Prem Quick Start

> Deploy the Forecasting API locally and make your first forecast request using the Python client.

Get started with Synthefy's Forecasting API in minutes. This guide will walk you through deploying the API locally and making your first forecast request using our Python client.

## Prerequisites

* Docker installed on your system
* Python 3.11+ installed
* Access to the Synthefy container registry

## Deployment

### Pull and Run the Container

If you'd like to try our forecasting API, please do the following:

```bash theme={null}
# Pull the image using a role with permissions to our repository.
docker pull 637245294713.dkr.ecr.us-east-2.amazonaws.com/on-premises-forecasting-api:latest

# Run the container
docker run -p 8014:8000 --gpus all -e USE_CELERY="false" -e SYNTHEFY_ROUTER="foundation_models" 637245294713.dkr.ecr.us-east-2.amazonaws.com/on-premises-forecasting-api:latest
```

## Python Client Setup

### Install the Synthefy Client

Install the Synthefy Python client from PyPI:

```bash theme={null}
pip install synthefy
```

### Authentication

The Synthefy client handles authentication differently depending on the target domain:

* **Synthefy Cloud (synthefy.com)**: Requires a valid API key for authentication
* **On-Premise/Local Deployments**: No API key required - set `api_key=None` or omit the parameter entirely

<Note>
  **Domain-Based Authentication**: The client automatically detects the target domain and adjusts authentication accordingly. For non-Synthefy domains (localhost, on-premise deployments, etc.), authentication is handled automatically without requiring an API key.
</Note>

### Basic Usage Example

Here's a complete example of using the Synthefy client to make forecast requests:

```python theme={null}
#!/usr/bin/env python3
"""
Basic example of using Synthefy client to make forecast requests.
"""

import os
import sys
import traceback
from typing import Optional

from synthefy import SynthefyAPIClient
from synthefy.api_client import (
    APIConnectionError,
    APITimeoutError,
    AuthenticationError,
    BadRequestError,
    InternalServerError,
    RateLimitError,
)
from synthefy.data_models import ForecastV2Request, SingleEvalSamplePayload


def main():
    """Main function to demonstrate basic forecast request."""

    # For localhost/on-premise deployments, API key should be None
    # For Synthefy Cloud (synthefy.com), provide your actual API key
    api_key = None

    # Create the forecast request matching the curl example
    samples = [
        [
            SingleEvalSamplePayload(
                sample_id="sales",
                history_timestamps=[
                    "2023-01-01",
                    "2023-01-02",
                    "2023-01-03",
                    "2023-01-04",
                    "2023-01-05",
                ],
                history_values=[100.0, 110.0, 120.0, 130.0, 140.0],
                target_timestamps=["2023-01-06", "2023-01-07", "2023-01-08"],
                target_values=[None, None, None],
                forecast=True,
                metadata=False,
                leak_target=False,
                column_name="sales",
            )
        ]
    ]

    request = ForecastV2Request(samples=samples, model="Migas-1.0")

    print("Making forecast request to localhost:8014...")
    print(f"Model: {request.model}")
    print(f"Number of samples: {len(request.samples)}")
    print(
        f"Sample details: {len(request.samples[0])} time series in first scenario"
    )

    try:
        # Configure client for localhost (no API key needed for non-Synthefy domains)
        with SynthefyAPIClient(
            api_key=api_key, base_url="http://localhost:8014"
        ) as client:
            print("\nSending request...")
            response = client.forecast(request)

            print("\n✅ Forecast successful!")
            print(f"Number of forecast scenarios: {len(response.forecasts)}")

            # Display results
            for i, forecast_scenario in enumerate(response.forecasts):
                print(f"\nScenario {i + 1}:")
                for forecast in forecast_scenario:
                    print(f"  Sample ID: {forecast.sample_id}")
                    print(f"  Model: {forecast.model_name}")
                    print(f"  Timestamps: {forecast.timestamps}")
                    print(f"  Values: {forecast.values}")

    except BadRequestError as e:
        print(f"❌ Bad Request Error: {e}")
        print(f"Stack trace: {traceback.format_exc()}")
        print(f"Status Code: {e.status_code}")
        if e.response_body:
            print(f"Response Body: {e.response_body}")
    except AuthenticationError as e:
        print(f"❌ Authentication Error: {e}")
        print("Please check your API key")
        print(f"Stack trace: {traceback.format_exc()}")
    except RateLimitError as e:
        print(f"❌ Rate Limit Error: {e}")
        print("Please wait before making another request")
        print(f"Stack trace: {traceback.format_exc()}")
    except APITimeoutError as e:
        print(f"❌ Timeout Error: {e}")
        print(f"Stack trace: {traceback.format_exc()}")
        print("The request took too long to complete")
    except APIConnectionError as e:
        print(f"❌ Connection Error: {e}")
        print(
            "Please check your network connection and ensure the server is running"
        )
        print(f"Stack trace: {traceback.format_exc()}")
    except InternalServerError as e:
        print(f"❌ Server Error: {e}")
        print("The server encountered an internal error")
        print(f"Stack trace: {traceback.format_exc()}")
    except Exception as e:
        print(f"❌ Unexpected Error: {e}")
        print(f"Error type: {type(e).__name__}")
        print(f"Stack trace: {traceback.format_exc()}")


if __name__ == "__main__":
    main()
```

### Understanding the Code

Let's break down the key components of this example:

#### 1. Imports and Setup

```python theme={null}
from synthefy import SynthefyAPIClient
from synthefy.data_models import ForecastV2Request, SingleEvalSamplePayload
```

The client provides typed data models for request/response handling and comprehensive error handling.

#### 2. Creating the Request

```python theme={null}
samples = [
    [
        SingleEvalSamplePayload(
            sample_id="sales",
            history_timestamps=["2023-01-01", "2023-01-02", "2023-01-03", "2023-01-04", "2023-01-05"],
            history_values=[100.0, 110.0, 120.0, 130.0, 140.0],
            target_timestamps=["2023-01-06", "2023-01-07", "2023-01-08"],
            target_values=[None, None, None],
            forecast=True,
            metadata=False,
            leak_target=False,
            column_name="sales",
        )
    ]
]

request = ForecastV2Request(samples=samples, model="Migas-1.0")
```

Each `SingleEvalSamplePayload` represents a time series with historical data and target timestamps for forecasting.

#### 3. Client Configuration and Request

```python theme={null}
with SynthefyAPIClient(api_key=api_key, base_url="http://localhost:8014") as client:
    response = client.forecast(request)
```

The client handles connection management and provides a clean interface for making requests.

<Note>
  **API Key for Non-Synthefy Domains**: When connecting to domains other than `synthefy.com` (like localhost or on-premise deployments), the `api_key` should be omitted or explicitly set to `None`. The client automatically handles authentication for non-Synthefy domains without requiring an API key.
</Note>

#### 4. Error Handling

The example includes comprehensive error handling for different types of API errors, making it easy to debug issues.

### Expected Output

When you run this example, you should see output similar to:

```
Making forecast request to localhost:8014...
Model: Migas-1.0
Number of samples: 1
Sample details: 1 time series in first scenario

Sending request...

✅ Forecast successful!
Number of forecast scenarios: 1

Scenario 1:
  Sample ID: sales
  Model: Migas-1.0
  Timestamps: ['2023-01-06', '2023-01-07', '2023-01-08']
  Values: [150.2, 160.1, 170.3]
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Python SDK Documentation" icon="code" href="/sdk/overview">
    Explore the complete Python SDK documentation.
  </Card>

  <Card title="Support" icon="life-ring" href="mailto:support@synthefy.com">
    Get help with deployment, authentication, or custom integrations.
  </Card>
</CardGroup>

<Info>
  **Need help?** Contact our support team at [support@synthefy.com](mailto:support@synthefy.com) for assistance with deployment or integration questions.
</Info>
