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

# Model

> Represents a machine learning model in the Fiddler platform.

Represents a machine learning model in the Fiddler platform.

The Model class is the central entity for ML model monitoring and management.
It encapsulates the model's schema, specification, and metadata, and provides
methods for data publishing, artifact management, and monitoring operations.

Key Concepts:

* **Schema** ([`ModelSchema`](/sdk-api/python-client/model-schema)): Defines the structure and data types of model inputs/outputs
* **Spec** ([`ModelSpec`](/sdk-api/python-client/model-spec)): Defines how columns are used (features, targets, predictions, etc.)
* **Task** ([`ModelTask`](/sdk-api/python-client/model-task)): The ML task type (classification, regression, ranking, etc.)
* **Artifacts** (`ModelArtifact`): Deployable model code and dependencies
* **Surrogates** (`Surrogate`): Simplified models for fast explanations

Lifecycle:

1. Create model with schema/spec (from data or manual definition)
2. Upload model artifacts for serving (optional)
3. Publish baseline/training data for drift detection
4. Publish production data for monitoring
5. Set up alerts and monitoring rules

Common Use Cases:

* **Tabular Models**: Traditional ML models with structured data
* **Text Models**: NLP models with text inputs and embeddings
* **Mixed Models**: Models combining tabular and unstructured data
* **Ranking Models**: Recommendation and search ranking systems
* **LLM Models**: Large language model monitoring

## Parameters

<ParamField path="name" type="str" required={true}>
  Model name, must be unique within the project version.
  Should be descriptive and follow naming conventions.
</ParamField>

<ParamField path="project_id" type="UUID | str" required={true}>
  UUID or string identifier of the parent project.
</ParamField>

<ParamField path="schema" type="ModelSchema" required={true}>
  [`ModelSchema`](/sdk-api/python-client/model-schema) defining column structure and data types.
  Can be created manually or generated from data.
</ParamField>

<ParamField path="spec" type="ModelSpec" required={true}>
  [`ModelSpec`](/sdk-api/python-client/model-spec) defining how columns are used (inputs, outputs, targets).
  Specifies the model's interface and column roles.
</ParamField>

<ParamField path="version" type="str | None" required={false} default="None">
  Optional version identifier for model versioning and A/B testing.
  Falls back to 'v1' when not specified.
</ParamField>

<ParamField path="input_type" type="str" required={false} default="ModelInputType.TABULAR">
  [`ModelInputType`](/sdk-api/python-client/model-input-type) - Type of input data the model processes.

  * TABULAR: Structured/tabular data (default)
  * TEXT: Natural language text data
  * MIXED: Combination of structured and unstructured data
</ParamField>

<ParamField path="task" type="str" required={false} default="ModelTask.NOT_SET">
  [`ModelTask`](/sdk-api/python-client/model-task) - Machine learning task type.

  * BINARY\_CLASSIFICATION: Binary classification (0/1, True/False)
  * MULTICLASS\_CLASSIFICATION: Multi-class classification
  * REGRESSION: Continuous value prediction
  * RANKING: Ranking/recommendation tasks
  * LLM: Large language model tasks
  * NOT\_SET: Task not specified (default)
</ParamField>

<ParamField path="task_params" type="ModelTaskParams | None" required={false} default="None">
  [`ModelTaskParams`](/sdk-api/python-client/model-task-params) - Task-specific parameters like classification thresholds,
  class weights, or ranking parameters.
</ParamField>

<ParamField path="description" type="str | None" required={false} default="None">
  Human-readable description of the model's purpose,
  training data, or other relevant information.
</ParamField>

<ParamField path="event_id_col" type="str | None" required={false} default="None">
  Column name containing unique identifiers for each
  prediction event. Used for event tracking and updates.
</ParamField>

<ParamField path="event_ts_col" type="str | None" required={false} default="None">
  Column name containing event timestamps.
  Used for time-based analysis and drift detection.
</ParamField>

<ParamField path="event_ts_format" type="str | None" required={false} default="None">
  Format string for parsing timestamps in event\_ts\_col.
  Examples: '%Y-%m-%d %H:%M:%S', '%Y-%m-%dT%H:%M:%SZ'
</ParamField>

<ParamField path="xai_params" type="XaiParams | None" required={false} default="None">
  [`XaiParams`](/sdk-api/python-client/xai-params) - Configuration for explainability features like
  explanation methods and custom feature definitions.
</ParamField>

<Info>
  The model exists only locally until .create() is called. Use Model.from\_data()
  for automatic schema/spec generation from DataFrames or files.
</Info>

## Examples

