gitarsenal-cli 1.9.21 → 1.9.24
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/.venv_status.json +1 -1
- package/package.json +1 -1
- package/python/__pycache__/auth_manager.cpython-313.pyc +0 -0
- package/python/__pycache__/command_manager.cpython-313.pyc +0 -0
- package/python/__pycache__/fetch_modal_tokens.cpython-313.pyc +0 -0
- package/python/__pycache__/llm_debugging.cpython-313.pyc +0 -0
- package/python/__pycache__/modal_container.cpython-313.pyc +0 -0
- package/python/__pycache__/shell.cpython-313.pyc +0 -0
- package/python/api_integration.py +0 -0
- package/python/command_manager.py +613 -0
- package/python/credentials_manager.py +0 -0
- package/python/fetch_modal_tokens.py +0 -0
- package/python/fix_modal_token.py +0 -0
- package/python/fix_modal_token_advanced.py +0 -0
- package/python/gitarsenal.py +0 -0
- package/python/gitarsenal_proxy_client.py +0 -0
- package/python/llm_debugging.py +1369 -0
- package/python/modal_container.py +626 -0
- package/python/setup.py +15 -0
- package/python/setup_modal_token.py +0 -39
- package/python/shell.py +627 -0
- package/python/test_modalSandboxScript.py +75 -2639
- package/scripts/postinstall.js +22 -23
- package/python/__pycache__/credentials_manager.cpython-313.pyc +0 -0
- package/python/__pycache__/test_modalSandboxScript.cpython-313.pyc +0 -0
- package/python/__pycache__/test_modalSandboxScript_stable.cpython-313.pyc +0 -0
- package/python/debug_delete.py +0 -167
- package/python/documentation.py +0 -76
- package/python/fix_setup_commands.py +0 -116
- package/python/modal_auth_patch.py +0 -178
- package/python/modal_proxy_service.py +0 -665
- package/python/modal_token_solution.py +0 -293
- package/python/test_dynamic_commands.py +0 -147
- package/test_modalSandboxScript.py +0 -5004
package/scripts/postinstall.js
CHANGED
|
@@ -293,29 +293,28 @@ async function postinstall() {
|
|
|
293
293
|
}
|
|
294
294
|
}
|
|
295
295
|
|
|
296
|
-
//
|
|
297
|
-
if (!scriptFound
|
|
298
|
-
|
|
299
|
-
await fs.
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
break;
|
|
296
|
+
// Only try to copy if the script doesn't exist or is minimal
|
|
297
|
+
if (!scriptFound) {
|
|
298
|
+
// Check if the original script exists in a different location
|
|
299
|
+
if (await fs.pathExists(originalScriptPath)) {
|
|
300
|
+
console.log(chalk.green('✅ Found original Python script in mcp-server'));
|
|
301
|
+
await fs.copy(originalScriptPath, pythonScriptPath);
|
|
302
|
+
scriptFound = true;
|
|
303
|
+
} else {
|
|
304
|
+
// Try to find the script in common locations
|
|
305
|
+
console.log(chalk.yellow('⚠️ Original script not found in expected location. Searching for alternatives...'));
|
|
306
|
+
|
|
307
|
+
const possibleLocations = [
|
|
308
|
+
path.join(process.cwd(), 'python', 'test_modalSandboxScript.py'),
|
|
309
|
+
];
|
|
310
|
+
|
|
311
|
+
for (const location of possibleLocations) {
|
|
312
|
+
if (await fs.pathExists(location) && location !== pythonScriptPath) {
|
|
313
|
+
console.log(chalk.green(`✅ Found Python script at ${location}`));
|
|
314
|
+
await fs.copy(location, pythonScriptPath);
|
|
315
|
+
scriptFound = true;
|
|
316
|
+
break;
|
|
317
|
+
}
|
|
319
318
|
}
|
|
320
319
|
}
|
|
321
320
|
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/python/debug_delete.py
DELETED
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""
|
|
3
|
-
Debug script for GitArsenal Keys delete functionality
|
|
4
|
-
"""
|
|
5
|
-
|
|
6
|
-
import sys
|
|
7
|
-
import os
|
|
8
|
-
from pathlib import Path
|
|
9
|
-
|
|
10
|
-
# Add the current directory to the path
|
|
11
|
-
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
|
12
|
-
|
|
13
|
-
from credentials_manager import CredentialsManager
|
|
14
|
-
from gitarsenal_keys import handle_delete
|
|
15
|
-
|
|
16
|
-
def test_delete_functionality():
|
|
17
|
-
"""Test the delete functionality step by step"""
|
|
18
|
-
print("🔍 Debugging GitArsenal Keys Delete Functionality")
|
|
19
|
-
print("=" * 60)
|
|
20
|
-
|
|
21
|
-
# Initialize credentials manager
|
|
22
|
-
credentials_manager = CredentialsManager()
|
|
23
|
-
|
|
24
|
-
print(f"📁 Credentials file: {credentials_manager.credentials_file}")
|
|
25
|
-
print(f"📁 Config directory: {credentials_manager.config_dir}")
|
|
26
|
-
|
|
27
|
-
# Check if credentials file exists
|
|
28
|
-
if credentials_manager.credentials_file.exists():
|
|
29
|
-
print("✅ Credentials file exists")
|
|
30
|
-
else:
|
|
31
|
-
print("❌ Credentials file does not exist")
|
|
32
|
-
return
|
|
33
|
-
|
|
34
|
-
# Load current credentials
|
|
35
|
-
credentials = credentials_manager.load_credentials()
|
|
36
|
-
print(f"📋 Current credentials: {list(credentials.keys())}")
|
|
37
|
-
|
|
38
|
-
# Test different service mappings
|
|
39
|
-
test_services = ['openai', 'wandb', 'huggingface', 'gitarsenal-openai', 'claude']
|
|
40
|
-
|
|
41
|
-
for service in test_services:
|
|
42
|
-
print(f"\n🔍 Testing service: {service}")
|
|
43
|
-
|
|
44
|
-
# Generate credential key from service name
|
|
45
|
-
credential_key = f"{service.replace('-', '_')}_api_key"
|
|
46
|
-
|
|
47
|
-
# Special mappings for backward compatibility
|
|
48
|
-
special_mappings = {
|
|
49
|
-
'openai': 'openai_api_key',
|
|
50
|
-
'wandb': 'wandb_api_key',
|
|
51
|
-
'huggingface': 'huggingface_token',
|
|
52
|
-
'gitarsenal-openai': 'gitarsenal_openai_api_key'
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
# Use special mapping if it exists, otherwise use generated key
|
|
56
|
-
credential_key = special_mappings.get(service, credential_key)
|
|
57
|
-
|
|
58
|
-
print(f" Service: {service}")
|
|
59
|
-
print(f" Generated key: {service.replace('-', '_')}_api_key")
|
|
60
|
-
print(f" Final key: {credential_key}")
|
|
61
|
-
print(f" Exists in credentials: {credential_key in credentials}")
|
|
62
|
-
|
|
63
|
-
if credential_key in credentials:
|
|
64
|
-
print(f" Current value: {credentials[credential_key][:8]}...")
|
|
65
|
-
|
|
66
|
-
# Test the clear_credential method directly
|
|
67
|
-
print(f"\n🧪 Testing clear_credential method directly")
|
|
68
|
-
|
|
69
|
-
# Try to delete a key that exists
|
|
70
|
-
existing_keys = list(credentials.keys())
|
|
71
|
-
if existing_keys:
|
|
72
|
-
test_key = existing_keys[0]
|
|
73
|
-
print(f" Testing deletion of: {test_key}")
|
|
74
|
-
|
|
75
|
-
# Check if key exists before deletion
|
|
76
|
-
before_delete = test_key in credentials
|
|
77
|
-
print(f" Key exists before deletion: {before_delete}")
|
|
78
|
-
|
|
79
|
-
# Delete the key
|
|
80
|
-
success = credentials_manager.clear_credential(test_key)
|
|
81
|
-
print(f" Deletion success: {success}")
|
|
82
|
-
|
|
83
|
-
# Check if key exists after deletion
|
|
84
|
-
credentials_after = credentials_manager.load_credentials()
|
|
85
|
-
after_delete = test_key in credentials_after
|
|
86
|
-
print(f" Key exists after deletion: {after_delete}")
|
|
87
|
-
|
|
88
|
-
# Restore the key for testing
|
|
89
|
-
if not after_delete and before_delete:
|
|
90
|
-
credentials_after[test_key] = credentials[test_key]
|
|
91
|
-
credentials_manager.save_credentials(credentials_after)
|
|
92
|
-
print(f" ✅ Key restored for further testing")
|
|
93
|
-
|
|
94
|
-
# Test with a non-existent key
|
|
95
|
-
print(f"\n🧪 Testing deletion of non-existent key")
|
|
96
|
-
fake_key = "fake_api_key_12345"
|
|
97
|
-
success = credentials_manager.clear_credential(fake_key)
|
|
98
|
-
print(f" Deletion of non-existent key success: {success}")
|
|
99
|
-
|
|
100
|
-
print(f"\n✅ Debug test completed!")
|
|
101
|
-
|
|
102
|
-
def test_delete_command():
|
|
103
|
-
"""Test the delete command with mock arguments"""
|
|
104
|
-
print(f"\n🔧 Testing delete command with mock arguments")
|
|
105
|
-
print("=" * 60)
|
|
106
|
-
|
|
107
|
-
from gitarsenal_keys import handle_delete
|
|
108
|
-
import argparse
|
|
109
|
-
|
|
110
|
-
# Create mock arguments
|
|
111
|
-
class MockArgs:
|
|
112
|
-
def __init__(self, service):
|
|
113
|
-
self.service = service
|
|
114
|
-
|
|
115
|
-
# Test with different services
|
|
116
|
-
test_services = ['openai', 'wandb', 'huggingface']
|
|
117
|
-
|
|
118
|
-
for service in test_services:
|
|
119
|
-
print(f"\n🔍 Testing delete command for: {service}")
|
|
120
|
-
|
|
121
|
-
try:
|
|
122
|
-
args = MockArgs(service)
|
|
123
|
-
handle_delete(None, args) # This will fail because we need a real credentials manager
|
|
124
|
-
except Exception as e:
|
|
125
|
-
print(f" Error: {e}")
|
|
126
|
-
|
|
127
|
-
print(f"\n✅ Delete command test completed!")
|
|
128
|
-
|
|
129
|
-
def show_usage_examples():
|
|
130
|
-
"""Show how to use the delete command"""
|
|
131
|
-
print(f"\n📋 Usage Examples")
|
|
132
|
-
print("=" * 60)
|
|
133
|
-
|
|
134
|
-
print("To delete an API key:")
|
|
135
|
-
print(" python gitarsenal_keys.py delete --service openai")
|
|
136
|
-
print(" python gitarsenal_keys.py delete --service wandb")
|
|
137
|
-
print(" python gitarsenal_keys.py delete --service huggingface")
|
|
138
|
-
print(" python gitarsenal_keys.py delete --service gitarsenal-openai")
|
|
139
|
-
|
|
140
|
-
print("\nTo list all stored keys:")
|
|
141
|
-
print(" python gitarsenal_keys.py list")
|
|
142
|
-
|
|
143
|
-
print("\nTo view a specific key (masked):")
|
|
144
|
-
print(" python gitarsenal_keys.py view --service openai")
|
|
145
|
-
|
|
146
|
-
print("\nTo add a new key:")
|
|
147
|
-
print(" python gitarsenal_keys.py add --service openai --key sk-...")
|
|
148
|
-
print(" python gitarsenal_keys.py add --service openai # Interactive mode")
|
|
149
|
-
|
|
150
|
-
if __name__ == "__main__":
|
|
151
|
-
print("GitArsenal Keys Delete Debug Tool")
|
|
152
|
-
print("=" * 60)
|
|
153
|
-
|
|
154
|
-
try:
|
|
155
|
-
test_delete_functionality()
|
|
156
|
-
test_delete_command()
|
|
157
|
-
show_usage_examples()
|
|
158
|
-
|
|
159
|
-
print(f"\n🎉 Debug completed!")
|
|
160
|
-
print(f"\nTo test the actual delete command:")
|
|
161
|
-
print(f" python gitarsenal_keys.py delete --service openai")
|
|
162
|
-
|
|
163
|
-
except Exception as e:
|
|
164
|
-
print(f"\n❌ Debug failed with error: {e}")
|
|
165
|
-
import traceback
|
|
166
|
-
traceback.print_exc()
|
|
167
|
-
sys.exit(1)
|
package/python/documentation.py
DELETED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
def show_usage_examples():
|
|
2
|
-
"""Display usage examples for the script."""
|
|
3
|
-
print("Usage Examples\n")
|
|
4
|
-
|
|
5
|
-
print("🔐 Authentication Commands")
|
|
6
|
-
print("┌────────────────────────────────────────────────────────────────────────────────────┐")
|
|
7
|
-
print("│ gitarsenal --register # Register new account │")
|
|
8
|
-
print("│ gitarsenal --login # Login to existing account │")
|
|
9
|
-
print("│ gitarsenal --logout # Logout from account │")
|
|
10
|
-
print("│ gitarsenal --user-info # Show current user information │")
|
|
11
|
-
print("│ gitarsenal --change-password # Change password │")
|
|
12
|
-
print("│ gitarsenal --delete-account # Delete account │")
|
|
13
|
-
print("│ gitarsenal --store-api-key openai # Store OpenAI API key │")
|
|
14
|
-
print("│ gitarsenal --auth # Interactive auth management │")
|
|
15
|
-
print("└────────────────────────────────────────────────────────────────────────────────────┘\n")
|
|
16
|
-
|
|
17
|
-
print("Basic Container Creation")
|
|
18
|
-
print("┌────────────────────────────────────────────────────────────────────────┐")
|
|
19
|
-
print("│ gitarsenal --gpu A10G --repo-url https://github.com/username/repo.git │")
|
|
20
|
-
print("└────────────────────────────────────────────────────────────────────────┘\n")
|
|
21
|
-
|
|
22
|
-
print("With Setup Commands")
|
|
23
|
-
print("┌────────────────────────────────────────────────────────────────────────────────────────────────────┐")
|
|
24
|
-
print("│ gitarsenal --gpu A100 --repo-url https://github.com/username/repo.git \\ │")
|
|
25
|
-
print("│ --setup-commands \"pip install -r requirements.txt\" \"python setup.py install\" │")
|
|
26
|
-
print("└────────────────────────────────────────────────────────────────────────────────────────────────────┘\n")
|
|
27
|
-
|
|
28
|
-
print("With Persistent Storage")
|
|
29
|
-
print("┌────────────────────────────────────────────────────────────────────────────────────┐")
|
|
30
|
-
print("│ gitarsenal --gpu A10G --repo-url https://github.com/username/repo.git \\ │")
|
|
31
|
-
print("│ --volume-name my-persistent-volume │")
|
|
32
|
-
print("└────────────────────────────────────────────────────────────────────────────────────┘\n")
|
|
33
|
-
|
|
34
|
-
print("With GitIngest API (default)")
|
|
35
|
-
print("┌────────────────────────────────────────────────────────────────────────────────────┐")
|
|
36
|
-
print("│ gitarsenal --gpu A10G --repo-url https://github.com/username/repo.git │")
|
|
37
|
-
print("└────────────────────────────────────────────────────────────────────────────────────┘\n")
|
|
38
|
-
|
|
39
|
-
print("Without GitIngest API")
|
|
40
|
-
print("┌────────────────────────────────────────────────────────────────────────────────────┐")
|
|
41
|
-
print("│ gitarsenal --gpu A10G --repo-url https://github.com/username/repo.git \\ │")
|
|
42
|
-
print("│ --no-gitingest │")
|
|
43
|
-
print("└────────────────────────────────────────────────────────────────────────────────────┘\n")
|
|
44
|
-
|
|
45
|
-
print("With Original API")
|
|
46
|
-
print("┌────────────────────────────────────────────────────────────────────────────────────┐")
|
|
47
|
-
print("│ gitarsenal --gpu A10G --repo-url https://github.com/username/repo.git \\ │")
|
|
48
|
-
print("│ --use-api │")
|
|
49
|
-
print("└────────────────────────────────────────────────────────────────────────────────────┘\n")
|
|
50
|
-
|
|
51
|
-
print("Development Mode (Skip Authentication)")
|
|
52
|
-
print("┌────────────────────────────────────────────────────────────────────────────────────┐")
|
|
53
|
-
print("│ gitarsenal --skip-auth --gpu A10G --repo-url https://github.com/username/repo.git │")
|
|
54
|
-
print("└────────────────────────────────────────────────────────────────────────────────────┘\n")
|
|
55
|
-
|
|
56
|
-
print("Available GPU Options:")
|
|
57
|
-
print(" T4, L4, A10G, A100-40GB, A100-80GB, L40S, H100, H200, B200")
|
|
58
|
-
print()
|
|
59
|
-
print("Authentication Behavior:")
|
|
60
|
-
print(" • First time: Interactive registration/login required")
|
|
61
|
-
print(" • Subsequent runs: Automatic login with stored session")
|
|
62
|
-
print(" • Use --skip-auth for development (bypasses auth)")
|
|
63
|
-
print()
|
|
64
|
-
print("GPU Selection Behavior:")
|
|
65
|
-
print(" • With --gpu: Uses specified GPU without prompting")
|
|
66
|
-
print(" • Without --gpu: Shows interactive GPU selection menu")
|
|
67
|
-
print()
|
|
68
|
-
print("Examples:")
|
|
69
|
-
print(" # First time setup (will prompt for registration):")
|
|
70
|
-
print(" gitarsenal --gpu A10G --repo-url https://github.com/username/repo.git")
|
|
71
|
-
print()
|
|
72
|
-
print(" # Subsequent runs (automatic login):")
|
|
73
|
-
print(" gitarsenal --repo-url https://github.com/username/repo.git")
|
|
74
|
-
print()
|
|
75
|
-
print(" # Development mode (skip authentication):")
|
|
76
|
-
print(" gitarsenal --skip-auth --repo-url https://github.com/username/repo.git")
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""
|
|
3
|
-
Fix setup commands for open-r1 repository
|
|
4
|
-
"""
|
|
5
|
-
|
|
6
|
-
import os
|
|
7
|
-
import sys
|
|
8
|
-
import subprocess
|
|
9
|
-
|
|
10
|
-
# Original problematic commands
|
|
11
|
-
original_commands = [
|
|
12
|
-
"git clone https://github.com/huggingface/open-r1.git",
|
|
13
|
-
"cd open-r1",
|
|
14
|
-
"uv venv openr1 --python 3.11 && source openr1/bin/activate && uv pip install --upgrade pip",
|
|
15
|
-
"uv pip install vllm==0.8.5.post1",
|
|
16
|
-
"uv pip install setuptools && uv pip install flash-attn --no-build-isolation"
|
|
17
|
-
]
|
|
18
|
-
|
|
19
|
-
# Fixed commands
|
|
20
|
-
fixed_commands = [
|
|
21
|
-
"git clone https://github.com/huggingface/open-r1.git",
|
|
22
|
-
"cd open-r1",
|
|
23
|
-
"uv venv openr1 --python 3.11 && . openr1/bin/activate && uv pip install --upgrade pip",
|
|
24
|
-
". openr1/bin/activate && uv pip install vllm==0.8.5.post1",
|
|
25
|
-
". openr1/bin/activate && uv pip install setuptools && uv pip install flash-attn --no-build-isolation"
|
|
26
|
-
]
|
|
27
|
-
|
|
28
|
-
def run_command(cmd, cwd=None):
|
|
29
|
-
"""Run a command and return the result"""
|
|
30
|
-
print(f"\n▶ {cmd}")
|
|
31
|
-
|
|
32
|
-
try:
|
|
33
|
-
result = subprocess.run(
|
|
34
|
-
cmd,
|
|
35
|
-
shell=True,
|
|
36
|
-
text=True,
|
|
37
|
-
capture_output=True,
|
|
38
|
-
cwd=cwd
|
|
39
|
-
)
|
|
40
|
-
|
|
41
|
-
# Print output
|
|
42
|
-
if result.stdout:
|
|
43
|
-
print(result.stdout)
|
|
44
|
-
|
|
45
|
-
# Print error
|
|
46
|
-
if result.stderr:
|
|
47
|
-
print(f"Error: {result.stderr}")
|
|
48
|
-
|
|
49
|
-
# Return success/failure
|
|
50
|
-
return result.returncode == 0, result.stdout, result.stderr
|
|
51
|
-
except Exception as e:
|
|
52
|
-
print(f"Error executing command: {e}")
|
|
53
|
-
return False, "", str(e)
|
|
54
|
-
|
|
55
|
-
def main():
|
|
56
|
-
"""Main function"""
|
|
57
|
-
print("🔧 Fixing setup commands for open-r1 repository")
|
|
58
|
-
|
|
59
|
-
# Check if we're in the right directory
|
|
60
|
-
cwd = os.getcwd()
|
|
61
|
-
print(f"📂 Current directory: {cwd}")
|
|
62
|
-
|
|
63
|
-
# Check if we need to change directory
|
|
64
|
-
if not cwd.endswith('open-r1'):
|
|
65
|
-
parent_dir = cwd
|
|
66
|
-
# Check if open-r1 exists in the current directory
|
|
67
|
-
if os.path.exists(os.path.join(cwd, 'open-r1')):
|
|
68
|
-
print(f"📂 Found open-r1 directory, changing to it")
|
|
69
|
-
os.chdir(os.path.join(cwd, 'open-r1'))
|
|
70
|
-
cwd = os.getcwd()
|
|
71
|
-
print(f"📂 New current directory: {cwd}")
|
|
72
|
-
|
|
73
|
-
# Run the fixed commands
|
|
74
|
-
for i, cmd in enumerate(fixed_commands):
|
|
75
|
-
print(f"\n📋 Running command {i+1}/{len(fixed_commands)}: {cmd}")
|
|
76
|
-
|
|
77
|
-
# Skip git clone if the directory already exists
|
|
78
|
-
if cmd.startswith("git clone") and os.path.exists("open-r1"):
|
|
79
|
-
print("✅ Repository already cloned, skipping")
|
|
80
|
-
continue
|
|
81
|
-
|
|
82
|
-
# Skip cd if we're already in the right directory
|
|
83
|
-
if cmd.startswith("cd "):
|
|
84
|
-
target_dir = cmd.split(" ", 1)[1]
|
|
85
|
-
if cwd.endswith(target_dir):
|
|
86
|
-
print(f"✅ Already in {target_dir}, skipping")
|
|
87
|
-
continue
|
|
88
|
-
|
|
89
|
-
# Run the command
|
|
90
|
-
success, stdout, stderr = run_command(cmd)
|
|
91
|
-
|
|
92
|
-
# Check if the command succeeded
|
|
93
|
-
if not success:
|
|
94
|
-
print(f"❌ Command failed: {cmd}")
|
|
95
|
-
print(f"❌ Error: {stderr}")
|
|
96
|
-
|
|
97
|
-
# If this is a cd command, try to continue
|
|
98
|
-
if cmd.startswith("cd "):
|
|
99
|
-
print("⚠️ Directory change failed, but continuing with next command")
|
|
100
|
-
continue
|
|
101
|
-
|
|
102
|
-
# For other commands, ask if the user wants to continue
|
|
103
|
-
try:
|
|
104
|
-
choice = input("Continue with next command? (y/n): ").strip().lower()
|
|
105
|
-
if choice != 'y':
|
|
106
|
-
print("🛑 Stopping execution")
|
|
107
|
-
return 1
|
|
108
|
-
except:
|
|
109
|
-
print("🛑 Stopping execution due to error")
|
|
110
|
-
return 1
|
|
111
|
-
|
|
112
|
-
print("\n✅ All commands executed")
|
|
113
|
-
return 0
|
|
114
|
-
|
|
115
|
-
if __name__ == "__main__":
|
|
116
|
-
sys.exit(main())
|
|
@@ -1,178 +0,0 @@
|
|
|
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
|
-
# print(f"⚠️ Using default tokens")
|
|
30
|
-
|
|
31
|
-
# Set environment variables
|
|
32
|
-
os.environ["MODAL_TOKEN_ID"] = TOKEN_ID
|
|
33
|
-
os.environ["MODAL_TOKEN_SECRET"] = TOKEN_SECRET
|
|
34
|
-
|
|
35
|
-
# Create token files
|
|
36
|
-
modal_dir = Path.home() / ".modal"
|
|
37
|
-
modal_dir.mkdir(exist_ok=True)
|
|
38
|
-
token_file = modal_dir / "token.json"
|
|
39
|
-
with open(token_file, 'w') as f:
|
|
40
|
-
f.write(f'{{"token_id": "{TOKEN_ID}", "token_secret": "{TOKEN_SECRET}"}}')
|
|
41
|
-
|
|
42
|
-
modalconfig_file = Path.home() / ".modalconfig"
|
|
43
|
-
with open(modalconfig_file, 'w') as f:
|
|
44
|
-
f.write(f"token_id = {TOKEN_ID}\n")
|
|
45
|
-
f.write(f"token_secret = {TOKEN_SECRET}\n")
|
|
46
|
-
|
|
47
|
-
# Define functions that will always return our tokens
|
|
48
|
-
def get_token_id(*args, **kwargs):
|
|
49
|
-
return TOKEN_ID
|
|
50
|
-
|
|
51
|
-
def get_token_secret(*args, **kwargs):
|
|
52
|
-
return TOKEN_SECRET
|
|
53
|
-
|
|
54
|
-
# Patch Modal's authentication system
|
|
55
|
-
try:
|
|
56
|
-
# Try to import modal.config
|
|
57
|
-
import modal.config
|
|
58
|
-
|
|
59
|
-
# Create a fake auth config object
|
|
60
|
-
class FakeAuthConfig:
|
|
61
|
-
token_id = TOKEN_ID
|
|
62
|
-
token_secret = TOKEN_SECRET
|
|
63
|
-
|
|
64
|
-
def get_token_id(self, *args, **kwargs):
|
|
65
|
-
return TOKEN_ID
|
|
66
|
-
|
|
67
|
-
def get_token_secret(self, *args, **kwargs):
|
|
68
|
-
return TOKEN_SECRET
|
|
69
|
-
|
|
70
|
-
# Replace Modal's auth config with our fake one
|
|
71
|
-
modal.config._auth_config = FakeAuthConfig()
|
|
72
|
-
|
|
73
|
-
# Also patch any token-related functions
|
|
74
|
-
for name in dir(modal.config):
|
|
75
|
-
if "token_id" in name.lower():
|
|
76
|
-
try:
|
|
77
|
-
attr = getattr(modal.config, name)
|
|
78
|
-
if callable(attr):
|
|
79
|
-
setattr(modal.config, name, get_token_id)
|
|
80
|
-
except:
|
|
81
|
-
pass
|
|
82
|
-
elif "token_secret" in name.lower() or "token" in name.lower():
|
|
83
|
-
try:
|
|
84
|
-
attr = getattr(modal.config, name)
|
|
85
|
-
if callable(attr):
|
|
86
|
-
setattr(modal.config, name, get_token_secret)
|
|
87
|
-
except:
|
|
88
|
-
pass
|
|
89
|
-
|
|
90
|
-
print("✅ Modal authentication patched successfully")
|
|
91
|
-
except ImportError:
|
|
92
|
-
# Modal not installed yet, we'll monkey-patch it when it's imported
|
|
93
|
-
print("⚠️ Modal not installed yet, setting up import hook")
|
|
94
|
-
|
|
95
|
-
# Original import function
|
|
96
|
-
original_import = __import__
|
|
97
|
-
|
|
98
|
-
# Our custom import function
|
|
99
|
-
def custom_import(name, globals=None, locals=None, fromlist=(), level=0):
|
|
100
|
-
# Call the original import function
|
|
101
|
-
module = original_import(name, globals, locals, fromlist, level)
|
|
102
|
-
|
|
103
|
-
# Check if this is modal or a submodule
|
|
104
|
-
if name == "modal" or name.startswith("modal."):
|
|
105
|
-
try:
|
|
106
|
-
# Try to patch modal.config
|
|
107
|
-
if hasattr(module, "config"):
|
|
108
|
-
config = module.config
|
|
109
|
-
|
|
110
|
-
# Create a fake auth config object if needed
|
|
111
|
-
if not hasattr(config, "_auth_config"):
|
|
112
|
-
class FakeAuthConfig:
|
|
113
|
-
token_id = TOKEN_ID
|
|
114
|
-
token_secret = TOKEN_SECRET
|
|
115
|
-
|
|
116
|
-
def get_token_id(self, *args, **kwargs):
|
|
117
|
-
return TOKEN_ID
|
|
118
|
-
|
|
119
|
-
def get_token_secret(self, *args, **kwargs):
|
|
120
|
-
return TOKEN_SECRET
|
|
121
|
-
|
|
122
|
-
config._auth_config = FakeAuthConfig()
|
|
123
|
-
else:
|
|
124
|
-
# Patch existing auth config
|
|
125
|
-
config._auth_config.token_id = TOKEN_ID
|
|
126
|
-
config._auth_config.token_secret = TOKEN_SECRET
|
|
127
|
-
|
|
128
|
-
# Patch methods
|
|
129
|
-
if hasattr(config._auth_config, "get_token_id"):
|
|
130
|
-
config._auth_config.get_token_id = get_token_id
|
|
131
|
-
if hasattr(config._auth_config, "get_token_secret"):
|
|
132
|
-
config._auth_config.get_token_secret = get_token_secret
|
|
133
|
-
|
|
134
|
-
# Also patch any token-related functions
|
|
135
|
-
for name in dir(config):
|
|
136
|
-
if "token_id" in name.lower():
|
|
137
|
-
try:
|
|
138
|
-
attr = getattr(config, name)
|
|
139
|
-
if callable(attr):
|
|
140
|
-
setattr(config, name, get_token_id)
|
|
141
|
-
except:
|
|
142
|
-
pass
|
|
143
|
-
elif "token_secret" in name.lower() or "token" in name.lower():
|
|
144
|
-
try:
|
|
145
|
-
attr = getattr(config, name)
|
|
146
|
-
if callable(attr):
|
|
147
|
-
setattr(config, name, get_token_secret)
|
|
148
|
-
except:
|
|
149
|
-
pass
|
|
150
|
-
|
|
151
|
-
print("✅ Modal authentication patched during import")
|
|
152
|
-
except Exception as e:
|
|
153
|
-
print(f"⚠️ Error patching Modal: {e}")
|
|
154
|
-
|
|
155
|
-
return module
|
|
156
|
-
|
|
157
|
-
# Replace the built-in import function
|
|
158
|
-
sys.modules["builtins"].__import__ = custom_import
|
|
159
|
-
|
|
160
|
-
print("✅ Modal authentication patch installed")
|
|
161
|
-
|
|
162
|
-
# Test the patch if Modal is already imported
|
|
163
|
-
try:
|
|
164
|
-
import modal
|
|
165
|
-
print("Testing Modal authentication patch...")
|
|
166
|
-
|
|
167
|
-
# Create a simple app
|
|
168
|
-
app = modal.App("test-auth-patch")
|
|
169
|
-
|
|
170
|
-
@app.function()
|
|
171
|
-
def hello():
|
|
172
|
-
return "Hello from patched Modal!"
|
|
173
|
-
|
|
174
|
-
print("✅ Modal app created successfully")
|
|
175
|
-
except ImportError:
|
|
176
|
-
print("⚠️ Modal not installed, patch will be applied when it's imported")
|
|
177
|
-
except Exception as e:
|
|
178
|
-
print(f"❌ Error testing Modal patch: {e}")
|