> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.nvidia.com/aistore/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.nvidia.com/aistore/_mcp/server.

# aistore.sdk.etl.webserver.flask_server

## Module Contents

### Classes

| Name                                                                                             | Description                                                          |
| ------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------- |
| [`FlaskServer`](#aistore-sdk-etl-webserver-flask_server-FlaskServer)                             | Flask server implementation for ETL transformations.                 |
| [`_FlaskRequestStreamReader`](#aistore-sdk-etl-webserver-flask_server-_FlaskRequestStreamReader) | Wrap Werkzeug's request.stream for no-FQN PUT on the streaming path. |

### API

```python
class aistore.sdk.etl.webserver.flask_server.FlaskServer(
    host: str = '0.0.0.0',
    port: int = 8000
)
```

**Bases:** [ETLServer](/python/aistore/sdk/etl/webserver/base_etl_server#aistore-sdk-etl-webserver-base_etl_server-ETLServer)

Flask server implementation for ETL transformations.
Compatible with environments where Flask is preferred over FastAPI.

```python
aistore.sdk.etl.webserver.flask_server.FlaskServer._direct_put(
    direct_put_url: str,
    data: bytes,
    remaining_pipeline: str = '',
    path: str = '',
    etl_args: str = ''
) -> typing.Tuple[int, bytes, int]
```

Sends the transformed object directly to the specified AIS node (`direct_put_url`),
eliminating the additional network hop through the original target.
Used only in bucket-to-bucket offline transforms.

Returns:
status code, transformed data, length of the transformed data (if any)

**Parameters:**

The first URL in the ETL pipeline

The transformed data to send

Comma-separated remaining pipeline stages to pass as header

The path of the object.

Per-request transform arguments to forward to the next stage.

```python
aistore.sdk.etl.webserver.flask_server.FlaskServer._direct_put_stream(
    direct_put_url: str,
    data_iter: typing.Iterator[bytes],
    remaining_pipeline: str = '',
    path: str = '',
    etl_args: str = ''
) -> typing.Tuple[int, bytes, int]
```

Stream transformed output directly to the next pipeline stage.

```python
aistore.sdk.etl.webserver.flask_server.FlaskServer._direct_put_stream_with_retry(
    direct_put_url: str,
    path: str,
    remaining_pipeline: str = '',
    etl_args: str = ''
) -> typing.Tuple[int, bytes, int]
```

Streaming direct-put with exponential-backoff retry on transient errors.

Replayable sources (FQN-backed or GET) close and reopen the reader on
each retry. No-FQN PUT bodies are one-shot (request body consumed from
the socket); effective\_retries is forced to 0 and a transient direct-put
error surfaces to AIS as a transform failure.

```python
aistore.sdk.etl.webserver.flask_server.FlaskServer._direct_put_with_retry(
    direct_put_url: str,
    data: bytes,
    remaining_pipeline: str = '',
    path: str = '',
    etl_args: str = ''
) -> typing.Tuple[int, bytes, int]
```

Buffered direct-put with exponential-backoff retry on transient errors.

```python
aistore.sdk.etl.webserver.flask_server.FlaskServer._get_fqn_content(
    path: str
) -> bytes
```

```python
aistore.sdk.etl.webserver.flask_server.FlaskServer._get_stream_reader(
    path
)
```

Get a BinaryIO reader for the request source data.

```python
aistore.sdk.etl.webserver.flask_server.FlaskServer._handle_get(
    path
)
```

```python
aistore.sdk.etl.webserver.flask_server.FlaskServer._handle_put(
    path
)
```

```python
aistore.sdk.etl.webserver.flask_server.FlaskServer._handle_request(
    path
)
```

```python
aistore.sdk.etl.webserver.flask_server.FlaskServer._handle_request_buffered(
    path
)
```

```python
aistore.sdk.etl.webserver.flask_server.FlaskServer._handle_request_streaming(
    path
)
```

```python
aistore.sdk.etl.webserver.flask_server.FlaskServer._health()
```

```python
aistore.sdk.etl.webserver.flask_server.FlaskServer._register_routes()
```

```python
aistore.sdk.etl.webserver.flask_server.FlaskServer.start()
```

```python
class aistore.sdk.etl.webserver.flask_server._FlaskRequestStreamReader(
    stream
)
```

**Bases:** `RawIOBase`

Wrap Werkzeug's request.stream for no-FQN PUT on the streaming path.

Werkzeug's LimitedStream inherits io.RawIOBase.close() without draining;
a transform that exits early would leave unread bytes on a keep-alive
connection. close() drains residual bytes in 64 KiB chunks (mirroring
\_RFileLimitedReader.close() in HTTPMultiThreadedServer).

```python
aistore.sdk.etl.webserver.flask_server._FlaskRequestStreamReader.close() -> None
```

```python
aistore.sdk.etl.webserver.flask_server._FlaskRequestStreamReader.read(
    size: int = -1
) -> bytes
```

```python
aistore.sdk.etl.webserver.flask_server._FlaskRequestStreamReader.readable() -> bool
```