syncable_cli/analyzer/frameworks/
python.rs

1use super::{LanguageFrameworkDetector, TechnologyRule, FrameworkDetectionUtils};
2use crate::analyzer::{DetectedTechnology, DetectedLanguage, TechnologyCategory, LibraryType};
3use crate::error::Result;
4
5pub struct PythonFrameworkDetector;
6
7impl LanguageFrameworkDetector for PythonFrameworkDetector {
8    fn detect_frameworks(&self, language: &DetectedLanguage) -> Result<Vec<DetectedTechnology>> {
9        let rules = get_python_technology_rules();
10        
11        // Combine main and dev dependencies for comprehensive detection
12        let all_deps: Vec<String> = language.main_dependencies.iter()
13            .chain(language.dev_dependencies.iter())
14            .cloned()
15            .collect();
16        
17        let technologies = FrameworkDetectionUtils::detect_technologies_by_dependencies(
18            &rules, &all_deps, language.confidence
19        );
20        
21        Ok(technologies)
22    }
23    
24    fn supported_languages(&self) -> Vec<&'static str> {
25        vec!["Python"]
26    }
27}
28
29/// Python technology detection rules with comprehensive framework coverage
30fn get_python_technology_rules() -> Vec<TechnologyRule> {
31    vec![
32        // WEB FRAMEWORKS - Full Stack
33        TechnologyRule {
34            name: "Django".to_string(),
35            category: TechnologyCategory::BackendFramework,
36            confidence: 0.95,
37            dependency_patterns: vec!["django".to_string(), "Django".to_string()],
38            requires: vec![],
39            conflicts_with: vec![],
40            is_primary_indicator: true,
41            alternative_names: vec![],
42            file_indicators: vec![],
43        },
44        TechnologyRule {
45            name: "Django REST Framework".to_string(),
46            category: TechnologyCategory::BackendFramework,
47            confidence: 0.90,
48            dependency_patterns: vec!["djangorestframework".to_string(), "rest_framework".to_string()],
49            requires: vec!["Django".to_string()],
50            conflicts_with: vec![],
51            is_primary_indicator: false,
52            alternative_names: vec!["DRF".to_string()],
53            file_indicators: vec![],
54        },
55        
56        // MICRO FRAMEWORKS
57        TechnologyRule {
58            name: "Flask".to_string(),
59            category: TechnologyCategory::BackendFramework,
60            confidence: 0.95,
61            dependency_patterns: vec!["flask".to_string(), "Flask".to_string()],
62            requires: vec![],
63            conflicts_with: vec![],
64            is_primary_indicator: true,
65            alternative_names: vec![],
66            file_indicators: vec![],
67        },
68        TechnologyRule {
69            name: "FastAPI".to_string(),
70            category: TechnologyCategory::BackendFramework,
71            confidence: 0.95,
72            dependency_patterns: vec!["fastapi".to_string(), "FastAPI".to_string()],
73            requires: vec![],
74            conflicts_with: vec![],
75            is_primary_indicator: true,
76            alternative_names: vec![],
77            file_indicators: vec![],
78        },
79        TechnologyRule {
80            name: "Starlette".to_string(),
81            category: TechnologyCategory::BackendFramework,
82            confidence: 0.90,
83            dependency_patterns: vec!["starlette".to_string(), "Starlette".to_string()],
84            requires: vec![],
85            conflicts_with: vec![],
86            is_primary_indicator: true,
87            alternative_names: vec![],
88            file_indicators: vec![],
89        },
90        TechnologyRule {
91            name: "Quart".to_string(),
92            category: TechnologyCategory::BackendFramework,
93            confidence: 0.90,
94            dependency_patterns: vec!["quart".to_string(), "Quart".to_string()],
95            requires: vec![],
96            conflicts_with: vec![],
97            is_primary_indicator: true,
98            alternative_names: vec![],
99            file_indicators: vec![],
100        },
101        TechnologyRule {
102            name: "Sanic".to_string(),
103            category: TechnologyCategory::BackendFramework,
104            confidence: 0.90,
105            dependency_patterns: vec!["sanic".to_string(), "Sanic".to_string()],
106            requires: vec![],
107            conflicts_with: vec![],
108            is_primary_indicator: true,
109            alternative_names: vec![],
110            file_indicators: vec![],
111        },
112        TechnologyRule {
113            name: "Bottle".to_string(),
114            category: TechnologyCategory::BackendFramework,
115            confidence: 0.85,
116            dependency_patterns: vec!["bottle".to_string(), "Bottle".to_string()],
117            requires: vec![],
118            conflicts_with: vec![],
119            is_primary_indicator: true,
120            alternative_names: vec![],
121            file_indicators: vec![],
122        },
123        TechnologyRule {
124            name: "Falcon".to_string(),
125            category: TechnologyCategory::BackendFramework,
126            confidence: 0.85,
127            dependency_patterns: vec!["falcon".to_string(), "Falcon".to_string()],
128            requires: vec![],
129            conflicts_with: vec![],
130            is_primary_indicator: true,
131            alternative_names: vec![],
132            file_indicators: vec![],
133        },
134        TechnologyRule {
135            name: "Hug".to_string(),
136            category: TechnologyCategory::BackendFramework,
137            confidence: 0.85,
138            dependency_patterns: vec!["hug".to_string(), "Hug".to_string()],
139            requires: vec![],
140            conflicts_with: vec![],
141            is_primary_indicator: true,
142            alternative_names: vec![],
143            file_indicators: vec![],
144        },
145        TechnologyRule {
146            name: "Molten".to_string(),
147            category: TechnologyCategory::BackendFramework,
148            confidence: 0.85,
149            dependency_patterns: vec!["molten".to_string(), "Molten".to_string()],
150            requires: vec![],
151            conflicts_with: vec![],
152            is_primary_indicator: true,
153            alternative_names: vec![],
154            file_indicators: vec![],
155        },
156        TechnologyRule {
157            name: "Responder".to_string(),
158            category: TechnologyCategory::BackendFramework,
159            confidence: 0.85,
160            dependency_patterns: vec!["responder".to_string(), "Responder".to_string()],
161            requires: vec![],
162            conflicts_with: vec![],
163            is_primary_indicator: true,
164            alternative_names: vec![],
165            file_indicators: vec![],
166        },
167        TechnologyRule {
168            name: "Vibora".to_string(),
169            category: TechnologyCategory::BackendFramework,
170            confidence: 0.85,
171            dependency_patterns: vec!["vibora".to_string(), "Vibora".to_string()],
172            requires: vec![],
173            conflicts_with: vec![],
174            is_primary_indicator: true,
175            alternative_names: vec![],
176            file_indicators: vec![],
177        },
178        TechnologyRule {
179            name: "Asgi".to_string(),
180            category: TechnologyCategory::BackendFramework,
181            confidence: 0.85,
182            dependency_patterns: vec!["asgi".to_string(), "Asgi".to_string()],
183            requires: vec![],
184            conflicts_with: vec![],
185            is_primary_indicator: true,
186            alternative_names: vec![],
187            file_indicators: vec![],
188        },
189        TechnologyRule {
190            name: "Tornado".to_string(),
191            category: TechnologyCategory::BackendFramework,
192            confidence: 0.90,
193            dependency_patterns: vec!["tornado".to_string(), "Tornado".to_string()],
194            requires: vec![],
195            conflicts_with: vec![],
196            is_primary_indicator: true,
197            alternative_names: vec![],
198            file_indicators: vec![],
199        },
200        TechnologyRule {
201            name: "CherryPy".to_string(),
202            category: TechnologyCategory::BackendFramework,
203            confidence: 0.85,
204            dependency_patterns: vec!["cherrypy".to_string(), "CherryPy".to_string()],
205            requires: vec![],
206            conflicts_with: vec![],
207            is_primary_indicator: true,
208            alternative_names: vec![],
209            file_indicators: vec![],
210        },
211        TechnologyRule {
212            name: "Web2py".to_string(),
213            category: TechnologyCategory::BackendFramework,
214            confidence: 0.85,
215            dependency_patterns: vec!["web2py".to_string(), "Web2py".to_string()],
216            requires: vec![],
217            conflicts_with: vec![],
218            is_primary_indicator: true,
219            alternative_names: vec![],
220            file_indicators: vec![],
221        },
222        TechnologyRule {
223            name: "Pyramid".to_string(),
224            category: TechnologyCategory::BackendFramework,
225            confidence: 0.90,
226            dependency_patterns: vec!["pyramid".to_string(), "Pyramid".to_string()],
227            requires: vec![],
228            conflicts_with: vec![],
229            is_primary_indicator: true,
230            alternative_names: vec![],
231            file_indicators: vec![],
232        },
233        TechnologyRule {
234            name: "TurboGears".to_string(),
235            category: TechnologyCategory::BackendFramework,
236            confidence: 0.85,
237            dependency_patterns: vec!["tg".to_string(), "TurboGears".to_string()],
238            requires: vec![],
239            conflicts_with: vec![],
240            is_primary_indicator: true,
241            alternative_names: vec![],
242            file_indicators: vec![],
243        },
244        TechnologyRule {
245            name: "Klein".to_string(),
246            category: TechnologyCategory::BackendFramework,
247            confidence: 0.85,
248            dependency_patterns: vec!["klein".to_string(), "Klein".to_string()],
249            requires: vec![],
250            conflicts_with: vec![],
251            is_primary_indicator: true,
252            alternative_names: vec![],
253            file_indicators: vec![],
254        },
255        TechnologyRule {
256            name: "Morepath".to_string(),
257            category: TechnologyCategory::BackendFramework,
258            confidence: 0.85,
259            dependency_patterns: vec!["morepath".to_string(), "Morepath".to_string()],
260            requires: vec![],
261            conflicts_with: vec![],
262            is_primary_indicator: true,
263            alternative_names: vec![],
264            file_indicators: vec![],
265        },
266        TechnologyRule {
267            name: "Masonite".to_string(),
268            category: TechnologyCategory::BackendFramework,
269            confidence: 0.85,
270            dependency_patterns: vec!["masonite".to_string(), "Masonite".to_string()],
271            requires: vec![],
272            conflicts_with: vec![],
273            is_primary_indicator: true,
274            alternative_names: vec![],
275            file_indicators: vec![],
276        },
277        TechnologyRule {
278            name: "Litestar".to_string(),
279            category: TechnologyCategory::BackendFramework,
280            confidence: 0.90,
281            dependency_patterns: vec!["litestar".to_string(), "Litestar".to_string()],
282            requires: vec![],
283            conflicts_with: vec![],
284            is_primary_indicator: true,
285            alternative_names: vec!["Starlite".to_string()],
286            file_indicators: vec![],
287        },
288        TechnologyRule {
289            name: "Connexion".to_string(),
290            category: TechnologyCategory::BackendFramework,
291            confidence: 0.85,
292            dependency_patterns: vec!["connexion".to_string(), "Connexion".to_string()],
293            requires: vec![],
294            conflicts_with: vec![],
295            is_primary_indicator: true,
296            alternative_names: vec![],
297            file_indicators: vec![],
298        },
299        TechnologyRule {
300            name: "Nameko".to_string(),
301            category: TechnologyCategory::BackendFramework,
302            confidence: 0.85,
303            dependency_patterns: vec!["nameko".to_string(), "Nameko".to_string()],
304            requires: vec![],
305            conflicts_with: vec![],
306            is_primary_indicator: true,
307            alternative_names: vec![],
308            file_indicators: vec![],
309        },
310        TechnologyRule {
311            name: "Aiohttp".to_string(),
312            category: TechnologyCategory::BackendFramework,
313            confidence: 0.90,
314            dependency_patterns: vec!["aiohttp".to_string(), "Aiohttp".to_string()],
315            requires: vec![],
316            conflicts_with: vec![],
317            is_primary_indicator: true,
318            alternative_names: vec![],
319            file_indicators: vec![],
320        },
321        
322        // ASYNC RUNTIMES
323        TechnologyRule {
324            name: "asyncio".to_string(),
325            category: TechnologyCategory::Runtime,
326            confidence: 0.85,
327            dependency_patterns: vec!["asyncio".to_string()],
328            requires: vec![],
329            conflicts_with: vec![],
330            is_primary_indicator: false,
331            alternative_names: vec![],
332            file_indicators: vec![],
333        },
334        TechnologyRule {
335            name: "Trio".to_string(),
336            category: TechnologyCategory::Runtime,
337            confidence: 0.85,
338            dependency_patterns: vec!["trio".to_string()],
339            requires: vec![],
340            conflicts_with: vec![],
341            is_primary_indicator: false,
342            alternative_names: vec![],
343            file_indicators: vec![],
344        },
345        TechnologyRule {
346            name: "Curio".to_string(),
347            category: TechnologyCategory::Runtime,
348            confidence: 0.85,
349            dependency_patterns: vec!["curio".to_string()],
350            requires: vec![],
351            conflicts_with: vec![],
352            is_primary_indicator: false,
353            alternative_names: vec![],
354            file_indicators: vec![],
355        },
356        
357        // FRONTEND FRAMEWORKS
358        TechnologyRule {
359            name: "Streamlit".to_string(),
360            category: TechnologyCategory::FrontendFramework,
361            confidence: 0.95,
362            dependency_patterns: vec!["streamlit".to_string(), "Streamlit".to_string()],
363            requires: vec![],
364            conflicts_with: vec![],
365            is_primary_indicator: true,
366            alternative_names: vec![],
367            file_indicators: vec![],
368        },
369        TechnologyRule {
370            name: "Gradio".to_string(),
371            category: TechnologyCategory::FrontendFramework,
372            confidence: 0.95,
373            dependency_patterns: vec!["gradio".to_string(), "Gradio".to_string()],
374            requires: vec![],
375            conflicts_with: vec![],
376            is_primary_indicator: true,
377            alternative_names: vec![],
378            file_indicators: vec![],
379        },
380        TechnologyRule {
381            name: "Dash".to_string(),
382            category: TechnologyCategory::FrontendFramework,
383            confidence: 0.90,
384            dependency_patterns: vec!["dash".to_string(), "Dash".to_string()],
385            requires: vec!["Flask".to_string()],
386            conflicts_with: vec![],
387            is_primary_indicator: true,
388            alternative_names: vec![],
389            file_indicators: vec![],
390        },
391        TechnologyRule {
392            name: "Panel".to_string(),
393            category: TechnologyCategory::FrontendFramework,
394            confidence: 0.90,
395            dependency_patterns: vec!["panel".to_string(), "Panel".to_string()],
396            requires: vec!["Bokeh".to_string()],
397            conflicts_with: vec![],
398            is_primary_indicator: true,
399            alternative_names: vec![],
400            file_indicators: vec![],
401        },
402        TechnologyRule {
403            name: "NiceGUI".to_string(),
404            category: TechnologyCategory::FrontendFramework,
405            confidence: 0.90,
406            dependency_patterns: vec!["nicegui".to_string(), "NiceGUI".to_string()],
407            requires: vec![],
408            conflicts_with: vec![],
409            is_primary_indicator: true,
410            alternative_names: vec![],
411            file_indicators: vec![],
412        },
413        TechnologyRule {
414            name: "Reflex".to_string(),
415            category: TechnologyCategory::FrontendFramework,
416            confidence: 0.90,
417            dependency_patterns: vec!["reflex".to_string(), "Reflex".to_string()],
418            requires: vec![],
419            conflicts_with: vec![],
420            is_primary_indicator: true,
421            alternative_names: vec!["pynecone".to_string()],
422            file_indicators: vec![],
423        },
424        TechnologyRule {
425            name: "PyWebIO".to_string(),
426            category: TechnologyCategory::FrontendFramework,
427            confidence: 0.85,
428            dependency_patterns: vec!["pywebio".to_string(), "PyWebIO".to_string()],
429            requires: vec![],
430            conflicts_with: vec![],
431            is_primary_indicator: true,
432            alternative_names: vec![],
433            file_indicators: vec![],
434        },
435        TechnologyRule {
436            name: "Anvil".to_string(),
437            category: TechnologyCategory::FrontendFramework,
438            confidence: 0.85,
439            dependency_patterns: vec!["anvil".to_string(), "Anvil".to_string()],
440            requires: vec![],
441            conflicts_with: vec![],
442            is_primary_indicator: true,
443            alternative_names: vec![],
444            file_indicators: vec![],
445        },
446        
447        // SCIENTIFIC COMPUTING
448        TechnologyRule {
449            name: "NumPy".to_string(),
450            category: TechnologyCategory::Library(LibraryType::Utility),
451            confidence: 0.90,
452            dependency_patterns: vec!["numpy".to_string(), "NumPy".to_string()],
453            requires: vec![],
454            conflicts_with: vec![],
455            is_primary_indicator: false,
456            alternative_names: vec![],
457            file_indicators: vec![],
458        },
459        TechnologyRule {
460            name: "SciPy".to_string(),
461            category: TechnologyCategory::Library(LibraryType::Utility),
462            confidence: 0.90,
463            dependency_patterns: vec!["scipy".to_string(), "SciPy".to_string()],
464            requires: vec!["NumPy".to_string()],
465            conflicts_with: vec![],
466            is_primary_indicator: false,
467            alternative_names: vec![],
468            file_indicators: vec![],
469        },
470        TechnologyRule {
471            name: "Pandas".to_string(),
472            category: TechnologyCategory::Library(LibraryType::Utility),
473            confidence: 0.90,
474            dependency_patterns: vec!["pandas".to_string(), "Pandas".to_string()],
475            requires: vec!["NumPy".to_string()],
476            conflicts_with: vec![],
477            is_primary_indicator: false,
478            alternative_names: vec![],
479            file_indicators: vec![],
480        },
481        TechnologyRule {
482            name: "Matplotlib".to_string(),
483            category: TechnologyCategory::Library(LibraryType::Utility),
484            confidence: 0.85,
485            dependency_patterns: vec!["matplotlib".to_string(), "Matplotlib".to_string()],
486            requires: vec![],
487            conflicts_with: vec![],
488            is_primary_indicator: false,
489            alternative_names: vec![],
490            file_indicators: vec![],
491        },
492        TechnologyRule {
493            name: "Seaborn".to_string(),
494            category: TechnologyCategory::Library(LibraryType::Utility),
495            confidence: 0.85,
496            dependency_patterns: vec!["seaborn".to_string(), "Seaborn".to_string()],
497            requires: vec!["Matplotlib".to_string(), "Pandas".to_string()],
498            conflicts_with: vec![],
499            is_primary_indicator: false,
500            alternative_names: vec![],
501            file_indicators: vec![],
502        },
503        TechnologyRule {
504            name: "Plotly".to_string(),
505            category: TechnologyCategory::Library(LibraryType::Utility),
506            confidence: 0.85,
507            dependency_patterns: vec!["plotly".to_string(), "Plotly".to_string()],
508            requires: vec![],
509            conflicts_with: vec![],
510            is_primary_indicator: false,
511            alternative_names: vec![],
512            file_indicators: vec![],
513        },
514        TechnologyRule {
515            name: "Bokeh".to_string(),
516            category: TechnologyCategory::Library(LibraryType::Utility),
517            confidence: 0.85,
518            dependency_patterns: vec!["bokeh".to_string(), "Bokeh".to_string()],
519            requires: vec![],
520            conflicts_with: vec![],
521            is_primary_indicator: false,
522            alternative_names: vec![],
523            file_indicators: vec![],
524        },
525        
526        // MACHINE LEARNING & AI
527        TechnologyRule {
528            name: "TensorFlow".to_string(),
529            category: TechnologyCategory::Library(LibraryType::Utility),
530            confidence: 0.95,
531            dependency_patterns: vec!["tensorflow".to_string(), "TensorFlow".to_string()],
532            requires: vec![],
533            conflicts_with: vec![],
534            is_primary_indicator: false,
535            alternative_names: vec![],
536            file_indicators: vec![],
537        },
538        TechnologyRule {
539            name: "PyTorch".to_string(),
540            category: TechnologyCategory::Library(LibraryType::Utility),
541            confidence: 0.95,
542            dependency_patterns: vec!["torch".to_string(), "PyTorch".to_string()],
543            requires: vec![],
544            conflicts_with: vec![],
545            is_primary_indicator: false,
546            alternative_names: vec![],
547            file_indicators: vec![],
548        },
549        TechnologyRule {
550            name: "Scikit-learn".to_string(),
551            category: TechnologyCategory::Library(LibraryType::Utility),
552            confidence: 0.90,
553            dependency_patterns: vec!["scikit-learn".to_string(), "sklearn".to_string()],
554            requires: vec!["NumPy".to_string(), "SciPy".to_string()],
555            conflicts_with: vec![],
556            is_primary_indicator: false,
557            alternative_names: vec!["sklearn".to_string()],
558            file_indicators: vec![],
559        },
560        TechnologyRule {
561            name: "Keras".to_string(),
562            category: TechnologyCategory::Library(LibraryType::Utility),
563            confidence: 0.90,
564            dependency_patterns: vec!["keras".to_string(), "Keras".to_string()],
565            requires: vec!["TensorFlow".to_string()],
566            conflicts_with: vec![],
567            is_primary_indicator: false,
568            alternative_names: vec![],
569            file_indicators: vec![],
570        },
571        TechnologyRule {
572            name: "XGBoost".to_string(),
573            category: TechnologyCategory::Library(LibraryType::Utility),
574            confidence: 0.85,
575            dependency_patterns: vec!["xgboost".to_string(), "XGBoost".to_string()],
576            requires: vec![],
577            conflicts_with: vec![],
578            is_primary_indicator: false,
579            alternative_names: vec![],
580            file_indicators: vec![],
581        },
582        TechnologyRule {
583            name: "LightGBM".to_string(),
584            category: TechnologyCategory::Library(LibraryType::Utility),
585            confidence: 0.85,
586            dependency_patterns: vec!["lightgbm".to_string(), "LightGBM".to_string()],
587            requires: vec![],
588            conflicts_with: vec![],
589            is_primary_indicator: false,
590            alternative_names: vec![],
591            file_indicators: vec![],
592        },
593        TechnologyRule {
594            name: "CatBoost".to_string(),
595            category: TechnologyCategory::Library(LibraryType::Utility),
596            confidence: 0.85,
597            dependency_patterns: vec!["catboost".to_string(), "CatBoost".to_string()],
598            requires: vec![],
599            conflicts_with: vec![],
600            is_primary_indicator: false,
601            alternative_names: vec![],
602            file_indicators: vec![],
603        },
604        
605        // DATABASE/ORM
606        TechnologyRule {
607            name: "SQLAlchemy".to_string(),
608            category: TechnologyCategory::Database,
609            confidence: 0.90,
610            dependency_patterns: vec!["sqlalchemy".to_string(), "SQLAlchemy".to_string()],
611            requires: vec![],
612            conflicts_with: vec![],
613            is_primary_indicator: false,
614            alternative_names: vec![],
615            file_indicators: vec![],
616        },
617        TechnologyRule {
618            name: "Peewee".to_string(),
619            category: TechnologyCategory::Database,
620            confidence: 0.85,
621            dependency_patterns: vec!["peewee".to_string(), "Peewee".to_string()],
622            requires: vec![],
623            conflicts_with: vec![],
624            is_primary_indicator: false,
625            alternative_names: vec![],
626            file_indicators: vec![],
627        },
628        TechnologyRule {
629            name: "Tortoise ORM".to_string(),
630            category: TechnologyCategory::Database,
631            confidence: 0.85,
632            dependency_patterns: vec!["tortoise-orm".to_string(), "tortoise".to_string()],
633            requires: vec![],
634            conflicts_with: vec![],
635            is_primary_indicator: false,
636            alternative_names: vec!["tortoise".to_string()],
637            file_indicators: vec![],
638        },
639        TechnologyRule {
640            name: "Django ORM".to_string(),
641            category: TechnologyCategory::Database,
642            confidence: 0.90,
643            dependency_patterns: vec!["django".to_string()],
644            requires: vec!["Django".to_string()],
645            conflicts_with: vec![],
646            is_primary_indicator: false,
647            alternative_names: vec![],
648            file_indicators: vec![],
649        },
650        TechnologyRule {
651            name: "MongoEngine".to_string(),
652            category: TechnologyCategory::Database,
653            confidence: 0.85,
654            dependency_patterns: vec!["mongoengine".to_string(), "MongoEngine".to_string()],
655            requires: vec![],
656            conflicts_with: vec![],
657            is_primary_indicator: false,
658            alternative_names: vec![],
659            file_indicators: vec![],
660        },
661        TechnologyRule {
662            name: "Pymongo".to_string(),
663            category: TechnologyCategory::Database,
664            confidence: 0.85,
665            dependency_patterns: vec!["pymongo".to_string(), "Pymongo".to_string()],
666            requires: vec![],
667            conflicts_with: vec![],
668            is_primary_indicator: false,
669            alternative_names: vec![],
670            file_indicators: vec![],
671        },
672        
673        // TESTING
674        TechnologyRule {
675            name: "Pytest".to_string(),
676            category: TechnologyCategory::Testing,
677            confidence: 0.90,
678            dependency_patterns: vec!["pytest".to_string(), "Pytest".to_string()],
679            requires: vec![],
680            conflicts_with: vec![],
681            is_primary_indicator: false,
682            alternative_names: vec![],
683            file_indicators: vec![],
684        },
685        TechnologyRule {
686            name: "Unittest".to_string(),
687            category: TechnologyCategory::Testing,
688            confidence: 0.80,
689            dependency_patterns: vec!["unittest".to_string()],
690            requires: vec![],
691            conflicts_with: vec![],
692            is_primary_indicator: false,
693            alternative_names: vec![],
694            file_indicators: vec![],
695        },
696        TechnologyRule {
697            name: "Tox".to_string(),
698            category: TechnologyCategory::Testing,
699            confidence: 0.80,
700            dependency_patterns: vec!["tox".to_string()],
701            requires: vec![],
702            conflicts_with: vec![],
703            is_primary_indicator: false,
704            alternative_names: vec![],
705            file_indicators: vec![],
706        },
707        TechnologyRule {
708            name: "Nose".to_string(),
709            category: TechnologyCategory::Testing,
710            confidence: 0.75,
711            dependency_patterns: vec!["nose".to_string(), "nose2".to_string()],
712            requires: vec![],
713            conflicts_with: vec![],
714            is_primary_indicator: false,
715            alternative_names: vec!["nose2".to_string()],
716            file_indicators: vec![],
717        },
718        TechnologyRule {
719            name: "Behave".to_string(),
720            category: TechnologyCategory::Testing,
721            confidence: 0.85,
722            dependency_patterns: vec!["behave".to_string()],
723            requires: vec![],
724            conflicts_with: vec![],
725            is_primary_indicator: false,
726            alternative_names: vec![],
727            file_indicators: vec![],
728        },
729        TechnologyRule {
730            name: "Hypothesis".to_string(),
731            category: TechnologyCategory::Testing,
732            confidence: 0.85,
733            dependency_patterns: vec!["hypothesis".to_string()],
734            requires: vec![],
735            conflicts_with: vec![],
736            is_primary_indicator: false,
737            alternative_names: vec![],
738            file_indicators: vec![],
739        },
740        
741        // CLI FRAMEWORKS
742        TechnologyRule {
743            name: "Click".to_string(),
744            category: TechnologyCategory::Library(LibraryType::CLI),
745            confidence: 0.90,
746            dependency_patterns: vec!["click".to_string(), "Click".to_string()],
747            requires: vec![],
748            conflicts_with: vec![],
749            is_primary_indicator: true,
750            alternative_names: vec![],
751            file_indicators: vec![],
752        },
753        TechnologyRule {
754            name: "Argparse".to_string(),
755            category: TechnologyCategory::Library(LibraryType::CLI),
756            confidence: 0.80,
757            dependency_patterns: vec!["argparse".to_string()],
758            requires: vec![],
759            conflicts_with: vec![],
760            is_primary_indicator: true,
761            alternative_names: vec![],
762            file_indicators: vec![],
763        },
764        TechnologyRule {
765            name: "Fire".to_string(),
766            category: TechnologyCategory::Library(LibraryType::CLI),
767            confidence: 0.85,
768            dependency_patterns: vec!["fire".to_string(), "Fire".to_string()],
769            requires: vec![],
770            conflicts_with: vec![],
771            is_primary_indicator: true,
772            alternative_names: vec![],
773            file_indicators: vec![],
774        },
775        TechnologyRule {
776            name: "Typer".to_string(),
777            category: TechnologyCategory::Library(LibraryType::CLI),
778            confidence: 0.85,
779            dependency_patterns: vec!["typer".to_string(), "Typer".to_string()],
780            requires: vec!["Click".to_string()],
781            conflicts_with: vec![],
782            is_primary_indicator: true,
783            alternative_names: vec![],
784            file_indicators: vec![],
785        },
786        TechnologyRule {
787            name: "Docopt".to_string(),
788            category: TechnologyCategory::Library(LibraryType::CLI),
789            confidence: 0.80,
790            dependency_patterns: vec!["docopt".to_string(), "Docopt".to_string()],
791            requires: vec![],
792            conflicts_with: vec![],
793            is_primary_indicator: true,
794            alternative_names: vec![],
795            file_indicators: vec![],
796        },
797        TechnologyRule {
798            name: "Plac".to_string(),
799            category: TechnologyCategory::Library(LibraryType::CLI),
800            confidence: 0.80,
801            dependency_patterns: vec!["plac".to_string(), "Plac".to_string()],
802            requires: vec![],
803            conflicts_with: vec![],
804            is_primary_indicator: true,
805            alternative_names: vec![],
806            file_indicators: vec![],
807        },
808        
809        // ASYNC TASK QUEUES
810        TechnologyRule {
811            name: "Celery".to_string(),
812            category: TechnologyCategory::Library(LibraryType::Utility),
813            confidence: 0.90,
814            dependency_patterns: vec!["celery".to_string(), "Celery".to_string()],
815            requires: vec![],
816            conflicts_with: vec![],
817            is_primary_indicator: false,
818            alternative_names: vec![],
819            file_indicators: vec![],
820        },
821        TechnologyRule {
822            name: "RQ".to_string(),
823            category: TechnologyCategory::Library(LibraryType::Utility),
824            confidence: 0.85,
825            dependency_patterns: vec!["rq".to_string(), "RQ".to_string()],
826            requires: vec![],
827            conflicts_with: vec![],
828            is_primary_indicator: false,
829            alternative_names: vec![],
830            file_indicators: vec![],
831        },
832        TechnologyRule {
833            name: "Dramatiq".to_string(),
834            category: TechnologyCategory::Library(LibraryType::Utility),
835            confidence: 0.85,
836            dependency_patterns: vec!["dramatiq".to_string(), "Dramatiq".to_string()],
837            requires: vec![],
838            conflicts_with: vec![],
839            is_primary_indicator: false,
840            alternative_names: vec![],
841            file_indicators: vec![],
842        },
843        TechnologyRule {
844            name: "Huey".to_string(),
845            category: TechnologyCategory::Library(LibraryType::Utility),
846            confidence: 0.85,
847            dependency_patterns: vec!["huey".to_string(), "Huey".to_string()],
848            requires: vec![],
849            conflicts_with: vec![],
850            is_primary_indicator: false,
851            alternative_names: vec![],
852            file_indicators: vec![],
853        },
854        
855        // CONFIGURATION
856        TechnologyRule {
857            name: "Pydantic".to_string(),
858            category: TechnologyCategory::Library(LibraryType::Utility),
859            confidence: 0.90,
860            dependency_patterns: vec!["pydantic".to_string(), "Pydantic".to_string()],
861            requires: vec![],
862            conflicts_with: vec![],
863            is_primary_indicator: false,
864            alternative_names: vec![],
865            file_indicators: vec![],
866        },
867        TechnologyRule {
868            name: "ConfigParser".to_string(),
869            category: TechnologyCategory::Library(LibraryType::Utility),
870            confidence: 0.80,
871            dependency_patterns: vec!["configparser".to_string()],
872            requires: vec![],
873            conflicts_with: vec![],
874            is_primary_indicator: false,
875            alternative_names: vec![],
876            file_indicators: vec![],
877        },
878        TechnologyRule {
879            name: "PyYAML".to_string(),
880            category: TechnologyCategory::Library(LibraryType::Utility),
881            confidence: 0.85,
882            dependency_patterns: vec!["pyyaml".to_string(), "PyYAML".to_string()],
883            requires: vec![],
884            conflicts_with: vec![],
885            is_primary_indicator: false,
886            alternative_names: vec!["yaml".to_string()],
887            file_indicators: vec![],
888        },
889        TechnologyRule {
890            name: "Toml".to_string(),
891            category: TechnologyCategory::Library(LibraryType::Utility),
892            confidence: 0.85,
893            dependency_patterns: vec!["toml".to_string(), "Toml".to_string()],
894            requires: vec![],
895            conflicts_with: vec![],
896            is_primary_indicator: false,
897            alternative_names: vec![],
898            file_indicators: vec![],
899        },
900        
901        // HTTP CLIENTS
902        TechnologyRule {
903            name: "Requests".to_string(),
904            category: TechnologyCategory::Library(LibraryType::HttpClient),
905            confidence: 0.90,
906            dependency_patterns: vec!["requests".to_string(), "Requests".to_string()],
907            requires: vec![],
908            conflicts_with: vec![],
909            is_primary_indicator: false,
910            alternative_names: vec![],
911            file_indicators: vec![],
912        },
913        TechnologyRule {
914            name: "Httpx".to_string(),
915            category: TechnologyCategory::Library(LibraryType::HttpClient),
916            confidence: 0.85,
917            dependency_patterns: vec!["httpx".to_string(), "Httpx".to_string()],
918            requires: vec![],
919            conflicts_with: vec![],
920            is_primary_indicator: false,
921            alternative_names: vec![],
922            file_indicators: vec![],
923        },
924        TechnologyRule {
925            name: "Aiohttp Client".to_string(),
926            category: TechnologyCategory::Library(LibraryType::HttpClient),
927            confidence: 0.85,
928            dependency_patterns: vec!["aiohttp".to_string()],
929            requires: vec![],
930            conflicts_with: vec![],
931            is_primary_indicator: false,
932            alternative_names: vec![],
933            file_indicators: vec![],
934        },
935        TechnologyRule {
936            name: "Urllib3".to_string(),
937            category: TechnologyCategory::Library(LibraryType::HttpClient),
938            confidence: 0.80,
939            dependency_patterns: vec!["urllib3".to_string(), "Urllib3".to_string()],
940            requires: vec![],
941            conflicts_with: vec![],
942            is_primary_indicator: false,
943            alternative_names: vec![],
944            file_indicators: vec![],
945        },
946    ]
947}