rust-crate-pipeline 1.1.0__py3-none-any.whl → 1.2.0__py3-none-any.whl
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.
- rust_crate_pipeline/ai_processing.py +10 -8
- rust_crate_pipeline/analysis.py +2 -1
- rust_crate_pipeline/github_token_checker.py +102 -0
- rust_crate_pipeline/main.py +20 -0
- rust_crate_pipeline/production_config.py +76 -0
- rust_crate_pipeline/version.py +11 -1
- rust_crate_pipeline-1.2.0.dist-info/METADATA +573 -0
- rust_crate_pipeline-1.2.0.dist-info/RECORD +19 -0
- rust_crate_pipeline-1.1.0.dist-info/METADATA +0 -473
- rust_crate_pipeline-1.1.0.dist-info/RECORD +0 -17
- {rust_crate_pipeline-1.1.0.dist-info → rust_crate_pipeline-1.2.0.dist-info}/WHEEL +0 -0
- {rust_crate_pipeline-1.1.0.dist-info → rust_crate_pipeline-1.2.0.dist-info}/entry_points.txt +0 -0
- {rust_crate_pipeline-1.1.0.dist-info → rust_crate_pipeline-1.2.0.dist-info}/licenses/LICENSE +0 -0
- {rust_crate_pipeline-1.1.0.dist-info → rust_crate_pipeline-1.2.0.dist-info}/top_level.txt +0 -0
@@ -166,8 +166,7 @@ class LLMEnricher:
|
|
166
166
|
prompt: str,
|
167
167
|
validation_func: Callable[[str], bool],
|
168
168
|
temp: float = 0.2,
|
169
|
-
max_tokens: int = 256,
|
170
|
-
retries: int = 3
|
169
|
+
max_tokens: int = 256, retries: int = 2 # Reduced default retries
|
171
170
|
) -> Optional[str]:
|
172
171
|
"""Run LLM with validation and automatic retry on failure"""
|
173
172
|
for attempt in range(retries):
|
@@ -180,8 +179,11 @@ class LLMEnricher:
|
|
180
179
|
if result and validation_func(result):
|
181
180
|
return result
|
182
181
|
|
183
|
-
# If we get here, validation failed
|
184
|
-
|
182
|
+
# If we get here, validation failed - use debug level for early attempts
|
183
|
+
if attempt == retries - 1:
|
184
|
+
logging.warning(f"Final validation attempt failed. Using best available result.")
|
185
|
+
else:
|
186
|
+
logging.debug(f"Validation failed on attempt {attempt+1}/{retries}. Retrying with modified parameters.")
|
185
187
|
|
186
188
|
# For the last attempt, simplify the prompt
|
187
189
|
if attempt == retries - 2:
|
@@ -190,11 +192,11 @@ class LLMEnricher:
|
|
190
192
|
except Exception as e:
|
191
193
|
logging.error(f"Generation error on attempt {attempt+1}: {str(e)}")
|
192
194
|
|
193
|
-
#
|
194
|
-
time.sleep(1.
|
195
|
+
# Reduced backoff to minimize waiting time
|
196
|
+
time.sleep(1.0 + (attempt * 0.5))
|
195
197
|
|
196
|
-
# If we
|
197
|
-
return None
|
198
|
+
# If we exhausted all retries, return the last result even if not perfect
|
199
|
+
return result if 'result' in locals() else None
|
198
200
|
|
199
201
|
def simplify_prompt(self, prompt: str) -> str:
|
200
202
|
"""Simplify a prompt by removing examples and reducing context"""
|
rust_crate_pipeline/analysis.py
CHANGED
@@ -8,7 +8,8 @@ import tarfile
|
|
8
8
|
import tempfile
|
9
9
|
import subprocess
|
10
10
|
import requests
|
11
|
-
from datetime import datetime
|
11
|
+
from datetime import datetime
|
12
|
+
from dateutil.relativedelta import relativedelta
|
12
13
|
from bs4 import BeautifulSoup
|
13
14
|
from typing import Dict, Optional, List
|
14
15
|
from .config import EnrichedCrate
|
@@ -0,0 +1,102 @@
|
|
1
|
+
# github_token_checker.py
|
2
|
+
"""
|
3
|
+
GitHub Token Checker Module
|
4
|
+
Lightweight version of the token checker for integration into the main pipeline.
|
5
|
+
"""
|
6
|
+
|
7
|
+
import os
|
8
|
+
import sys
|
9
|
+
import requests
|
10
|
+
import logging
|
11
|
+
|
12
|
+
def check_github_token_quick():
|
13
|
+
"""Quick check if GitHub token is available and valid"""
|
14
|
+
token = os.getenv("GITHUB_TOKEN")
|
15
|
+
|
16
|
+
if not token:
|
17
|
+
return False, "GITHUB_TOKEN environment variable not set"
|
18
|
+
|
19
|
+
if len(token) < 20:
|
20
|
+
return False, "GITHUB_TOKEN seems too short - may be invalid"
|
21
|
+
|
22
|
+
try:
|
23
|
+
# Quick API check
|
24
|
+
headers = {
|
25
|
+
"Accept": "application/vnd.github.v3+json",
|
26
|
+
"Authorization": f"token {token}"
|
27
|
+
}
|
28
|
+
|
29
|
+
response = requests.get("https://api.github.com/rate_limit", headers=headers, timeout=10)
|
30
|
+
|
31
|
+
if response.status_code == 200:
|
32
|
+
data = response.json()
|
33
|
+
remaining = data["resources"]["core"]["remaining"]
|
34
|
+
return True, f"Token valid, {remaining} API calls remaining"
|
35
|
+
elif response.status_code == 401:
|
36
|
+
return False, "GitHub token is invalid or expired"
|
37
|
+
else:
|
38
|
+
return False, f"GitHub API returned status code: {response.status_code}"
|
39
|
+
|
40
|
+
except requests.exceptions.RequestException as e:
|
41
|
+
return False, f"Network error checking token: {str(e)}"
|
42
|
+
except Exception as e:
|
43
|
+
return False, f"Error checking token: {str(e)}"
|
44
|
+
|
45
|
+
def prompt_for_token_setup():
|
46
|
+
"""Prompt user to set up GitHub token"""
|
47
|
+
print("\n" + "="*60)
|
48
|
+
print("🔑 GitHub Token Required")
|
49
|
+
print("="*60)
|
50
|
+
print("\nThe Rust Crate Pipeline requires a GitHub Personal Access Token")
|
51
|
+
print("to access repository information and avoid rate limits.")
|
52
|
+
print("\n📋 Quick Setup:")
|
53
|
+
print("1. Get token: https://github.com/settings/tokens")
|
54
|
+
print("2. Required scopes: public_repo, read:user")
|
55
|
+
print("3. Set in environment:")
|
56
|
+
print(" export GITHUB_TOKEN=\"your_token_here\"")
|
57
|
+
print("\n🔧 Setup Scripts Available:")
|
58
|
+
print(" ./setup_github_token.sh (Interactive setup)")
|
59
|
+
print(" python3 check_github_token.py (Full verification)")
|
60
|
+
print("\n" + "="*60)
|
61
|
+
|
62
|
+
# Ask if user wants to continue without token (limited functionality)
|
63
|
+
response = input("\nContinue without GitHub token? (y/N): ").strip().lower()
|
64
|
+
|
65
|
+
if response in ['y', 'yes']:
|
66
|
+
print("⚠️ Running with limited GitHub API access (60 requests/hour)")
|
67
|
+
print(" You may encounter rate limit warnings.")
|
68
|
+
return True
|
69
|
+
else:
|
70
|
+
print("\n🛑 Please set up your GitHub token and try again.")
|
71
|
+
return False
|
72
|
+
|
73
|
+
def check_and_setup_github_token():
|
74
|
+
"""
|
75
|
+
Check GitHub token and prompt for setup if missing.
|
76
|
+
Returns True if should continue, False if should exit.
|
77
|
+
"""
|
78
|
+
is_valid, message = check_github_token_quick()
|
79
|
+
|
80
|
+
if is_valid:
|
81
|
+
logging.debug(f"GitHub token check: {message}")
|
82
|
+
return True
|
83
|
+
|
84
|
+
# Token is missing or invalid
|
85
|
+
logging.warning(f"GitHub token issue: {message}")
|
86
|
+
|
87
|
+
# Check if we're in a non-interactive environment
|
88
|
+
if not sys.stdin.isatty():
|
89
|
+
logging.error("GitHub token not configured and running in non-interactive mode")
|
90
|
+
logging.error("Set GITHUB_TOKEN environment variable before running")
|
91
|
+
return False
|
92
|
+
|
93
|
+
# Interactive prompt
|
94
|
+
return prompt_for_token_setup()
|
95
|
+
|
96
|
+
if __name__ == "__main__":
|
97
|
+
# Allow running this module directly for testing
|
98
|
+
is_valid, message = check_github_token_quick()
|
99
|
+
print(f"Token check: {'✅' if is_valid else '❌'} {message}")
|
100
|
+
|
101
|
+
if not is_valid:
|
102
|
+
check_and_setup_github_token()
|
rust_crate_pipeline/main.py
CHANGED
@@ -8,6 +8,8 @@ import argparse
|
|
8
8
|
from typing import Optional
|
9
9
|
from .config import PipelineConfig
|
10
10
|
from .pipeline import CrateDataPipeline
|
11
|
+
from .production_config import setup_production_environment
|
12
|
+
from .github_token_checker import check_and_setup_github_token
|
11
13
|
|
12
14
|
def parse_arguments():
|
13
15
|
"""Parse command line arguments"""
|
@@ -21,6 +23,7 @@ Examples:
|
|
21
23
|
python -m rust_crate_pipeline --batch-size 5 # Smaller batches
|
22
24
|
python -m rust_crate_pipeline --output-dir ./data # Custom output directory
|
23
25
|
python -m rust_crate_pipeline --log-level DEBUG # Verbose logging
|
26
|
+
PRODUCTION=true python -m rust_crate_pipeline # Production mode (quieter)
|
24
27
|
"""
|
25
28
|
)
|
26
29
|
|
@@ -123,14 +126,31 @@ def check_disk_space():
|
|
123
126
|
logging.warning("Low disk space! This may affect performance.")
|
124
127
|
|
125
128
|
def main():
|
129
|
+
# Setup production environment first for optimal logging
|
130
|
+
prod_config = setup_production_environment()
|
131
|
+
|
126
132
|
args = parse_arguments()
|
127
133
|
configure_logging(args.log_level)
|
128
134
|
check_disk_space()
|
129
135
|
|
136
|
+
# Check GitHub token before proceeding
|
137
|
+
if not check_and_setup_github_token():
|
138
|
+
logging.error("GitHub token setup cancelled or failed. Exiting.")
|
139
|
+
sys.exit(1)
|
140
|
+
|
130
141
|
try:
|
131
142
|
# Create config from command line arguments
|
132
143
|
config_kwargs = {}
|
133
144
|
|
145
|
+
# Apply production optimizations if available
|
146
|
+
if prod_config:
|
147
|
+
config_kwargs.update({
|
148
|
+
'max_retries': prod_config.get('max_retries', 3),
|
149
|
+
'batch_size': prod_config.get('batch_size', 10),
|
150
|
+
'checkpoint_interval': prod_config.get('checkpoint_interval', 10),
|
151
|
+
'cache_ttl': prod_config.get('cache_ttl', 3600),
|
152
|
+
})
|
153
|
+
|
134
154
|
if args.batch_size:
|
135
155
|
config_kwargs['batch_size'] = args.batch_size
|
136
156
|
if args.workers:
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# production_config.py
|
2
|
+
"""
|
3
|
+
Production configuration to reduce runtime warnings and optimize performance.
|
4
|
+
This file contains settings that can be imported to minimize verbose logging
|
5
|
+
and improve the user experience in production environments.
|
6
|
+
"""
|
7
|
+
|
8
|
+
import logging
|
9
|
+
import os
|
10
|
+
|
11
|
+
# Production logging configuration
|
12
|
+
def configure_production_logging():
|
13
|
+
"""Configure logging for production to reduce verbose warnings"""
|
14
|
+
|
15
|
+
# Set up logging format
|
16
|
+
logging.basicConfig(
|
17
|
+
level=logging.INFO, # Default to INFO level
|
18
|
+
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
19
|
+
datefmt='%Y-%m-%d %H:%M:%S'
|
20
|
+
)
|
21
|
+
|
22
|
+
# Set specific loggers to less verbose levels
|
23
|
+
logging.getLogger('requests').setLevel(logging.WARNING)
|
24
|
+
logging.getLogger('urllib3').setLevel(logging.WARNING)
|
25
|
+
logging.getLogger('requests_cache').setLevel(logging.WARNING)
|
26
|
+
|
27
|
+
# If PRODUCTION environment variable is set, be even quieter
|
28
|
+
if os.getenv('PRODUCTION', 'false').lower() == 'true':
|
29
|
+
logging.getLogger().setLevel(logging.WARNING)
|
30
|
+
logging.getLogger('rust_crate_pipeline').setLevel(logging.INFO)
|
31
|
+
|
32
|
+
# Production-optimized settings
|
33
|
+
PRODUCTION_SETTINGS = {
|
34
|
+
# Reduced retries to minimize warnings
|
35
|
+
'max_retries': 2,
|
36
|
+
'validation_retries': 2,
|
37
|
+
|
38
|
+
# GitHub API management
|
39
|
+
'github_rate_limit_threshold': 100,
|
40
|
+
'github_critical_threshold': 50,
|
41
|
+
|
42
|
+
# LLM settings
|
43
|
+
'llm_timeout': 30,
|
44
|
+
'llm_max_attempts': 2,
|
45
|
+
|
46
|
+
# Logging preferences
|
47
|
+
'quiet_mode': True,
|
48
|
+
'log_level': 'INFO',
|
49
|
+
|
50
|
+
# Performance settings
|
51
|
+
'batch_size': 10,
|
52
|
+
'checkpoint_interval': 10,
|
53
|
+
'cache_ttl': 3600,
|
54
|
+
}
|
55
|
+
|
56
|
+
def get_production_config():
|
57
|
+
"""Get production configuration dictionary"""
|
58
|
+
return PRODUCTION_SETTINGS.copy()
|
59
|
+
|
60
|
+
def is_production():
|
61
|
+
"""Check if running in production mode"""
|
62
|
+
return os.getenv('PRODUCTION', 'false').lower() == 'true'
|
63
|
+
|
64
|
+
def setup_production_environment():
|
65
|
+
"""Set up the complete production environment"""
|
66
|
+
configure_production_logging()
|
67
|
+
|
68
|
+
# Set environment variables for quieter operation
|
69
|
+
os.environ.setdefault('PYTHONWARNINGS', 'ignore::UserWarning')
|
70
|
+
|
71
|
+
if is_production():
|
72
|
+
print("🚀 Production mode enabled - optimized for minimal warnings")
|
73
|
+
return get_production_config()
|
74
|
+
else:
|
75
|
+
print("🔧 Development mode - full logging enabled")
|
76
|
+
return {}
|
rust_crate_pipeline/version.py
CHANGED
@@ -1,9 +1,19 @@
|
|
1
1
|
"""Version information for rust-crate-pipeline."""
|
2
2
|
|
3
|
-
__version__ = "1.
|
3
|
+
__version__ = "1.2.0"
|
4
4
|
__version_info__ = tuple(int(x) for x in __version__.split("."))
|
5
5
|
|
6
6
|
# Version history
|
7
|
+
# 1.2.0 - Major release: Production-ready, cleaned codebase
|
8
|
+
# - Unified documentation into single comprehensive README
|
9
|
+
# - Removed all non-essential development and test files
|
10
|
+
# - Optimized for PyPI distribution and Docker deployment
|
11
|
+
# - Enhanced GitHub token integration and setup
|
12
|
+
# 1.1.2 - Production release: Cleaned up non-essential files
|
13
|
+
# - Unified documentation into single README
|
14
|
+
# - Optimized for PyPI distribution
|
15
|
+
# 1.1.1 - Bug fix: Added missing python-dateutil dependency
|
16
|
+
# - Fixed relativedelta import error
|
7
17
|
# 1.1.0 - Updated author and contact information
|
8
18
|
# - Enhanced package configuration
|
9
19
|
# 0.1.0 - Initial release
|