Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 30 additions & 1 deletion src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@ def main():
if len(sys.argv) > 1 and sys.argv[1] == "--help":
print("Claude-to-OpenAI API Proxy v1.0.0")
print("")
print("Usage: python start_proxy.py")
print("Usage: python start_proxy.py [--help|--selftest]")
print("")
print(" --selftest Hit /test-connection in-process and exit 0 if it")
print(" succeeds, non-zero otherwise. Intended for CI and")
print(" install scripts.")
print("")
print("Required environment variables:")
print(" OPENAI_API_KEY - Your provider API key")
Expand Down Expand Up @@ -63,6 +67,31 @@ def main():
print(f" Requests with images -> {config.vision_model}")
sys.exit(0)

if len(sys.argv) > 1 and sys.argv[1] == "--selftest":
# In-process smoke test: invoke /test-connection via Starlette's
# TestClient (no uvicorn, no port binding) and exit 0/1 based on
# the result. We deliberately don't enter TestClient as a context
# manager so FastAPI lifespan handlers (which would open the
# observability sqlite database) do not fire.
import json

from fastapi.testclient import TestClient

client = TestClient(app)
response = client.get("/test-connection")
try:
result = response.json()
except ValueError:
print(
f"selftest: non-JSON response (status {response.status_code}): "
f"{response.text}",
file=sys.stderr,
)
sys.exit(2)
json.dump(result, sys.stdout, indent=2)
sys.stdout.write("\n")
sys.exit(0 if result.get("status") == "success" else 1)

# Configuration summary
print("🚀 Claude-to-OpenAI API Proxy v1.0.0")
print(f"✅ Configuration loaded successfully")
Expand Down
Loading