mirror of
https://github.com/BerriAI/litellm.git
synced 2025-04-25 02:34:29 +00:00
Add new model provider Novita AI (#7582)
* feat: add new model provider Novita AI * feat: use deepseek r1 model for examples in Novita AI docs * fix: fix tests * fix: fix tests for novita * fix: fix novita transformation
This commit is contained in:
parent
b33c56cf10
commit
7a92a03565
22 changed files with 581 additions and 86 deletions
|
@ -20,8 +20,10 @@ REPLICATE_API_TOKEN = ""
|
||||||
ANTHROPIC_API_KEY = ""
|
ANTHROPIC_API_KEY = ""
|
||||||
# Infisical
|
# Infisical
|
||||||
INFISICAL_TOKEN = ""
|
INFISICAL_TOKEN = ""
|
||||||
|
# Novita AI
|
||||||
|
NOVITA_API_KEY = ""
|
||||||
|
|
||||||
# Development Configs
|
# Development Configs
|
||||||
LITELLM_MASTER_KEY = "sk-1234"
|
LITELLM_MASTER_KEY = "sk-1234"
|
||||||
DATABASE_URL = "postgresql://llmproxy:dbpassword9090@db:5432/litellm"
|
DATABASE_URL = "postgresql://llmproxy:dbpassword9090@db:5432/litellm"
|
||||||
STORE_MODEL_IN_DB = "True"
|
STORE_MODEL_IN_DB = "True"
|
||||||
|
|
|
@ -335,6 +335,7 @@ curl 'http://0.0.0.0:4000/key/generate' \
|
||||||
| [xinference [Xorbits Inference]](https://docs.litellm.ai/docs/providers/xinference) | | | | | ✅ | |
|
| [xinference [Xorbits Inference]](https://docs.litellm.ai/docs/providers/xinference) | | | | | ✅ | |
|
||||||
| [FriendliAI](https://docs.litellm.ai/docs/providers/friendliai) | ✅ | ✅ | ✅ | ✅ | | |
|
| [FriendliAI](https://docs.litellm.ai/docs/providers/friendliai) | ✅ | ✅ | ✅ | ✅ | | |
|
||||||
| [Galadriel](https://docs.litellm.ai/docs/providers/galadriel) | ✅ | ✅ | ✅ | ✅ | | |
|
| [Galadriel](https://docs.litellm.ai/docs/providers/galadriel) | ✅ | ✅ | ✅ | ✅ | | |
|
||||||
|
| [Novita AI](https://novita.ai/models/llm?utm_source=github_litellm&utm_medium=github_readme&utm_campaign=github_link) | ✅ | ✅ | ✅ | ✅ | | |
|
||||||
|
|
||||||
[**Read the Docs**](https://docs.litellm.ai/docs/)
|
[**Read the Docs**](https://docs.litellm.ai/docs/)
|
||||||
|
|
||||||
|
|
97
cookbook/LiteLLM_NovitaAI_Cookbook.ipynb
vendored
Normal file
97
cookbook/LiteLLM_NovitaAI_Cookbook.ipynb
vendored
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
{
|
||||||
|
"cells": [
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {
|
||||||
|
"id": "iFEmsVJI_2BR"
|
||||||
|
},
|
||||||
|
"source": [
|
||||||
|
"# LiteLLM NovitaAI Cookbook"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"id": "cBlUhCEP_xj4"
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"!pip install litellm"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"id": "p-MQqWOT_1a7"
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"import os\n",
|
||||||
|
"\n",
|
||||||
|
"os.environ['NOVITA_API_KEY'] = \"\""
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"id": "Ze8JqMqWAARO"
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"from litellm import completion\n",
|
||||||
|
"response = completion(\n",
|
||||||
|
" model=\"novita/deepseek/deepseek-r1\",\n",
|
||||||
|
" messages=[{\"role\": \"user\", \"content\": \"write code for saying hi\"}]\n",
|
||||||
|
")\n",
|
||||||
|
"response"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"id": "-LnhELrnAM_J"
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"response = completion(\n",
|
||||||
|
" model=\"novita/deepseek/deepseek-r1\",\n",
|
||||||
|
" messages=[{\"role\": \"user\", \"content\": \"write code for saying hi\"}]\n",
|
||||||
|
")\n",
|
||||||
|
"response"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"id": "dJBOUYdwCEn1"
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"response = completion(\n",
|
||||||
|
" model=\"mistralai/mistral-7b-instruct\",\n",
|
||||||
|
" messages=[{\"role\": \"user\", \"content\": \"write code for saying hi\"}]\n",
|
||||||
|
")\n",
|
||||||
|
"response"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"colab": {
|
||||||
|
"provenance": []
|
||||||
|
},
|
||||||
|
"kernelspec": {
|
||||||
|
"display_name": "Python 3",
|
||||||
|
"name": "python3"
|
||||||
|
},
|
||||||
|
"language_info": {
|
||||||
|
"name": "python"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nbformat": 4,
|
||||||
|
"nbformat_minor": 0
|
||||||
|
}
|
114
cookbook/LiteLLM_OpenRouter.ipynb
vendored
114
cookbook/LiteLLM_OpenRouter.ipynb
vendored
|
@ -1,27 +1,13 @@
|
||||||
{
|
{
|
||||||
"nbformat": 4,
|
|
||||||
"nbformat_minor": 0,
|
|
||||||
"metadata": {
|
|
||||||
"colab": {
|
|
||||||
"provenance": []
|
|
||||||
},
|
|
||||||
"kernelspec": {
|
|
||||||
"name": "python3",
|
|
||||||
"display_name": "Python 3"
|
|
||||||
},
|
|
||||||
"language_info": {
|
|
||||||
"name": "python"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"cells": [
|
"cells": [
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"source": [
|
|
||||||
"# LiteLLM OpenRouter Cookbook"
|
|
||||||
],
|
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"id": "iFEmsVJI_2BR"
|
"id": "iFEmsVJI_2BR"
|
||||||
}
|
},
|
||||||
|
"source": [
|
||||||
|
"# LiteLLM OpenRouter Cookbook"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
|
@ -36,27 +22,20 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
|
"execution_count": 14,
|
||||||
|
"metadata": {
|
||||||
|
"id": "p-MQqWOT_1a7"
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"import os\n",
|
"import os\n",
|
||||||
"\n",
|
"\n",
|
||||||
"os.environ['OPENROUTER_API_KEY'] = \"\""
|
"os.environ['OPENROUTER_API_KEY'] = \"\""
|
||||||
],
|
]
|
||||||
"metadata": {
|
|
||||||
"id": "p-MQqWOT_1a7"
|
|
||||||
},
|
|
||||||
"execution_count": 14,
|
|
||||||
"outputs": []
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"source": [
|
"execution_count": 11,
|
||||||
"from litellm import completion\n",
|
|
||||||
"response = completion(\n",
|
|
||||||
" model=\"openrouter/google/palm-2-chat-bison\",\n",
|
|
||||||
" messages=[{\"role\": \"user\", \"content\": \"write code for saying hi\"}]\n",
|
|
||||||
")\n",
|
|
||||||
"response"
|
|
||||||
],
|
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"colab": {
|
"colab": {
|
||||||
"base_uri": "https://localhost:8080/"
|
"base_uri": "https://localhost:8080/"
|
||||||
|
@ -64,10 +43,8 @@
|
||||||
"id": "Ze8JqMqWAARO",
|
"id": "Ze8JqMqWAARO",
|
||||||
"outputId": "64f3e836-69fa-4f8e-fb35-088a913bbe98"
|
"outputId": "64f3e836-69fa-4f8e-fb35-088a913bbe98"
|
||||||
},
|
},
|
||||||
"execution_count": 11,
|
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"output_type": "execute_result",
|
|
||||||
"data": {
|
"data": {
|
||||||
"text/plain": [
|
"text/plain": [
|
||||||
"<OpenAIObject id=gen-W8FTMSIEorCp3vG5iYIgNMR4IeBv at 0x7c3dcef1f060> JSON: {\n",
|
"<OpenAIObject id=gen-W8FTMSIEorCp3vG5iYIgNMR4IeBv at 0x7c3dcef1f060> JSON: {\n",
|
||||||
|
@ -85,20 +62,23 @@
|
||||||
"}"
|
"}"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"execution_count": 11,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"execution_count": 11
|
"output_type": "execute_result"
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"from litellm import completion\n",
|
||||||
|
"response = completion(\n",
|
||||||
|
" model=\"openrouter/google/palm-2-chat-bison\",\n",
|
||||||
|
" messages=[{\"role\": \"user\", \"content\": \"write code for saying hi\"}]\n",
|
||||||
|
")\n",
|
||||||
|
"response"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"source": [
|
"execution_count": 12,
|
||||||
"response = completion(\n",
|
|
||||||
" model=\"openrouter/anthropic/claude-2\",\n",
|
|
||||||
" messages=[{\"role\": \"user\", \"content\": \"write code for saying hi\"}]\n",
|
|
||||||
")\n",
|
|
||||||
"response"
|
|
||||||
],
|
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"colab": {
|
"colab": {
|
||||||
"base_uri": "https://localhost:8080/"
|
"base_uri": "https://localhost:8080/"
|
||||||
|
@ -106,10 +86,8 @@
|
||||||
"id": "-LnhELrnAM_J",
|
"id": "-LnhELrnAM_J",
|
||||||
"outputId": "d51c7ab7-d761-4bd1-f849-1534d9df4cd0"
|
"outputId": "d51c7ab7-d761-4bd1-f849-1534d9df4cd0"
|
||||||
},
|
},
|
||||||
"execution_count": 12,
|
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"output_type": "execute_result",
|
|
||||||
"data": {
|
"data": {
|
||||||
"text/plain": [
|
"text/plain": [
|
||||||
"<OpenAIObject id=gen-IiuV7ZNimDufVeutBHrl8ajPuzEh at 0x7c3dcea67560> JSON: {\n",
|
"<OpenAIObject id=gen-IiuV7ZNimDufVeutBHrl8ajPuzEh at 0x7c3dcea67560> JSON: {\n",
|
||||||
|
@ -128,20 +106,22 @@
|
||||||
"}"
|
"}"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"execution_count": 12,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"execution_count": 12
|
"output_type": "execute_result"
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"response = completion(\n",
|
||||||
|
" model=\"openrouter/anthropic/claude-2\",\n",
|
||||||
|
" messages=[{\"role\": \"user\", \"content\": \"write code for saying hi\"}]\n",
|
||||||
|
")\n",
|
||||||
|
"response"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"source": [
|
"execution_count": 13,
|
||||||
"response = completion(\n",
|
|
||||||
" model=\"openrouter/meta-llama/llama-2-70b-chat\",\n",
|
|
||||||
" messages=[{\"role\": \"user\", \"content\": \"write code for saying hi\"}]\n",
|
|
||||||
")\n",
|
|
||||||
"response"
|
|
||||||
],
|
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"colab": {
|
"colab": {
|
||||||
"base_uri": "https://localhost:8080/"
|
"base_uri": "https://localhost:8080/"
|
||||||
|
@ -149,10 +129,8 @@
|
||||||
"id": "dJBOUYdwCEn1",
|
"id": "dJBOUYdwCEn1",
|
||||||
"outputId": "ffa18679-ec15-4dad-fe2b-68665cdf36b0"
|
"outputId": "ffa18679-ec15-4dad-fe2b-68665cdf36b0"
|
||||||
},
|
},
|
||||||
"execution_count": 13,
|
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"output_type": "execute_result",
|
|
||||||
"data": {
|
"data": {
|
||||||
"text/plain": [
|
"text/plain": [
|
||||||
"<OpenAIObject id=gen-PyMd3yyJ0aQsCgIY9R8XGZoAtPbl at 0x7c3dceefcae0> JSON: {\n",
|
"<OpenAIObject id=gen-PyMd3yyJ0aQsCgIY9R8XGZoAtPbl at 0x7c3dceefcae0> JSON: {\n",
|
||||||
|
@ -170,10 +148,32 @@
|
||||||
"}"
|
"}"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"execution_count": 13,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"execution_count": 13
|
"output_type": "execute_result"
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"response = completion(\n",
|
||||||
|
" model=\"openrouter/meta-llama/llama-2-70b-chat\",\n",
|
||||||
|
" messages=[{\"role\": \"user\", \"content\": \"write code for saying hi\"}]\n",
|
||||||
|
")\n",
|
||||||
|
"response"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
}
|
"metadata": {
|
||||||
|
"colab": {
|
||||||
|
"provenance": []
|
||||||
|
},
|
||||||
|
"kernelspec": {
|
||||||
|
"display_name": "Python 3",
|
||||||
|
"name": "python3"
|
||||||
|
},
|
||||||
|
"language_info": {
|
||||||
|
"name": "python"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nbformat": 4,
|
||||||
|
"nbformat_minor": 0
|
||||||
|
}
|
||||||
|
|
|
@ -62,6 +62,7 @@ Use `litellm.get_supported_openai_params()` for an updated list of params for ea
|
||||||
|Databricks| ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | | | | | | | | | |
|
|Databricks| ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | | | | | | | | | |
|
||||||
|ClarifAI| ✅ | ✅ | ✅ | |✅ | ✅ | | | | | | | | | | |
|
|ClarifAI| ✅ | ✅ | ✅ | |✅ | ✅ | | | | | | | | | | |
|
||||||
|Github| ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | | | | ✅ |✅ (model dependent)|✅ (model dependent)| | |
|
|Github| ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | | | | ✅ |✅ (model dependent)|✅ (model dependent)| | |
|
||||||
|
|Novita AI| ✅ | ✅ | | ✅ | ✅ | ✅ | | ✅ | ✅ | ✅ | ✅ | | | ✅ | | | | | | | |
|
||||||
:::note
|
:::note
|
||||||
|
|
||||||
By default, LiteLLM raises an exception if the openai param being passed in isn't supported.
|
By default, LiteLLM raises an exception if the openai param being passed in isn't supported.
|
||||||
|
|
|
@ -208,6 +208,22 @@ response = completion(
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
<TabItem value="novita" label="Novita AI">
|
||||||
|
|
||||||
|
```python
|
||||||
|
from litellm import completion
|
||||||
|
import os
|
||||||
|
|
||||||
|
## set ENV variables. Visit https://novita.ai/settings/key-management to get your API key
|
||||||
|
os.environ["NOVITA_API_KEY"] = "novita-api-key"
|
||||||
|
|
||||||
|
response = completion(
|
||||||
|
model="novita/deepseek/deepseek-r1",
|
||||||
|
messages=[{ "content": "Hello, how are you?","role": "user"}]
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
</TabItem>
|
</TabItem>
|
||||||
|
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
@ -411,6 +427,23 @@ response = completion(
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
<TabItem value="novita" label="Novita AI">
|
||||||
|
|
||||||
|
```python
|
||||||
|
from litellm import completion
|
||||||
|
import os
|
||||||
|
|
||||||
|
## set ENV variables. Visit https://novita.ai/settings/key-management to get your API key
|
||||||
|
os.environ["NOVITA_API_KEY"] = "novita_api_key"
|
||||||
|
|
||||||
|
response = completion(
|
||||||
|
model="novita/deepseek/deepseek-r1",
|
||||||
|
messages = [{ "content": "Hello, how are you?","role": "user"}],
|
||||||
|
stream=True,
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
</TabItem>
|
</TabItem>
|
||||||
|
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|
39
docs/my-website/docs/providers/novita.md
Normal file
39
docs/my-website/docs/providers/novita.md
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
# Novita AI
|
||||||
|
LiteLLM supports all models from [Novita AI](https://novita.ai/models/llm?utm_source=github_litellm&utm_medium=github_readme&utm_campaign=github_link)
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
```python
|
||||||
|
import os
|
||||||
|
from litellm import completion
|
||||||
|
os.environ["NOVITA_API_KEY"] = ""
|
||||||
|
|
||||||
|
response = completion(
|
||||||
|
model="meta-llama/llama-3.3-70b-instruct",
|
||||||
|
messages=messages,
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Novita AI Completion Models
|
||||||
|
|
||||||
|
🚨 LiteLLM supports ALL Novita AI models, send `model=novita/<your-novita-model>` to send it to Novita AI. See all Novita AI models [here](https://novita.ai/models/llm?utm_source=github_litellm&utm_medium=github_readme&utm_campaign=github_link)
|
||||||
|
|
||||||
|
| Model Name | Function Call |
|
||||||
|
|---------------------------|-----------------------------------------------------|
|
||||||
|
| novita/deepseek/deepseek-r1 | `completion('novita/deepseek/deepseek-r1', messages)` | `os.environ['NOVITA_API_KEY']` |
|
||||||
|
| novita/deepseek/deepseek_v3 | `completion('novita/deepseek/deepseek_v3', messages)` | `os.environ['NOVITA_API_KEY']` |
|
||||||
|
| novita/meta-llama/llama-3.3-70b-instruct | `completion('novita/meta-llama/llama-3.3-70b-instruct', messages)` | `os.environ['NOVITA_API_KEY']` |
|
||||||
|
| novita/meta-llama/llama-3.1-8b-instruct | `completion('novita/meta-llama/llama-3.1-8b-instruct', messages)` | `os.environ['NOVITA_API_KEY']` |
|
||||||
|
| novita/meta-llama/llama-3.1-8b-instruct-max | `completion('novita/meta-llama/llama-3.1-8b-instruct-max', messages)` | `os.environ['NOVITA_API_KEY']` |
|
||||||
|
| novita/meta-llama/llama-3.1-70b-instruct | `completion('novita/meta-llama/llama-3.1-70b-instruct', messages)` | `os.environ['NOVITA_API_KEY']` |
|
||||||
|
| novita/meta-llama/llama-3-8b-instruct | `completion('novita/meta-llama/llama-3-8b-instruct', messages)` | `os.environ['NOVITA_API_KEY']` |
|
||||||
|
| novita/meta-llama/llama-3-70b-instruct | `completion('novita/meta-llama/llama-3-70b-instruct', messages)` | `os.environ['NOVITA_API_KEY']` |
|
||||||
|
| novita/meta-llama/llama-3.2-1b-instruct | `completion('novita/meta-llama/llama-3.2-1b-instruct', messages)` | `os.environ['NOVITA_API_KEY']` |
|
||||||
|
| novita/meta-llama/llama-3.2-11b-vision-instruct | `completion('novita/meta-llama/llama-3.2-11b-vision-instruct', messages)` | `os.environ['NOVITA_API_KEY']` |
|
||||||
|
| novita/meta-llama/llama-3.2-3b-instruct | `completion('novita/meta-llama/llama-3.2-3b-instruct', messages)` | `os.environ['NOVITA_API_KEY']` |
|
||||||
|
| novita/gryphe/mythomax-l2-13b | `completion('novita/gryphe/mythomax-l2-13b', messages)` | `os.environ['NOVITA_API_KEY']` |
|
||||||
|
| novita/google/gemma-2-9b-it | `completion('novita/google/gemma-2-9b-it', messages)` | `os.environ['NOVITA_API_KEY']` |
|
||||||
|
| novita/mistralai/mistral-nemo | `completion('novita/mistralai/mistral-nemo', messages)` | `os.environ['NOVITA_API_KEY']` |
|
||||||
|
| novita/mistralai/mistral-7b-instruct | `completion('novita/mistralai/mistral-7b-instruct', messages)` | `os.environ['NOVITA_API_KEY']` |
|
||||||
|
| novita/qwen/qwen-2.5-72b-instruct | `completion('novita/qwen/qwen-2.5-72b-instruct', messages)` | `os.environ['NOVITA_API_KEY']` |
|
||||||
|
| novita/qwen/qwen-2-vl-72b-instruct | `completion('novita/qwen/qwen-2-vl-72b-instruct', messages)` | `os.environ['NOVITA_API_KEY']` |
|
||||||
|
|
|
@ -225,6 +225,7 @@ const sidebars = {
|
||||||
"providers/nlp_cloud",
|
"providers/nlp_cloud",
|
||||||
"providers/replicate",
|
"providers/replicate",
|
||||||
"providers/togetherai",
|
"providers/togetherai",
|
||||||
|
"providers/novita",
|
||||||
"providers/voyage",
|
"providers/voyage",
|
||||||
"providers/jina_ai",
|
"providers/jina_ai",
|
||||||
"providers/aleph_alpha",
|
"providers/aleph_alpha",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# Completion Function - completion()
|
# Completion Function - completion()
|
||||||
The Input params are **exactly the same** as the
|
The Input params are **exactly the same** as the
|
||||||
<a href="https://platform.openai.com/docs/api-reference/chat/create" target="_blank" rel="noopener noreferrer">OpenAI Create chat completion</a>, and let you call **Azure OpenAI, Anthropic, Cohere, Replicate, OpenRouter** models in the same format.
|
<a href="https://platform.openai.com/docs/api-reference/chat/create" target="_blank" rel="noopener noreferrer">OpenAI Create chat completion</a>, and let you call **Azure OpenAI, Anthropic, Cohere, Replicate, OpenRouter, Novita AI** models in the same format.
|
||||||
|
|
||||||
In addition, liteLLM allows you to pass in the following **Optional** liteLLM args:
|
In addition, liteLLM allows you to pass in the following **Optional** liteLLM args:
|
||||||
`force_timeout`, `azure`, `logger_fn`, `verbose`
|
`force_timeout`, `azure`, `logger_fn`, `verbose`
|
||||||
|
|
|
@ -70,4 +70,28 @@ All the text models from [OpenRouter](https://openrouter.ai/docs) are supported
|
||||||
| google/palm-2-chat-bison | `completion('google/palm-2-chat-bison', messages)` | `os.environ['OR_SITE_URL']`,`os.environ['OR_APP_NAME']`,`os.environ['OR_API_KEY']` |
|
| google/palm-2-chat-bison | `completion('google/palm-2-chat-bison', messages)` | `os.environ['OR_SITE_URL']`,`os.environ['OR_APP_NAME']`,`os.environ['OR_API_KEY']` |
|
||||||
| google/palm-2-codechat-bison | `completion('google/palm-2-codechat-bison', messages)` | `os.environ['OR_SITE_URL']`,`os.environ['OR_APP_NAME']`,`os.environ['OR_API_KEY']` |
|
| google/palm-2-codechat-bison | `completion('google/palm-2-codechat-bison', messages)` | `os.environ['OR_SITE_URL']`,`os.environ['OR_APP_NAME']`,`os.environ['OR_API_KEY']` |
|
||||||
| meta-llama/llama-2-13b-chat | `completion('meta-llama/llama-2-13b-chat', messages)` | `os.environ['OR_SITE_URL']`,`os.environ['OR_APP_NAME']`,`os.environ['OR_API_KEY']` |
|
| meta-llama/llama-2-13b-chat | `completion('meta-llama/llama-2-13b-chat', messages)` | `os.environ['OR_SITE_URL']`,`os.environ['OR_APP_NAME']`,`os.environ['OR_API_KEY']` |
|
||||||
| meta-llama/llama-2-70b-chat | `completion('meta-llama/llama-2-70b-chat', messages)` | `os.environ['OR_SITE_URL']`,`os.environ['OR_APP_NAME']`,`os.environ['OR_API_KEY']` |
|
| meta-llama/llama-2-70b-chat | `completion('meta-llama/llama-2-70b-chat', messages)` | `os.environ['OR_SITE_URL']`,`os.environ['OR_APP_NAME']`,`os.environ['OR_API_KEY']` |
|
||||||
|
|
||||||
|
## Novita AI Completion Models
|
||||||
|
|
||||||
|
🚨 LiteLLM supports ALL Novita AI models, send `model=novita/<your-novita-model>` to send it to Novita AI. See all Novita AI models [here](https://novita.ai/models/llm?utm_source=github_litellm&utm_medium=github_readme&utm_campaign=github_link)
|
||||||
|
|
||||||
|
| Model Name | Function Call | Required OS Variables |
|
||||||
|
|------------------|--------------------------------------------|--------------------------------------|
|
||||||
|
| novita/deepseek/deepseek-r1 | `completion('novita/deepseek/deepseek-r1', messages)` | `os.environ['NOVITA_API_KEY']` |
|
||||||
|
| novita/deepseek/deepseek_v3 | `completion('novita/deepseek/deepseek_v3', messages)` | `os.environ['NOVITA_API_KEY']` |
|
||||||
|
| novita/meta-llama/llama-3.3-70b-instruct | `completion('novita/meta-llama/llama-3.3-70b-instruct', messages)` | `os.environ['NOVITA_API_KEY']` |
|
||||||
|
| novita/meta-llama/llama-3.1-8b-instruct | `completion('novita/meta-llama/llama-3.1-8b-instruct', messages)` | `os.environ['NOVITA_API_KEY']` |
|
||||||
|
| novita/meta-llama/llama-3.1-8b-instruct-max | `completion('novita/meta-llama/llama-3.1-8b-instruct-max', messages)` | `os.environ['NOVITA_API_KEY']` |
|
||||||
|
| novita/meta-llama/llama-3.1-70b-instruct | `completion('novita/meta-llama/llama-3.1-70b-instruct', messages)` | `os.environ['NOVITA_API_KEY']` |
|
||||||
|
| novita/meta-llama/llama-3-8b-instruct | `completion('novita/meta-llama/llama-3-8b-instruct', messages)` | `os.environ['NOVITA_API_KEY']` |
|
||||||
|
| novita/meta-llama/llama-3-70b-instruct | `completion('novita/meta-llama/llama-3-70b-instruct', messages)` | `os.environ['NOVITA_API_KEY']` |
|
||||||
|
| novita/meta-llama/llama-3.2-1b-instruct | `completion('novita/meta-llama/llama-3.2-1b-instruct', messages)` | `os.environ['NOVITA_API_KEY']` |
|
||||||
|
| novita/meta-llama/llama-3.2-11b-vision-instruct | `completion('novita/meta-llama/llama-3.2-11b-vision-instruct', messages)` | `os.environ['NOVITA_API_KEY']` |
|
||||||
|
| novita/meta-llama/llama-3.2-3b-instruct | `completion('novita/meta-llama/llama-3.2-3b-instruct', messages)` | `os.environ['NOVITA_API_KEY']` |
|
||||||
|
| novita/gryphe/mythomax-l2-13b | `completion('novita/gryphe/mythomax-l2-13b', messages)` | `os.environ['NOVITA_API_KEY']` |
|
||||||
|
| novita/google/gemma-2-9b-it | `completion('novita/google/gemma-2-9b-it', messages)` | `os.environ['NOVITA_API_KEY']` |
|
||||||
|
| novita/mistralai/mistral-nemo | `completion('novita/mistralai/mistral-nemo', messages)` | `os.environ['NOVITA_API_KEY']` |
|
||||||
|
| novita/mistralai/mistral-7b-instruct | `completion('novita/mistralai/mistral-7b-instruct', messages)` | `os.environ['NOVITA_API_KEY']` |
|
||||||
|
| novita/qwen/qwen-2.5-72b-instruct | `completion('novita/qwen/qwen-2.5-72b-instruct', messages)` | `os.environ['NOVITA_API_KEY']` |
|
||||||
|
| novita/qwen/qwen-2-vl-72b-instruct | `completion('novita/qwen/qwen-2-vl-72b-instruct', messages)` | `os.environ['NOVITA_API_KEY']` |
|
|
@ -194,6 +194,22 @@ response = completion(
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
<TabItem value="novita" label="Novita AI">
|
||||||
|
|
||||||
|
```python
|
||||||
|
from litellm import completion
|
||||||
|
import os
|
||||||
|
|
||||||
|
## set ENV variables. Visit https://novita.ai/settings/key-management to get your API key
|
||||||
|
os.environ["NOVITA_API_KEY"] = "novita-api-key"
|
||||||
|
|
||||||
|
response = completion(
|
||||||
|
model="novita/deepseek/deepseek-r1",
|
||||||
|
messages=[{ "content": "Hello, how are you?","role": "user"}]
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
</TabItem>
|
</TabItem>
|
||||||
|
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
@ -347,7 +363,23 @@ response = completion(
|
||||||
```
|
```
|
||||||
|
|
||||||
</TabItem>
|
</TabItem>
|
||||||
|
<TabItem value="novita" label="Novita AI">
|
||||||
|
|
||||||
|
```python
|
||||||
|
from litellm import completion
|
||||||
|
import os
|
||||||
|
|
||||||
|
## set ENV variables. Visit https://novita.ai/settings/key-management to get your API key
|
||||||
|
os.environ["NOVITA_API_KEY"] = "novita_api_key"
|
||||||
|
|
||||||
|
response = completion(
|
||||||
|
model="novita/deepseek/deepseek-r1",
|
||||||
|
messages = [{ "content": "Hello, how are you?","role": "user"}],
|
||||||
|
stream=True,
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|
||||||
### Exception handling
|
### Exception handling
|
||||||
|
|
|
@ -182,6 +182,7 @@ cloudflare_api_key: Optional[str] = None
|
||||||
baseten_key: Optional[str] = None
|
baseten_key: Optional[str] = None
|
||||||
aleph_alpha_key: Optional[str] = None
|
aleph_alpha_key: Optional[str] = None
|
||||||
nlp_cloud_key: Optional[str] = None
|
nlp_cloud_key: Optional[str] = None
|
||||||
|
novita_api_key: Optional[str] = None
|
||||||
snowflake_key: Optional[str] = None
|
snowflake_key: Optional[str] = None
|
||||||
common_cloud_provider_auth_params: dict = {
|
common_cloud_provider_auth_params: dict = {
|
||||||
"params": ["project", "region_name", "token"],
|
"params": ["project", "region_name", "token"],
|
||||||
|
@ -416,10 +417,10 @@ anyscale_models: List = []
|
||||||
cerebras_models: List = []
|
cerebras_models: List = []
|
||||||
galadriel_models: List = []
|
galadriel_models: List = []
|
||||||
sambanova_models: List = []
|
sambanova_models: List = []
|
||||||
|
novita_models: List = []
|
||||||
assemblyai_models: List = []
|
assemblyai_models: List = []
|
||||||
snowflake_models: List = []
|
snowflake_models: List = []
|
||||||
|
|
||||||
|
|
||||||
def is_bedrock_pricing_only_model(key: str) -> bool:
|
def is_bedrock_pricing_only_model(key: str) -> bool:
|
||||||
"""
|
"""
|
||||||
Excludes keys with the pattern 'bedrock/<region>/<model>'. These are in the model_prices_and_context_window.json file for pricing purposes only.
|
Excludes keys with the pattern 'bedrock/<region>/<model>'. These are in the model_prices_and_context_window.json file for pricing purposes only.
|
||||||
|
@ -567,6 +568,8 @@ def add_known_models():
|
||||||
galadriel_models.append(key)
|
galadriel_models.append(key)
|
||||||
elif value.get("litellm_provider") == "sambanova_models":
|
elif value.get("litellm_provider") == "sambanova_models":
|
||||||
sambanova_models.append(key)
|
sambanova_models.append(key)
|
||||||
|
elif value.get("litellm_provider") == "novita":
|
||||||
|
novita_models.append(key)
|
||||||
elif value.get("litellm_provider") == "assemblyai":
|
elif value.get("litellm_provider") == "assemblyai":
|
||||||
assemblyai_models.append(key)
|
assemblyai_models.append(key)
|
||||||
elif value.get("litellm_provider") == "jina_ai":
|
elif value.get("litellm_provider") == "jina_ai":
|
||||||
|
@ -645,6 +648,7 @@ model_list = (
|
||||||
+ galadriel_models
|
+ galadriel_models
|
||||||
+ sambanova_models
|
+ sambanova_models
|
||||||
+ azure_text_models
|
+ azure_text_models
|
||||||
|
+ novita_models
|
||||||
+ assemblyai_models
|
+ assemblyai_models
|
||||||
+ jina_ai_models
|
+ jina_ai_models
|
||||||
+ snowflake_models
|
+ snowflake_models
|
||||||
|
@ -701,6 +705,7 @@ models_by_provider: dict = {
|
||||||
"cerebras": cerebras_models,
|
"cerebras": cerebras_models,
|
||||||
"galadriel": galadriel_models,
|
"galadriel": galadriel_models,
|
||||||
"sambanova": sambanova_models,
|
"sambanova": sambanova_models,
|
||||||
|
"novita": novita_models,
|
||||||
"assemblyai": assemblyai_models,
|
"assemblyai": assemblyai_models,
|
||||||
"jina_ai": jina_ai_models,
|
"jina_ai": jina_ai_models,
|
||||||
"snowflake": snowflake_models,
|
"snowflake": snowflake_models,
|
||||||
|
@ -835,6 +840,7 @@ from .llms.anthropic.experimental_pass_through.messages.transformation import (
|
||||||
from .llms.together_ai.chat import TogetherAIConfig
|
from .llms.together_ai.chat import TogetherAIConfig
|
||||||
from .llms.together_ai.completion.transformation import TogetherAITextCompletionConfig
|
from .llms.together_ai.completion.transformation import TogetherAITextCompletionConfig
|
||||||
from .llms.cloudflare.chat.transformation import CloudflareChatConfig
|
from .llms.cloudflare.chat.transformation import CloudflareChatConfig
|
||||||
|
from .llms.novita.chat.transformation import NovitaConfig
|
||||||
from .llms.deprecated_providers.palm import (
|
from .llms.deprecated_providers.palm import (
|
||||||
PalmConfig,
|
PalmConfig,
|
||||||
) # here to prevent breaking changes
|
) # here to prevent breaking changes
|
||||||
|
|
|
@ -82,6 +82,7 @@ LITELLM_CHAT_PROVIDERS = [
|
||||||
"hosted_vllm",
|
"hosted_vllm",
|
||||||
"lm_studio",
|
"lm_studio",
|
||||||
"galadriel",
|
"galadriel",
|
||||||
|
"novita",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -171,6 +172,7 @@ openai_compatible_providers: List = [
|
||||||
"hosted_vllm",
|
"hosted_vllm",
|
||||||
"lm_studio",
|
"lm_studio",
|
||||||
"galadriel",
|
"galadriel",
|
||||||
|
"novita",
|
||||||
]
|
]
|
||||||
openai_text_completion_compatible_providers: List = (
|
openai_text_completion_compatible_providers: List = (
|
||||||
[ # providers that support `/v1/completions`
|
[ # providers that support `/v1/completions`
|
||||||
|
|
|
@ -569,6 +569,13 @@ def _get_openai_compatible_provider_info( # noqa: PLR0915
|
||||||
or "https://api.galadriel.com/v1"
|
or "https://api.galadriel.com/v1"
|
||||||
) # type: ignore
|
) # type: ignore
|
||||||
dynamic_api_key = api_key or get_secret_str("GALADRIEL_API_KEY")
|
dynamic_api_key = api_key or get_secret_str("GALADRIEL_API_KEY")
|
||||||
|
elif custom_llm_provider == "novita":
|
||||||
|
api_base = (
|
||||||
|
api_base
|
||||||
|
or get_secret("NOVITA_API_BASE")
|
||||||
|
or "https://api.novita.ai/v3/openai"
|
||||||
|
) # type: ignore
|
||||||
|
dynamic_api_key = api_key or get_secret_str("NOVITA_API_KEY")
|
||||||
elif custom_llm_provider == "snowflake":
|
elif custom_llm_provider == "snowflake":
|
||||||
api_base = (
|
api_base = (
|
||||||
api_base
|
api_base
|
||||||
|
|
|
@ -119,6 +119,8 @@ def get_supported_openai_params( # noqa: PLR0915
|
||||||
return litellm.GoogleAIStudioGeminiConfig().get_supported_openai_params(
|
return litellm.GoogleAIStudioGeminiConfig().get_supported_openai_params(
|
||||||
model=model
|
model=model
|
||||||
)
|
)
|
||||||
|
elif custom_llm_provider == "novita":
|
||||||
|
return litellm.NovitaConfig().get_supported_openai_params(model=model)
|
||||||
elif custom_llm_provider == "vertex_ai" or custom_llm_provider == "vertex_ai_beta":
|
elif custom_llm_provider == "vertex_ai" or custom_llm_provider == "vertex_ai_beta":
|
||||||
if request_type == "chat_completion":
|
if request_type == "chat_completion":
|
||||||
if model.startswith("mistral"):
|
if model.startswith("mistral"):
|
||||||
|
|
35
litellm/llms/novita/chat/transformation.py
Normal file
35
litellm/llms/novita/chat/transformation.py
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
"""
|
||||||
|
Support for OpenAI's `/v1/chat/completions` endpoint.
|
||||||
|
|
||||||
|
Calls done in OpenAI/openai.py as Novita AI is openai-compatible.
|
||||||
|
|
||||||
|
Docs: https://novita.ai/docs/guides/llm-api
|
||||||
|
"""
|
||||||
|
|
||||||
|
from typing import List, Optional
|
||||||
|
|
||||||
|
from ....types.llms.openai import AllMessageValues
|
||||||
|
from ...openai.chat.gpt_transformation import OpenAIGPTConfig
|
||||||
|
|
||||||
|
|
||||||
|
class NovitaConfig(OpenAIGPTConfig):
|
||||||
|
def validate_environment(
|
||||||
|
self,
|
||||||
|
headers: dict,
|
||||||
|
model: str,
|
||||||
|
messages: List[AllMessageValues],
|
||||||
|
optional_params: dict,
|
||||||
|
api_key: Optional[str] = None,
|
||||||
|
api_base: Optional[str] = None,
|
||||||
|
) -> dict:
|
||||||
|
if api_key is None:
|
||||||
|
raise ValueError(
|
||||||
|
"Missing Novita AI API Key - A call is being made to novita but no key is set either in the environment variables or via params"
|
||||||
|
)
|
||||||
|
|
||||||
|
headers = {
|
||||||
|
"Authorization": f"Bearer {api_key}",
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"X-Novita-Source": "litellm",
|
||||||
|
}
|
||||||
|
return headers
|
|
@ -3252,7 +3252,6 @@ async def aembedding(*args, **kwargs) -> EmbeddingResponse:
|
||||||
response = init_response
|
response = init_response
|
||||||
elif asyncio.iscoroutine(init_response):
|
elif asyncio.iscoroutine(init_response):
|
||||||
response = await init_response # type: ignore
|
response = await init_response # type: ignore
|
||||||
|
|
||||||
if (
|
if (
|
||||||
response is not None
|
response is not None
|
||||||
and isinstance(response, EmbeddingResponse)
|
and isinstance(response, EmbeddingResponse)
|
||||||
|
|
|
@ -2015,6 +2015,7 @@ class LlmProviders(str, Enum):
|
||||||
GALADRIEL = "galadriel"
|
GALADRIEL = "galadriel"
|
||||||
INFINITY = "infinity"
|
INFINITY = "infinity"
|
||||||
DEEPGRAM = "deepgram"
|
DEEPGRAM = "deepgram"
|
||||||
|
NOVITA = "novita"
|
||||||
AIOHTTP_OPENAI = "aiohttp_openai"
|
AIOHTTP_OPENAI = "aiohttp_openai"
|
||||||
LANGFUSE = "langfuse"
|
LANGFUSE = "langfuse"
|
||||||
HUMANLOOP = "humanloop"
|
HUMANLOOP = "humanloop"
|
||||||
|
|
|
@ -2317,6 +2317,9 @@ def register_model(model_cost: Union[str, dict]): # noqa: PLR0915
|
||||||
elif value.get("litellm_provider") == "bedrock":
|
elif value.get("litellm_provider") == "bedrock":
|
||||||
if key not in litellm.bedrock_models:
|
if key not in litellm.bedrock_models:
|
||||||
litellm.bedrock_models.append(key)
|
litellm.bedrock_models.append(key)
|
||||||
|
elif value.get("litellm_provider") == "novita":
|
||||||
|
if key not in litellm.novita_models:
|
||||||
|
litellm.novita_models.append(key)
|
||||||
return model_cost
|
return model_cost
|
||||||
|
|
||||||
|
|
||||||
|
@ -5073,6 +5076,11 @@ def validate_environment( # noqa: PLR0915
|
||||||
else:
|
else:
|
||||||
missing_keys.append("CLOUDFLARE_API_KEY")
|
missing_keys.append("CLOUDFLARE_API_KEY")
|
||||||
missing_keys.append("CLOUDFLARE_API_BASE")
|
missing_keys.append("CLOUDFLARE_API_BASE")
|
||||||
|
elif custom_llm_provider == "novita":
|
||||||
|
if "NOVITA_API_KEY" in os.environ:
|
||||||
|
keys_in_environment = True
|
||||||
|
else:
|
||||||
|
missing_keys.append("NOVITA_API_KEY")
|
||||||
else:
|
else:
|
||||||
## openai - chatcompletion + text completion
|
## openai - chatcompletion + text completion
|
||||||
if (
|
if (
|
||||||
|
@ -5155,6 +5163,11 @@ def validate_environment( # noqa: PLR0915
|
||||||
keys_in_environment = True
|
keys_in_environment = True
|
||||||
else:
|
else:
|
||||||
missing_keys.append("NLP_CLOUD_API_KEY")
|
missing_keys.append("NLP_CLOUD_API_KEY")
|
||||||
|
elif model in litellm.novita_models:
|
||||||
|
if "NOVITA_API_KEY" in os.environ:
|
||||||
|
keys_in_environment = True
|
||||||
|
else:
|
||||||
|
missing_keys.append("NOVITA_API_KEY")
|
||||||
|
|
||||||
if api_key is not None:
|
if api_key is not None:
|
||||||
new_missing_keys = []
|
new_missing_keys = []
|
||||||
|
@ -6281,6 +6294,8 @@ class ProviderConfigManager:
|
||||||
return litellm.TritonConfig()
|
return litellm.TritonConfig()
|
||||||
elif litellm.LlmProviders.PETALS == provider:
|
elif litellm.LlmProviders.PETALS == provider:
|
||||||
return litellm.PetalsConfig()
|
return litellm.PetalsConfig()
|
||||||
|
elif litellm.LlmProviders.NOVITA == provider:
|
||||||
|
return litellm.NovitaConfig()
|
||||||
elif litellm.LlmProviders.BEDROCK == provider:
|
elif litellm.LlmProviders.BEDROCK == provider:
|
||||||
bedrock_route = BedrockModelInfo.get_bedrock_route(model)
|
bedrock_route = BedrockModelInfo.get_bedrock_route(model)
|
||||||
bedrock_invoke_provider = litellm.BedrockLLM.get_bedrock_invoke_provider(
|
bedrock_invoke_provider = litellm.BedrockLLM.get_bedrock_invoke_provider(
|
||||||
|
|
108
poetry.lock
generated
108
poetry.lock
generated
|
@ -123,7 +123,7 @@ multidict = ">=4.5,<7.0"
|
||||||
yarl = ">=1.12.0,<2.0"
|
yarl = ">=1.12.0,<2.0"
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
speedups = ["Brotli", "aiodns (>=3.2.0)", "brotlicffi"]
|
speedups = ["Brotli ; platform_python_implementation == \"CPython\"", "aiodns (>=3.2.0) ; sys_platform == \"linux\" or sys_platform == \"darwin\"", "brotlicffi ; platform_python_implementation != \"CPython\""]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aiosignal"
|
name = "aiosignal"
|
||||||
|
@ -175,7 +175,7 @@ typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""}
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"]
|
doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"]
|
||||||
test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21.0b1)"]
|
test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1) ; python_version >= \"3.10\"", "uvloop (>=0.21.0b1) ; platform_python_implementation == \"CPython\" and platform_system != \"Windows\""]
|
||||||
trio = ["trio (>=0.26.1)"]
|
trio = ["trio (>=0.26.1)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -203,7 +203,7 @@ mongodb = ["pymongo (>=3.0)"]
|
||||||
redis = ["redis (>=3.0)"]
|
redis = ["redis (>=3.0)"]
|
||||||
rethinkdb = ["rethinkdb (>=2.4.0)"]
|
rethinkdb = ["rethinkdb (>=2.4.0)"]
|
||||||
sqlalchemy = ["sqlalchemy (>=1.4)"]
|
sqlalchemy = ["sqlalchemy (>=1.4)"]
|
||||||
test = ["APScheduler[etcd,mongodb,redis,rethinkdb,sqlalchemy,tornado,zookeeper]", "PySide6", "anyio (>=4.5.2)", "gevent", "pytest", "pytz", "twisted"]
|
test = ["APScheduler[etcd,mongodb,redis,rethinkdb,sqlalchemy,tornado,zookeeper]", "PySide6 ; platform_python_implementation == \"CPython\" and python_version < \"3.14\"", "anyio (>=4.5.2)", "gevent ; python_version < \"3.14\"", "pytest", "pytz", "twisted ; python_version < \"3.14\""]
|
||||||
tornado = ["tornado (>=4.3)"]
|
tornado = ["tornado (>=4.3)"]
|
||||||
twisted = ["twisted"]
|
twisted = ["twisted"]
|
||||||
zookeeper = ["kazoo"]
|
zookeeper = ["kazoo"]
|
||||||
|
@ -234,12 +234,12 @@ files = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"]
|
benchmark = ["cloudpickle ; platform_python_implementation == \"CPython\"", "hypothesis", "mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-xdist[psutil]"]
|
||||||
cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"]
|
cov = ["cloudpickle ; platform_python_implementation == \"CPython\"", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-xdist[psutil]"]
|
||||||
dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"]
|
dev = ["cloudpickle ; platform_python_implementation == \"CPython\"", "hypothesis", "mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-xdist[psutil]"]
|
||||||
docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier"]
|
docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier"]
|
||||||
tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"]
|
tests = ["cloudpickle ; platform_python_implementation == \"CPython\"", "hypothesis", "mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-xdist[psutil]"]
|
||||||
tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"]
|
tests-mypy = ["mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\""]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "azure-core"
|
name = "azure-core"
|
||||||
|
@ -386,7 +386,7 @@ typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""}
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
colorama = ["colorama (>=0.4.3)"]
|
colorama = ["colorama (>=0.4.3)"]
|
||||||
d = ["aiohttp (>=3.7.4)", "aiohttp (>=3.7.4,!=3.9.0)"]
|
d = ["aiohttp (>=3.7.4) ; sys_platform != \"win32\" or implementation_name != \"pypy\"", "aiohttp (>=3.7.4,!=3.9.0) ; sys_platform == \"win32\" and implementation_name == \"pypy\""]
|
||||||
jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"]
|
jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"]
|
||||||
uvloop = ["uvloop (>=0.15.2)"]
|
uvloop = ["uvloop (>=0.15.2)"]
|
||||||
|
|
||||||
|
@ -865,7 +865,7 @@ files = [
|
||||||
[package.extras]
|
[package.extras]
|
||||||
docs = ["furo (>=2024.8.6)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4.1)"]
|
docs = ["furo (>=2024.8.6)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4.1)"]
|
||||||
testing = ["covdefaults (>=2.3)", "coverage (>=7.6.1)", "diff-cover (>=9.2)", "pytest (>=8.3.3)", "pytest-asyncio (>=0.24)", "pytest-cov (>=5)", "pytest-mock (>=3.14)", "pytest-timeout (>=2.3.1)", "virtualenv (>=20.26.4)"]
|
testing = ["covdefaults (>=2.3)", "coverage (>=7.6.1)", "diff-cover (>=9.2)", "pytest (>=8.3.3)", "pytest-asyncio (>=0.24)", "pytest-cov (>=5)", "pytest-mock (>=3.14)", "pytest-timeout (>=2.3.1)", "virtualenv (>=20.26.4)"]
|
||||||
typing = ["typing-extensions (>=4.12.2)"]
|
typing = ["typing-extensions (>=4.12.2) ; python_version < \"3.11\""]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "flake8"
|
name = "flake8"
|
||||||
|
@ -1043,12 +1043,12 @@ files = [
|
||||||
google-auth = ">=2.14.1,<3.0.0"
|
google-auth = ">=2.14.1,<3.0.0"
|
||||||
googleapis-common-protos = ">=1.56.2,<2.0.0"
|
googleapis-common-protos = ">=1.56.2,<2.0.0"
|
||||||
grpcio = [
|
grpcio = [
|
||||||
|
{version = ">=1.33.2,<2.0dev", optional = true, markers = "extra == \"grpc\""},
|
||||||
{version = ">=1.49.1,<2.0dev", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""},
|
{version = ">=1.49.1,<2.0dev", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""},
|
||||||
{version = ">=1.33.2,<2.0dev", optional = true, markers = "python_version < \"3.11\" and extra == \"grpc\""},
|
|
||||||
]
|
]
|
||||||
grpcio-status = [
|
grpcio-status = [
|
||||||
|
{version = ">=1.33.2,<2.0.dev0", optional = true, markers = "extra == \"grpc\""},
|
||||||
{version = ">=1.49.1,<2.0.dev0", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""},
|
{version = ">=1.49.1,<2.0.dev0", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""},
|
||||||
{version = ">=1.33.2,<2.0.dev0", optional = true, markers = "python_version < \"3.11\" and extra == \"grpc\""},
|
|
||||||
]
|
]
|
||||||
proto-plus = [
|
proto-plus = [
|
||||||
{version = ">=1.22.3,<2.0.0", markers = "python_version < \"3.13\""},
|
{version = ">=1.22.3,<2.0.0", markers = "python_version < \"3.13\""},
|
||||||
|
@ -1059,7 +1059,7 @@ requests = ">=2.18.0,<3.0.0"
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
async-rest = ["google-auth[aiohttp] (>=2.35.0,<3.0.dev0)"]
|
async-rest = ["google-auth[aiohttp] (>=2.35.0,<3.0.dev0)"]
|
||||||
grpc = ["grpcio (>=1.33.2,<2.0dev)", "grpcio (>=1.49.1,<2.0dev)", "grpcio-status (>=1.33.2,<2.0.dev0)", "grpcio-status (>=1.49.1,<2.0.dev0)"]
|
grpc = ["grpcio (>=1.33.2,<2.0dev)", "grpcio (>=1.49.1,<2.0dev) ; python_version >= \"3.11\"", "grpcio-status (>=1.33.2,<2.0.dev0)", "grpcio-status (>=1.49.1,<2.0.dev0) ; python_version >= \"3.11\""]
|
||||||
grpcgcp = ["grpcio-gcp (>=0.2.2,<1.0.dev0)"]
|
grpcgcp = ["grpcio-gcp (>=0.2.2,<1.0.dev0)"]
|
||||||
grpcio-gcp = ["grpcio-gcp (>=0.2.2,<1.0.dev0)"]
|
grpcio-gcp = ["grpcio-gcp (>=0.2.2,<1.0.dev0)"]
|
||||||
|
|
||||||
|
@ -1352,6 +1352,66 @@ files = [
|
||||||
{file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"},
|
{file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "h2"
|
||||||
|
version = "4.1.0"
|
||||||
|
description = "HTTP/2 State-Machine based protocol implementation"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.6.1"
|
||||||
|
groups = ["main"]
|
||||||
|
markers = "python_version < \"3.10\""
|
||||||
|
files = [
|
||||||
|
{file = "h2-4.1.0-py3-none-any.whl", hash = "sha256:03a46bcf682256c95b5fd9e9a99c1323584c3eec6440d379b9903d709476bc6d"},
|
||||||
|
{file = "h2-4.1.0.tar.gz", hash = "sha256:a83aca08fbe7aacb79fec788c9c0bac936343560ed9ec18b82a13a12c28d2abb"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
hpack = ">=4.0,<5"
|
||||||
|
hyperframe = ">=6.0,<7"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "h2"
|
||||||
|
version = "4.2.0"
|
||||||
|
description = "Pure-Python HTTP/2 protocol implementation"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.9"
|
||||||
|
groups = ["main"]
|
||||||
|
markers = "python_version >= \"3.10\""
|
||||||
|
files = [
|
||||||
|
{file = "h2-4.2.0-py3-none-any.whl", hash = "sha256:479a53ad425bb29af087f3458a61d30780bc818e4ebcf01f0b536ba916462ed0"},
|
||||||
|
{file = "h2-4.2.0.tar.gz", hash = "sha256:c8a52129695e88b1a0578d8d2cc6842bbd79128ac685463b887ee278126ad01f"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
hpack = ">=4.1,<5"
|
||||||
|
hyperframe = ">=6.1,<7"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hpack"
|
||||||
|
version = "4.0.0"
|
||||||
|
description = "Pure-Python HPACK header compression"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.6.1"
|
||||||
|
groups = ["main"]
|
||||||
|
markers = "python_version < \"3.10\""
|
||||||
|
files = [
|
||||||
|
{file = "hpack-4.0.0-py3-none-any.whl", hash = "sha256:84a076fad3dc9a9f8063ccb8041ef100867b1878b25ef0ee63847a5d53818a6c"},
|
||||||
|
{file = "hpack-4.0.0.tar.gz", hash = "sha256:fc41de0c63e687ebffde81187a948221294896f6bdc0ae2312708df339430095"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hpack"
|
||||||
|
version = "4.1.0"
|
||||||
|
description = "Pure-Python HPACK header encoding"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.9"
|
||||||
|
groups = ["main"]
|
||||||
|
markers = "python_version >= \"3.10\""
|
||||||
|
files = [
|
||||||
|
{file = "hpack-4.1.0-py3-none-any.whl", hash = "sha256:157ac792668d995c657d93111f46b4535ed114f0c9c8d672271bbec7eae1b496"},
|
||||||
|
{file = "hpack-4.1.0.tar.gz", hash = "sha256:ec5eca154f7056aa06f196a557655c5b009b382873ac8d1e66e79e87535f1dca"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "httpcore"
|
name = "httpcore"
|
||||||
version = "1.0.7"
|
version = "1.0.7"
|
||||||
|
@ -1393,7 +1453,7 @@ httpcore = "==1.*"
|
||||||
idna = "*"
|
idna = "*"
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
brotli = ["brotli", "brotlicffi"]
|
brotli = ["brotli ; platform_python_implementation == \"CPython\"", "brotlicffi ; platform_python_implementation != \"CPython\""]
|
||||||
cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"]
|
cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"]
|
||||||
http2 = ["h2 (>=3,<5)"]
|
http2 = ["h2 (>=3,<5)"]
|
||||||
socks = ["socksio (==1.*)"]
|
socks = ["socksio (==1.*)"]
|
||||||
|
@ -1481,12 +1541,12 @@ files = [
|
||||||
zipp = ">=3.20"
|
zipp = ">=3.20"
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"]
|
check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""]
|
||||||
cover = ["pytest-cov"]
|
cover = ["pytest-cov"]
|
||||||
doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
|
doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
|
||||||
enabler = ["pytest-enabler (>=2.2)"]
|
enabler = ["pytest-enabler (>=2.2)"]
|
||||||
perf = ["ipython"]
|
perf = ["ipython"]
|
||||||
test = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-perf (>=0.9.2)"]
|
test = ["flufl.flake8", "importlib-resources (>=1.3) ; python_version < \"3.9\"", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-perf (>=0.9.2)"]
|
||||||
type = ["pytest-mypy"]
|
type = ["pytest-mypy"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1506,7 +1566,7 @@ files = [
|
||||||
zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""}
|
zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""}
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"]
|
check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""]
|
||||||
cover = ["pytest-cov"]
|
cover = ["pytest-cov"]
|
||||||
doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
|
doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
|
||||||
enabler = ["pytest-enabler (>=2.2)"]
|
enabler = ["pytest-enabler (>=2.2)"]
|
||||||
|
@ -1835,7 +1895,7 @@ PyJWT = {version = ">=1.0.0,<3", extras = ["crypto"]}
|
||||||
requests = ">=2.0.0,<3"
|
requests = ">=2.0.0,<3"
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
broker = ["pymsalruntime (>=0.14,<0.18)", "pymsalruntime (>=0.17,<0.18)"]
|
broker = ["pymsalruntime (>=0.14,<0.18) ; python_version >= \"3.6\" and platform_system == \"Windows\"", "pymsalruntime (>=0.17,<0.18) ; python_version >= \"3.8\" and platform_system == \"Darwin\""]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "msal-extensions"
|
name = "msal-extensions"
|
||||||
|
@ -2614,7 +2674,7 @@ typing-extensions = ">=4.12.2"
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
email = ["email-validator (>=2.0.0)"]
|
email = ["email-validator (>=2.0.0)"]
|
||||||
timezone = ["tzdata"]
|
timezone = ["tzdata ; python_version >= \"3.9\" and platform_system == \"Windows\""]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pydantic-core"
|
name = "pydantic-core"
|
||||||
|
@ -3373,7 +3433,7 @@ crt = ["botocore[crt] (>=1.33.2,<2.0a.0)"]
|
||||||
name = "six"
|
name = "six"
|
||||||
version = "1.17.0"
|
version = "1.17.0"
|
||||||
description = "Python 2 and 3 compatibility utilities"
|
description = "Python 2 and 3 compatibility utilities"
|
||||||
optional = true
|
optional = false
|
||||||
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7"
|
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7"
|
||||||
groups = ["main"]
|
groups = ["main"]
|
||||||
markers = "extra == \"extra-proxy\" or extra == \"proxy\""
|
markers = "extra == \"extra-proxy\" or extra == \"proxy\""
|
||||||
|
@ -3688,7 +3748,7 @@ files = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"]
|
brotli = ["brotli (>=1.0.9) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\""]
|
||||||
h2 = ["h2 (>=4,<5)"]
|
h2 = ["h2 (>=4,<5)"]
|
||||||
socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"]
|
socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"]
|
||||||
zstd = ["zstandard (>=0.18.0)"]
|
zstd = ["zstandard (>=0.18.0)"]
|
||||||
|
@ -3712,7 +3772,7 @@ h11 = ">=0.8"
|
||||||
typing-extensions = {version = ">=4.0", markers = "python_version < \"3.11\""}
|
typing-extensions = {version = ">=4.0", markers = "python_version < \"3.11\""}
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
standard = ["colorama (>=0.4)", "httptools (>=0.5.0)", "python-dotenv (>=0.13)", "pyyaml (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "watchfiles (>=0.13)", "websockets (>=10.4)"]
|
standard = ["colorama (>=0.4) ; sys_platform == \"win32\"", "httptools (>=0.5.0)", "python-dotenv (>=0.13)", "pyyaml (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1) ; sys_platform != \"win32\" and sys_platform != \"cygwin\" and platform_python_implementation != \"PyPy\"", "watchfiles (>=0.13)", "websockets (>=10.4)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "uvloop"
|
name = "uvloop"
|
||||||
|
@ -3990,11 +4050,11 @@ files = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"]
|
check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""]
|
||||||
cover = ["pytest-cov"]
|
cover = ["pytest-cov"]
|
||||||
doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
|
doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
|
||||||
enabler = ["pytest-enabler (>=2.2)"]
|
enabler = ["pytest-enabler (>=2.2)"]
|
||||||
test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"]
|
test = ["big-O", "importlib-resources ; python_version < \"3.9\"", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"]
|
||||||
type = ["pytest-mypy"]
|
type = ["pytest-mypy"]
|
||||||
|
|
||||||
[extras]
|
[extras]
|
||||||
|
|
67
tests/litellm/llms/novita/chat/test_transformation.py
Normal file
67
tests/litellm/llms/novita/chat/test_transformation.py
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
"""
|
||||||
|
Unit tests for Novita AI configuration.
|
||||||
|
|
||||||
|
These tests validate the NovitaConfig class which extends OpenAIGPTConfig.
|
||||||
|
Novita AI is an OpenAI-compatible provider with a few customizations.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
from typing import Dict, List, Optional
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
sys.path.insert(
|
||||||
|
0, os.path.abspath("../../../../..")
|
||||||
|
) # Adds the parent directory to the system path
|
||||||
|
|
||||||
|
from litellm.llms.novita.chat.transformation import NovitaConfig
|
||||||
|
|
||||||
|
|
||||||
|
class TestNovitaConfig:
|
||||||
|
"""Test class for NovitaConfig functionality"""
|
||||||
|
|
||||||
|
def test_validate_environment(self):
|
||||||
|
"""Test that validate_environment adds correct headers"""
|
||||||
|
config = NovitaConfig()
|
||||||
|
headers = {}
|
||||||
|
api_key = "fake-novita-key"
|
||||||
|
|
||||||
|
result = config.validate_environment(
|
||||||
|
headers=headers,
|
||||||
|
model="novita/meta-llama/llama-3.3-70b-instruct",
|
||||||
|
messages=[{"role": "user", "content": "Hello"}],
|
||||||
|
optional_params={},
|
||||||
|
api_key=api_key,
|
||||||
|
api_base="https://api.novita.ai/v3/openai"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Verify headers
|
||||||
|
assert result["Authorization"] == f"Bearer {api_key}"
|
||||||
|
assert result["Content-Type"] == "application/json"
|
||||||
|
assert result["X-Novita-Source"] == "litellm"
|
||||||
|
|
||||||
|
def test_missing_api_key(self):
|
||||||
|
"""Test error handling when API key is missing"""
|
||||||
|
config = NovitaConfig()
|
||||||
|
|
||||||
|
with pytest.raises(ValueError) as excinfo:
|
||||||
|
config.validate_environment(
|
||||||
|
headers={},
|
||||||
|
model="novita/meta-llama/llama-3.3-70b-instruct",
|
||||||
|
messages=[{"role": "user", "content": "Hello"}],
|
||||||
|
optional_params={},
|
||||||
|
api_key=None,
|
||||||
|
api_base="https://api.novita.ai/v3/openai"
|
||||||
|
)
|
||||||
|
|
||||||
|
assert "Missing Novita AI API Key" in str(excinfo.value)
|
||||||
|
|
||||||
|
def test_inheritance(self):
|
||||||
|
"""Test proper inheritance from OpenAIGPTConfig"""
|
||||||
|
config = NovitaConfig()
|
||||||
|
|
||||||
|
from litellm.llms.openai.chat.gpt_transformation import OpenAIGPTConfig
|
||||||
|
assert isinstance(config, OpenAIGPTConfig)
|
||||||
|
assert hasattr(config, "get_supported_openai_params")
|
|
@ -4658,6 +4658,77 @@ def test_humanloop_completion(monkeypatch):
|
||||||
messages=[{"role": "user", "content": "Tell me a joke."}],
|
messages=[{"role": "user", "content": "Tell me a joke."}],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_completion_novita_ai():
|
||||||
|
litellm.set_verbose = True
|
||||||
|
messages = [
|
||||||
|
{"role": "system", "content": "You're a good bot"},
|
||||||
|
{
|
||||||
|
"role": "user",
|
||||||
|
"content": "Hey",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
from openai import OpenAI
|
||||||
|
openai_client = OpenAI(api_key="fake-key")
|
||||||
|
|
||||||
|
with patch.object(
|
||||||
|
openai_client.chat.completions, "create", new=MagicMock()
|
||||||
|
) as mock_call:
|
||||||
|
try:
|
||||||
|
completion(
|
||||||
|
model="novita/meta-llama/llama-3.3-70b-instruct",
|
||||||
|
messages=messages,
|
||||||
|
client=openai_client,
|
||||||
|
api_base="https://api.novita.ai/v3/openai",
|
||||||
|
)
|
||||||
|
|
||||||
|
mock_call.assert_called_once()
|
||||||
|
|
||||||
|
# Verify model is passed correctly
|
||||||
|
assert mock_call.call_args.kwargs["model"] == "meta-llama/llama-3.3-70b-instruct"
|
||||||
|
# Verify messages are passed correctly
|
||||||
|
assert mock_call.call_args.kwargs["messages"] == messages
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
pytest.fail(f"Error occurred: {e}")
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"api_key", ["my-bad-api-key"]
|
||||||
|
)
|
||||||
|
def test_completion_novita_ai_dynamic_params(api_key):
|
||||||
|
try:
|
||||||
|
litellm.set_verbose = True
|
||||||
|
messages = [
|
||||||
|
{"role": "system", "content": "You're a good bot"},
|
||||||
|
{
|
||||||
|
"role": "user",
|
||||||
|
"content": "Hey",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
from openai import OpenAI
|
||||||
|
openai_client = OpenAI(api_key="fake-key")
|
||||||
|
|
||||||
|
with patch.object(
|
||||||
|
openai_client.chat.completions, "create", side_effect=Exception("Invalid API key")
|
||||||
|
) as mock_call:
|
||||||
|
try:
|
||||||
|
completion(
|
||||||
|
model="novita/meta-llama/llama-3.3-70b-instruct",
|
||||||
|
messages=messages,
|
||||||
|
api_key=api_key,
|
||||||
|
client=openai_client,
|
||||||
|
api_base="https://api.novita.ai/v3/openai",
|
||||||
|
)
|
||||||
|
pytest.fail(f"This call should have failed!")
|
||||||
|
except Exception as e:
|
||||||
|
# This should fail with the mocked exception
|
||||||
|
assert "Invalid API key" in str(e)
|
||||||
|
|
||||||
|
mock_call.assert_called_once()
|
||||||
|
except Exception as e:
|
||||||
|
pytest.fail(f"Unexpected error: {e}")
|
||||||
|
|
||||||
def test_deepseek_reasoning_content_completion():
|
def test_deepseek_reasoning_content_completion():
|
||||||
try:
|
try:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue