diff --git a/.circleci/config.yml b/.circleci/config.yml
index 2ee3f24a08dd..acf8612eacd9 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -105,7 +105,7 @@ jobs:
           command: |
             pwd
             ls
-            python -m pytest -vv tests/local_testing --cov=litellm --cov-report=xml -x --junitxml=test-results/junit.xml --durations=5 -k "not test_python_38.py and not router and not assistants and not langfuse and not caching and not cache" -n 4
+            python -m pytest -vv tests/local_testing --cov=litellm --cov-report=xml -x --junitxml=test-results/junit.xml --durations=5 -k "not test_python_38.py and not test_basic_python_version.py and not router and not assistants and not langfuse and not caching and not cache" -n 4
           no_output_timeout: 120m
       - run:
           name: Rename the coverage files
@@ -895,6 +895,7 @@ jobs:
             pip install "pytest-retry==1.6.3"
             pip install "pytest-asyncio==0.21.1"
             pip install "pytest-cov==5.0.0"
+            pip install "tomli==2.2.1"
       - run:
           name: Run tests
           command: |
diff --git a/README.md b/README.md
index b1e6c9db3843..c7ea44cf462e 100644
--- a/README.md
+++ b/README.md
@@ -358,7 +358,7 @@ poetry install -E extra_proxy -E proxy
 Step 3: Test your change:
 
 ```
-cd litellm/tests # pwd: Documents/litellm/litellm/tests
+cd tests # pwd: Documents/litellm/litellm/tests
 poetry run flake8
 poetry run pytest .
 ```
