1+ """Custom setup.py for golf-mcp with URL injection."""
2+
3+ from setuptools import setup
4+ from setuptools .command .build_py import build_py as _build_py
5+ from setuptools .command .develop import develop as _develop
6+ import os
7+ import pathlib
8+ import sys
9+
10+ TEMPLATE_REL = "src/golf/_endpoints.py.in"
11+ PACKAGE_OUT_REL = "golf/_endpoints.py"
12+
13+
14+ def render_endpoints (require_env_vars : bool = True ):
15+ """Render the endpoints template with environment variables."""
16+ tpl_path = pathlib .Path (TEMPLATE_REL )
17+ if not tpl_path .exists ():
18+ raise FileNotFoundError (f"Template not found: { tpl_path } " )
19+
20+ # Get environment variables
21+ platform_url = os .environ .get ("GOLF_PLATFORM_API_URL" )
22+ otel_url = os .environ .get ("GOLF_OTEL_ENDPOINT" )
23+
24+ # For production builds, require environment variables
25+ # For development/editable installs, use fallback values
26+ if require_env_vars and (not platform_url or not otel_url ):
27+ raise SystemExit (
28+ "Missing required environment variables for URL injection:\n "
29+ " GOLF_PLATFORM_API_URL\n "
30+ " GOLF_OTEL_ENDPOINT\n "
31+ "Set these before building the package."
32+ )
33+
34+ # Use environment variables if available, otherwise fallback to development URLs
35+ values = {
36+ "PLATFORM_API_URL" : platform_url or "http://localhost:8000/api/resources" ,
37+ "OTEL_ENDPOINT" : otel_url or "http://localhost:4318/v1/traces" ,
38+ }
39+
40+ try :
41+ rendered = tpl_path .read_text (encoding = "utf-8" ).format (** values )
42+ except KeyError as e :
43+ raise SystemExit (f"Missing template key: { e } " ) from e
44+
45+ return rendered
46+
47+
48+ class build_py (_build_py ):
49+ """Custom build_py that renders endpoints into the build_lib (wheel contents)."""
50+
51+ def run (self ):
52+ # First run the normal build
53+ super ().run ()
54+
55+ # Then render endpoints into the build_lib
56+ # Skip env var requirement if in CI environment or if this looks like a test install
57+ is_ci = os .environ .get ("CI" ) or os .environ .get ("GITHUB_ACTIONS" )
58+ rendered = render_endpoints (require_env_vars = not is_ci )
59+ out_file = pathlib .Path (self .build_lib ) / PACKAGE_OUT_REL
60+ out_file .parent .mkdir (parents = True , exist_ok = True )
61+ out_file .write_text (rendered , encoding = "utf-8" )
62+ print (f"Generated { PACKAGE_OUT_REL } with injected URLs" , file = sys .stderr )
63+
64+
65+ class develop (_develop ):
66+ """Custom develop for editable installs - generates endpoints file in source tree."""
67+
68+ def run (self ):
69+ # Run normal develop command first
70+ super ().run ()
71+
72+ # Generate a working copy file for editable installs (use fallback URLs if env vars missing)
73+ rendered = render_endpoints (require_env_vars = False )
74+ # For editable installs, write into the source tree so imports work
75+ src_file = pathlib .Path ("src" ) / PACKAGE_OUT_REL
76+ src_file .parent .mkdir (parents = True , exist_ok = True )
77+ src_file .write_text (rendered , encoding = "utf-8" )
78+ print (f"Generated dev-time { PACKAGE_OUT_REL } in source tree" , file = sys .stderr )
79+ print (f"Note: { src_file } is gitignored and should not be committed" , file = sys .stderr )
80+
81+
82+ setup (
83+ cmdclass = {
84+ "build_py" : build_py ,
85+ "develop" : develop ,
86+ }
87+ )
0 commit comments