langvision 0.0.1__py3-none-any.whl → 0.1.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.

Potentially problematic release.


This version of langvision might be problematic. Click here for more details.

Files changed (41) hide show
  1. langvision/__init__.py +77 -2
  2. langvision/callbacks/base.py +166 -7
  3. langvision/cli/__init__.py +85 -0
  4. langvision/cli/complete_cli.py +319 -0
  5. langvision/cli/config.py +344 -0
  6. langvision/cli/evaluate.py +201 -0
  7. langvision/cli/export.py +177 -0
  8. langvision/cli/finetune.py +165 -48
  9. langvision/cli/model_zoo.py +162 -0
  10. langvision/cli/train.py +27 -13
  11. langvision/cli/utils.py +258 -0
  12. langvision/components/attention.py +4 -1
  13. langvision/concepts/__init__.py +9 -0
  14. langvision/concepts/ccot.py +30 -0
  15. langvision/concepts/cot.py +29 -0
  16. langvision/concepts/dpo.py +37 -0
  17. langvision/concepts/grpo.py +25 -0
  18. langvision/concepts/lime.py +37 -0
  19. langvision/concepts/ppo.py +47 -0
  20. langvision/concepts/rlhf.py +40 -0
  21. langvision/concepts/rlvr.py +25 -0
  22. langvision/concepts/shap.py +37 -0
  23. langvision/data/enhanced_datasets.py +582 -0
  24. langvision/model_zoo.py +169 -2
  25. langvision/models/lora.py +189 -17
  26. langvision/models/multimodal.py +297 -0
  27. langvision/models/resnet.py +303 -0
  28. langvision/training/advanced_trainer.py +478 -0
  29. langvision/training/trainer.py +30 -2
  30. langvision/utils/config.py +180 -9
  31. langvision/utils/metrics.py +448 -0
  32. langvision/utils/setup.py +266 -0
  33. langvision-0.1.0.dist-info/METADATA +50 -0
  34. langvision-0.1.0.dist-info/RECORD +61 -0
  35. {langvision-0.0.1.dist-info → langvision-0.1.0.dist-info}/WHEEL +1 -1
  36. langvision-0.1.0.dist-info/entry_points.txt +2 -0
  37. langvision-0.0.1.dist-info/METADATA +0 -463
  38. langvision-0.0.1.dist-info/RECORD +0 -40
  39. langvision-0.0.1.dist-info/entry_points.txt +0 -2
  40. langvision-0.0.1.dist-info/licenses/LICENSE +0 -21
  41. {langvision-0.0.1.dist-info → langvision-0.1.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,266 @@
1
+ """
2
+ Setup utilities for Langvision framework initialization and validation.
3
+ """
4
+
5
+ import torch
6
+ import logging
7
+ import warnings
8
+ from typing import Optional, Dict, Any
9
+ import sys
10
+ import os
11
+ from pathlib import Path
12
+
13
+
14
+ def setup_logging(level: str = "INFO",
15
+ log_file: Optional[str] = None,
16
+ format_string: Optional[str] = None) -> logging.Logger:
17
+ """Setup comprehensive logging for Langvision."""
18
+
19
+ if format_string is None:
20
+ format_string = '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
21
+
22
+ # Configure root logger
23
+ logging.basicConfig(
24
+ level=getattr(logging, level.upper()),
25
+ format=format_string,
26
+ handlers=[
27
+ logging.StreamHandler(sys.stdout),
28
+ ] + ([logging.FileHandler(log_file)] if log_file else [])
29
+ )
30
+
31
+ # Get langvision logger
32
+ logger = logging.getLogger("langvision")
33
+ logger.info(f"Langvision logging initialized at {level} level")
34
+
35
+ return logger
36
+
37
+
38
+ def validate_environment() -> Dict[str, Any]:
39
+ """Validate the environment for Langvision usage."""
40
+
41
+ validation_results = {
42
+ "python_version": sys.version,
43
+ "pytorch_version": torch.__version__,
44
+ "cuda_available": torch.cuda.is_available(),
45
+ "cuda_version": None,
46
+ "gpu_count": 0,
47
+ "mps_available": False,
48
+ "warnings": [],
49
+ "errors": []
50
+ }
51
+
52
+ # Check CUDA
53
+ if torch.cuda.is_available():
54
+ validation_results["cuda_version"] = torch.version.cuda
55
+ validation_results["gpu_count"] = torch.cuda.device_count()
56
+ validation_results["gpu_names"] = [
57
+ torch.cuda.get_device_name(i) for i in range(torch.cuda.device_count())
58
+ ]
59
+ else:
60
+ validation_results["warnings"].append("CUDA not available - using CPU")
61
+
62
+ # Check MPS (Apple Silicon)
63
+ if hasattr(torch.backends, 'mps') and torch.backends.mps.is_available():
64
+ validation_results["mps_available"] = True
65
+
66
+ # Check Python version
67
+ if sys.version_info < (3, 8):
68
+ validation_results["errors"].append(
69
+ f"Python 3.8+ required, found {sys.version_info.major}.{sys.version_info.minor}"
70
+ )
71
+
72
+ # Check PyTorch version
73
+ torch_version = tuple(map(int, torch.__version__.split('.')[:2]))
74
+ if torch_version < (1, 10):
75
+ validation_results["warnings"].append(
76
+ f"PyTorch 1.10+ recommended, found {torch.__version__}"
77
+ )
78
+
79
+ return validation_results
80
+
81
+
82
+ def setup_cuda(seed: int = 42,
83
+ deterministic: bool = False,
84
+ benchmark: bool = True,
85
+ max_split_size_mb: Optional[int] = None) -> None:
86
+ """Setup CUDA environment for optimal performance."""
87
+
88
+ if not torch.cuda.is_available():
89
+ warnings.warn("CUDA not available, skipping CUDA setup")
90
+ return
91
+
92
+ # Set random seeds
93
+ torch.manual_seed(seed)
94
+ torch.cuda.manual_seed(seed)
95
+ torch.cuda.manual_seed_all(seed)
96
+
97
+ # Configure CUDA settings
98
+ torch.backends.cudnn.deterministic = deterministic
99
+ torch.backends.cudnn.benchmark = benchmark
100
+
101
+ # Memory management
102
+ if max_split_size_mb:
103
+ os.environ['PYTORCH_CUDA_ALLOC_CONF'] = f'max_split_size_mb:{max_split_size_mb}'
104
+
105
+ # Clear cache
106
+ torch.cuda.empty_cache()
107
+
108
+ logger = logging.getLogger("langvision.setup")
109
+ logger.info(f"CUDA setup completed with {torch.cuda.device_count()} GPUs")
110
+
111
+
112
+ def set_seed(seed: int = 42) -> None:
113
+ """Set random seeds for reproducibility."""
114
+ import random
115
+ import numpy as np
116
+
117
+ random.seed(seed)
118
+ np.random.seed(seed)
119
+ torch.manual_seed(seed)
120
+
121
+ if torch.cuda.is_available():
122
+ torch.cuda.manual_seed(seed)
123
+ torch.cuda.manual_seed_all(seed)
124
+
125
+ # For deterministic behavior
126
+ torch.backends.cudnn.deterministic = True
127
+ torch.backends.cudnn.benchmark = False
128
+
129
+
130
+ def check_dependencies() -> Dict[str, bool]:
131
+ """Check if optional dependencies are available."""
132
+
133
+ dependencies = {}
134
+
135
+ # Core dependencies
136
+ try:
137
+ import torch
138
+ dependencies["torch"] = True
139
+ except ImportError:
140
+ dependencies["torch"] = False
141
+
142
+ try:
143
+ import torchvision
144
+ dependencies["torchvision"] = True
145
+ except ImportError:
146
+ dependencies["torchvision"] = False
147
+
148
+ # Optional dependencies
149
+ try:
150
+ import transformers
151
+ dependencies["transformers"] = True
152
+ except ImportError:
153
+ dependencies["transformers"] = False
154
+
155
+ try:
156
+ import wandb
157
+ dependencies["wandb"] = True
158
+ except ImportError:
159
+ dependencies["wandb"] = False
160
+
161
+ try:
162
+ import sklearn
163
+ dependencies["sklearn"] = True
164
+ except ImportError:
165
+ dependencies["sklearn"] = False
166
+
167
+ try:
168
+ import cv2
169
+ dependencies["opencv"] = True
170
+ except ImportError:
171
+ dependencies["opencv"] = False
172
+
173
+ try:
174
+ import pandas
175
+ dependencies["pandas"] = True
176
+ except ImportError:
177
+ dependencies["pandas"] = False
178
+
179
+ return dependencies
180
+
181
+
182
+ def initialize_langvision(config: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
183
+ """Initialize Langvision framework with comprehensive setup."""
184
+
185
+ if config is None:
186
+ config = {}
187
+
188
+ # Setup logging
189
+ log_level = config.get("log_level", "INFO")
190
+ log_file = config.get("log_file", None)
191
+ logger = setup_logging(log_level, log_file)
192
+
193
+ logger.info("Initializing Langvision framework...")
194
+
195
+ # Validate environment
196
+ validation_results = validate_environment()
197
+
198
+ # Log validation results
199
+ logger.info(f"Python version: {validation_results['python_version']}")
200
+ logger.info(f"PyTorch version: {validation_results['pytorch_version']}")
201
+
202
+ if validation_results["cuda_available"]:
203
+ logger.info(f"CUDA version: {validation_results['cuda_version']}")
204
+ logger.info(f"GPU count: {validation_results['gpu_count']}")
205
+ for i, gpu_name in enumerate(validation_results.get("gpu_names", [])):
206
+ logger.info(f"GPU {i}: {gpu_name}")
207
+
208
+ if validation_results["mps_available"]:
209
+ logger.info("MPS (Apple Silicon) available")
210
+
211
+ # Log warnings and errors
212
+ for warning in validation_results["warnings"]:
213
+ logger.warning(warning)
214
+
215
+ for error in validation_results["errors"]:
216
+ logger.error(error)
217
+
218
+ if validation_results["errors"]:
219
+ raise RuntimeError("Environment validation failed with errors")
220
+
221
+ # Setup CUDA if requested and available
222
+ if config.get("setup_cuda", True) and validation_results["cuda_available"]:
223
+ setup_cuda(
224
+ seed=config.get("seed", 42),
225
+ deterministic=config.get("deterministic", False),
226
+ benchmark=config.get("benchmark", True),
227
+ max_split_size_mb=config.get("max_split_size_mb", None)
228
+ )
229
+
230
+ # Set random seed
231
+ if "seed" in config:
232
+ set_seed(config["seed"])
233
+ logger.info(f"Random seed set to {config['seed']}")
234
+
235
+ # Check dependencies
236
+ dependencies = check_dependencies()
237
+ missing_deps = [dep for dep, available in dependencies.items() if not available]
238
+
239
+ if missing_deps:
240
+ logger.warning(f"Missing optional dependencies: {missing_deps}")
241
+ logger.info("Install with: pip install langvision[all] for full functionality")
242
+
243
+ logger.info("Langvision framework initialization completed successfully!")
244
+
245
+ return {
246
+ "validation_results": validation_results,
247
+ "dependencies": dependencies,
248
+ "config": config
249
+ }
250
+
251
+
252
+ # Convenience function for quick setup
253
+ def quick_setup(seed: int = 42,
254
+ log_level: str = "INFO",
255
+ use_cuda: bool = True) -> None:
256
+ """Quick setup for Langvision with sensible defaults."""
257
+
258
+ config = {
259
+ "seed": seed,
260
+ "log_level": log_level,
261
+ "setup_cuda": use_cuda,
262
+ "benchmark": True,
263
+ "deterministic": False
264
+ }
265
+
266
+ initialize_langvision(config)
@@ -0,0 +1,50 @@
1
+ Metadata-Version: 2.1
2
+ Name: langvision
3
+ Version: 0.1.0
4
+ Summary: Efficient LoRA Fine-Tuning for Vision LLMs with advanced CLI and model zoo
5
+ Home-page: https://github.com/langtrain-ai/langtrain
6
+ Author: Pritesh Raj
7
+ Author-email: priteshraj10@gmail.com
8
+ Keywords: vision,transformer,lora,fine-tuning,deep-learning,computer-vision
9
+ Classifier: Development Status :: 4 - Beta
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Intended Audience :: Science/Research
12
+ Classifier: Operating System :: OS Independent
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.8
15
+ Classifier: Programming Language :: Python :: 3.9
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
20
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
21
+ Requires-Python: >=3.8
22
+ Requires-Dist: torch>=1.10.0
23
+ Requires-Dist: torchvision>=0.11.0
24
+ Requires-Dist: numpy>=1.21.0
25
+ Requires-Dist: pillow>=8.3.0
26
+ Requires-Dist: tqdm>=4.62.0
27
+ Requires-Dist: pyyaml>=6.0
28
+ Requires-Dist: tensorboard>=2.9.0
29
+ Requires-Dist: wandb>=0.13.0
30
+ Provides-Extra: dev
31
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
32
+ Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
33
+ Requires-Dist: pytest-mock>=3.8.0; extra == "dev"
34
+ Requires-Dist: black>=22.0.0; extra == "dev"
35
+ Requires-Dist: isort>=5.10.0; extra == "dev"
36
+ Requires-Dist: flake8>=5.0.0; extra == "dev"
37
+ Requires-Dist: mypy>=1.0.0; extra == "dev"
38
+ Requires-Dist: pre-commit>=2.20.0; extra == "dev"
39
+ Requires-Dist: bandit>=1.7.0; extra == "dev"
40
+ Provides-Extra: docs
41
+ Requires-Dist: sphinx>=5.0.0; extra == "docs"
42
+ Requires-Dist: sphinx-rtd-theme>=1.0.0; extra == "docs"
43
+ Requires-Dist: myst-parser>=0.18.0; extra == "docs"
44
+ Requires-Dist: sphinx-autodoc-typehints>=1.19.0; extra == "docs"
45
+ Provides-Extra: examples
46
+ Requires-Dist: jupyter>=1.0.0; extra == "examples"
47
+ Requires-Dist: ipywidgets>=7.6.0; extra == "examples"
48
+ Requires-Dist: tensorboard>=2.9.0; extra == "examples"
49
+ Requires-Dist: wandb>=0.13.0; extra == "examples"
50
+
@@ -0,0 +1,61 @@
1
+ langvision/__init__.py,sha256=1K-pmG7huJTVWdGXiWQmmvaI2QYJoFVty2X-5kkebu8,2758
2
+ langvision/example.py,sha256=KpPS_3hV4eFBysTRH4qcVQffVlkcwcWjDhhafbcXku0,85
3
+ langvision/model_zoo.py,sha256=S3_rtAQV_eswIyJICfiwoBw9jQqlXy9fu0irlM8GETs,5491
4
+ langvision/agents/__init__.py,sha256=8whI81DC6F9ZoV24_GOzD8LwYKcUXIc53TgWQILM6ng,141
5
+ langvision/callbacks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ langvision/callbacks/base.py,sha256=hnShvmpOtv3fH9LAPzklOOx1Xi1v32awb9i8F0LZtCM,6794
7
+ langvision/callbacks/early_stopping.py,sha256=LKWO5TiQ05WCNabO1utm9tdOfBgp9lwRmIGmXO73Gaw,543
8
+ langvision/callbacks/logging.py,sha256=Wk882TpUa_CyhbGKgp8IZyOUYuQPnO5l-uBACWdxFKs,404
9
+ langvision/callbacks/registry.py,sha256=70Zq-hYWBuqxxSKEOUbKEBEdwdHY3qJc8GLpz7am0IM,191
10
+ langvision/cli/__init__.py,sha256=WEFs8f61xkxialeYOW2A67utuT6JSRRoTcgGcFuWoSc,3381
11
+ langvision/cli/complete_cli.py,sha256=Dqv-eAhMTNyq8YWsofAuPhHX6NkYfs8hB5wZlYUGm7o,13870
12
+ langvision/cli/config.py,sha256=nuOgEhBMdetDmaF9-KI-58LBUsloCCd2JYKrnEiemSg,13181
13
+ langvision/cli/evaluate.py,sha256=a4KsI61BGZ3X-16ruGQRqWMANV-cVYuecsrzPcNdpmY,7593
14
+ langvision/cli/export.py,sha256=ufkB7sa1vNTwW0WT-PsxP3Jsvpf87wgkYIFZSatkSf0,6781
15
+ langvision/cli/finetune.py,sha256=66f88ViTImq7mC6pqq39_76WRN7OnBs4y4J0zYEU2Zk,14668
16
+ langvision/cli/model_zoo.py,sha256=lbuiYiLu39a3MWGB24CpsY8684rv4wCcpfknr9YogeE,6369
17
+ langvision/cli/train.py,sha256=RFPV0GsH9cexfUVM1Sbk_nqcLOK9QD1cswWL9AkLmKY,5301
18
+ langvision/cli/utils.py,sha256=-Ymmr_-x2U-za13KF5kfmdnpxCs8zXiyNh95y8qjQBs,7509
19
+ langvision/components/__init__.py,sha256=Nqnn8clbgv-5l0PgxcTOldg8mkMKrFn4TvPL-rYUUGg,1
20
+ langvision/components/attention.py,sha256=NVWIEkZ8pIi8K3iS5KQpKC3hJgMl7UozIFf7vkpx9Ro,2163
21
+ langvision/components/mlp.py,sha256=t9ELFMGLhG8zTICG5xRmrYm7b-IcszRUNGIBSwBVCas,246
22
+ langvision/components/patch_embedding.py,sha256=C_HFjD4rixhxoxg2QhRjY-j_iwd0_eCnPdveVBos3D8,574
23
+ langvision/concepts/__init__.py,sha256=_kYp1XEiLJIQQz0s_lM11K8r-qGc4vdJtpUNntt57RA,201
24
+ langvision/concepts/ccot.py,sha256=yIgvGOdezW8ZtmxodLvMUtzF4JzxuZw-6lCK16UHXY0,1149
25
+ langvision/concepts/cot.py,sha256=KwUpP3JbXu6GfPfl_jnZC1siXs3VgETCnmdXW94jMug,941
26
+ langvision/concepts/dpo.py,sha256=o6mCuV-axjA61j_fslvHGcJPgdupX5j-XPC0lYvXgOU,1428
27
+ langvision/concepts/grpo.py,sha256=QzAOaOzMcIhJTWqCjMOIrDYV3hoa6R3BRe9t1wV-hCc,810
28
+ langvision/concepts/lime.py,sha256=NUO8-rC7AtjMLFKNOc-a87uA_4zPSXKfBILNMdwBF-g,1500
29
+ langvision/concepts/ppo.py,sha256=MpnuDsxbTM2iPnwKRkM3qtxXNxrZfzaM1tudLE-Wc8E,1855
30
+ langvision/concepts/rlhf.py,sha256=0v6tiqi8LXwgYDKcOYzzgWkq5eaAFSSE_yJbrUs-JXs,1594
31
+ langvision/concepts/rlvr.py,sha256=wfhODtH_rw3dIiEe4ZgDaNVGPLmKnyQg01aK14Uc9vU,765
32
+ langvision/concepts/shap.py,sha256=c1NzDO5QoKn_rnG2uW4RPrtnObWaBIl6INWwn6gIVwM,1295
33
+ langvision/config/__init__.py,sha256=1V4Mn4_qbz0xmPYcboNjorImNkqYyRlL5r0amFdVu98,312
34
+ langvision/data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
35
+ langvision/data/datasets.py,sha256=B27d0BX87RR1kNlwuT1QUszSP-b3zbCKQVR2lebIs1A,739
36
+ langvision/data/enhanced_datasets.py,sha256=G7S_o74tDVRXk5vtSg4vchZiGd-Drt4uvwUxaonylNU,22023
37
+ langvision/filesystem/__init__.py,sha256=XvdZcHNCAk3mdLesBIdUEvp9Of9wVlYKqAfDGDmqbbA,318
38
+ langvision/llm/__init__.py,sha256=KFZ0plTNQU72wS3cLUxEbz15HtcOhBJrdt4rZUnOyvE,85
39
+ langvision/memory/__init__.py,sha256=j3hnLDohdr_eVOHCgvPU7XlG3taBbC1u-YhR_Kqd5xw,487
40
+ langvision/models/__init__.py,sha256=Nqnn8clbgv-5l0PgxcTOldg8mkMKrFn4TvPL-rYUUGg,1
41
+ langvision/models/lora.py,sha256=SfY7csz8kUQWI26ZmeQTO_twffxeT_Wpon9S0oO2fZs,7582
42
+ langvision/models/multimodal.py,sha256=VYXM3jHl3Yr5_cdOYyn0e4G7mQ2NEi3LELwtgdvXeP0,11953
43
+ langvision/models/resnet.py,sha256=0EObpib94xywm1-5wxSUVwAg6uGxoZZaOvBIX8eaVVI,11733
44
+ langvision/models/vision_transformer.py,sha256=oA01la5qvRn8i4lGaQ7da71_ExHmNtGq2mrqUByIpNs,1244
45
+ langvision/sync/__init__.py,sha256=MdC6UeCjrrsrmaOy1qNK0hA9ijd1CJvWMkVHo7B7gwU,373
46
+ langvision/telemetry/__init__.py,sha256=DMz1ACz7KtSOr2uqtKfEQ_yk_PrvdlH2zHeMH-NdHiA,210
47
+ langvision/training/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
48
+ langvision/training/advanced_trainer.py,sha256=OrfOjDomM5XZFAVfrXBTUrTGzLjQdxwnqq4KTkiZrnM,18438
49
+ langvision/training/trainer.py,sha256=xqtyUkUMiHZLJvGCc8iqfODKmuXxsadPxSsRA_engTE,5635
50
+ langvision/utils/__init__.py,sha256=xwagF_TAjkaFPDMv67lqOZblpkiWBrM5lwNYpntvFds,828
51
+ langvision/utils/config.py,sha256=KALv8nP8WN31Q9Uij2ihF6tgp4z8u9MxtU42hIarEoA,5453
52
+ langvision/utils/cuda.py,sha256=rpp0j-tvwGK6uWVe7fFTOS1BdZcsfRkw2AS5B08L-R0,1372
53
+ langvision/utils/data.py,sha256=95U8Z_R2slwpaBVFrqyvcBA6kYINcEuzp1r5djvwQYg,277
54
+ langvision/utils/device.py,sha256=TLVwXHFcildDyKh1Q7zczIyU702UJj7OHpsGhjRwLjk,552
55
+ langvision/utils/metrics.py,sha256=gcPKrAamz2YKGKk07bdT0DxpgnQc3DHcccnK5CB_dgw,17272
56
+ langvision/utils/setup.py,sha256=tHv9_G8q0C0VAZ5UqN8HIIz4LX5QVSqrd1PKqYFp9P0,8046
57
+ langvision-0.1.0.dist-info/METADATA,sha256=qyiyvK3EO6CphApDm5y53OpY_klOBjDPPhznOlq8Pr0,2129
58
+ langvision-0.1.0.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
59
+ langvision-0.1.0.dist-info/entry_points.txt,sha256=KAVJFWwV8QDww6yOit8YrkhJDujHd8RKFbuKcRpdajg,51
60
+ langvision-0.1.0.dist-info/top_level.txt,sha256=l3g51kgU-5cacP4nhASSfYADOCAwLC4UzlgVwuoJCgc,11
61
+ langvision-0.1.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (75.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ langvision = langvision.cli:main