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

# Handling Input / Output with Inferless

Inferless allows you to easily define input and output schemas for APIs following the **Inference Protocol v2**. You can now define your inputs and outputs directly within your code using Pydantic models or use an `input_schema.py` file. This document explains both methods.

***

## Input Schema with Pydantic

With the new approach, you define your input schema directly in your code using Pydantic models. You no longer need to define an external schema file. Simply use the `@inferless.request` decorator to define the required inputs. you need to inferless python clinet

```shell theme={null}
pip install inferless
```

### Code Example:

```python theme={null}
import inferless
from pydantic import BaseModel, Field
from typing import List, Optional

@inferless.request
class RequestObjects(BaseModel):
    input_image_url: str = Field(default='https://hello.world')  # URL input for an image
    count_iterations: int = Field(default=4)  # Number of iterations for processing
    prompt: str = Field(default="a horse near a beach")  # Text prompt input
    mask_arr: List[int] = Field(default=[1, 5])  # List of integers for mask
    is_bytes: Optional[bool] = None  # Optional boolean field

```

### Explanation:

* **Field**: Used to provide a default value and metadata for each input parameter.
* **Optional Fields**: If a field is optional (e.g., `is_aws`), you can set it using `Optional`.
* **Field Types**: Use Pydantic field types such as `str`, `int` , `bool` , `float`, `List`, etc., to define the expected data types.
* **Default Values**: You can set default values for inputs if needed.

## Output Schema with Pydantic

For outputs, instead of manually handling dictionary returns, you can define the output schema directly within the code using the `@inferless.response` decorator. This allows you to declare structured outputs in a more maintainable way.

### Code Example:

```python theme={null}
@inferless.response
class ResponseObjects(BaseModel):
    generated_txt: str = Field(default='Test output')  # Generated text
    count_iterations: int = Field(default=4)  # Return number of iterations
    quality: float = Field(default=0.7)  # Quality score as a float
    positions: List[int] = Field(default=[1, 5])  # List of integer positions
    is_color: Optional[float] = Field(default=False)  # Optional boolean field

```

### Explanation:

* **Field**: Used to provide a default value and metadata for each output parameter.
* **Optional Fields**: If a field is optional (e.g., `is_aws`), you can set it using `Optional`.
* **Field Types**: Use Pydantic field types such as `str`, `int` , `bool` , `float`, `List`, etc., to define the expected data types.
* **Default Values**: You can set default values for outputs if needed.

***

## Example Usage

Here’s an example showing how you can process these input and output schemas inside your API:

### Code Example:

```python theme={null}
def infer(self, request: RequestObjects) -> ResponseObjects:
    prompt = request.prompt  # Access the prompt from the request
    iterations = request.count_iterations  # Access count of iterations
    
    # Perform your inference logic here
    
    # Example response
    return ResponseObjects(
        generated_txt="Inference completed", 
        count_iterations=iterations, 
        quality=0.9, 
        positions=[10, 20],
        is_color=False
    )
```

### Explanation:

* **Request Object**: The `infer` function takes a `request` object of type `RequestObjects` as input.
* **Accessing Inputs**: You can access the input parameters directly from the `request` object.
* **Perform Inference**: Perform your inference logic using the input parameters.
* **Return Response**: Return a `ResponseObjects` object with the output parameters.

### Input Schema  with input\_schema.py

For backward compatibility, you can still use the older method of defining an input schema using an external input\_schema.py file. In this method, you create a dictionary that defines the required inputs for your model.

For each input, there are 3 fields required

* **datatype**: "STRING", "BOOL", "INT8", "INT16", "INT32", "FP16" "FP32", "UINT8", "UINT16", "UINT32", "UINT64", "INT64" , "FP64" , "BYTES", "BF16"

* **shape**: The length of the array, If the shape is \[1] you will get the variable, if the array > 1 you will get an array, If the length is variable you can put -1

* **required**: If the parameter is required in all API calls

* **example**( optional ): Sample value for calling the API

In code

```API theme={null}
def infer(self, inputs):
    prompt = inputs["prompt"] # "There is a fine house in the forest"
    shape = inputs["shape"] # [ 512,1 ]
```

In input\_schema.py

```input_schema Example theme={null}
INPUT_SCHEMA = {
    "prompt": {
        'datatype': 'STRING',
        'required': True,
        'shape': [1],
        'example': ["There is a fine house in the forest"]
    },
    'shape': {
        'datatype': 'INT8',
        'required': False,
        'example': [ 512, 1 ],
        'shape': [2]
    },
}
```

More example of varrible length array <a href="/concepts/multiple-inputs"> here </a>

### Output Schema

You can return any dictionary in the return statement of app.py. You don't need to provide any configuration. There are some limitations on the dictories that you can return.

Possible return types are

* String
* Float
* Int
* Boolean
* List\[String|Float|Int|Boolean]

You can't have nested dictionaries, arrays of arrays, or arrays of dictionaries.

If you have nested Object/Dictionary you can serialise the object to JSON and return the JSON string.

### Returning Dicts

```
# Example Return Statement 

return { "label_1" : 0.398 , "label_2" : 0.563, "label_3" : 0.434 }
```

### Returning Variable Length Array

```
# Example Return Statement 
return { "generated_images_base64" : [ img_str1 , img_str2 , img_str3 ] }
```

### Returning Dictionary with Variable keys

```
# Example Return Statement 
dict = {"label_x": 0.4554 , "label_y", 0.3232 }
return { "result": json.dumps(dict) }
```

### Returning List of Dictionaries

```
# Example Return Statement
List =  [ {"label_x": 0.4554 , "label_y", 0.3232 } , {"label_x": 0.4554 , "label_y", 0.3232 } ]
return { "list_result" : json.dumps(List) }
```

More example of complex outputs <a href="/concepts/multiple-outputs"> here </a>

***
