diff --git a/litellm/model_prices_and_context_window_backup.json b/litellm/model_prices_and_context_window_backup.json index b665f4381..f8dd86cbc 100644 --- a/litellm/model_prices_and_context_window_backup.json +++ b/litellm/model_prices_and_context_window_backup.json @@ -2803,6 +2803,18 @@ "supports_vision": true, "supports_assistant_prefill": true }, + "vertex_ai/claude-3-5-haiku@20241022": { + "max_tokens": 8192, + "max_input_tokens": 200000, + "max_output_tokens": 8192, + "input_cost_per_token": 0.00000025, + "output_cost_per_token": 0.00000125, + "litellm_provider": "vertex_ai-anthropic_models", + "mode": "chat", + "supports_function_calling": true, + "supports_vision": true, + "supports_assistant_prefill": true + }, "vertex_ai/claude-3-haiku@20240307": { "max_tokens": 4096, "max_input_tokens": 200000, @@ -4662,7 +4674,8 @@ "litellm_provider": "bedrock", "mode": "chat", "supports_assistant_prefill": true, - "supports_function_calling": true + "supports_function_calling": true, + "supports_vision": true }, "us.anthropic.claude-3-opus-20240229-v1:0": { "max_tokens": 4096, @@ -4728,7 +4741,8 @@ "output_cost_per_token": 0.000005, "litellm_provider": "bedrock", "mode": "chat", - "supports_function_calling": true + "supports_function_calling": true, + "supports_vision": true }, "eu.anthropic.claude-3-opus-20240229-v1:0": { "max_tokens": 4096, diff --git a/litellm/proxy/management_endpoints/organization_endpoints.py b/litellm/proxy/management_endpoints/organization_endpoints.py index f448d2fad..5f58c4231 100644 --- a/litellm/proxy/management_endpoints/organization_endpoints.py +++ b/litellm/proxy/management_endpoints/organization_endpoints.py @@ -198,6 +198,45 @@ async def delete_organization(): pass +@router.get( + "/organization/list", + tags=["organization management"], + dependencies=[Depends(user_api_key_auth)], +) +async def list_organization( + user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth), +): + """ + ``` + curl --location --request GET 'http://0.0.0.0:4000/organization/list' \ + --header 'Authorization: Bearer sk-1234' + ``` + """ + from litellm.proxy.proxy_server import prisma_client + + if prisma_client is None: + raise HTTPException(status_code=500, detail={"error": "No db connected"}) + + if ( + user_api_key_dict.user_role is None + or user_api_key_dict.user_role != LitellmUserRoles.PROXY_ADMIN + ): + raise HTTPException( + status_code=401, + detail={ + "error": f"Only admins can list orgs. Your role is = {user_api_key_dict.user_role}" + }, + ) + if prisma_client is None: + raise HTTPException( + status_code=400, + detail={"error": CommonProxyErrors.db_not_connected_error.value}, + ) + response= await prisma_client.db.litellm_organizationtable.find_many() + + return response + + @router.post( "/organization/info", tags=["organization management"], diff --git a/model_prices_and_context_window.json b/model_prices_and_context_window.json index b665f4381..815672ff2 100644 --- a/model_prices_and_context_window.json +++ b/model_prices_and_context_window.json @@ -2803,6 +2803,18 @@ "supports_vision": true, "supports_assistant_prefill": true }, + "vertex_ai/claude-3-5-haiku@20241022": { + "max_tokens": 8192, + "max_input_tokens": 200000, + "max_output_tokens": 8192, + "input_cost_per_token": 0.00000025, + "output_cost_per_token": 0.00000125, + "litellm_provider": "vertex_ai-anthropic_models", + "mode": "chat", + "supports_function_calling": true, + "supports_vision": true, + "supports_assistant_prefill": true + }, "vertex_ai/claude-3-haiku@20240307": { "max_tokens": 4096, "max_input_tokens": 200000, diff --git a/tests/test_organizations.py b/tests/test_organizations.py index 5d9eb2e27..d62380b4a 100644 --- a/tests/test_organizations.py +++ b/tests/test_organizations.py @@ -29,6 +29,22 @@ async def new_organization(session, i, organization_alias, max_budget=None): return await response.json() +async def list_organization(session, i): + url = "http://0.0.0.0:4000/organization/list" + headers = {"Authorization": "Bearer sk-1234", "Content-Type": "application/json"} + + async with session.post(url, headers=headers) as response: + status = response.status + response_json = await response.json() + + print(f"Response {i} (Status code: {status}):") + print(response_json) + print() + + if status != 200: + raise Exception(f"Request {i} did not return a 200 status code: {status}") + + return await response.json() @pytest.mark.asyncio async def test_organization_new(): @@ -44,3 +60,25 @@ async def test_organization_new(): for i in range(1, 20) ] await asyncio.gather(*tasks) + +@pytest.mark.asyncio +async def test_organization_list(): + """ + create 2 new Organizations + check if the Organization list is not empty + """ + organization_alias = f"Organization: {uuid.uuid4()}" + async with aiohttp.ClientSession() as session: + tasks = [ + new_organization( + session=session, i=0, organization_alias=organization_alias + ) + for i in range(1, 2) + ] + await asyncio.gather(*tasks) + + response_json = await list_organization(session) + print(len(response_json)) + + if len(response_json)==0: + raise Exception(f"Return empty list of organization")