```python theme={null}
# Create model from DataFrame with automatic schema detection
import fiddler as fdl
import pandas as pd

df = pd.DataFrame({
    'age': [25, 35, 45],
    'income': [50000, 75000, 100000],
    'approved': [0, 1, 1]  # target
})

model = fdl.Model.from_data(
    source=df,
    name="credit_approval",
    project_id='<YOUR_PROJECT_ID>',
    task=fdl.ModelTask.BINARY_CLASSIFICATION,
    description="Credit approval model v1.0"
)
model.create()

# Publish production events
events = [
    {'age': 30, 'income': 60000, 'prediction': 0.8},
    {'age': 40, 'income': 80000, 'prediction': 0.9}
]
event_ids = model.publish(source=events)

# Get model info
print(f"Model: {model.name} (Task: {model.task})")
print(f"Columns: {len(model.schema.columns)}")
print(f"Features: {model.spec.inputs}")
```

## download\_data()

Download production or pre-production event data to a local Parquet or CSV file.

Replaces the removed `get_slice()` and `download_slice()` methods.

### Parameters

<ParamField path="output_dir" type="Path | str" required={true}>
  Directory where the output file is written. Created if it does
  not exist.
</ParamField>

<ParamField path="env_type" type="EnvType" required={true}>
  Environment to query. One of `EnvType.PRODUCTION` or
  `EnvType.PRE_PRODUCTION`.
</ParamField>

<ParamField path="env_id" type="UUID | None" required={false} default="None">
  When `env_type=EnvType.PRE_PRODUCTION`, the UUID of the dataset
  to query. Ignored for PRODUCTION.
</ParamField>

<ParamField path="start_time" type="datetime | None" required={false} default="None">
  Start of the query window. PRODUCTION only. Naive datetimes
  are interpreted as UTC.
</ParamField>

<ParamField path="segment_id" type="UUID | None" required={false} default="None">
  UUID of a saved Segment associated with the model. Mutually
  exclusive with `segment_definition`.
</ParamField>

<ParamField path="segment_definition" type="str | None" required={false} default="None">
  Inline FQL (Fiddler Query Language) segment expression.
  The segment is applied transiently and not saved. Mutually exclusive
  with `segment_id`.
</ParamField>

<ParamField path="max_rows" type="int | None" required={false} default="None">
  Maximum number of rows to return. When omitted, the server
  applies a limit of 1,000 rows. Maximum allowed value is 10,000,000.
</ParamField>

<ParamField path="columns" type="list[str] | None" required={false} default="None">
  Column names to include. When omitted, all model columns are
  returned.
</ParamField>

<ParamField path="chunk_size" type="int | None" required={false} default="1000">
  Row count per download chunk. You can increase this for faster
  downloads when querying fewer than 1000 columns and no vector columns.
</ParamField>

<ParamField path="fetch_vectors" type="bool | None" required={false} default="None">
  When `True`, vector columns are included in the output.
  When omitted or `False`, vector columns are filtered out.
</ParamField>

<ParamField path="output_format" type="DownloadFormat" required={false} default="DownloadFormat.PARQUET">
  Output file format. One of `DownloadFormat.PARQUET` or
  `DownloadFormat.CSV`.
</ParamField>

### Returns

<ResponseField>
  None. Writes a file named `output.parquet` (default) or `output.csv`
  (when `output_format=DownloadFormat.CSV`) into `output_dir`.
</ResponseField>

### Raises

**ApiError** – If the request fails, the model is a draft model, or no data
matches the query.

### Example

```python theme={null}
from datetime import datetime, timedelta, timezone

import fiddler as fdl
import pandas as pd

model = fdl.Model.from_name(name='my_model', project_id='<YOUR_PROJECT_ID>')

end_time = datetime.now(timezone.utc)
start_time = end_time - timedelta(days=7)

model.download_data(
    output_dir='./exports',
    env_type=fdl.EnvType.PRODUCTION,
    start_time=start_time,
    end_time=end_time,
    output_format=fdl.DownloadFormat.CSV,
)

df = pd.read_csv('./exports/output.csv')
```

<Info>
  This method is not available for draft models. Caller must have READ
  permission on the model's project.
</Info>

## *classmethod* get()

Retrieve a model by its unique identifier.

Fetches a model from the Fiddler platform using its UUID. This is the most
direct way to retrieve a model when you know its ID.

### Parameters

<ParamField path="id_" type="UUID | str" required={true}>
  The unique identifier (UUID) of the model to retrieve.
  Can be provided as a UUID object or string representation.
</ParamField>

### Returns

<ResponseField type="Model">
  The model instance with all its configuration and metadata.
</ResponseField>

### Raises

* **NotFound** – If no model exists with the specified ID.
* **ApiError** – If there's an error communicating with the Fiddler API.

### Example

```python theme={null}
# Get model by UUID
model = Model.get(id_="550e8400-e29b-41d4-a716-446655440000")
print(f"Retrieved model: {model.name} (Task: {model.task})")

# Access model properties
print(f"Project ID: {model.project_id}")
print(f"Input columns: {model.spec.inputs}")
print(f"Created: {model.created_at}")
```

