Skip to content

Commit b31e845

Browse files
support for uvicorn factory method creation
1 parent 6e2a84d commit b31e845

File tree

1 file changed

+19
-6
lines changed

1 file changed

+19
-6
lines changed

guardrails_api/app.py

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,16 @@
2020

2121
from starlette.middleware.base import BaseHTTPMiddleware
2222

23+
GR_ENV_FILE = os.environ.get("GR_ENV_FILE", None)
24+
GR_CONFIG_FILE_PATH = os.environ.get("GR_CONFIG_FILE_PATH", None)
25+
PORT = int(os.environ.get("PORT", 8000))
2326

2427
class RequestInfoMiddleware(BaseHTTPMiddleware):
2528
async def dispatch(self, request: Request, call_next):
2629
tracer = trace.get_tracer(__name__)
2730
# Get the current context and attach it to this task
2831
with tracer.start_as_current_span("request_info") as span:
29-
client_ip = request.client.host
32+
client_ip = request.client.host if request.client else None
3033
user_agent = request.headers.get("user-agent", "unknown")
3134
referrer = request.headers.get("referrer", "unknown")
3235
user_id = request.headers.get("x-user-id", "unknown")
@@ -40,13 +43,15 @@ async def dispatch(self, request: Request, call_next):
4043
context.attach(baggage.set_baggage("organization", organization))
4144
context.attach(baggage.set_baggage("app", app))
4245

43-
span.set_attribute("client.ip", client_ip)
4446
span.set_attribute("http.user_agent", user_agent)
4547
span.set_attribute("http.referrer", referrer)
4648
span.set_attribute("user.id", user_id)
4749
span.set_attribute("organization", organization)
4850
span.set_attribute("app", app)
4951

52+
if client_ip:
53+
span.set_attribute("client.ip", client_ip)
54+
5055
response = await call_next(request)
5156
return response
5257

@@ -70,9 +75,13 @@ def register_config(config: Optional[str] = None):
7075
config_module = importlib.util.module_from_spec(spec)
7176
spec.loader.exec_module(config_module)
7277

78+
return config_file_path
7379

80+
# Support for providing env vars as uvicorn does not support supplying args to create_app
81+
# - Usage: uvicorn --factory 'guardrails_api.app:create_app' --host 0.0.0.0 --port $PORT --workers 2 --timeout-keep-alive 90
82+
# - Usage: gunicorn -k uvicorn.workers.UvicornWorker --bind 0.0.0.0:$PORT --timeout=90 --workers=2 "guardrails_api.app:create_app(None, None, $PORT)"
7483
def create_app(
75-
env: Optional[str] = None, config: Optional[str] = None, port: Optional[int] = None
84+
env: Optional[str] = GR_ENV_FILE, config: Optional[str] = GR_CONFIG_FILE_PATH, port: Optional[int] = PORT
7685
):
7786
trace_server_start_if_enabled()
7887
# used to print user-facing messages during server startup
@@ -89,12 +98,12 @@ def create_app(
8998
env_file_path = os.path.abspath(env)
9099
load_dotenv(env_file_path, override=True)
91100

92-
set_port = port or os.environ.get("PORT", 8000)
101+
set_port = port or PORT
93102
host = os.environ.get("HOST", "http://localhost")
94103
self_endpoint = os.environ.get("SELF_ENDPOINT", f"{host}:{set_port}")
95104
os.environ["SELF_ENDPOINT"] = self_endpoint
96105

97-
register_config(config)
106+
resolved_config_file_path = register_config(config)
98107

99108
app = FastAPI(openapi_url="")
100109

@@ -159,6 +168,10 @@ async def value_error_handler(request: Request, exc: ValueError):
159168
)
160169

161170
console.print("")
171+
console.print("Using the following configuration:")
172+
console.print(f"- Guardrails Log Level: {guardrails_log_level}")
173+
console.print(f"- Self Endpoint: {self_endpoint}")
174+
console.print(f"- Config File Path: {resolved_config_file_path} [Provided: {config}]")
162175
console.print(
163176
Rule("[bold grey]Server Logs[/bold grey]", characters="=", style="white")
164177
)
@@ -170,4 +183,4 @@ async def value_error_handler(request: Request, exc: ValueError):
170183
import uvicorn
171184

172185
app = create_app()
173-
uvicorn.run(app, host="0.0.0.0", port=8000)
186+
uvicorn.run(app, host="0.0.0.0", port=PORT)

0 commit comments

Comments
 (0)