1010from golf .auth .providers import AuthConfig
1111
1212
13+ def _config_has_callables (config : AuthConfig ) -> bool :
14+ """Check if an auth config has any callable fields that can't be serialized.
15+
16+ Callable fields (like allowed_redirect_patterns_func) cannot be embedded
17+ in generated code using repr(), so configs with callables need to use
18+ runtime config loading instead.
19+ """
20+ # Check for OAuthProxyConfig callable fields
21+ callable_fields = [
22+ "allowed_redirect_patterns_func" ,
23+ "allowed_redirect_schemes_func" ,
24+ "redirect_uri_validator" ,
25+ ]
26+
27+ for field_name in callable_fields :
28+ if hasattr (config , field_name ) and getattr (config , field_name ) is not None :
29+ return True
30+
31+ return False
32+
33+
1334def generate_auth_code (
1435 server_name : str ,
1536 host : str = "localhost" ,
@@ -47,29 +68,60 @@ def generate_auth_code(
4768 "Please update your auth.py file."
4869 )
4970
50- # Generate modern auth components with embedded configuration
51- auth_imports = [
52- "import os" ,
53- "import sys" ,
54- "from golf.auth.factory import create_auth_provider" ,
55- "from golf.auth.providers import RemoteAuthConfig, JWTAuthConfig, StaticTokenConfig, OAuthServerConfig, OAuthProxyConfig" ,
56- ]
71+ # Check if the auth config has callable fields (can't be embedded with repr)
72+ has_callable_fields = _config_has_callables (auth_config )
5773
58- # Embed the auth configuration directly in the generated code
59- # Convert the auth config to its string representation for embedding
60- auth_config_repr = repr (auth_config )
74+ if has_callable_fields :
75+ # For configs with callables, import and use auth module at runtime
76+ # auth.py is copied to dist and imported to register the config
77+ auth_imports = [
78+ "import os" ,
79+ "import sys" ,
80+ "from golf.auth import get_auth_config" ,
81+ "from golf.auth.factory import create_auth_provider" ,
82+ "# Import auth module to execute configure_*() and register auth config" ,
83+ "import auth # noqa: F401 - executes auth.py to register config" ,
84+ ]
6185
62- setup_code_lines = [
63- "# Modern FastMCP 2.11+ authentication setup with embedded configuration" ,
64- f"auth_config = { auth_config_repr } " ,
65- "try:" ,
66- " auth_provider = create_auth_provider(auth_config)" ,
67- " # Authentication configured with {auth_config.provider_type} provider" ,
68- "except Exception as e:" ,
69- " print(f'Authentication setup failed: {e}', file=sys.stderr)" ,
70- " auth_provider = None" ,
71- "" ,
72- ]
86+ setup_code_lines = [
87+ "# Modern FastMCP 2.11+ authentication setup (runtime config with callables)" ,
88+ "# Auth config registered by auth.py import above" ,
89+ "auth_config = get_auth_config()" ,
90+ "try:" ,
91+ " auth_provider = create_auth_provider(auth_config)" ,
92+ f" # Authentication configured with { auth_config .provider_type } provider" ,
93+ "except Exception as e:" ,
94+ " print(f'Authentication setup failed: {{e}}', file=sys.stderr)" ,
95+ " auth_provider = None" ,
96+ "" ,
97+ ]
98+ else :
99+ # For configs without callables, embed the configuration directly
100+ auth_imports = [
101+ "import os" ,
102+ "import sys" ,
103+ "from golf.auth.factory import create_auth_provider" ,
104+ "from golf.auth.providers import (" ,
105+ " RemoteAuthConfig, JWTAuthConfig, StaticTokenConfig," ,
106+ " OAuthServerConfig, OAuthProxyConfig," ,
107+ ")" ,
108+ ]
109+
110+ # Embed the auth configuration directly in the generated code
111+ # Convert the auth config to its string representation for embedding
112+ auth_config_repr = repr (auth_config )
113+
114+ setup_code_lines = [
115+ "# Modern FastMCP 2.11+ authentication setup with embedded configuration" ,
116+ f"auth_config = { auth_config_repr } " ,
117+ "try:" ,
118+ " auth_provider = create_auth_provider(auth_config)" ,
119+ f" # Authentication configured with { auth_config .provider_type } provider" ,
120+ "except Exception as e:" ,
121+ " print(f'Authentication setup failed: {{e}}', file=sys.stderr)" ,
122+ " auth_provider = None" ,
123+ "" ,
124+ ]
73125
74126 # FastMCP constructor arguments - FastMCP 2.11+ uses auth parameter
75127 fastmcp_args = {"auth" : "auth_provider" }
@@ -79,6 +131,7 @@ def generate_auth_code(
79131 "setup_code" : setup_code_lines ,
80132 "fastmcp_args" : fastmcp_args ,
81133 "has_auth" : True ,
134+ "copy_auth_file" : has_callable_fields , # Copy auth.py to dist for runtime loading
82135 }
83136
84137
0 commit comments