<Info>
  This method makes an API call to fetch the latest model state from the server.
  The returned model instance reflects the current state in Fiddler.
</Info>

## *classmethod* from\_name()

Retrieve a model by name within a project.

Finds and returns a model using its name and project context. This is useful
when you know the model name but not its UUID. Supports version-specific
retrieval and latest version lookup.

### Parameters

<ParamField path="name" type="str" required={true}>
  The name of the model to retrieve. Model names are unique
  within a project but may have multiple versions.
</ParamField>

<ParamField path="project_id" type="UUID | str" required={true}>
  UUID or string identifier of the project containing the model.
</ParamField>

<ParamField path="version" type="str | None" required={false} default="None">
  Specific version name to retrieve. If None, behavior depends
  on the 'latest' parameter.
</ParamField>

<ParamField path="latest" type="bool" required={false} default="False">
  If True and version is None, retrieves the most recently created
  version. If False, retrieves the first (oldest) version.
  Ignored if version is specified.
</ParamField>

### Returns

<ResponseField type="Model">
  The model instance matching the specified criteria.
</ResponseField>

### Raises

* **NotFound** – If no model exists with the specified name/version in the project.
* **ApiError** – If there's an error communicating with the Fiddler API.

### Example

```python theme={null}
# Get specific version
model = Model.from_name(
    name="fraud_detector",
    project_id=project.id,
    version="v2.1"
)

# Get latest version
latest_model = Model.from_name(
    name="fraud_detector",
    project_id=project.id,
    latest=True
)

# Get first version (default behavior)
first_model = Model.from_name(
    name="fraud_detector",
    project_id=project.id
)

print(f"Model versions: {first_model.version} -> {latest_model.version}")
```

<Info>
  When version is None and latest=False, returns the first version created.
  This provides consistent behavior for accessing the "original" model version.
</Info>

## create()

Create the model on the Fiddler platform.

Persists this model instance to the Fiddler platform, making it available
for monitoring, data publishing, and other operations. The model must have
a valid schema, spec, and be associated with an existing project.

### Returns

<ResponseField type="Model">
  This model instance, updated with server-assigned fields like
  ID, creation timestamp, and other metadata.
</ResponseField>

### Raises

* **Conflict** – If a model with the same name and version already exists
  in the project.
* **ValidationError** – If the model configuration is invalid (e.g., invalid
  schema, spec, or task parameters).
* **ApiError** – If there's an error communicating with the Fiddler API.

### Example

```python theme={null}
# Create model from DataFrame
model = Model.from_data(
    source=training_df,
    name="churn_predictor",
    project_id=project.id,
    task=ModelTask.BINARY_CLASSIFICATION
)

# Create on platform
created_model = model.create()
print(f"Created model with ID: {created_model.id}")
print(f"Created at: {created_model.created_at}")

# Model is now available for monitoring
assert created_model.id is not None

# Can now publish data, set up alerts, etc.
job = created_model.publish(source=production_data)
```

<Info>
  After successful creation, the model instance is updated in-place with
  server-assigned metadata. The same instance can be used for subsequent
  operations without needing to fetch it again.
</Info>

## update()

Update an existing model.

## add\_column()

Add a new column to the model schema.

Updates both the schema and spec to include the new column. This allows
you to extend your model with additional columns after initial creation.

**New in version 3.11.0**

### Parameters

<ParamField path="column" type="Column" required={true}>
  Column object defining the new column's properties (name, data\_type, etc.)
</ParamField>

<ParamField path="column_type" type="str" required={false} default="'metadata'">
  Type of column in spec. One of: 'inputs', 'outputs', 'targets',
  'decisions', 'metadata'. Defaults to 'metadata'.
</ParamField>

### Raises

* **ValueError** – If column already exists or column\_type is invalid
* **BadRequest** – If column definition is invalid per backend validation

### Example

```python theme={null}
# Add a numeric metadata column
new_col = Column(
    name="customer_segment",
    data_type=DataType.INTEGER,
    min=1,
    max=5
)
model.add_column(column=new_col, column_type='metadata')

# Add a categorical feature
category_col = Column(
    name="region",
    data_type=DataType.CATEGORY,
    categories=["US", "EU", "APAC"]
)
model.add_column(column=category_col, column_type='inputs')
```

<Info>
  * Adding a column doesn't populate historical data; new column will be null
    for past events
  * Column names must be unique within the model
  * After adding a column, include it in future event publishing
</Info>

## *classmethod* list()

List models in a project with optional filtering.

Retrieves all models or model versions within a project. Returns lightweight
ModelCompact objects that can be used to fetch full Model instances when needed.

### Parameters

<ParamField path="project_id" type="UUID | str" required={true}>
  UUID or string identifier of the project to search within.
