vega-framework 0.1.20__py3-none-any.whl → 0.1.23__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.
- vega/cli/commands/generate.py +98 -2
- vega/cli/main.py +8 -3
- vega/cli/templates/infrastructure/repository_impl.py.j2 +2 -2
- vega/cli/templates/infrastructure/service_impl.py.j2 +1 -1
- vega/cli/templates/project/ARCHITECTURE.md.j2 +75 -0
- vega/cli/templates/web/request_model.py.j2 +18 -0
- vega/cli/templates/web/response_model.py.j2 +18 -0
- {vega_framework-0.1.20.dist-info → vega_framework-0.1.23.dist-info}/METADATA +1 -1
- {vega_framework-0.1.20.dist-info → vega_framework-0.1.23.dist-info}/RECORD +12 -10
- {vega_framework-0.1.20.dist-info → vega_framework-0.1.23.dist-info}/WHEEL +0 -0
- {vega_framework-0.1.20.dist-info → vega_framework-0.1.23.dist-info}/entry_points.txt +0 -0
- {vega_framework-0.1.20.dist-info → vega_framework-0.1.23.dist-info}/licenses/LICENSE +0 -0
vega/cli/commands/generate.py
CHANGED
@@ -16,6 +16,7 @@ from vega.cli.templates import (
|
|
16
16
|
render_sqlalchemy_model,
|
17
17
|
render_cli_command,
|
18
18
|
render_cli_command_simple,
|
19
|
+
render_template,
|
19
20
|
)
|
20
21
|
from vega.cli.scaffolds import create_fastapi_scaffold
|
21
22
|
|
@@ -69,6 +70,8 @@ def generate_component(
|
|
69
70
|
name: str,
|
70
71
|
project_path: str,
|
71
72
|
implementation: str | None = None,
|
73
|
+
is_request: bool = False,
|
74
|
+
is_response: bool = False,
|
72
75
|
):
|
73
76
|
"""Generate a component in the Vega project"""
|
74
77
|
|
@@ -126,6 +129,8 @@ def generate_component(
|
|
126
129
|
_generate_middleware(project_root, project_name, class_name, file_name)
|
127
130
|
elif component_type == 'model':
|
128
131
|
_generate_sqlalchemy_model(project_root, project_name, class_name, file_name)
|
132
|
+
elif component_type == 'webmodel':
|
133
|
+
_generate_web_models(project_root, project_name, name, is_request, is_response)
|
129
134
|
elif component_type == 'command':
|
130
135
|
_generate_command(project_root, project_name, name, implementation)
|
131
136
|
|
@@ -448,7 +453,98 @@ def _generate_router(project_root: Path, project_name: str, name: str) -> None:
|
|
448
453
|
click.echo(f" 1. Create Pydantic models in presentation/web/models/{resource_file}_models.py")
|
449
454
|
click.echo(f" 2. Implement domain interactors for {resource_name} operations")
|
450
455
|
click.echo(f" 3. Replace in-memory storage with actual use cases")
|
451
|
-
click.echo(click.style(f" (Router auto-discovered from web/routes/)", fg='
|
456
|
+
click.echo(click.style(f" (Router auto-discovered from web/routes/)", fg='bright_black'))
|
457
|
+
|
458
|
+
|
459
|
+
def _generate_web_models(project_root: Path, project_name: str, name: str, is_request: bool, is_response: bool) -> None:
|
460
|
+
"""Generate Pydantic request or response model for FastAPI"""
|
461
|
+
|
462
|
+
# Check if web folder exists
|
463
|
+
web_path = project_root / "presentation" / "web"
|
464
|
+
if not web_path.exists():
|
465
|
+
click.echo(click.style("ERROR: Web module not found", fg='red'))
|
466
|
+
click.echo(" Model generation requires FastAPI web module")
|
467
|
+
click.echo(" Install it with: vega add web")
|
468
|
+
return
|
469
|
+
|
470
|
+
# Validate flags
|
471
|
+
if not is_request and not is_response:
|
472
|
+
click.echo(click.style("ERROR: Must specify either --request or --response", fg='red'))
|
473
|
+
click.echo(" Examples:")
|
474
|
+
click.echo(" vega generate webmodel CreateUserRequest --request")
|
475
|
+
click.echo(" vega generate webmodel UserResponse --response")
|
476
|
+
return
|
477
|
+
|
478
|
+
if is_request and is_response:
|
479
|
+
click.echo(click.style("ERROR: Cannot specify both --request and --response", fg='red'))
|
480
|
+
click.echo(" Use separate commands to generate both types")
|
481
|
+
return
|
482
|
+
|
483
|
+
# Ensure models directory exists
|
484
|
+
models_path = web_path / "models"
|
485
|
+
models_path.mkdir(exist_ok=True)
|
486
|
+
|
487
|
+
# Ensure __init__.py exists
|
488
|
+
init_file = models_path / "__init__.py"
|
489
|
+
if not init_file.exists():
|
490
|
+
init_file.write_text('"""Pydantic models for API validation"""\n')
|
491
|
+
|
492
|
+
# Convert name to PascalCase for class names
|
493
|
+
model_name = to_pascal_case(name)
|
494
|
+
model_file = to_snake_case(model_name)
|
495
|
+
|
496
|
+
# Determine model type
|
497
|
+
if is_request:
|
498
|
+
template_file = "request_model.py.j2"
|
499
|
+
description = "Request model for API validation"
|
500
|
+
model_type = "request"
|
501
|
+
else:
|
502
|
+
template_file = "response_model.py.j2"
|
503
|
+
description = "Response model for API data"
|
504
|
+
model_type = "response"
|
505
|
+
|
506
|
+
# Generate model file
|
507
|
+
file_path = models_path / f"{model_file}.py"
|
508
|
+
|
509
|
+
if file_path.exists():
|
510
|
+
# Append to existing file
|
511
|
+
click.echo(click.style(f"WARNING: {file_path.relative_to(project_root)} already exists", fg='yellow'))
|
512
|
+
click.echo(f" Appending {model_name} to existing file...")
|
513
|
+
|
514
|
+
content = render_template(
|
515
|
+
template_file,
|
516
|
+
subfolder="web",
|
517
|
+
model_name=model_name,
|
518
|
+
description=description
|
519
|
+
)
|
520
|
+
|
521
|
+
# Remove imports from template since they're already in the file
|
522
|
+
lines = content.split('\n')
|
523
|
+
class_start = next((i for i, line in enumerate(lines) if line.startswith('class ')), 0)
|
524
|
+
content_to_append = '\n\n' + '\n'.join(lines[class_start:])
|
525
|
+
|
526
|
+
with file_path.open('a', encoding='utf-8') as f:
|
527
|
+
f.write(content_to_append)
|
528
|
+
|
529
|
+
click.echo(click.style("+ ", fg='green', bold=True) + f"Added {model_name} to {file_path.relative_to(project_root)}")
|
530
|
+
else:
|
531
|
+
# Create new file
|
532
|
+
content = render_template(
|
533
|
+
template_file,
|
534
|
+
subfolder="web",
|
535
|
+
model_name=model_name,
|
536
|
+
description=description
|
537
|
+
)
|
538
|
+
file_path.write_text(content, encoding='utf-8')
|
539
|
+
|
540
|
+
click.echo(click.style("+ ", fg='green', bold=True) + f"Created {file_path.relative_to(project_root)}")
|
541
|
+
|
542
|
+
# Instructions for next steps
|
543
|
+
click.echo(f"\nNext steps:")
|
544
|
+
click.echo(f" 1. Add fields to {model_name} in {file_path.relative_to(project_root)}")
|
545
|
+
click.echo(f" 2. Update the Config.json_schema_extra with example values")
|
546
|
+
click.echo(f" 3. Import in your router:")
|
547
|
+
click.echo(f" from presentation.web.models.{model_file} import {model_name}")
|
452
548
|
|
453
549
|
|
454
550
|
def _generate_middleware(project_root: Path, project_name: str, class_name: str, file_name: str) -> None:
|
@@ -804,6 +900,6 @@ def _generate_command(project_root: Path, project_name: str, name: str, is_async
|
|
804
900
|
click.echo(f"\nNext steps:")
|
805
901
|
click.echo(f" 1. Implement your command logic in {command_file.relative_to(project_root)}")
|
806
902
|
click.echo(f" 2. Run your command: python main.py {command_name}")
|
807
|
-
click.echo(click.style(f" (Commands are auto-discovered from cli/commands/)", fg='
|
903
|
+
click.echo(click.style(f" (Commands are auto-discovered from cli/commands/)", fg='bright_black'))
|
808
904
|
if with_interactor:
|
809
905
|
click.echo(f" 3. Create interactor: vega generate interactor {interactor_name}")
|
vega/cli/main.py
CHANGED
@@ -56,12 +56,14 @@ def init(project_name, template, path):
|
|
56
56
|
|
57
57
|
@cli.command()
|
58
58
|
@click.argument('component_type', type=click.Choice([
|
59
|
-
'entity', 'repository', 'repo', 'service', 'interactor', 'mediator', 'router', 'middleware', 'model', 'command'
|
59
|
+
'entity', 'repository', 'repo', 'service', 'interactor', 'mediator', 'router', 'middleware', 'webmodel', 'model', 'command'
|
60
60
|
]))
|
61
61
|
@click.argument('name')
|
62
62
|
@click.option('--path', default='.', help='Project root path')
|
63
63
|
@click.option('--impl', default=None, help='Generate infrastructure implementation for repository/service (e.g., memory, sql) or command type (async, sync)')
|
64
|
-
|
64
|
+
@click.option('--request', is_flag=True, help='Generate request model (for webmodel)')
|
65
|
+
@click.option('--response', is_flag=True, help='Generate response model (for webmodel)')
|
66
|
+
def generate(component_type, name, path, impl, request, response):
|
65
67
|
"""
|
66
68
|
Generate a component in your Vega project.
|
67
69
|
|
@@ -74,6 +76,7 @@ def generate(component_type, name, path, impl):
|
|
74
76
|
mediator - Workflow (orchestrates use cases)
|
75
77
|
router - FastAPI router (requires web module)
|
76
78
|
middleware - FastAPI middleware (requires web module)
|
79
|
+
webmodel - Pydantic request/response models (requires web module)
|
77
80
|
model - SQLAlchemy model (requires sqlalchemy module)
|
78
81
|
command - CLI command (async by default)
|
79
82
|
|
@@ -85,6 +88,8 @@ def generate(component_type, name, path, impl):
|
|
85
88
|
vega generate mediator CheckoutFlow
|
86
89
|
vega generate router Product
|
87
90
|
vega generate middleware Logging
|
91
|
+
vega generate webmodel CreateUserRequest --request
|
92
|
+
vega generate webmodel UserResponse --response
|
88
93
|
vega generate model User
|
89
94
|
vega generate command CreateUser
|
90
95
|
vega generate command ListUsers --impl sync
|
@@ -93,7 +98,7 @@ def generate(component_type, name, path, impl):
|
|
93
98
|
if component_type == 'repo':
|
94
99
|
component_type = 'repository'
|
95
100
|
|
96
|
-
generate_component(component_type, name, path, impl)
|
101
|
+
generate_component(component_type, name, path, impl, request, response)
|
97
102
|
|
98
103
|
|
99
104
|
@cli.command()
|
@@ -1,8 +1,8 @@
|
|
1
1
|
"""{{ impl_class }} implementation"""
|
2
2
|
from typing import List
|
3
3
|
|
4
|
-
from
|
5
|
-
from
|
4
|
+
from domain.entities.{{ entity_file }} import {{ entity_name }}
|
5
|
+
from domain.repositories.{{ interface_file_name }} import {{ interface_class_name }}
|
6
6
|
|
7
7
|
|
8
8
|
class {{ impl_class }}({{ interface_class_name }}):
|
@@ -342,6 +342,8 @@ The generator will interactively prompt for:
|
|
342
342
|
- Whether to use interactors
|
343
343
|
- Parameter types and validation
|
344
344
|
|
345
|
+
Commands are **automatically discovered** from `presentation/cli/commands/` - no manual registration required.
|
346
|
+
|
345
347
|
**FastAPI Routers** - HTTP API endpoints (requires web support):
|
346
348
|
```bash
|
347
349
|
vega generate router User
|
@@ -349,6 +351,8 @@ vega generate router Product
|
|
349
351
|
vega generate router Order
|
350
352
|
```
|
351
353
|
|
354
|
+
Routers are **automatically discovered** from `presentation/web/routes/` - no manual registration required.
|
355
|
+
|
352
356
|
**FastAPI Middleware** - Request/response processing (requires web support):
|
353
357
|
```bash
|
354
358
|
vega generate middleware Logging
|
@@ -488,6 +492,77 @@ vega doctor
|
|
488
492
|
|
489
493
|
For complete documentation, see the [README](README.md#cli-commands).
|
490
494
|
|
495
|
+
## Auto-Discovery
|
496
|
+
|
497
|
+
Vega Framework provides **automatic component discovery** for routers and commands, eliminating manual registration boilerplate.
|
498
|
+
|
499
|
+
### How It Works
|
500
|
+
|
501
|
+
The framework automatically scans specific directories and registers components at runtime:
|
502
|
+
|
503
|
+
**CLI Commands Discovery:**
|
504
|
+
- Location: `presentation/cli/commands/`
|
505
|
+
- Discovers: All `click.Command` instances
|
506
|
+
- Convention: Export commands in module files
|
507
|
+
|
508
|
+
**Router Discovery:**
|
509
|
+
- Location: `presentation/web/routes/`
|
510
|
+
- Discovers: All `APIRouter` instances named `router`
|
511
|
+
- Convention: Each file exports a `router = APIRouter()`
|
512
|
+
|
513
|
+
### Usage Example
|
514
|
+
|
515
|
+
**Creating a new router:**
|
516
|
+
```bash
|
517
|
+
vega generate router Product
|
518
|
+
```
|
519
|
+
|
520
|
+
This creates `presentation/web/routes/product.py`:
|
521
|
+
```python
|
522
|
+
from fastapi import APIRouter
|
523
|
+
|
524
|
+
router = APIRouter() # MUST be named 'router'
|
525
|
+
|
526
|
+
@router.get("/")
|
527
|
+
async def list_products():
|
528
|
+
return {"products": []}
|
529
|
+
```
|
530
|
+
|
531
|
+
The router is **automatically**:
|
532
|
+
- ✅ Discovered by scanning the routes directory
|
533
|
+
- ✅ Registered with prefix `/product`
|
534
|
+
- ✅ Tagged as "Product"
|
535
|
+
- ✅ Available at `/api/product`
|
536
|
+
|
537
|
+
**No manual registration needed!**
|
538
|
+
|
539
|
+
### Framework Implementation
|
540
|
+
|
541
|
+
The discovery system is centralized in the framework:
|
542
|
+
|
543
|
+
```python
|
544
|
+
# In presentation/web/routes/__init__.py (auto-generated)
|
545
|
+
from vega.discovery import discover_routers
|
546
|
+
|
547
|
+
def get_api_router():
|
548
|
+
return discover_routers(__package__)
|
549
|
+
```
|
550
|
+
|
551
|
+
```python
|
552
|
+
# In presentation/cli/commands/__init__.py (auto-generated)
|
553
|
+
from vega.discovery import discover_commands
|
554
|
+
|
555
|
+
def get_commands():
|
556
|
+
return discover_commands(__package__)
|
557
|
+
```
|
558
|
+
|
559
|
+
### Benefits
|
560
|
+
|
561
|
+
- **Zero Boilerplate**: No need to manually import and register components
|
562
|
+
- **Convention Over Configuration**: Follow naming conventions, get automatic registration
|
563
|
+
- **Maintainability**: Add/remove components without touching configuration files
|
564
|
+
- **Consistency**: Same pattern as dependency injection (`@bind`, `@injectable`)
|
565
|
+
|
491
566
|
## Dependency Injection
|
492
567
|
|
493
568
|
Vega provides automatic dependency injection through decorators and a container.
|
@@ -0,0 +1,18 @@
|
|
1
|
+
from pydantic import BaseModel, Field
|
2
|
+
from typing import Optional
|
3
|
+
|
4
|
+
|
5
|
+
class {{ model_name }}(BaseModel):
|
6
|
+
"""{{ description }}"""
|
7
|
+
# Add your fields here
|
8
|
+
# Example:
|
9
|
+
# name: str = Field(..., min_length=1, max_length=100, description="Name field")
|
10
|
+
# email: str = Field(..., description="Email address")
|
11
|
+
# age: Optional[int] = Field(None, ge=0, description="Age field")
|
12
|
+
|
13
|
+
class Config:
|
14
|
+
json_schema_extra = {
|
15
|
+
"example": {
|
16
|
+
# Add example values here
|
17
|
+
}
|
18
|
+
}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
from pydantic import BaseModel, Field
|
2
|
+
from typing import Optional
|
3
|
+
|
4
|
+
|
5
|
+
class {{ model_name }}(BaseModel):
|
6
|
+
"""{{ description }}"""
|
7
|
+
# Add your fields here
|
8
|
+
# Example:
|
9
|
+
# id: str = Field(..., description="Unique identifier")
|
10
|
+
# name: str = Field(..., description="Name field")
|
11
|
+
# created_at: str = Field(..., description="Creation timestamp")
|
12
|
+
|
13
|
+
class Config:
|
14
|
+
json_schema_extra = {
|
15
|
+
"example": {
|
16
|
+
# Add example values here
|
17
|
+
}
|
18
|
+
}
|
@@ -2,11 +2,11 @@ vega/__init__.py,sha256=A05RwOYXooAZUz3GnbJ--ofLXgtRZK9gaSmsLVRdGPY,1811
|
|
2
2
|
vega/cli/__init__.py,sha256=NCzOOyhKHqLeN1r80ekhMfkQwBdAQXKcKiKoNwYPNiY,304
|
3
3
|
vega/cli/commands/__init__.py,sha256=UH7MdYduBG_YoulgdiWkUCtcgGLzuYRGFzxaqoa0pyg,19
|
4
4
|
vega/cli/commands/add.py,sha256=yiFXD4wb6gc_1nA-ofzt7VQKOaNbeMGNmJ-LQWG6Gh4,5110
|
5
|
-
vega/cli/commands/generate.py,sha256=
|
5
|
+
vega/cli/commands/generate.py,sha256=sR8d-0mgF9Aq0qy-QGAB_-JndCw82EpkwHcXQQxDMnM,34569
|
6
6
|
vega/cli/commands/init.py,sha256=C_ye_hOIyaIUalSfXmLBE7QfSpHoZ_LTB-h2HPP6_R8,6064
|
7
7
|
vega/cli/commands/migrate.py,sha256=00swKeVhmKr1_1VJhg3GpIMcJ6Jfgz5FUpmJoLf5qSQ,3805
|
8
8
|
vega/cli/commands/update.py,sha256=0zRWkHvQwKGlJL9XF3bi--dThkFapyNOugL6AgGr6Ic,5897
|
9
|
-
vega/cli/main.py,sha256=
|
9
|
+
vega/cli/main.py,sha256=_UEgiHj9OrNu-pqNrTQ6Fkp_fRBfs2wxU4n7JCMadyo,5072
|
10
10
|
vega/cli/scaffolds/__init__.py,sha256=WFJf2H_4UWL89gDxX8PXKkTVSVOfw7hFfyaPWKokp1g,217
|
11
11
|
vega/cli/scaffolds/fastapi.py,sha256=a_vZVSfMgyteRURFZAShbtjSRMOSM4YeEIKKvBtAOfo,3788
|
12
12
|
vega/cli/scaffolds/sqlalchemy.py,sha256=il5JqiA8LSQKnNoOYfAFD82rdYx5l_ZsqsjHnplYohw,6164
|
@@ -21,12 +21,12 @@ vega/cli/templates/domain/mediator.py.j2,sha256=gdEDNscYaB3wOemaVrFr3qKVE5sTS5wR
|
|
21
21
|
vega/cli/templates/domain/repository_interface.py.j2,sha256=oywc1Uvyx-bBrUveE-bMt4x4eO2LCf5EUbddPbNGXm8,579
|
22
22
|
vega/cli/templates/domain/service_interface.py.j2,sha256=Pq-wwGvGbns9Z_2lqL8Xi2_G-MMU-0JjAuGW94H6mrE,330
|
23
23
|
vega/cli/templates/infrastructure/model.py.j2,sha256=zNY4m7BZJeQhdu_bTFY6WIhizsYW4eJY6PS1DCs0vbE,796
|
24
|
-
vega/cli/templates/infrastructure/repository_impl.py.j2,sha256=
|
25
|
-
vega/cli/templates/infrastructure/service_impl.py.j2,sha256=
|
24
|
+
vega/cli/templates/infrastructure/repository_impl.py.j2,sha256=Rmip4Swh3wdJRioVOWKgJVQgl45Y9STu3M-oviaOrPM,488
|
25
|
+
vega/cli/templates/infrastructure/service_impl.py.j2,sha256=JYCfPDOcdVd-x1Y0nSh7qoHLc2yEsDhEraS1YGm5iiQ,376
|
26
26
|
vega/cli/templates/loader.py,sha256=cyt9ZOVLwBgv4ijPxoqR4JgFSbdkXCMzviHcq3fdv8Q,2712
|
27
27
|
vega/cli/templates/project/.env.example,sha256=BqfRxYeOasgZMz4_B2kybu6areIy9dHCt5BJ6fa56ik,221
|
28
28
|
vega/cli/templates/project/.gitignore,sha256=7JSDihCtBznd-QxQ4wUtHM9fnbYnbw6PK4Auh56ofAY,229
|
29
|
-
vega/cli/templates/project/ARCHITECTURE.md.j2,sha256=
|
29
|
+
vega/cli/templates/project/ARCHITECTURE.md.j2,sha256=HunrJ_9LlPxd5-GONaJxjoLlw-XfjYaLpsVHFa72Yf4,25868
|
30
30
|
vega/cli/templates/project/README.md.j2,sha256=Oea0AiDb_rm-GPsLFAPhYEpMmtHt_pqCRjrreymZj8Y,4601
|
31
31
|
vega/cli/templates/project/config.py.j2,sha256=1Iva9JEz5ej_WmTbRVBvOfSBhYUKIzN88p6GYKR0m4s,866
|
32
32
|
vega/cli/templates/project/main.py.j2,sha256=RfasD-JOYv8rjtZOapmh7YNybvtsdIGED7pzyRxNyAM,2733
|
@@ -44,6 +44,8 @@ vega/cli/templates/web/health_route.py.j2,sha256=iq30wENqti14j3JOfVqJNO4WAE2NiNY
|
|
44
44
|
vega/cli/templates/web/main.py.j2,sha256=QKWFDUNeIESkmVrvUIcRQH0DXnMu5fRCH2uHp3u8Sws,312
|
45
45
|
vega/cli/templates/web/middleware.py.j2,sha256=ild8nAdq45HGCiA-XVcWgmMBCfwIgORcZ7qsykmOclw,2165
|
46
46
|
vega/cli/templates/web/models_init.py.j2,sha256=QdNOaZ6iMh3Tz7uut1VA3XUIivYD1SkHFmDHCfstqho,159
|
47
|
+
vega/cli/templates/web/request_model.py.j2,sha256=sD91Gxgeelj6g3XV9QgqyfpAn86EdD4zVESD54B-eZU,527
|
48
|
+
vega/cli/templates/web/response_model.py.j2,sha256=tDZoeMRb7OweACG77jAixJgOcx0Vv7HwirrjkanLQ2s,497
|
47
49
|
vega/cli/templates/web/router.py.j2,sha256=5FgBYTcsdHH24Y9GtlsPWMllwygFO5aaCNCqNQGlhgc,4295
|
48
50
|
vega/cli/templates/web/routes_init.py.j2,sha256=uyeuLGRZ-bDY-xefJ1eI9wU1kt9z7lwoVjw_nvY7Vk4,397
|
49
51
|
vega/cli/templates/web/routes_init_autodiscovery.py.j2,sha256=jxvFGmWsmW1tMCeOoYfPi4l0U94YkUxcZm2VFsGgTsw,310
|
@@ -69,8 +71,8 @@ vega/patterns/repository.py,sha256=uYUyLs-O8OqW1Wb9ZqIo8UUcCjZ5UFuHors_F2iDg9A,1
|
|
69
71
|
vega/patterns/service.py,sha256=buFRgJoeQtZQK22Upb4vh84c1elWKFXWBaB0X4RaruE,1374
|
70
72
|
vega/settings/__init__.py,sha256=Eb8PMUyXAlCAQIcL2W8QhTTUHUbVlkAfXdpTUlADo1I,786
|
71
73
|
vega/settings/base.py,sha256=bL45hyoa3t-hQOvur860eSo7O833sQMsXJJPwbTVbwE,1321
|
72
|
-
vega_framework-0.1.
|
73
|
-
vega_framework-0.1.
|
74
|
-
vega_framework-0.1.
|
75
|
-
vega_framework-0.1.
|
76
|
-
vega_framework-0.1.
|
74
|
+
vega_framework-0.1.23.dist-info/METADATA,sha256=BXMTa0Evjhiw7vC2JOIJDOPZQYWCisC02AZUDB-pRFc,12271
|
75
|
+
vega_framework-0.1.23.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
|
76
|
+
vega_framework-0.1.23.dist-info/entry_points.txt,sha256=p3gyTmPYjNRLbuiKS-hG3ytWd-ssBweFy6VZ-F9FTNk,42
|
77
|
+
vega_framework-0.1.23.dist-info/licenses/LICENSE,sha256=wlHh1MBTcs2kSQr99P30mZ61s7uh7Cp9Rk0YiJxots0,1084
|
78
|
+
vega_framework-0.1.23.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|