gitarsenal-cli 1.1.18 → 1.1.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gitarsenal-cli",
3
- "version": "1.1.18",
3
+ "version": "1.1.20",
4
4
  "description": "CLI tool for creating Modal sandboxes with GitHub repositories",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -0,0 +1,77 @@
1
+ # Modal Token Solution
2
+
3
+ This directory contains several scripts to solve the Modal token authentication issue. The problem occurs when Modal cannot find or validate the authentication token, resulting in errors like "Token missing" or "Could not authenticate client".
4
+
5
+ ## Overview of the Solution
6
+
7
+ We've implemented a comprehensive solution that uses multiple approaches to ensure Modal can authenticate properly:
8
+
9
+ 1. **fetch_modal_tokens.py**: Fetches tokens from the proxy server.
10
+ 2. **modal_token_solution.py**: The main comprehensive solution that combines all approaches.
11
+ 3. **modal_auth_patch.py**: A direct patch for Modal's authentication system.
12
+ 4. **fix_modal_token.py**: A basic token setup script.
13
+ 5. **fix_modal_token_advanced.py**: An advanced version with more approaches.
14
+
15
+ ## How It Works
16
+
17
+ Our solution uses multiple approaches to ensure Modal authentication works:
18
+
19
+ 1. **Token Fetching**: Tries to fetch tokens from the proxy server.
20
+ 2. **Environment Variables**: Sets `MODAL_TOKEN_ID` and `MODAL_TOKEN_SECRET` environment variables.
21
+ 3. **Token Files**: Creates token files in various formats and locations that Modal might look for.
22
+ 4. **Modal CLI**: Attempts to use the Modal CLI to set the token with the correct profile.
23
+ 5. **Direct Patching**: Directly patches Modal's authentication system to always return our tokens.
24
+ 6. **Monkey Patching**: Monkey-patches Modal's import system to inject our tokens.
25
+ 7. **Authentication Testing**: Tests that the authentication works by creating a simple Modal app.
26
+
27
+ ## Usage
28
+
29
+ The scripts are used in this order of preference:
30
+
31
+ 1. First, try `modal_token_solution.py` (most comprehensive)
32
+ 2. If that fails, fall back to `modal_auth_patch.py`
33
+ 3. If that fails, fall back to `fix_modal_token.py`
34
+
35
+ In most cases, you should simply import `modal_token_solution` before importing Modal:
36
+
37
+ ```python
38
+ import modal_token_solution
39
+ import modal
40
+
41
+ # Now Modal will use our tokens
42
+ ```
43
+
44
+ ## Proxy Server Integration
45
+
46
+ The solution now integrates with the proxy server to fetch tokens:
47
+
48
+ 1. **fetch_modal_tokens.py**: This script fetches tokens from the proxy server using the `MODAL_PROXY_URL` and `MODAL_PROXY_API_KEY` environment variables.
49
+ 2. If the proxy server is not available, it falls back to hardcoded tokens.
50
+ 3. All other scripts try to use the fetch_modal_tokens module first before falling back to hardcoded tokens.
51
+
52
+ ## Troubleshooting
53
+
54
+ If you still encounter token issues:
55
+
56
+ 1. Check that the tokens are correct (token ID: `ak-sLhYqCjkvixiYcb9LAuCHp`, token secret: `as-fPzD0Zm0dl6IFAEkhaH9pq`).
57
+ 2. Verify that the token files are created in the correct locations:
58
+ - `~/.modal/token.json`
59
+ - `~/.modalconfig`
60
+ 3. Check if the proxy server is accessible and returning valid tokens.
61
+ 4. Try running the scripts manually to see detailed output.
62
+
63
+ ## Implementation Details
64
+
65
+ - **Token Values**: We try to fetch tokens from the proxy server, with fallback to hardcoded values.
66
+ - **File Locations**: Token files are created in the user's home directory under `~/.modal/`.
67
+ - **Patching**: We use Python's dynamic nature to patch Modal's authentication system at runtime.
68
+ - **Profile**: We use the `fr8mafia` profile when setting tokens via the CLI.
69
+
70
+ ## Files
71
+
72
+ - **fetch_modal_tokens.py**: Fetches tokens from the proxy server.
73
+ - **modal_token_solution.py**: Comprehensive solution combining all approaches.
74
+ - **modal_auth_patch.py**: Direct patch for Modal's authentication system.
75
+ - **fix_modal_token.py**: Basic token setup script.
76
+ - **fix_modal_token_advanced.py**: Advanced version with more approaches.
77
+ - **test_modal_auth.py**: Test script for Modal authentication.
File without changes
@@ -0,0 +1,108 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Fetch Modal Tokens
4
+
5
+ This script fetches Modal tokens from the proxy server.
6
+ """
7
+
8
+ import os
9
+ import sys
10
+ import json
11
+ import requests
12
+ from pathlib import Path
13
+
14
+ # Default tokens to use if we can't fetch from the server
15
+ DEFAULT_TOKEN_ID = "ak-sLhYqCjkvixiYcb9LAuCHp"
16
+ DEFAULT_TOKEN_SECRET = "as-fPzD0Zm0dl6IFAEkhaH9pq"
17
+
18
+ def fetch_tokens_from_proxy(proxy_url=None, api_key=None):
19
+ """
20
+ Fetch Modal tokens from the proxy server.
21
+
22
+ Args:
23
+ proxy_url: URL of the proxy server
24
+ api_key: API key for authentication
25
+
26
+ Returns:
27
+ tuple: (token_id, token_secret) if successful, (None, None) otherwise
28
+ """
29
+ # Use environment variables if not provided
30
+ if not proxy_url:
31
+ proxy_url = os.environ.get("MODAL_PROXY_URL")
32
+
33
+ if not api_key:
34
+ api_key = os.environ.get("MODAL_PROXY_API_KEY")
35
+
36
+ # Check if we have the necessary information
37
+ if not proxy_url:
38
+ print("❌ No proxy URL provided or found in environment")
39
+ return None, None
40
+
41
+ if not api_key:
42
+ print("❌ No API key provided or found in environment")
43
+ return None, None
44
+
45
+ # Ensure the URL ends with a slash
46
+ if not proxy_url.endswith("/"):
47
+ proxy_url += "/"
48
+
49
+ # Add the endpoint for fetching tokens
50
+ token_url = f"{proxy_url}api/modal-tokens"
51
+
52
+ try:
53
+ # Make the request
54
+ print(f"🔄 Fetching tokens from {token_url}")
55
+ response = requests.get(
56
+ token_url,
57
+ headers={"X-API-Key": api_key}
58
+ )
59
+
60
+ # Check if the request was successful
61
+ if response.status_code == 200:
62
+ data = response.json()
63
+ token_id = data.get("token_id")
64
+ token_secret = data.get("token_secret")
65
+
66
+ if token_id and token_secret:
67
+ print("✅ Successfully fetched tokens from proxy server")
68
+ return token_id, token_secret
69
+ else:
70
+ print("❌ Tokens not found in response")
71
+ return None, None
72
+ else:
73
+ print(f"❌ Failed to fetch tokens: {response.status_code} - {response.text}")
74
+ return None, None
75
+ except Exception as e:
76
+ print(f"❌ Error fetching tokens: {e}")
77
+ return None, None
78
+
79
+ def get_tokens():
80
+ """
81
+ Get Modal tokens, trying to fetch from the proxy server first.
82
+
83
+ Returns:
84
+ tuple: (token_id, token_secret)
85
+ """
86
+ # Try to fetch from the proxy server
87
+ token_id, token_secret = fetch_tokens_from_proxy()
88
+
89
+ # If we couldn't fetch from the server, use the default tokens
90
+ if not token_id or not token_secret:
91
+ print("⚠️ Using default tokens")
92
+ return DEFAULT_TOKEN_ID, DEFAULT_TOKEN_SECRET
93
+
94
+ return token_id, token_secret
95
+
96
+ if __name__ == "__main__":
97
+ token_id, token_secret = get_tokens()
98
+ print(f"Token ID: {token_id}")
99
+ print(f"Token Secret: {token_secret}")
100
+
101
+ # Write the tokens to a file for use by other scripts
102
+ tokens_file = Path(__file__).parent / "modal_tokens.json"
103
+ with open(tokens_file, 'w') as f:
104
+ json.dump({
105
+ "token_id": token_id,
106
+ "token_secret": token_secret
107
+ }, f)
108
+ print(f"✅ Tokens written to {tokens_file}")
@@ -0,0 +1,75 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Fix Modal Token
4
+
5
+ This script tries different approaches to fix the Modal token issue.
6
+ """
7
+
8
+ import os
9
+ import sys
10
+ import subprocess
11
+ from pathlib import Path
12
+
13
+ # Just run the advanced token fixer
14
+ try:
15
+ # Get the directory of this script
16
+ script_dir = Path(__file__).parent.absolute()
17
+
18
+ # Path to the advanced fixer
19
+ advanced_fixer = script_dir / "fix_modal_token_advanced.py"
20
+
21
+ # Check if the advanced fixer exists
22
+ if advanced_fixer.exists():
23
+ print(f"🔄 Running advanced Modal token fixer: {advanced_fixer}")
24
+
25
+ # Execute the advanced fixer
26
+ result = subprocess.run(
27
+ ["python", str(advanced_fixer)],
28
+ check=True # Raise an exception if the command fails
29
+ )
30
+
31
+ # Exit with the same code as the advanced fixer
32
+ sys.exit(result.returncode)
33
+ else:
34
+ print(f"❌ Advanced Modal token fixer not found at {advanced_fixer}")
35
+ # Fall back to the basic implementation
36
+ print("🔄 Falling back to basic implementation")
37
+ except Exception as e:
38
+ print(f"❌ Error running advanced Modal token fixer: {e}")
39
+ print("🔄 Falling back to basic implementation")
40
+
41
+ # Try to get tokens from the proxy server
42
+ try:
43
+ # First, try to import the fetch_modal_tokens module
44
+ from fetch_modal_tokens import get_tokens
45
+ TOKEN_ID, TOKEN_SECRET = get_tokens()
46
+ print(f"✅ Using tokens from proxy server or defaults")
47
+ except ImportError:
48
+ # If the module is not available, use hardcoded tokens
49
+ TOKEN_ID = "ak-sLhYqCjkvixiYcb9LAuCHp"
50
+ TOKEN_SECRET = "as-fPzD0Zm0dl6IFAEkhaH9pq" # Real token secret from fr8mafia profile
51
+ print(f"⚠️ Using hardcoded tokens")
52
+
53
+ print("🔧 Fixing Modal token (basic implementation)...")
54
+
55
+ # Set environment variables
56
+ os.environ["MODAL_TOKEN_ID"] = TOKEN_ID
57
+ os.environ["MODAL_TOKEN_SECRET"] = TOKEN_SECRET
58
+ print(f"✅ Set MODAL_TOKEN_ID and MODAL_TOKEN_SECRET environment variables")
59
+
60
+ # Create token file
61
+ modal_dir = Path.home() / ".modal"
62
+ modal_dir.mkdir(exist_ok=True)
63
+ token_file = modal_dir / "token.json"
64
+ with open(token_file, 'w') as f:
65
+ f.write(f'{{"token_id": "{TOKEN_ID}", "token_secret": "{TOKEN_SECRET}"}}')
66
+ print(f"✅ Created token file at {token_file}")
67
+
68
+ # Create .modalconfig file
69
+ modalconfig_file = Path.home() / ".modalconfig"
70
+ with open(modalconfig_file, 'w') as f:
71
+ f.write(f"token_id = {TOKEN_ID}\n")
72
+ f.write(f"token_secret = {TOKEN_SECRET}\n")
73
+ print(f"✅ Created .modalconfig file at {modalconfig_file}")
74
+
75
+ print("\n✅ Done fixing Modal token. Please try your command again.")
@@ -0,0 +1,228 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Advanced Modal Token Fixer
4
+
5
+ This script tries multiple approaches to fix Modal token issues, including:
6
+ 1. Setting environment variables
7
+ 2. Creating token files in various formats
8
+ 3. Using Modal CLI
9
+ 4. Directly modifying Modal's internal configuration
10
+ 5. Monkey-patching Modal's authentication system
11
+ """
12
+
13
+ import os
14
+ import sys
15
+ import json
16
+ import subprocess
17
+ import importlib
18
+ import inspect
19
+ from pathlib import Path
20
+ import time
21
+
22
+ # Try to get tokens from the proxy server
23
+ try:
24
+ # First, try to import the fetch_modal_tokens module
25
+ from fetch_modal_tokens import get_tokens
26
+ TOKEN_ID, TOKEN_SECRET = get_tokens()
27
+ print(f"✅ Using tokens from proxy server or defaults")
28
+ except ImportError:
29
+ # If the module is not available, use hardcoded tokens
30
+ TOKEN_ID = "ak-sLhYqCjkvixiYcb9LAuCHp"
31
+ TOKEN_SECRET = "as-fPzD0Zm0dl6IFAEkhaH9pq" # Real token secret from fr8mafia profile
32
+ print(f"⚠️ Using hardcoded tokens")
33
+
34
+ print("🔧 Advanced Modal Token Fixer")
35
+
36
+ # Approach 1: Set environment variables
37
+ print("\n📋 Approach 1: Setting environment variables")
38
+ os.environ["MODAL_TOKEN_ID"] = TOKEN_ID
39
+ os.environ["MODAL_TOKEN_SECRET"] = TOKEN_SECRET
40
+ print(f"✅ Set MODAL_TOKEN_ID = {TOKEN_ID}")
41
+ print(f"✅ Set MODAL_TOKEN_SECRET = {TOKEN_SECRET}")
42
+
43
+ # Approach 2: Create token files in various formats
44
+ print("\n📋 Approach 2: Creating token files in various formats")
45
+ modal_dir = Path.home() / ".modal"
46
+ modal_dir.mkdir(exist_ok=True)
47
+
48
+ # Format 1: Standard token.json
49
+ token_file = modal_dir / "token.json"
50
+ with open(token_file, 'w') as f:
51
+ token_data = {
52
+ "token_id": TOKEN_ID,
53
+ "token_secret": TOKEN_SECRET
54
+ }
55
+ json.dump(token_data, f)
56
+ print(f"✅ Created token file at {token_file}")
57
+
58
+ # Format 2: Alternative token.json format
59
+ token_file_alt = modal_dir / "token_alt.json"
60
+ with open(token_file_alt, 'w') as f:
61
+ token_data_alt = {
62
+ "id": TOKEN_ID,
63
+ "secret": TOKEN_SECRET
64
+ }
65
+ json.dump(token_data_alt, f)
66
+ print(f"✅ Created alternative token file at {token_file_alt}")
67
+
68
+ # Format 3: Create .modalconfig file
69
+ modalconfig_file = Path.home() / ".modalconfig"
70
+ with open(modalconfig_file, 'w') as f:
71
+ f.write(f"token_id = {TOKEN_ID}\n")
72
+ f.write(f"token_secret = {TOKEN_SECRET}\n")
73
+ print(f"✅ Created .modalconfig file at {modalconfig_file}")
74
+
75
+ # Format 4: Create config.json file
76
+ config_file = modal_dir / "config.json"
77
+ with open(config_file, 'w') as f:
78
+ config_data = {
79
+ "token_id": TOKEN_ID,
80
+ "token_secret": TOKEN_SECRET
81
+ }
82
+ json.dump(config_data, f)
83
+ print(f"✅ Created config.json file at {config_file}")
84
+
85
+ # Approach 3: Use Modal CLI to set token
86
+ print("\n📋 Approach 3: Using Modal CLI")
87
+ try:
88
+ # Use the CLI to set the token directly
89
+ result = subprocess.run(
90
+ ["modal", "token", "set", "--token-id", TOKEN_ID, "--token-secret", TOKEN_SECRET, "--profile=fr8mafia", "--no-verify"],
91
+ capture_output=True, text=True
92
+ )
93
+
94
+ if result.returncode == 0:
95
+ print(f"✅ Successfully set token via Modal CLI")
96
+ else:
97
+ print(f"❌ Failed to set token via Modal CLI: {result.stderr}")
98
+ except Exception as e:
99
+ print(f"❌ Error using Modal CLI: {e}")
100
+
101
+ # Approach 4: Use Modal Python API to set token
102
+ print("\n📋 Approach 4: Using Modal Python API")
103
+ try:
104
+ import modal
105
+ print(f"✅ Successfully imported Modal")
106
+
107
+ # Try to set token directly in Modal's config
108
+ try:
109
+ import modal.config
110
+
111
+ # Try different approaches to set the token
112
+ try:
113
+ # Approach 4.1: Set token via _auth_config
114
+ if hasattr(modal.config, '_auth_config'):
115
+ modal.config._auth_config.token_id = TOKEN_ID
116
+ modal.config._auth_config.token_secret = TOKEN_SECRET
117
+ print(f"✅ Set tokens via _auth_config")
118
+ except Exception as e:
119
+ print(f"❌ Error setting tokens via _auth_config: {e}")
120
+
121
+ try:
122
+ # Approach 4.2: Set token via set_token() if it exists
123
+ if hasattr(modal.config, 'set_token'):
124
+ modal.config.set_token(TOKEN_ID, TOKEN_SECRET)
125
+ print(f"✅ Set tokens via set_token()")
126
+ except Exception as e:
127
+ print(f"❌ Error setting tokens via set_token(): {e}")
128
+
129
+ try:
130
+ # Approach 4.3: Set token via Config
131
+ if hasattr(modal.config, 'Config'):
132
+ modal.config.Config.token_id = TOKEN_ID
133
+ modal.config.Config.token_secret = TOKEN_SECRET
134
+ print(f"✅ Set tokens via Config")
135
+ except Exception as e:
136
+ print(f"❌ Error setting tokens via Config: {e}")
137
+
138
+ # Approach 4.4: Inspect modal.config and try to find token-related attributes
139
+ print("\n🔍 Inspecting modal.config for token-related attributes...")
140
+ for name in dir(modal.config):
141
+ if "token" in name.lower() or "auth" in name.lower():
142
+ print(f"Found potential token-related attribute: {name}")
143
+ try:
144
+ attr = getattr(modal.config, name)
145
+ if hasattr(attr, "token_id"):
146
+ print(f" - Setting token_id in {name}")
147
+ setattr(attr, "token_id", TOKEN_ID)
148
+ if hasattr(attr, "token_secret"):
149
+ print(f" - Setting token_secret in {name}")
150
+ setattr(attr, "token_secret", TOKEN_SECRET)
151
+ except Exception as e:
152
+ print(f" - Error setting tokens in {name}: {e}")
153
+ except Exception as e:
154
+ print(f"❌ Error setting tokens in Modal config: {e}")
155
+ except Exception as e:
156
+ print(f"❌ Error importing Modal: {e}")
157
+
158
+ # Approach 5: Monkey-patch Modal's authentication system
159
+ print("\n📋 Approach 5: Monkey-patching Modal's authentication system")
160
+ try:
161
+ import modal
162
+
163
+ # Define functions that will always return our tokens
164
+ def get_token_id(*args, **kwargs):
165
+ return TOKEN_ID
166
+
167
+ def get_token_secret(*args, **kwargs):
168
+ return TOKEN_SECRET
169
+
170
+ # Find all authentication-related classes and functions
171
+ auth_related = []
172
+ for module_name in dir(modal):
173
+ if "auth" in module_name.lower() or "token" in module_name.lower() or "config" in module_name.lower():
174
+ try:
175
+ module = getattr(modal, module_name)
176
+ auth_related.append((module_name, module))
177
+ print(f"Found potential auth-related module: {module_name}")
178
+ except Exception:
179
+ pass
180
+
181
+ # Try to monkey-patch auth functions to always return valid credentials
182
+ for name, module in auth_related:
183
+ if inspect.ismodule(module):
184
+ for func_name in dir(module):
185
+ if "get" in func_name.lower():
186
+ if "token_id" in func_name.lower():
187
+ try:
188
+ original_func = getattr(module, func_name)
189
+ if callable(original_func):
190
+ print(f" - Patching {name}.{func_name} to return token_id")
191
+ setattr(module, func_name, get_token_id)
192
+ except Exception as e:
193
+ print(f" - Error patching {name}.{func_name}: {e}")
194
+ elif "token_secret" in func_name.lower() or "token" in func_name.lower():
195
+ try:
196
+ original_func = getattr(module, func_name)
197
+ if callable(original_func):
198
+ print(f" - Patching {name}.{func_name} to return token_secret")
199
+ setattr(module, func_name, get_token_secret)
200
+ except Exception as e:
201
+ print(f" - Error patching {name}.{func_name}: {e}")
202
+ except Exception as e:
203
+ print(f"❌ Error monkey-patching Modal: {e}")
204
+
205
+ # Approach 6: Create a test Modal app to verify token
206
+ print("\n📋 Approach 6: Testing Modal authentication")
207
+ try:
208
+ import modal
209
+
210
+ print("Creating a test Modal app...")
211
+ app = modal.App("test-auth")
212
+
213
+ @app.function()
214
+ def hello():
215
+ return "Hello, world!"
216
+
217
+ print("Running the test function...")
218
+ try:
219
+ with app.run():
220
+ result = hello.remote()
221
+ print(f"✅ Successfully ran Modal function: {result}")
222
+ print("🎉 Modal authentication is working!")
223
+ except Exception as e:
224
+ print(f"❌ Error running Modal function: {e}")
225
+ except Exception as e:
226
+ print(f"❌ Error testing Modal authentication: {e}")
227
+
228
+ print("\n✅ Done fixing Modal token. Please try your command again.")
File without changes
@@ -0,0 +1,180 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Modal Authentication Patcher
4
+
5
+ This script directly patches Modal's authentication system to always return our token.
6
+ It should be imported before any Modal code is used.
7
+
8
+ Usage:
9
+ import modal_auth_patch
10
+ import modal
11
+ # Now Modal will use our token
12
+ """
13
+
14
+ import os
15
+ import sys
16
+ import importlib
17
+ import types
18
+ import json
19
+ from pathlib import Path
20
+
21
+ # Try to get tokens from the proxy server
22
+ try:
23
+ # First, try to import the fetch_modal_tokens module
24
+ from fetch_modal_tokens import get_tokens
25
+ TOKEN_ID, TOKEN_SECRET = get_tokens()
26
+ print(f"✅ Using tokens from proxy server or defaults")
27
+ except ImportError:
28
+ # If the module is not available, use hardcoded tokens
29
+ TOKEN_ID = "ak-sLhYqCjkvixiYcb9LAuCHp"
30
+ TOKEN_SECRET = "as-fPzD0Zm0dl6IFAEkhaH9pq" # Real token secret from fr8mafia profile
31
+ print(f"⚠️ Using hardcoded tokens")
32
+
33
+ # Set environment variables
34
+ os.environ["MODAL_TOKEN_ID"] = TOKEN_ID
35
+ os.environ["MODAL_TOKEN_SECRET"] = TOKEN_SECRET
36
+
37
+ # Create token files
38
+ modal_dir = Path.home() / ".modal"
39
+ modal_dir.mkdir(exist_ok=True)
40
+ token_file = modal_dir / "token.json"
41
+ with open(token_file, 'w') as f:
42
+ f.write(f'{{"token_id": "{TOKEN_ID}", "token_secret": "{TOKEN_SECRET}"}}')
43
+
44
+ modalconfig_file = Path.home() / ".modalconfig"
45
+ with open(modalconfig_file, 'w') as f:
46
+ f.write(f"token_id = {TOKEN_ID}\n")
47
+ f.write(f"token_secret = {TOKEN_SECRET}\n")
48
+
49
+ # Define functions that will always return our tokens
50
+ def get_token_id(*args, **kwargs):
51
+ return TOKEN_ID
52
+
53
+ def get_token_secret(*args, **kwargs):
54
+ return TOKEN_SECRET
55
+
56
+ # Patch Modal's authentication system
57
+ try:
58
+ # Try to import modal.config
59
+ import modal.config
60
+
61
+ # Create a fake auth config object
62
+ class FakeAuthConfig:
63
+ token_id = TOKEN_ID
64
+ token_secret = TOKEN_SECRET
65
+
66
+ def get_token_id(self, *args, **kwargs):
67
+ return TOKEN_ID
68
+
69
+ def get_token_secret(self, *args, **kwargs):
70
+ return TOKEN_SECRET
71
+
72
+ # Replace Modal's auth config with our fake one
73
+ modal.config._auth_config = FakeAuthConfig()
74
+
75
+ # Also patch any token-related functions
76
+ for name in dir(modal.config):
77
+ if "token_id" in name.lower():
78
+ try:
79
+ attr = getattr(modal.config, name)
80
+ if callable(attr):
81
+ setattr(modal.config, name, get_token_id)
82
+ except:
83
+ pass
84
+ elif "token_secret" in name.lower() or "token" in name.lower():
85
+ try:
86
+ attr = getattr(modal.config, name)
87
+ if callable(attr):
88
+ setattr(modal.config, name, get_token_secret)
89
+ except:
90
+ pass
91
+
92
+ print("✅ Modal authentication patched successfully")
93
+ except ImportError:
94
+ # Modal not installed yet, we'll monkey-patch it when it's imported
95
+ print("⚠️ Modal not installed yet, setting up import hook")
96
+
97
+ # Original import function
98
+ original_import = __import__
99
+
100
+ # Our custom import function
101
+ def custom_import(name, globals=None, locals=None, fromlist=(), level=0):
102
+ # Call the original import function
103
+ module = original_import(name, globals, locals, fromlist, level)
104
+
105
+ # Check if this is modal or a submodule
106
+ if name == "modal" or name.startswith("modal."):
107
+ try:
108
+ # Try to patch modal.config
109
+ if hasattr(module, "config"):
110
+ config = module.config
111
+
112
+ # Create a fake auth config object if needed
113
+ if not hasattr(config, "_auth_config"):
114
+ class FakeAuthConfig:
115
+ token_id = TOKEN_ID
116
+ token_secret = TOKEN_SECRET
117
+
118
+ def get_token_id(self, *args, **kwargs):
119
+ return TOKEN_ID
120
+
121
+ def get_token_secret(self, *args, **kwargs):
122
+ return TOKEN_SECRET
123
+
124
+ config._auth_config = FakeAuthConfig()
125
+ else:
126
+ # Patch existing auth config
127
+ config._auth_config.token_id = TOKEN_ID
128
+ config._auth_config.token_secret = TOKEN_SECRET
129
+
130
+ # Patch methods
131
+ if hasattr(config._auth_config, "get_token_id"):
132
+ config._auth_config.get_token_id = get_token_id
133
+ if hasattr(config._auth_config, "get_token_secret"):
134
+ config._auth_config.get_token_secret = get_token_secret
135
+
136
+ # Also patch any token-related functions
137
+ for name in dir(config):
138
+ if "token_id" in name.lower():
139
+ try:
140
+ attr = getattr(config, name)
141
+ if callable(attr):
142
+ setattr(config, name, get_token_id)
143
+ except:
144
+ pass
145
+ elif "token_secret" in name.lower() or "token" in name.lower():
146
+ try:
147
+ attr = getattr(config, name)
148
+ if callable(attr):
149
+ setattr(config, name, get_token_secret)
150
+ except:
151
+ pass
152
+
153
+ print("✅ Modal authentication patched during import")
154
+ except Exception as e:
155
+ print(f"⚠️ Error patching Modal: {e}")
156
+
157
+ return module
158
+
159
+ # Replace the built-in import function
160
+ sys.modules["builtins"].__import__ = custom_import
161
+
162
+ print("✅ Modal authentication patch installed")
163
+
164
+ # Test the patch if Modal is already imported
165
+ try:
166
+ import modal
167
+ print("Testing Modal authentication patch...")
168
+
169
+ # Create a simple app
170
+ app = modal.App("test-auth-patch")
171
+
172
+ @app.function()
173
+ def hello():
174
+ return "Hello from patched Modal!"
175
+
176
+ print("✅ Modal app created successfully")
177
+ except ImportError:
178
+ print("⚠️ Modal not installed, patch will be applied when it's imported")
179
+ except Exception as e:
180
+ print(f"❌ Error testing Modal patch: {e}")