</ParamField>

<ParamField path="name" type="str | None" required={false} default="None">
  Optional model name filter. If provided, returns all versions
  of the specified model. If None, returns all models in the project.
</ParamField>

### Yields

*ModelCompact* –

Lightweight model objects containing id, name, and version.
Call .fetch() on any ModelCompact to get the full Model instance.

### Returns

`Iterator[ModelCompact]`

### Example

```python theme={null}
# List all models in project
for model_compact in Model.list(project_id=project.id):

    print(f"Model: {model_compact.name} v{model_compact.version}")
    print(f"  ID: {model_compact.id}")

    # List all versions of a specific model
    for version in Model.list(project_id=project.id, name="fraud_detector"):

        print(f"Version: {version.version}")

        ...
        # Get full model details if needed
        full_model = version.fetch()
        print(f"  Task: {full_model.task}")
        print(f"  Created: {full_model.created_at}")

        # Convert to list for counting
        models = list(Model.list(project_id=project.id))
        print(f"Total models in project: {len(models)}")
```

<Info>
  This method returns an iterator for memory efficiency when dealing with
  many models. The ModelCompact objects are lightweight and don't include
  full schema/spec information - use .fetch() when you need complete details.
</Info>

## duplicate()

Duplicate the model instance with the given version name.

This call will not save the model on server. After making changes to the model
instance call .create() to add the model version to Fiddler Platform.

### Parameters

<ParamField path="version" type="str | None" required={false} default="None">
  Version name for the new instance
</ParamField>

### Returns

<ResponseField type="Model">
  Model instance
</ResponseField>

## *property* datasets

Get all datasets associated with this model.

Returns an iterator over all datasets that have been published to this model,
including both production data and pre-production datasets used for baselines
and drift comparison.

### Yields

[`Dataset`](/sdk-api/python-client/dataset) –

Dataset objects containing metadata and data access methods.
Each dataset represents a collection of events published to the model.

### Example

```python theme={null}
# List all datasets for the model
for dataset in model.datasets:

    print(f"Dataset: {dataset.name}")
    print(f"  Environment: {dataset.environment}")
    print(f"  Size: {dataset.size} events")
    print(f"  Created: {dataset.created_at}")

    # Find specific dataset
    baseline_datasets = [
        ds for ds in model.datasets
        if ds.environment == EnvType.PRE_PRODUCTION
    ]
    print(f"Found {len(baseline_datasets)} baseline datasets")
```

<Info>
  This includes both production event data and named pre-production datasets.
  Use the Dataset objects to download data, analyze distributions, or
  set up baseline comparisons for drift detection.
</Info>

## *property* baselines

Get all baselines configured for this model.

Returns an iterator over all baseline configurations used for drift detection
and performance monitoring. Baselines define reference distributions and
metrics for comparison with production data.

### Yields

[`Baseline`](/sdk-api/python-client/baseline) –

Baseline objects containing configuration and reference data.
Each baseline defines how drift and performance should be measured
against historical or reference datasets.

### Example

```python theme={null}
# List all baselines
for baseline in model.baselines:

    print(f"Baseline: {baseline.name}")
    print(f"  Type: {baseline.type}")  # STATIC or ROLLING
    print(f"  Dataset: {baseline.dataset_name}")
    print(f"  Created: {baseline.created_at}")

    # Find production baseline
    prod_baselines = [
        bl for bl in model.baselines
        if "production" in bl.name.lower()
    ]

    # Use baseline for drift comparison
    if prod_baselines:

        baseline = prod_baselines[0]
        drift_metrics = baseline.compute_drift(recent_data)
```

<Info>
  Baselines are essential for drift detection and alerting. They define
  the "normal" behavior against which production data is compared.
  Static baselines use fixed reference data, while rolling baselines
  update automatically with recent data.
</Info>

## *property* deployment

Fetch model deployment instance of this model.

### Returns

<ResponseField type="ModelDeployment">
  The deployment configuration for this model.
</ResponseField>

## *classmethod* from\_data()

Create a Model instance with automatic schema generation from data.

This is the most convenient way to create models when you have training data
or representative samples. The method automatically analyzes the data to
generate appropriate schema (column types) and spec (column roles) definitions.

### Parameters

<ParamField path="source" type="DataFrame | Path | str" required={true}>
  Data source for schema generation. Can be:

  * pandas.DataFrame: Direct data analysis
  * Path/str: File path (.csv, .parquet, .json supported)
    The data should be representative of your model's inputs/outputs.
</ParamField>

<ParamField path="name" type="str" required={true}>
  Model name, must be unique within the project version.
  Use descriptive names like "fraud\_detector\_v1" or "churn\_model".
</ParamField>

<ParamField path="project_id" type="UUID | str" required={true}>
  UUID or string identifier of the parent project.
</ParamField>