diff --git a/dist/litellm-1.57.6.tar.gz b/dist/litellm-1.57.6.tar.gz
new file mode 100644
index 000000000000..01a039cf6eea
Binary files /dev/null and b/dist/litellm-1.57.6.tar.gz differ
diff --git a/docs/my-website/docs/secret.md b/docs/my-website/docs/secret.md
index 22bad6fec18b..a65c696f367b 100644
--- a/docs/my-website/docs/secret.md
+++ b/docs/my-website/docs/secret.md
@@ -72,6 +72,20 @@ general_settings:
     prefix_for_stored_virtual_keys: "litellm/" # OPTIONAL. If set, this prefix will be used for stored virtual keys in the secret manager
     access_mode: "write_only" # Literal["read_only", "write_only", "read_and_write"]
 ```
+</TabItem>
+<TabItem value="read_and_write" label="Read + Write Keys with AWS Secret Manager">
+
+```yaml
+general_settings:
+  master_key: os.environ/litellm_master_key 
+  key_management_system: "aws_secret_manager" # 👈 KEY CHANGE
+  key_management_settings: 
+    store_virtual_keys: true # OPTIONAL. Defaults to False, when True will store virtual keys in secret manager
+    prefix_for_stored_virtual_keys: "litellm/" # OPTIONAL. If set, this prefix will be used for stored virtual keys in the secret manager
+    access_mode: "read_and_write" # Literal["read_only", "write_only", "read_and_write"]
+    hosted_keys: ["litellm_master_key"] # OPTIONAL. Specify which env keys you stored on AWS
+```
+
 </TabItem>
 </Tabs>
 
@@ -186,34 +200,6 @@ LiteLLM stores secret under the `prefix_for_stored_virtual_keys` path (default:
 
 
 ## Azure Key Vault
-<!-- 
-### Quick Start
-
-```python 
-### Instantiate Azure Key Vault Client ###
-from azure.keyvault.secrets import SecretClient
-from azure.identity import ClientSecretCredential
-
-# Set your Azure Key Vault URI
-KVUri = os.getenv("AZURE_KEY_VAULT_URI")
-
-# Set your Azure AD application/client ID, client secret, and tenant ID - create an application with permission to call your key vault
-client_id = os.getenv("AZURE_CLIENT_ID") 
-client_secret = os.getenv("AZURE_CLIENT_SECRET")
-tenant_id = os.getenv("AZURE_TENANT_ID") 
-
-# Initialize the ClientSecretCredential
-credential = ClientSecretCredential(client_id=client_id, client_secret=client_secret, tenant_id=tenant_id)
-
-# Create the SecretClient using the credential
-client = SecretClient(vault_url=KVUri, credential=credential)
-
-### Connect to LiteLLM ###
-import litellm
-litellm.secret_manager = client
-
-litellm.get_secret("your-test-key")
-``` -->
 
 #### Usage with LiteLLM Proxy Server
 
diff --git a/litellm/proxy/_experimental/out/404.html b/litellm/proxy/_experimental/out/404.html
deleted file mode 100644
index 3bbcc888404d..000000000000
--- a/litellm/proxy/_experimental/out/404.html
+++ /dev/null
@@ -1 +0,0 @@
-<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" href="/ui/_next/static/media/a34f9d1faa5f3315-s.p.woff2" as="font" crossorigin="" type="font/woff2"/><link rel="stylesheet" href="/ui/_next/static/css/86f6cc749f6b8493.css" data-precedence="next"/><link rel="stylesheet" href="/ui/_next/static/css/08bcb9dd1e7e65fa.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/ui/_next/static/chunks/webpack-75a5453f51d60261.js"/><script src="/ui/_next/static/chunks/fd9d1056-896c4ac5495ec10d.js" async=""></script><script src="/ui/_next/static/chunks/117-7dac20504d3a26dd.js" async=""></script><script src="/ui/_next/static/chunks/main-app-4f7318ae681a6d94.js" async=""></script><meta name="robots" content="noindex"/><title>404: This page could not be found.</title><title>LiteLLM Dashboard</title><meta name="description" content="LiteLLM Proxy Admin UI"/><meta name="next-size-adjust"/><script src="/ui/_next/static/chunks/polyfills-42372ed130431b0a.js" noModule=""></script></head><body class="__className_cf7686"><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding:0 23px 0 0;font-size:24px;font-weight:500;vertical-align:top;line-height:49px">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:49px;margin:0">This page could not be found.</h2></div></div></div><script src="/ui/_next/static/chunks/webpack-75a5453f51d60261.js" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0]);self.__next_f.push([2,null])</script><script>self.__next_f.push([1,"1:HL[\"/ui/_next/static/media/a34f9d1faa5f3315-s.p.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n2:HL[\"/ui/_next/static/css/86f6cc749f6b8493.css\",\"style\"]\n3:HL[\"/ui/_next/static/css/08bcb9dd1e7e65fa.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"4:I[12846,[],\"\"]\n6:I[4707,[],\"\"]\n7:I[36423,[],\"\"]\nd:I[61060,[],\"\"]\n8:{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"}\n9:{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"}\na:{\"display\":\"inline-block\"}\nb:{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0}\ne:[]\n"])</script><script>self.__next_f.push([1,"0:[\"$\",\"$L4\",null,{\"buildId\":\"cqOIY3Hj19kDs5fgiHCMl\",\"assetPrefix\":\"/ui\",\"urlParts\":[\"\",\"_not-found\"],\"initialTree\":[\"\",{\"children\":[\"/_not-found\",{\"children\":[\"__PAGE__\",{}]}]},\"$undefined\",\"$undefined\",true],\"initialSeedData\":[\"\",{\"children\":[\"/_not-found\",{\"children\":[\"__PAGE__\",{},[[\"$L5\",[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":\"404\"}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],null],null],null]},[null,[\"$\",\"$L6\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\",\"/_not-found\",\"children\"],\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L7\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"notFoundStyles\":\"$undefined\"}]],null]},[[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/ui/_next/static/css/86f6cc749f6b8493.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\"}],[\"$\",\"link\",\"1\",{\"rel\":\"stylesheet\",\"href\":\"/ui/_next/static/css/08bcb9dd1e7e65fa.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"children\":[\"$\",\"body\",null,{\"className\":\"__className_cf7686\",\"children\":[\"$\",\"$L6\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\"],\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L7\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":\"$8\",\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":\"$9\",\"children\":\"404\"}],[\"$\",\"div\",null,{\"style\":\"$a\",\"children\":[\"$\",\"h2\",null,{\"style\":\"$b\",\"children\":\"This page could not be found.\"}]}]]}]}]],\"notFoundStyles\":[]}]}]}]],null],null],\"couldBeIntercepted\":false,\"initialHead\":[[\"$\",\"meta\",null,{\"name\":\"robots\",\"content\":\"noindex\"}],\"$Lc\"],\"globalErrorComponent\":\"$d\",\"missingSlots\":\"$We\"}]\n"])</script><script>self.__next_f.push([1,"c:[[\"$\",\"meta\",\"0\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}],[\"$\",\"meta\",\"1\",{\"charSet\":\"utf-8\"}],[\"$\",\"title\",\"2\",{\"children\":\"LiteLLM Dashboard\"}],[\"$\",\"meta\",\"3\",{\"name\":\"description\",\"content\":\"LiteLLM Proxy Admin UI\"}],[\"$\",\"meta\",\"4\",{\"name\":\"next-size-adjust\"}]]\n5:null\n"])</script></body></html>
\ No newline at end of file
diff --git a/litellm/proxy/_experimental/out/model_hub.html b/litellm/proxy/_experimental/out/model_hub.html
deleted file mode 100644
index 8a63b4419fad..000000000000
--- a/litellm/proxy/_experimental/out/model_hub.html
+++ /dev/null
@@ -1 +0,0 @@
-<!DOCTYPE html><html id="__next_error__"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" as="script" fetchPriority="low" href="/ui/_next/static/chunks/webpack-75a5453f51d60261.js"/><script src="/ui/_next/static/chunks/fd9d1056-896c4ac5495ec10d.js" async=""></script><script src="/ui/_next/static/chunks/117-7dac20504d3a26dd.js" async=""></script><script src="/ui/_next/static/chunks/main-app-4f7318ae681a6d94.js" async=""></script><title>LiteLLM Dashboard</title><meta name="description" content="LiteLLM Proxy Admin UI"/><link rel="icon" href="/ui/favicon.ico" type="image/x-icon" sizes="16x16"/><meta name="next-size-adjust"/><script src="/ui/_next/static/chunks/polyfills-42372ed130431b0a.js" noModule=""></script></head><body><script src="/ui/_next/static/chunks/webpack-75a5453f51d60261.js" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0]);self.__next_f.push([2,null])</script><script>self.__next_f.push([1,"1:HL[\"/ui/_next/static/media/a34f9d1faa5f3315-s.p.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n2:HL[\"/ui/_next/static/css/86f6cc749f6b8493.css\",\"style\"]\n3:HL[\"/ui/_next/static/css/08bcb9dd1e7e65fa.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"4:I[12846,[],\"\"]\n6:I[19107,[],\"ClientPageRoot\"]\n7:I[52829,[\"42\",\"static/chunks/42-4c9a56afdf4d8d5b.js\",\"261\",\"static/chunks/261-43203500d1424c9b.js\",\"250\",\"static/chunks/250-d54039b9fc5c0e65.js\",\"699\",\"static/chunks/699-9b535c39d02fc7c5.js\",\"418\",\"static/chunks/app/model_hub/page-3fcdb9cdde4e72fa.js\"],\"default\",1]\n8:I[4707,[],\"\"]\n9:I[36423,[],\"\"]\nb:I[61060,[],\"\"]\nc:[]\n"])</script><script>self.__next_f.push([1,"0:[\"$\",\"$L4\",null,{\"buildId\":\"cqOIY3Hj19kDs5fgiHCMl\",\"assetPrefix\":\"/ui\",\"urlParts\":[\"\",\"model_hub\"],\"initialTree\":[\"\",{\"children\":[\"model_hub\",{\"children\":[\"__PAGE__\",{}]}]},\"$undefined\",\"$undefined\",true],\"initialSeedData\":[\"\",{\"children\":[\"model_hub\",{\"children\":[\"__PAGE__\",{},[[\"$L5\",[\"$\",\"$L6\",null,{\"props\":{\"params\":{},\"searchParams\":{}},\"Component\":\"$7\"}],null],null],null]},[null,[\"$\",\"$L8\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\",\"model_hub\",\"children\"],\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L9\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"notFoundStyles\":\"$undefined\"}]],null]},[[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/ui/_next/static/css/86f6cc749f6b8493.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\"}],[\"$\",\"link\",\"1\",{\"rel\":\"stylesheet\",\"href\":\"/ui/_next/static/css/08bcb9dd1e7e65fa.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"children\":[\"$\",\"body\",null,{\"className\":\"__className_cf7686\",\"children\":[\"$\",\"$L8\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\"],\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L9\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":\"404\"}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],\"notFoundStyles\":[]}]}]}]],null],null],\"couldBeIntercepted\":false,\"initialHead\":[null,\"$La\"],\"globalErrorComponent\":\"$b\",\"missingSlots\":\"$Wc\"}]\n"])</script><script>self.__next_f.push([1,"a:[[\"$\",\"meta\",\"0\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}],[\"$\",\"meta\",\"1\",{\"charSet\":\"utf-8\"}],[\"$\",\"title\",\"2\",{\"children\":\"LiteLLM Dashboard\"}],[\"$\",\"meta\",\"3\",{\"name\":\"description\",\"content\":\"LiteLLM Proxy Admin UI\"}],[\"$\",\"link\",\"4\",{\"rel\":\"icon\",\"href\":\"/ui/favicon.ico\",\"type\":\"image/x-icon\",\"sizes\":\"16x16\"}],[\"$\",\"meta\",\"5\",{\"name\":\"next-size-adjust\"}]]\n5:null\n"])</script></body></html>
\ No newline at end of file
diff --git a/litellm/proxy/_experimental/out/onboarding.html b/litellm/proxy/_experimental/out/onboarding.html
deleted file mode 100644
index 070f19d8e3f5..000000000000
--- a/litellm/proxy/_experimental/out/onboarding.html
+++ /dev/null
@@ -1 +0,0 @@
-<!DOCTYPE html><html id="__next_error__"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" as="script" fetchPriority="low" href="/ui/_next/static/chunks/webpack-75a5453f51d60261.js"/><script src="/ui/_next/static/chunks/fd9d1056-896c4ac5495ec10d.js" async=""></script><script src="/ui/_next/static/chunks/117-7dac20504d3a26dd.js" async=""></script><script src="/ui/_next/static/chunks/main-app-4f7318ae681a6d94.js" async=""></script><title>LiteLLM Dashboard</title><meta name="description" content="LiteLLM Proxy Admin UI"/><link rel="icon" href="/ui/favicon.ico" type="image/x-icon" sizes="16x16"/><meta name="next-size-adjust"/><script src="/ui/_next/static/chunks/polyfills-42372ed130431b0a.js" noModule=""></script></head><body><script src="/ui/_next/static/chunks/webpack-75a5453f51d60261.js" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0]);self.__next_f.push([2,null])</script><script>self.__next_f.push([1,"1:HL[\"/ui/_next/static/media/a34f9d1faa5f3315-s.p.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n2:HL[\"/ui/_next/static/css/86f6cc749f6b8493.css\",\"style\"]\n3:HL[\"/ui/_next/static/css/08bcb9dd1e7e65fa.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"4:I[12846,[],\"\"]\n6:I[19107,[],\"ClientPageRoot\"]\n7:I[12011,[\"665\",\"static/chunks/3014691f-879b58d3fc1547e5.js\",\"42\",\"static/chunks/42-4c9a56afdf4d8d5b.js\",\"755\",\"static/chunks/755-c7e0ae255f32cb18.js\",\"250\",\"static/chunks/250-d54039b9fc5c0e65.js\",\"461\",\"static/chunks/app/onboarding/page-786f929a4f77e0e6.js\"],\"default\",1]\n8:I[4707,[],\"\"]\n9:I[36423,[],\"\"]\nb:I[61060,[],\"\"]\nc:[]\n"])</script><script>self.__next_f.push([1,"0:[\"$\",\"$L4\",null,{\"buildId\":\"cqOIY3Hj19kDs5fgiHCMl\",\"assetPrefix\":\"/ui\",\"urlParts\":[\"\",\"onboarding\"],\"initialTree\":[\"\",{\"children\":[\"onboarding\",{\"children\":[\"__PAGE__\",{}]}]},\"$undefined\",\"$undefined\",true],\"initialSeedData\":[\"\",{\"children\":[\"onboarding\",{\"children\":[\"__PAGE__\",{},[[\"$L5\",[\"$\",\"$L6\",null,{\"props\":{\"params\":{},\"searchParams\":{}},\"Component\":\"$7\"}],null],null],null]},[null,[\"$\",\"$L8\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\",\"onboarding\",\"children\"],\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L9\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"notFoundStyles\":\"$undefined\"}]],null]},[[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/ui/_next/static/css/86f6cc749f6b8493.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\"}],[\"$\",\"link\",\"1\",{\"rel\":\"stylesheet\",\"href\":\"/ui/_next/static/css/08bcb9dd1e7e65fa.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"children\":[\"$\",\"body\",null,{\"className\":\"__className_cf7686\",\"children\":[\"$\",\"$L8\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\"],\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L9\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":\"404\"}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],\"notFoundStyles\":[]}]}]}]],null],null],\"couldBeIntercepted\":false,\"initialHead\":[null,\"$La\"],\"globalErrorComponent\":\"$b\",\"missingSlots\":\"$Wc\"}]\n"])</script><script>self.__next_f.push([1,"a:[[\"$\",\"meta\",\"0\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}],[\"$\",\"meta\",\"1\",{\"charSet\":\"utf-8\"}],[\"$\",\"title\",\"2\",{\"children\":\"LiteLLM Dashboard\"}],[\"$\",\"meta\",\"3\",{\"name\":\"description\",\"content\":\"LiteLLM Proxy Admin UI\"}],[\"$\",\"link\",\"4\",{\"rel\":\"icon\",\"href\":\"/ui/favicon.ico\",\"type\":\"image/x-icon\",\"sizes\":\"16x16\"}],[\"$\",\"meta\",\"5\",{\"name\":\"next-size-adjust\"}]]\n5:null\n"])</script></body></html>
\ No newline at end of file
diff --git a/litellm/proxy/_types.py b/litellm/proxy/_types.py
index d08105988d7a..c5fe5518786d 100644
--- a/litellm/proxy/_types.py
+++ b/litellm/proxy/_types.py
@@ -2101,12 +2101,13 @@ class TeamMemberDeleteRequest(MemberDeleteRequest):
 
 
 class TeamMemberUpdateRequest(TeamMemberDeleteRequest):
-    max_budget_in_team: float
+    max_budget_in_team: Optional[float] = None
+    role: Optional[Literal["admin", "user"]] = None
 
 
 class TeamMemberUpdateResponse(MemberUpdateResponse):
     team_id: str
-    max_budget_in_team: float
+    max_budget_in_team: Optional[float] = None
 
 
 # Organization Member Requests
diff --git a/litellm/proxy/management_endpoints/team_endpoints.py b/litellm/proxy/management_endpoints/team_endpoints.py
index 1d21e315b37a..6ebfed0eef11 100644
--- a/litellm/proxy/management_endpoints/team_endpoints.py
+++ b/litellm/proxy/management_endpoints/team_endpoints.py
@@ -920,7 +920,7 @@ async def team_member_update(
     """
     [BETA]
 
-    Update team member budgets
+    Update team member budgets and team member role
     """
     from litellm.proxy.proxy_server import prisma_client
 
@@ -970,6 +970,8 @@ async def team_member_update(
         user_api_key_dict=user_api_key_dict,
     )
 
+    team_table = returned_team_info["team_info"]
+
     ## get user id
     received_user_id: Optional[str] = None
     if data.user_id is not None:
@@ -995,26 +997,50 @@ async def team_member_update(
             break
 
     ### upsert new budget
-    if identified_budget_id is None:
-        new_budget = await prisma_client.db.litellm_budgettable.create(
-            data={
-                "max_budget": data.max_budget_in_team,
-                "created_by": user_api_key_dict.user_id or "",
-                "updated_by": user_api_key_dict.user_id or "",
-            }
-        )
+    if data.max_budget_in_team is not None:
+        if identified_budget_id is None:
+            new_budget = await prisma_client.db.litellm_budgettable.create(
+                data={
+                    "max_budget": data.max_budget_in_team,
+                    "created_by": user_api_key_dict.user_id or "",
+                    "updated_by": user_api_key_dict.user_id or "",
+                }
+            )
 
-        await prisma_client.db.litellm_teammembership.create(
-            data={
-                "team_id": data.team_id,
-                "user_id": received_user_id,
-                "budget_id": new_budget.budget_id,
-            },
-        )
-    else:
-        await prisma_client.db.litellm_budgettable.update(
-            where={"budget_id": identified_budget_id},
-            data={"max_budget": data.max_budget_in_team},
+            await prisma_client.db.litellm_teammembership.create(
+                data={
+                    "team_id": data.team_id,
+                    "user_id": received_user_id,
+                    "budget_id": new_budget.budget_id,
+                },
+            )
+        elif identified_budget_id is not None:
+            await prisma_client.db.litellm_budgettable.update(
+                where={"budget_id": identified_budget_id},
+                data={"max_budget": data.max_budget_in_team},
+            )
+
+    ### update team member role
+    if data.role is not None:
+        team_members: List[Member] = []
+        for member in team_table.members_with_roles:
+            if member.user_id == received_user_id:
+                team_members.append(
+                    Member(
+                        user_id=member.user_id,
+                        role=data.role,
+                        user_email=data.user_email or member.user_email,
+                    )
+                )
+            else:
+                team_members.append(member)
+
+        team_table.members_with_roles = team_members
+
+        _db_team_members: List[dict] = [m.model_dump() for m in team_members]
+        await prisma_client.db.litellm_teamtable.update(
+            where={"team_id": data.team_id},
+            data={"members_with_roles": json.dumps(_db_team_members)},  # type: ignore
         )
 
     return TeamMemberUpdateResponse(
diff --git a/tests/local_testing/test_basic_python_version.py b/tests/local_testing/test_basic_python_version.py
index 5fa48f09699d..c629ef3df8e9 100644
--- a/tests/local_testing/test_basic_python_version.py
+++ b/tests/local_testing/test_basic_python_version.py
@@ -37,6 +37,51 @@ def test_litellm_proxy_server():
     assert True
 
 
+def test_package_dependencies():
+    try:
+        import tomli
+        import pathlib
+        import litellm
+
+        # Get the litellm package root path
+        litellm_path = pathlib.Path(litellm.__file__).parent.parent
+        pyproject_path = litellm_path / "pyproject.toml"
+
+        # Read and parse pyproject.toml
+        with open(pyproject_path, "rb") as f:
+            pyproject = tomli.load(f)
+
+        # Get all optional dependencies from poetry.dependencies
+        poetry_deps = pyproject["tool"]["poetry"]["dependencies"]
+        optional_deps = {
+            name.lower()
+            for name, value in poetry_deps.items()
+            if isinstance(value, dict) and value.get("optional", False)
+        }
+        print(optional_deps)
+        # Get all packages listed in extras
+        extras = pyproject["tool"]["poetry"]["extras"]
+        all_extra_deps = set()
+        for extra_group in extras.values():
+            all_extra_deps.update(dep.lower() for dep in extra_group)
+        print(all_extra_deps)
+        # Check that all optional dependencies are in some extras group
+        missing_from_extras = optional_deps - all_extra_deps
+        assert (
+            not missing_from_extras
+        ), f"Optional dependencies missing from extras: {missing_from_extras}"
+
+        print(
+            f"All {len(optional_deps)} optional dependencies are correctly specified in extras"
+        )
+
+    except Exception as e:
+        pytest.fail(
+            f"Error occurred while checking dependencies: {str(e)}\n"
+            + traceback.format_exc()
+        )
+
+
 import os
 import subprocess
 import time
diff --git a/ui/litellm-dashboard/src/components/networking.tsx b/ui/litellm-dashboard/src/components/networking.tsx
index 75c50727576c..159bc035d196 100644
--- a/ui/litellm-dashboard/src/components/networking.tsx
+++ b/ui/litellm-dashboard/src/components/networking.tsx
@@ -2321,6 +2321,47 @@ export const teamMemberAddCall = async (
   }
 };
 
+export const teamMemberUpdateCall = async (
+  accessToken: string,
+  teamId: string,
+  formValues: Member // Assuming formValues is an object
+) => {
+  try {
+    console.log("Form Values in teamMemberAddCall:", formValues); // Log the form values before making the API call
+
+    const url = proxyBaseUrl
+      ? `${proxyBaseUrl}/team/member_update`
+      : `/team/member_update`;
+    const response = await fetch(url, {
+      method: "POST",
+      headers: {
+        [globalLitellmHeaderName]: `Bearer ${accessToken}`,
+        "Content-Type": "application/json",
+      },
+      body: JSON.stringify({
+        team_id: teamId,
+        role: formValues.role,  
+        user_id: formValues.user_id,
+      }),
+    });
+
+    if (!response.ok) {
+      const errorData = await response.text();
+      handleError(errorData);
+      console.error("Error response from the server:", errorData);
+      throw new Error("Network response was not ok");
+    }
+
+    const data = await response.json();
+    console.log("API Response:", data);
+    return data;
+    // Handle success - you might want to update some state or UI based on the created key
+  } catch (error) {
+    console.error("Failed to create key:", error);
+    throw error;
+  }
+}
+
 export const organizationMemberAddCall = async (
   accessToken: string,
   organizationId: string,
diff --git a/ui/litellm-dashboard/src/components/teams.tsx b/ui/litellm-dashboard/src/components/teams.tsx
index 8979a96a3b4c..e988b65e3a70 100644
--- a/ui/litellm-dashboard/src/components/teams.tsx
+++ b/ui/litellm-dashboard/src/components/teams.tsx
@@ -2,6 +2,7 @@ import React, { useState, useEffect } from "react";
 import Link from "next/link";
 import { Typography } from "antd";
 import { teamDeleteCall, teamUpdateCall, teamInfoCall } from "./networking";
+import TeamMemberModal, { TeamMember } from "@/components/team/edit_membership";
 import {
   InformationCircleIcon,
   PencilAltIcon,
@@ -65,12 +66,12 @@ interface EditTeamModalProps {
 import {
   teamCreateCall,
   teamMemberAddCall,
+  teamMemberUpdateCall,
   Member,
   modelAvailableCall,
   teamListCall
 } from "./networking";
 
-
 const Team: React.FC<TeamProps> = ({
   teams,
   searchParams,
@@ -112,11 +113,12 @@ const Team: React.FC<TeamProps> = ({
 
   const [isTeamModalVisible, setIsTeamModalVisible] = useState(false);
   const [isAddMemberModalVisible, setIsAddMemberModalVisible] = useState(false);
+  const [isEditMemberModalVisible, setIsEditMemberModalVisible] = useState(false);
   const [userModels, setUserModels] = useState([]);
   const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
   const [teamToDelete, setTeamToDelete] = useState<string | null>(null);
+  const [selectedEditMember, setSelectedEditMember] = useState<null | TeamMember>(null);
 
-  // store team info as {"team_id": team_info_object}
   const [perTeamInfo, setPerTeamInfo] = useState<Record<string, any>>({});
 
   const EditTeamModal: React.FC<EditTeamModalProps> = ({
@@ -257,16 +259,19 @@ const Team: React.FC<TeamProps> = ({
 
   const handleMemberOk = () => {
     setIsAddMemberModalVisible(false);
+    setIsEditMemberModalVisible(false);
     memberForm.resetFields();
   };
 
   const handleCancel = () => {
     setIsTeamModalVisible(false);
+
     form.resetFields();
   };
 
   const handleMemberCancel = () => {
     setIsAddMemberModalVisible(false);
+    setIsEditMemberModalVisible(false);
     memberForm.resetFields();
   };
 
@@ -412,7 +417,7 @@ const Team: React.FC<TeamProps> = ({
     return false;
   }
 
-  const handleMemberCreate = async (formValues: Record<string, any>) => {
+  const _common_member_update_call = async (formValues: Record<string, any>, callType: "add" | "edit") => {
     try {
       if (accessToken != null && teams != null) {
         message.info("Adding Member");
@@ -421,13 +426,27 @@ const Team: React.FC<TeamProps> = ({
           user_email: formValues.user_email,
           user_id: formValues.user_id,
         };
-        const response: any = await teamMemberAddCall(
-          accessToken,
-          selectedTeam["team_id"],
-          user_role
-        );
-        message.success("Member added");
-        console.log(`response for team create call: ${response["data"]}`);
+        let response: any;
+        if (callType == "add") {
+          response = await teamMemberAddCall(
+            accessToken,
+            selectedTeam["team_id"],
+            user_role
+          );
+          message.success("Member added");
+        } else {
+          response = await teamMemberUpdateCall(
+            accessToken,
+            selectedTeam["team_id"],
+            {
+              "role": formValues.role,
+              "user_id": formValues.id,
+              "user_email": formValues.email
+            }
+          );
+          message.success("Member updated");
+        }
+        
         // Checking if the team exists in the list and updating or adding accordingly
         const foundIndex = teams.findIndex((team) => {
           console.log(
@@ -449,7 +468,15 @@ const Team: React.FC<TeamProps> = ({
     } catch (error) {
       console.error("Error creating the team:", error);
     }
+  }
+
+  const handleMemberCreate = async (formValues: Record<string, any>) => {
+    _common_member_update_call(formValues, "add");
   };
+
+  const handleMemberUpdate = async (formValues: Record<string, any>) => {
+    _common_member_update_call(formValues, "edit");
+  }
   return (
     <div className="w-full mx-4">
       <Grid numItems={1} className="gap-2 p-8 h-[75vh] w-full mt-2">
@@ -831,6 +858,29 @@ const Team: React.FC<TeamProps> = ({
                                 : null}
                           </TableCell>
                           <TableCell>{member["role"]}</TableCell>
+                          <TableCell>
+                          {userRole == "Admin" ? (
+                            <>
+                            <Icon
+                              icon={PencilAltIcon}
+                              size="sm"
+                              onClick={() => {
+                                setIsEditMemberModalVisible(true);
+                                setSelectedEditMember({
+                                  "id": member["user_id"],
+                                  "email": member["user_email"],
+                                  "role": member["role"]
+                                })
+                              }}
+                            />
+                            <Icon
+                              onClick={() => {}}
+                              icon={TrashIcon}
+                              size="sm"
+                            />
+                            </>
+                          ) : null}
+                        </TableCell>
                         </TableRow>
                       )
                     )
@@ -838,6 +888,13 @@ const Team: React.FC<TeamProps> = ({
               </TableBody>
             </Table>
           </Card>
+          <TeamMemberModal
+            visible={isEditMemberModalVisible}
+            onCancel={handleMemberCancel}
+            onSubmit={handleMemberUpdate}
+            initialData={selectedEditMember}
+            mode="edit"
+          />
           {selectedTeam && (
             <EditTeamModal
               visible={editModalVisible}
diff --git a/ui/litellm-dashboard/src/components/user_dashboard.tsx b/ui/litellm-dashboard/src/components/user_dashboard.tsx
index cb5055100e93..e00f36023270 100644
--- a/ui/litellm-dashboard/src/components/user_dashboard.tsx
+++ b/ui/litellm-dashboard/src/components/user_dashboard.tsx
@@ -5,6 +5,7 @@ import {
   modelAvailableCall,
   getTotalSpendCall,
   getProxyUISettings,
+  teamListCall,
 } from "./networking";
 import { Grid, Col, Card, Text, Title } from "@tremor/react";
 import CreateKey from "./create_key_button";
@@ -172,6 +173,18 @@ const UserDashboard: React.FC<UserDashboardProps> = ({
       if (cachedUserModels) {
         setUserModels(JSON.parse(cachedUserModels));
       } else {
+        const fetchTeams = async () => {
+          let givenTeams;
+          if (userRole != "Admin" && userRole != "Admin Viewer") {
+            givenTeams = await teamListCall(accessToken, userID)
+          } else {
+            givenTeams = await teamListCall(accessToken)
+          }
+          
+          console.log(`givenTeams: ${givenTeams}`)
+
+          setTeams(givenTeams)
+        }
         const fetchData = async () => {
           try {
             const proxy_settings: ProxySettings = await getProxyUISettings(accessToken);
@@ -193,7 +206,6 @@ const UserDashboard: React.FC<UserDashboardProps> = ({
 
             setUserSpendData(response["user_info"]);
             console.log(`userSpendData: ${JSON.stringify(userSpendData)}`)
-            
             const teamsArray = [...response["teams"]];
             if (teamsArray.length > 0) {
               console.log(`response['teams']: ${JSON.stringify(teamsArray)}`);
@@ -236,6 +248,7 @@ const UserDashboard: React.FC<UserDashboardProps> = ({
           }
         };
         fetchData();
+        fetchTeams();
       }
     }
   }, [userID, token, accessToken, keys, userRole]);
diff --git a/ui/litellm-dashboard/src/components/view_key_table.tsx b/ui/litellm-dashboard/src/components/view_key_table.tsx
index 9cc417601f68..184c817faae2 100644
--- a/ui/litellm-dashboard/src/components/view_key_table.tsx
+++ b/ui/litellm-dashboard/src/components/view_key_table.tsx
@@ -133,6 +133,58 @@ const ViewKeyTable: React.FC<ViewKeyTableProps> = ({
   const [knownTeamIDs, setKnownTeamIDs] = useState(initialKnownTeamIDs);
   const [guardrailsList, setGuardrailsList] = useState<string[]>([]);
 
+  // Function to check if user is admin of a team
+  const isUserTeamAdmin = (team: any) => {
+    if (!team.members_with_roles) return false;
+    return team.members_with_roles.some(
+      (member: any) => member.role === "admin" && member.user_id === userID
+    );
+  };
+
+  // Combine all keys that user should have access to
+  const all_keys_to_display = React.useMemo(() => {
+    let allKeys: any[] = [];
+
+    // If no teams, return personal keys
+    if (!teams || teams.length === 0) {
+      return data;
+    }
+
+    teams.forEach(team => {
+      // For default team or when user is not admin, use personal keys (data)
+      if (team.team_id === "default-team" || !isUserTeamAdmin(team)) {
+        if (selectedTeam && selectedTeam.team_id === team.team_id && data) {
+          allKeys = [...allKeys, ...data.filter(key => key.team_id === team.team_id)];
+        }
+      }
+      // For teams where user is admin, use team keys
+      else if (isUserTeamAdmin(team)) {
+        if (selectedTeam && selectedTeam.team_id === team.team_id) {
+          allKeys = [...allKeys, ...(team.keys || [])];
+        }
+      }
+    });
+
+    // If no team is selected, show all accessible keys
+    if (!selectedTeam && data) {
+      const personalKeys = data.filter(key => !key.team_id || key.team_id === "default-team");
+      const adminTeamKeys = teams
+        .filter(team => isUserTeamAdmin(team))
+        .flatMap(team => team.keys || []);
+      allKeys = [...personalKeys, ...adminTeamKeys];
+    }
+
+    // Filter out litellm-dashboard keys
+    allKeys = allKeys.filter(key => key.team_id !== "litellm-dashboard");
+
+    // Remove duplicates based on token
+    const uniqueKeys = Array.from(
+      new Map(allKeys.map(key => [key.token, key])).values()
+    );
+
+    return uniqueKeys;
+  }, [data, teams, selectedTeam, userID]);
+
   useEffect(() => {
     const calculateNewExpiryTime = (duration: string | undefined) => {
       if (!duration) {
@@ -901,7 +953,7 @@ const ViewKeyTable: React.FC<ViewKeyTableProps> = ({
           </TableRow>
         </TableHead>
         <TableBody>
-          {data.map((item) => {
+          {all_keys_to_display && all_keys_to_display.map((item) => {
             console.log(item);
             // skip item if item.team_id == "litellm-dashboard"
             if (item.team_id === "litellm-dashboard") {