diff --git a/.circleci/config.yml b/.circleci/config.yml index e0e6f5743..64eef5dea 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -156,6 +156,7 @@ jobs: --config /app/config.yaml \ --port 4000 \ --num_workers 8 \ + --run_gunicorn \ --debug - run: name: Install curl and dockerize diff --git a/Dockerfile b/Dockerfile index e18d5d979..0de52b8e7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -52,4 +52,4 @@ RUN chmod +x entrypoint.sh EXPOSE 4000/tcp ENTRYPOINT ["litellm"] -CMD ["--port", "4000", "--config", "./proxy_server_config.yaml", "--detailed_debug"] \ No newline at end of file +CMD ["--port", "4000", "--config", "./proxy_server_config.yaml", "--detailed_debug", "--run_gunicorn"] \ No newline at end of file diff --git a/Dockerfile.database b/Dockerfile.database index 5c0c4ad36..9e9fb7fc4 100644 --- a/Dockerfile.database +++ b/Dockerfile.database @@ -56,4 +56,4 @@ EXPOSE 4000/tcp # # Set your entrypoint and command ENTRYPOINT ["litellm"] -CMD ["--port", "4000"] +CMD ["--port", "4000", "--run_gunicorn"] diff --git a/litellm/proxy/proxy_cli.py b/litellm/proxy/proxy_cli.py index 6583dbed1..82bdbd625 100644 --- a/litellm/proxy/proxy_cli.py +++ b/litellm/proxy/proxy_cli.py @@ -157,6 +157,12 @@ def is_port_in_use(port): type=int, help="Number of requests to hit async endpoint with", ) +@click.option( + "--run_gunicorn", + default=False, + is_flag=True, + help="Starts proxy via gunicorn, instead of uvicorn (better for managing multiple workers)", +) @click.option("--local", is_flag=True, default=False, help="for local debugging") def run_server( host, @@ -186,6 +192,7 @@ def run_server( use_queue, health, version, + run_gunicorn, ): global feature_telemetry args = locals() @@ -439,9 +446,9 @@ def run_server( port = random.randint(1024, 49152) from litellm.proxy.proxy_server import app - if os.name == "nt": + if run_gunicorn == False: uvicorn.run(app, host=host, port=port) # run uvicorn - else: + elif run_gunicorn == True: import gunicorn.app.base # Gunicorn Application Class diff --git a/litellm/proxy/proxy_server.py b/litellm/proxy/proxy_server.py index d9944e6e1..56958c50c 100644 --- a/litellm/proxy/proxy_server.py +++ b/litellm/proxy/proxy_server.py @@ -245,8 +245,6 @@ async def user_api_key_auth( response = await user_custom_auth(request=request, api_key=api_key) return UserAPIKeyAuth.model_validate(response) ### LITELLM-DEFINED AUTH FUNCTION ### - if isinstance(api_key, str): - assert api_key.startswith("sk-") # prevent token hashes from being used if master_key is None: if isinstance(api_key, str): return UserAPIKeyAuth(api_key=api_key) @@ -283,6 +281,10 @@ async def user_api_key_auth( if is_master_key_valid: return UserAPIKeyAuth(api_key=master_key) + if isinstance( + api_key, str + ): # if generated token, make sure it starts with sk-. + assert api_key.startswith("sk-") # prevent token hashes from being used if route.startswith("/config/") and not is_master_key_valid: raise Exception(f"Only admin can modify config")