<ParamField path="spec" type="ModelSpec | None" required={false} default="None">
  Optional [`ModelSpec`](/sdk-api/python-client/model-spec) defining column roles. If None, automatic
  detection attempts to identify inputs, outputs, and targets
  based on column names and data patterns.
</ParamField>

<ParamField path="version" type="str | None" required={false} default="&#x22;v1&#x22;">
  Model version identifier. If None, defaults to "v1".
  Use semantic versioning like "v1.0", "v2.1", etc.
</ParamField>

<ParamField path="input_type" type="str" required={false} default="ModelInputType.TABULAR">
  [`ModelInputType`](/sdk-api/python-client/model-input-type) - Type of input data the model processes.

  * TABULAR: Structured/tabular data (default)
  * TEXT: Natural language text data
  * MIXED: Combination of structured and unstructured data
</ParamField>

<ParamField path="task" type="str" required={false} default="ModelTask.NOT_SET">
  [`ModelTask`](/sdk-api/python-client/model-task) - Machine learning task type:

  * BINARY\_CLASSIFICATION: Binary classification (0/1, True/False)
  * MULTICLASS\_CLASSIFICATION: Multi-class classification
  * REGRESSION: Continuous value prediction
  * RANKING: Ranking/recommendation tasks
  * LLM: Large language model tasks
  * NOT\_SET: Task not specified (default)
</ParamField>

<ParamField path="task_params" type="ModelTaskParams | None" required={false} default="None">
  [`ModelTaskParams`](/sdk-api/python-client/model-task-params) - Task-specific parameters:

  * binary\_classification\_threshold: Decision threshold (0.5)
  * target\_class\_order: Class label ordering
  * group\_by: Column for ranking model grouping
  * top\_k: Top-k evaluation for ranking
</ParamField>

<ParamField path="description" type="str | None" required={false} default="None">
  Human-readable description of the model's purpose,
  training approach, or other relevant information.
</ParamField>

<ParamField path="event_id_col" type="str | None" required={false} default="None">
  Column name for unique event identifiers. Used for
  tracking individual predictions and enabling updates.
</ParamField>

<ParamField path="event_ts_col" type="str | None" required={false} default="None">
  Column name for event timestamps. Used for time-based
  analysis, drift detection, and temporal monitoring.
</ParamField>

<ParamField path="event_ts_format" type="str | None" required={false} default="None">
  Timestamp format string for parsing event\_ts\_col.
  Examples: '%Y-%m-%d %H:%M:%S', '%Y-%m-%dT%H:%M:%SZ'
</ParamField>

<ParamField path="xai_params" type="XaiParams | None" required={false} default="None">
  [`XaiParams`](/sdk-api/python-client/xai-params) - Explainability configuration including explanation methods
  and custom feature definitions.
</ParamField>

<ParamField path="max_cardinality" type="int | None" required={false} default="None">
  Maximum unique values to consider a column categorical.
  Columns with more unique values are treated as continuous.
  Default is typically 100-1000 depending on data size.
</ParamField>

<ParamField path="sample_size" type="int | None" required={false} default="None">
  Number of rows to sample for schema generation. Useful
  for large datasets to speed up analysis. If None, uses
  entire dataset (up to reasonable limits).
</ParamField>

### Returns

<ResponseField type="Model">
  A new Model instance with automatically generated schema and spec.
  The model is not yet created on the platform - call .create() to persist.
</ResponseField>

### Raises

* **ValueError** – If the data source is invalid or cannot be processed.
* **FileNotFoundError** – If source is a file path that doesn't exist.
* **ValidationError** – If the generated schema/spec is invalid.

### Example

```python theme={null}
import pandas as pd

# Create from DataFrame
df = pd.DataFrame({
    'age': [25, 35, 45, 55],
    'income': [30000, 50000, 70000, 90000],
    'credit_score': [650, 700, 750, 800],
    'approved': [0, 1, 1, 1],  # target
    'prediction': [0.2, 0.8, 0.9, 0.95],  # model output
    'prediction_score': [0.2, 0.8, 0.9, 0.95]  # alternative output
})

model = Model.from_data(
    source=df,
    name="credit_approval_v1",
    project_id=project.id,
    task=ModelTask.BINARY_CLASSIFICATION,
    description="Credit approval model trained on 2024 data",
    event_id_col="application_id",  # if present in real data
    event_ts_col="timestamp"        # if present in real data
)

# Review generated schema
print(f"Columns detected: {len(model.schema.columns)}")
for col in model.schema.columns:

    print(f"  {col.name}: {col.data_type}")

    # Review generated spec
    print(f"Inputs: {model.spec.inputs}")
    print(f"Outputs: {model.spec.outputs}")
    print(f"Targets: {model.spec.targets}")

    # Create on platform
    model.create()

    # Create from file
    model = Model.from_data(
        source="training_data.csv",
        name="file_based_model",
        project_id=project.id,
        task=ModelTask.REGRESSION,
        sample_size=10000  # Sample large files
    )
```

