# Basic usage

The Imagine SDK exposes two clients, each with a different programming paradigm:
synchronous and asynchronous.

{class}`~imagine.ImagineClient` is the synchronous Imagine client. If you don't need
asynchronous programming on your Python code, or simply you are not familiar with
asynchronous programming, this is the client you want to use.

Otherwise, if you are leveraging {obj}`asyncio` on your codebase,
{class}`~imagine.ImagineAsyncClient` might be a better choice.

The examples of this page are mostly focused on the synchronous client, as the async
client offers a very similar interface. Check
the [API documentation](../api/imagine_clients) for more details about their
differences.

```{include} /snippets/imagine_api_help.md
```

## Available models

When calling any of the inference methods, you can pass a model name as a string to
specify which model to use (for example, see the documentation for {py:obj}`imagine.ImagineClient.chat`).

You can get a list of available models with:

```{literalinclude} ../../examples/sync/list_models.py
```

Alternatively, if you don't pass a model name explicitly when invoking the method, the
default model will be used. The current default models are:

| Model type    | Default model              |
|---------------|----------------------------|
| LLM           | Llama-3.1-8B               |
| Text to Image | sdxl-turbo                 |
| Translate     | Helsinki-NLP/opus-mt-en-es |
| Transcribe    | whisper-tiny               |
| Embedding     | BAAI/bge-large-en-v1.5     |
| Reranker      | BAAI/bge-reranker-base     |


(tutorials-basic-chat)=
## Chat

This is the most basic example of using a Large Language Model (LLM) to generate text.
It instantiates the client `ImagineClient` and starts a new conversation by asking a
question.

```{literalinclude} ../../examples/sync/chat_no_streaming.py
```

This will print something similar to:

```text
Spain is renowned for its rich variety of cheeses, each with its unique flavor profile
and texture. The "best" Spanish cheese is subjective and often depends on personal
taste preferences. However, here are some of the most popular and highly-regarded
Spanish cheeses:

1. Manchego: A firm, crumbly cheese made from sheep's milk, Manchego is a classic
   Spanish cheese with a nutty, slightly sweet flavor.
2. Mahon: A semi-soft cheese from the island of Minorca, Mahon has a mild,
   creamy flavor and a smooth texture.
3. Idiazabal: A smoked cheese from the Basque region, Idiazabal has a strong, savory
   flavor and a firm texture.
4. Garrotxa: A soft, creamy cheese from Catalonia, Garrotxa has a mild, buttery flavor
   and a delicate aroma.
...
```

### Streaming response

The example above returns the response all at once. But on your application you might
want to get the result in small chunks, so that you can start providing some feedback
to the user as soon as possible. This is particularly useful for long responses that
might take a long time to complete.

```{literalinclude} ../../examples/sync/chat_streaming.py
```

This will provide an output similar to the example above, but the text will be printed
progressively instead of all at once.

### Asynchronous client

If you are interested in the async client, this is the non-streaming example for it:

```{literalinclude} ../../examples/async/chat_no_streaming.py
```

And with streaming enabled:

```{literalinclude} ../../examples/async/chat_streaming.py
```

Notice how on both cases the methods and the input arguments are the same, making it
very easy to transition from synchronous code to async code.

## Code completion

Code completion works very similar to the [Chat feature](#tutorials-basic-chat). The following example
illustrates how to generate some Python code:

```{literalinclude} ../../examples/sync/completion_no_streaming.py
```

This will print a response similar to:

````markdown
Here is a Python function that generates the Fibonacci series up to a given number:

```Python
def fibonacci(n):
    fib_series = [0, 1]
    while fib_series[-1] + fib_series[-2] <= n:
        fib_series.append(fib_series[-1] + fib_series[-2])
    return fib_series

n = int(input("Enter a number: "))
print(fibonacci(n))
```
````

The equivalent streaming and async outputs are available as shown on
the [Chat examples](#tutorials-basic-chat). Check the [API documentation](../api/imagine_clients) for
details.

## Translation

The Imagine SDK can be used to translate text between languages. Make sure to select the
right model for the desired input and output language. This is the example with
non-streaming using the synchronous client:

```{literalinclude} ../../examples/sync/translate_no_streaming.py
```

This will print a response similar to:

```text
San Diego es una de las ciudades más hermosas de América!
```

## Images

This is an example of how to generate one image using a text prompt and save it to disk.

```{literalinclude} ../../examples/sync/images_no_streaming.py
```

## Transcribe audio

This is an example of how to convert an audio file to text.

```{literalinclude} ../../examples/sync/transcribe_no_streaming.py
```

That will print a text with the transcription of the mp3 file.

## Embeddings

Imagine SDK supports creating embeddings from a given text input. Embeddings are
numerical representations of text that capture semantic meaning, making them useful for
various natural language processing (NLP) tasks.

Use Cases:
- Similarity Search: Find texts that are semantically similar.
- Clustering: Group similar texts together.
- Classification: Improve the performance of text classification models.
- Recommendation Systems: Enhance content recommendations based on text similarity.

See the following example to generate embeddings:

```{literalinclude} ../../examples/sync/embeddings.py
```

## Reranking

If you need reranking as part of your RAG workflow, you can use it like this:

```{literalinclude} ../../examples/sync/reranker.py
```