<Info>
  The automatic schema generation uses heuristics to detect column types
  and roles. Review the generated schema and spec before calling .create()
  to ensure they match your model's actual interface. You can modify the
  schema and spec after creation if needed.
</Info>

## delete()

Delete a model and it's associated resources.

### Returns

<ResponseField type="Job">
  model deletion job instance
</ResponseField>

## remove\_column()

Remove a column from the model schema and spec

This method is only to modify model object before creating and
will not save the model on Fiddler Platform. After making
changes to the model instance, call .create() to add the model
to Fiddler Platform.

### Parameters

<ParamField path="column_name" type="str" required={true}>
  Column name to be removed
</ParamField>

<ParamField path="missing_ok" type="bool" required={false} default="True">
  If True, do not raise an error if the column is not found
</ParamField>

### Returns

<ResponseField>
  None
</ResponseField>

### Raises

**KeyError** – If the column name is not found and missing\_ok is False

## publish()

Publish data to the model for monitoring and analysis.

<Warning>Deprecated: Use [`publish_stream()`](#publish_stream) for streaming events (list of dicts) or [`publish_batch()`](#publish_batch) for batch publishing (file path or DataFrame).</Warning>

Uploads prediction events, training data, or reference datasets to Fiddler
for monitoring, drift detection, and performance analysis. This is how you
send your model's real-world data to the platform.

### Parameters

<ParamField path="source" type="list[dict[str, Any]] | str | Path | DataFrame" required={true}>
  Data to publish. Supported formats:

  * **File path (str/Path)**: CSV or Parquet files.
    > Best for large datasets and batch uploads.
  * **DataFrame**: Pandas DataFrame with prediction events.
    Good for programmatic uploads and real-time data.
  * **List of dicts**: Individual events as dictionaries.
    Perfect for streaming/real-time publishing (max 1000 events).
    Each dict should match the model's schema.
</ParamField>

<ParamField path="environment" type="EnvType" required={false} default="EnvType.PRODUCTION">
  [`EnvType`](/sdk-api/python-client/env-type) - Data environment type:

  * **PRODUCTION**: Live production prediction data.
    > Used for real-time monitoring and alerting.
  * **PRE\_PRODUCTION**: Training, validation, or baseline data.
    Used for drift comparison and model evaluation.
</ParamField>

<ParamField path="dataset_name" type="str | None" required={false} default="None">
  Name for the dataset when using PRE\_PRODUCTION environment.
  Creates a named dataset for baseline comparisons.
  Not used for PRODUCTION data.
</ParamField>

<ParamField path="update" type="bool" required={false} default="False">
  Whether these events update previously published data.
  Set to True when republishing corrected predictions or
  adding ground truth labels to existing events.
</ParamField>

### Returns

<ResponseField>
  Event IDs when source is list of dicts or DataFrame.
  Use these IDs to reference specific events later.

  * [`Job`](/sdk-api/python-client/job): Async job object when source is a file path.
    Use job.wait() to wait for completion or check job.status.
</ResponseField>

### Raises

* **ValidationError** – If the data doesn't match the model's schema or
  contains invalid values.
* **ApiError** – If there's an error uploading the data to Fiddler.
* **ValueError** – If the source format is unsupported or parameters
  are incompatible (e.g., dataset\_name with PRODUCTION).

### Example

```python theme={null}
# Publish production events from DataFrame
# (assumes model is a fdl.Model instance; see Model.from_name() or Model.from_data())
import fiddler as fdl
import pandas as pd

prod_df = pd.DataFrame({
    'age': [30, 25, 45],
    'income': [60000, 45000, 80000],
    'prediction': [0.8, 0.3, 0.9],
    'timestamp': ['2024-01-01 10:00:00', '2024-01-01 11:00:00', '2024-01-01 12:00:00']
})

# Returns list of event UUIDs
event_ids = model.publish(
    source=prod_df,
    environment=fdl.EnvType.PRODUCTION
)
print(f"Published {len(event_ids)} events")

# Publish baseline data for drift comparison
job = model.publish(
    source="training_data.csv",  # File path
    environment=fdl.EnvType.PRE_PRODUCTION,
    dataset_name="training_baseline_2024"
)
job.wait()  # Wait for upload to complete
print(f"Baseline upload status: {job.status}")

# Publish real-time streaming events
events = [
    {
        'age': 35,
        'income': 70000,
        'prediction': 0.75,
        'event_id': 'pred_001',
        'timestamp': '2024-01-01 13:00:00'
    },
    {
        'age': 28,
        'income': 55000,
        'prediction': 0.45,
        'event_id': 'pred_002',
        'timestamp': '2024-01-01 13:01:00'
    }
]
event_ids = model.publish(source=events)
print(f"Published {len(events)} streaming events")

# Update existing events with ground truth
corrected_events = [
    {
        'event_id': 'pred_001',
        'ground_truth': 1,  # Actual outcome
        'timestamp': '2024-01-01 13:00:00'
    }
]
model.publish(source=corrected_events, update=True)
```

<Warning>
  * **Schema Validation**: All published data must match the model's schema.
    Column names, types, and value ranges are validated.
  * **Event IDs**: Include event\_id\_col if specified in model config for
    event tracking and updates.
  * **Timestamps**: Include event\_ts\_col for time-based analysis and drift detection.
  * **Batch Limits**: List of dicts is limited to 1000 events per call.
    Use files or multiple calls for larger datasets.
</Warning>

<Info>
  Production data publishing enables real-time monitoring, alerting, and
  drift detection. Pre-production data creates reference datasets for
  comparison and model evaluation.
</Info>

## publish\_stream()

Publish events via streaming for real-time monitoring.

Sends events synchronously to Fiddler. Events are written to an
in-memory queue and asynchronously persisted.

### Parameters

<ParamField path="events" type="list[dict[str, Any]]" required={true}>
  List of event dicts matching the model's schema. Each dict
  represents a single prediction event with feature values,
  predictions, and optional metadata (event\_id, timestamp).
</ParamField>

<ParamField path="environment" type="EnvType" required={false} default="EnvType.PRODUCTION">
  [`EnvType`](/sdk-api/python-client/env-type) - Data environment type:

  * **PRODUCTION**: Live production prediction data.
  * **PRE\_PRODUCTION**: Training, validation, or baseline data.
</ParamField>

<ParamField path="dataset_name" type="str | None" required={false} default="None">
  Name for the dataset when using PRE\_PRODUCTION environment.
  Not used for PRODUCTION data.
</ParamField>

<ParamField path="update" type="bool" required={false} default="False">
  Whether these events update previously published data.
  Set to True when adding ground truth labels to existing events.
</ParamField>

### Returns

<ResponseField type="list[UUID]">
  Event IDs for the published events. Use these IDs to
  reference specific events later.
</ResponseField>

### Raises

* **ValidationError** – If the data doesn't match the model's schema.
* **ApiError** – If there's an error publishing the events to Fiddler.

### Example

```python theme={null}
events = [
    {
        'age': 35,
        'income': 70000,
        'prediction': 0.75,
        'event_id': 'pred_001',
        'timestamp': '2024-01-01 13:00:00'
    },
    {
        'age': 28,
        'income': 55000,
        'prediction': 0.45,
        'event_id': 'pred_002',
        'timestamp': '2024-01-01 13:01:00'
    }
]
event_ids = model.publish_stream(events=events)
print(f"Published {len(event_ids)} streaming events")

# Update existing events with ground truth
ground_truth = [
    {'event_id': 'pred_001', 'ground_truth': 1}
]
model.publish_stream(events=ground_truth, update=True)
```

<Info>
  For large datasets, consider using [`publish_batch()`](#publish_batch) with a file
  path or DataFrame instead. Streaming is best suited for real-time
  or near-real-time event publishing.
</Info>

## publish\_batch()

Publish data via batch upload for monitoring and analysis.

Uploads data as a file and kicks off an asynchronous server-side job.
Use the returned Job object to track progress. Best suited for large
datasets, historical data uploads, and baseline/reference datasets.

### Parameters

<ParamField path="source" type="str | Path | DataFrame" required={true}>
  Data to publish. Supported formats:

  * **File path (str/Path)**: CSV or Parquet files.
    > Best for large datasets already on disk.
  * **DataFrame**: Pandas DataFrame with prediction events.
    Automatically converted to Parquet (falls back to CSV).
</ParamField>

<ParamField path="environment" type="EnvType" required={false} default="EnvType.PRODUCTION">
  [`EnvType`](/sdk-api/python-client/env-type) - Data environment type:

  * **PRODUCTION**: Live production prediction data.
  * **PRE\_PRODUCTION**: Training, validation, or baseline data.
</ParamField>

<ParamField path="dataset_name" type="str | None" required={false} default="None">
  Name for the dataset when using PRE\_PRODUCTION environment.
  Creates a named dataset for baseline comparisons.
  Not used for PRODUCTION data.
</ParamField>

<ParamField path="update" type="bool" required={false} default="False">
  Whether these events update previously published data.
  Set to True when republishing corrected predictions or
  adding ground truth labels to existing events.
</ParamField>

### Returns

<ResponseField type="Job">
  Async job object. Use `job.wait()`
  to block until completion, or check `job.status` to poll.
</ResponseField>

### Raises

* **ValidationError** – If the data doesn't match the model's schema.
* **ApiError** – If there's an error uploading the data to Fiddler.
* **ValueError** – If the source format is unsupported.

### Example

```python theme={null}
# Batch upload from file
job = model.publish_batch(
    source="training_data.csv",
    environment=EnvType.PRE_PRODUCTION,
    dataset_name="training_baseline_2024"
)
job.wait()
print(f"Upload status: {job.status}")

# Batch upload from DataFrame
import pandas as pd
prod_df = pd.DataFrame({
    'age': [30, 25, 45],
    'income': [60000, 45000, 80000],
    'prediction': [0.8, 0.3, 0.9],
})
job = model.publish_batch(source=prod_df)
job.wait()
```

<Info>
  For real-time or near-real-time event publishing, consider using
  [`publish_stream()`](#publish_stream) instead.
</Info>

## delete\_events()

Delete published production events for this model.

Select events to delete by a time range or by an explicit list of event
IDs (the two are mutually exclusive). Deletion runs asynchronously on the
server; use the returned Job to track progress.

### Parameters

<ParamField path="start_time" type="datetime | str | None" required={false} default="None">
  Inclusive start of the time window to delete. Accepts a
  timezone-aware `datetime` or an ISO 8601 string with an
  explicit offset (e.g. `'2025-11-17T01:00:00Z'`); the
  value is normalized to UTC. Naive datetimes are rejected.
  Must be given together with `end_time`.
</ParamField>

<ParamField path="end_time" type="datetime | str | None" required={false} default="None">
  Exclusive end of the time window to delete. Same format
  rules as `start_time`. Must be given together with
  `start_time`.
</ParamField>

<ParamField path="event_ids" type="list[str] | None" required={false} default="None">
  List of event IDs to delete, up to the documented
  per-call limit. An empty list is treated as "no ID
  filter" (the same as `None`). Cannot be combined with a time range.
</ParamField>

<ParamField path="update_metrics" type="bool" required={false} default="False">
  Whether the server should recompute metrics after
  the events are deleted. Applies to time-range deletions only;
  combining `update_metrics=True` with `event_ids` is rejected.
</ParamField>

### Returns

<ResponseField type="Job">
  Async job object. Use `job.wait()`
  to block until completion, or check `job.status` to poll.
</ResponseField>

### Raises

* **ValueError** – If neither a time range nor `event_ids` is given (to
  avoid accidentally deleting all events for the model), if
  only one of `start_time`/`end_time` is provided, or if
  `event_ids` exceeds the documented per-call limit.
* **ApiError** – If there's an error deleting the events on Fiddler.

### Example

```python theme={null}
# Delete a window of production events
job = model.delete_events(
    start_time='2025-11-17T01:00:00.000Z',
    end_time='2025-11-17T02:00:00.000Z',
    update_metrics=True,
)
job.wait()
print(f"Delete status: {job.status}")

# Delete specific events by ID
job = model.delete_events(event_ids=['pred_001', 'pred_002'])
job.wait()
```

<Info>
  Deletion is irreversible. Provide either a time range or `event_ids`
  to scope the deletion (not both); a call with no filter is rejected.
</Info>

## add\_artifact()

Upload and deploy model artifact.

### Parameters

<ParamField path="model_dir" type="str | Path" required={true}>
  Path to model artifact tar file
</ParamField>

<ParamField path="deployment_params" type="DeploymentParams | None" required={false} default="None">
  Model deployment parameters
</ParamField>

### Returns

<ResponseField type="Job">
  Async job instance
</ResponseField>

## update\_artifact()

Update existing model artifact.

### Parameters

<ParamField path="model_dir" type="str | Path" required={true}>
  Path to model artifact tar file
</ParamField>

<ParamField path="deployment_params" type="DeploymentParams | None" required={false} default="None">
  Model deployment parameters
</ParamField>

### Returns

<ResponseField type="Job">
  Async job instance
</ResponseField>

## download\_artifact()

Download existing model artifact.

### Parameters

<ParamField path="output_dir" type="str | Path" required={true}>
  Path to download model artifact tar file
</ParamField>

## add\_surrogate()

Add a new surrogate model

### Parameters

<ParamField path="dataset_id" type="UUID | str" required={true}>
  Dataset to be used for generating surrogate model
</ParamField>

<ParamField path="deployment_params" type="DeploymentParams | None" required={false} default="None">
  Model deployment parameters
</ParamField>

### Returns

<ResponseField type="Job">
  Async job
</ResponseField>

## update\_surrogate()

Update an existing surrogate model

### Parameters

<ParamField path="dataset_id" type="UUID | str" required={true}>
  Dataset to be used for generating surrogate model
</ParamField>

<ParamField path="deployment_params" type="DeploymentParams | None" required={false} default="None">
  Model deployment parameters
</ParamField>

### Returns

<ResponseField type="Job">
  Async job
</ResponseField>
