speculast 1.0.1__tar.gz
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.
- speculast-1.0.1/.gitignore +8 -0
- speculast-1.0.1/PKG-INFO +292 -0
- speculast-1.0.1/README.md +264 -0
- speculast-1.0.1/demo_shop/__init__.py +22 -0
- speculast-1.0.1/demo_shop/database.py +89 -0
- speculast-1.0.1/demo_shop/logic.py +50 -0
- speculast-1.0.1/demo_shop/models.py +94 -0
- speculast-1.0.1/demo_shop/service.py +88 -0
- speculast-1.0.1/engine/__init__.py +64 -0
- speculast-1.0.1/engine/analyzer/__init__.py +12 -0
- speculast-1.0.1/engine/analyzer/engine.py +414 -0
- speculast-1.0.1/engine/analyzer/visitors.py +304 -0
- speculast-1.0.1/engine/core/__init__.py +47 -0
- speculast-1.0.1/engine/core/i18n.py +635 -0
- speculast-1.0.1/engine/core/models.py +225 -0
- speculast-1.0.1/engine/core/protocols.py +71 -0
- speculast-1.0.1/engine/generator/__init__.py +5 -0
- speculast-1.0.1/engine/generator/engine.py +267 -0
- speculast-1.0.1/engine/generator/templates/__init__.py +1 -0
- speculast-1.0.1/engine/generator/templates/integration_service_template.jinja2 +77 -0
- speculast-1.0.1/engine/generator/templates/pytest_template.jinja2 +690 -0
- speculast-1.0.1/engine/generator/templates/tests_conftest_template.jinja2 +75 -0
- speculast-1.0.1/engine/generator/templates/tests_pyproject_template.jinja2 +7 -0
- speculast-1.0.1/engine/generator/templates/unit_logic_template.jinja2 +45 -0
- speculast-1.0.1/engine/infra/__init__.py +6 -0
- speculast-1.0.1/engine/infra/manager.py +111 -0
- speculast-1.0.1/engine/infra/registry.py +52 -0
- speculast-1.0.1/engine/visualizer/__init__.py +6 -0
- speculast-1.0.1/engine/visualizer/dashboard.py +260 -0
- speculast-1.0.1/engine/visualizer/renderer.py +1373 -0
- speculast-1.0.1/engine/visualizer/templates/__init__.py +1 -0
- speculast-1.0.1/engine/visualizer/templates/report.html +2689 -0
- speculast-1.0.1/main.py +1107 -0
- speculast-1.0.1/pyproject.toml +81 -0
- speculast-1.0.1/tests/__init__.py +0 -0
- speculast-1.0.1/tests/conftest.py +75 -0
- speculast-1.0.1/tests/integration/__init__.py +0 -0
- speculast-1.0.1/tests/integration/test_service.py +72 -0
- speculast-1.0.1/tests/pyproject.toml +7 -0
- speculast-1.0.1/tests/unit/__init__.py +0 -0
- speculast-1.0.1/tests/unit/test_cli_defaults.py +76 -0
- speculast-1.0.1/tests/unit/test_dashboard_builder.py +10 -0
- speculast-1.0.1/tests/unit/test_logic.py +37 -0
- speculast-1.0.1/tests/unit/test_reporting_storage.py +177 -0
speculast-1.0.1/PKG-INFO
ADDED
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: speculast
|
|
3
|
+
Version: 1.0.1
|
|
4
|
+
Summary: Semantic-first framework for Python architecture analysis, automated test generation, and infrastructure-aware reporting.
|
|
5
|
+
Author: speculast team
|
|
6
|
+
License: Proprietary
|
|
7
|
+
Keywords: architecture-analysis,ast,automation,docker,pytest,python,reporting,semantic-analysis,testing
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
12
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
13
|
+
Classifier: Topic :: Software Development :: Testing
|
|
14
|
+
Requires-Python: >=3.12
|
|
15
|
+
Requires-Dist: asyncpg<1.0.0,>=0.29.0
|
|
16
|
+
Requires-Dist: jinja2<4.0.0,>=3.1.4
|
|
17
|
+
Requires-Dist: pydantic<3.0.0,>=2.7.0
|
|
18
|
+
Requires-Dist: pytest-asyncio<1.0.0,>=0.23.0
|
|
19
|
+
Requires-Dist: pytest-cov<7.0.0,>=5.0.0
|
|
20
|
+
Requires-Dist: pytest-json-report<2.0.0,>=1.5.0
|
|
21
|
+
Requires-Dist: pytest<9.0.0,>=8.2.0
|
|
22
|
+
Requires-Dist: rich<15.0.0,>=13.7.0
|
|
23
|
+
Requires-Dist: sqlalchemy<3.0.0,>=2.0.0
|
|
24
|
+
Provides-Extra: dev
|
|
25
|
+
Requires-Dist: ruff<1.0.0,>=0.5.0; extra == 'dev'
|
|
26
|
+
Requires-Dist: testcontainers[postgresql,redis]<5.0.0,>=4.8.0; extra == 'dev'
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
|
|
29
|
+
# speculast
|
|
30
|
+
|
|
31
|
+
`speculast` is an installable Python framework for semantic code analysis,
|
|
32
|
+
automatic pytest generation, infrastructure detection, and visual reporting.
|
|
33
|
+
|
|
34
|
+
speculast parses Python projects through AST analysis, tracks semantic changes,
|
|
35
|
+
detects external dependencies, prepares test suites, can orchestrate Docker-backed
|
|
36
|
+
integration runs, and produces a self-contained HTML report.
|
|
37
|
+
|
|
38
|
+
## What speculast Does
|
|
39
|
+
|
|
40
|
+
- analyzes Python modules and projects at the semantic level;
|
|
41
|
+
- extracts functions, methods, imports, and external calls;
|
|
42
|
+
- detects infrastructure requirements such as PostgreSQL and Redis;
|
|
43
|
+
- generates production-style pytest suites;
|
|
44
|
+
- runs a full cycle with Docker, pytest, coverage, and JSON reports;
|
|
45
|
+
- builds timestamped HTML dashboards grouped by day under `reports/`.
|
|
46
|
+
|
|
47
|
+
## Installation
|
|
48
|
+
|
|
49
|
+
Use Python `3.12+`. The project is packaged through `pyproject.toml`.
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
python -m venv .venv
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Windows:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
.venv\Scripts\activate
|
|
59
|
+
python -m pip install --upgrade pip
|
|
60
|
+
python -m pip install .
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Linux / macOS:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
source .venv/bin/activate
|
|
67
|
+
python -m pip install --upgrade pip
|
|
68
|
+
python -m pip install .
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
After installation, the CLI command `speculast` becomes available in the active environment.
|
|
72
|
+
|
|
73
|
+
## CLI Quick Reference
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
speculast [PATH] [--no-tests] [--no-viz] [--no-real-db] [--no-cleanup] [--lang ru|en] [--cleanup-reports] [--report-retention-days N]
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Examples:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
speculast
|
|
83
|
+
speculast path/to/module.py
|
|
84
|
+
speculast . --cleanup-reports --report-retention-days 7
|
|
85
|
+
speculast . --no-tests
|
|
86
|
+
speculast . --no-viz --lang en
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
By default, `speculast` runs in Full Auto mode:
|
|
90
|
+
|
|
91
|
+
- uses the current directory when `PATH` is omitted;
|
|
92
|
+
- cleans temporary root-level technical noise automatically;
|
|
93
|
+
- enables real DB mode by default;
|
|
94
|
+
- runs generated tests;
|
|
95
|
+
- builds the HTML report;
|
|
96
|
+
- opens the fresh report in the browser automatically.
|
|
97
|
+
|
|
98
|
+
`--cleanup-reports` additionally prunes aged HTML reports from `reports/`.
|
|
99
|
+
|
|
100
|
+
The default full cycle performs:
|
|
101
|
+
|
|
102
|
+
1. semantic analysis;
|
|
103
|
+
2. test generation;
|
|
104
|
+
3. infrastructure planning;
|
|
105
|
+
4. `docker compose up -d` when services are required;
|
|
106
|
+
5. pytest execution with coverage and JSON reports;
|
|
107
|
+
6. HTML report generation;
|
|
108
|
+
7. `docker compose down --remove-orphans`.
|
|
109
|
+
|
|
110
|
+
## Template and Report Portability
|
|
111
|
+
|
|
112
|
+
speculast resolves Jinja and HTML templates through `importlib.resources`.
|
|
113
|
+
This means the package can locate bundled templates correctly after `pip install .`,
|
|
114
|
+
even when `speculast` is started from an unrelated working directory.
|
|
115
|
+
|
|
116
|
+
Bundled resources include:
|
|
117
|
+
|
|
118
|
+
- `engine/generator/templates/*.jinja2`
|
|
119
|
+
- `engine/visualizer/templates/report.html`
|
|
120
|
+
|
|
121
|
+
## Scenario A: Quick Start on Any OS
|
|
122
|
+
|
|
123
|
+
Install the package and run the full autonomous cycle against the current project:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
python -m pip install .
|
|
127
|
+
speculast
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Expected outputs:
|
|
131
|
+
|
|
132
|
+
- generated test suite under `tests/`;
|
|
133
|
+
- `docker-compose.yaml` when infrastructure is required;
|
|
134
|
+
- date-grouped reports such as `reports/2026-05-14/report_131530.html`.
|
|
135
|
+
|
|
136
|
+
If you also want to keep raw pytest and coverage JSON artifacts:
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
speculast . --no-cleanup
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
If you only need the report without pytest execution:
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
speculast . --no-tests
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Scenario B: Windows + Docker Desktop
|
|
149
|
+
|
|
150
|
+
Recommended stack:
|
|
151
|
+
|
|
152
|
+
- Python `3.12+`
|
|
153
|
+
- Docker Desktop
|
|
154
|
+
- PowerShell or Windows Terminal
|
|
155
|
+
|
|
156
|
+
Typical workflow:
|
|
157
|
+
|
|
158
|
+
```powershell
|
|
159
|
+
.venv\Scripts\activate
|
|
160
|
+
python -m pip install .
|
|
161
|
+
speculast
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Notes for Windows:
|
|
165
|
+
|
|
166
|
+
- `speculast` can start and stop Docker-backed infrastructure for integration scenarios.
|
|
167
|
+
- If PostgreSQL-backed tests are generated, make sure Docker Desktop is installed and available in PATH.
|
|
168
|
+
- speculast writes final diagnostics into timestamped files inside `reports/`, while terminal output stays compact.
|
|
169
|
+
|
|
170
|
+
## Scenario C: Linux / macOS Server Mode
|
|
171
|
+
|
|
172
|
+
speculast does not require a desktop UI. The report is generated as a plain HTML file
|
|
173
|
+
that can be opened locally or archived as a build artifact.
|
|
174
|
+
|
|
175
|
+
Typical workflow:
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
source .venv/bin/activate
|
|
179
|
+
python -m pip install .
|
|
180
|
+
speculast /opt/projects/my-service --lang en
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Recommended environment preparation:
|
|
184
|
+
|
|
185
|
+
- install Docker Engine or Docker Desktop for container-backed tests;
|
|
186
|
+
- ensure the current user can run `docker compose`;
|
|
187
|
+
- run inside a CI worker, VM, or server shell without GUI if needed.
|
|
188
|
+
|
|
189
|
+
For analysis-only mode on a server:
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
speculast /opt/projects/my-service --no-tests --no-viz
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
## Scenario D: CI/CD Integration
|
|
196
|
+
|
|
197
|
+
The CLI is designed to be called directly from automated validation pipelines.
|
|
198
|
+
|
|
199
|
+
Minimal pipeline step:
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
python -m pip install .
|
|
203
|
+
speculast . --lang en
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
Recommended artifacts to publish from the job:
|
|
207
|
+
|
|
208
|
+
- `reports/`
|
|
209
|
+
- generated `tests/` directory if you want to inspect emitted suites
|
|
210
|
+
|
|
211
|
+
If the pipeline should also retain raw pytest and coverage JSON files, run with `--no-cleanup` and publish:
|
|
212
|
+
|
|
213
|
+
- `.speculast/pytest-report.json`
|
|
214
|
+
- `.speculast/coverage.json`
|
|
215
|
+
|
|
216
|
+
Example GitHub Actions step:
|
|
217
|
+
|
|
218
|
+
```yaml
|
|
219
|
+
- name: Install framework
|
|
220
|
+
run: python -m pip install .
|
|
221
|
+
|
|
222
|
+
- name: Run semantic analysis and tests
|
|
223
|
+
run: speculast . --lang en
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
Example GitLab CI job:
|
|
227
|
+
|
|
228
|
+
```yaml
|
|
229
|
+
speculast:
|
|
230
|
+
stage: test
|
|
231
|
+
script:
|
|
232
|
+
- python -m pip install .
|
|
233
|
+
- speculast . --lang en
|
|
234
|
+
artifacts:
|
|
235
|
+
when: always
|
|
236
|
+
paths:
|
|
237
|
+
- reports/
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
## Project Layout
|
|
241
|
+
|
|
242
|
+
```text
|
|
243
|
+
engine/
|
|
244
|
+
analyzer/ Semantic analysis and AST visitors
|
|
245
|
+
core/ Pydantic models, i18n, protocols
|
|
246
|
+
generator/ Jinja-based pytest generation templates and engine
|
|
247
|
+
infra/ Infrastructure detection and Docker Compose helpers
|
|
248
|
+
visualizer/ HTML dashboard rendering
|
|
249
|
+
main.py CLI entry module
|
|
250
|
+
pyproject.toml Packaging metadata and script entry points
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
## Installed CLI Entry Point
|
|
254
|
+
|
|
255
|
+
The package registers:
|
|
256
|
+
|
|
257
|
+
```toml
|
|
258
|
+
[project.scripts]
|
|
259
|
+
speculast = "main:main"
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
So after installation, `speculast` runs the same autonomous CLI cycle exposed by `main.py`.
|
|
263
|
+
|
|
264
|
+
## Output Artifacts
|
|
265
|
+
|
|
266
|
+
Depending on the mode, the framework can generate:
|
|
267
|
+
|
|
268
|
+
- `tests/`
|
|
269
|
+
- `docker-compose.yaml`
|
|
270
|
+
- `reports/`
|
|
271
|
+
|
|
272
|
+
Temporary technical artifacts such as `.speculast/`, cache folders, and browser-check profiles are removed automatically unless `--no-cleanup` is used.
|
|
273
|
+
|
|
274
|
+
## Development Notes
|
|
275
|
+
|
|
276
|
+
Runtime dependencies are declared in `pyproject.toml` and include:
|
|
277
|
+
|
|
278
|
+
- `pydantic`
|
|
279
|
+
- `jinja2`
|
|
280
|
+
- `sqlalchemy`
|
|
281
|
+
- `asyncpg`
|
|
282
|
+
- `pytest`
|
|
283
|
+
- `pytest-asyncio`
|
|
284
|
+
- `pytest-cov`
|
|
285
|
+
- `pytest-json-report`
|
|
286
|
+
- `rich`
|
|
287
|
+
|
|
288
|
+
Optional development extras:
|
|
289
|
+
|
|
290
|
+
```bash
|
|
291
|
+
python -m pip install .[dev]
|
|
292
|
+
```
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
# speculast
|
|
2
|
+
|
|
3
|
+
`speculast` is an installable Python framework for semantic code analysis,
|
|
4
|
+
automatic pytest generation, infrastructure detection, and visual reporting.
|
|
5
|
+
|
|
6
|
+
speculast parses Python projects through AST analysis, tracks semantic changes,
|
|
7
|
+
detects external dependencies, prepares test suites, can orchestrate Docker-backed
|
|
8
|
+
integration runs, and produces a self-contained HTML report.
|
|
9
|
+
|
|
10
|
+
## What speculast Does
|
|
11
|
+
|
|
12
|
+
- analyzes Python modules and projects at the semantic level;
|
|
13
|
+
- extracts functions, methods, imports, and external calls;
|
|
14
|
+
- detects infrastructure requirements such as PostgreSQL and Redis;
|
|
15
|
+
- generates production-style pytest suites;
|
|
16
|
+
- runs a full cycle with Docker, pytest, coverage, and JSON reports;
|
|
17
|
+
- builds timestamped HTML dashboards grouped by day under `reports/`.
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
Use Python `3.12+`. The project is packaged through `pyproject.toml`.
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
python -m venv .venv
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Windows:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
.venv\Scripts\activate
|
|
31
|
+
python -m pip install --upgrade pip
|
|
32
|
+
python -m pip install .
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Linux / macOS:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
source .venv/bin/activate
|
|
39
|
+
python -m pip install --upgrade pip
|
|
40
|
+
python -m pip install .
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
After installation, the CLI command `speculast` becomes available in the active environment.
|
|
44
|
+
|
|
45
|
+
## CLI Quick Reference
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
speculast [PATH] [--no-tests] [--no-viz] [--no-real-db] [--no-cleanup] [--lang ru|en] [--cleanup-reports] [--report-retention-days N]
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Examples:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
speculast
|
|
55
|
+
speculast path/to/module.py
|
|
56
|
+
speculast . --cleanup-reports --report-retention-days 7
|
|
57
|
+
speculast . --no-tests
|
|
58
|
+
speculast . --no-viz --lang en
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
By default, `speculast` runs in Full Auto mode:
|
|
62
|
+
|
|
63
|
+
- uses the current directory when `PATH` is omitted;
|
|
64
|
+
- cleans temporary root-level technical noise automatically;
|
|
65
|
+
- enables real DB mode by default;
|
|
66
|
+
- runs generated tests;
|
|
67
|
+
- builds the HTML report;
|
|
68
|
+
- opens the fresh report in the browser automatically.
|
|
69
|
+
|
|
70
|
+
`--cleanup-reports` additionally prunes aged HTML reports from `reports/`.
|
|
71
|
+
|
|
72
|
+
The default full cycle performs:
|
|
73
|
+
|
|
74
|
+
1. semantic analysis;
|
|
75
|
+
2. test generation;
|
|
76
|
+
3. infrastructure planning;
|
|
77
|
+
4. `docker compose up -d` when services are required;
|
|
78
|
+
5. pytest execution with coverage and JSON reports;
|
|
79
|
+
6. HTML report generation;
|
|
80
|
+
7. `docker compose down --remove-orphans`.
|
|
81
|
+
|
|
82
|
+
## Template and Report Portability
|
|
83
|
+
|
|
84
|
+
speculast resolves Jinja and HTML templates through `importlib.resources`.
|
|
85
|
+
This means the package can locate bundled templates correctly after `pip install .`,
|
|
86
|
+
even when `speculast` is started from an unrelated working directory.
|
|
87
|
+
|
|
88
|
+
Bundled resources include:
|
|
89
|
+
|
|
90
|
+
- `engine/generator/templates/*.jinja2`
|
|
91
|
+
- `engine/visualizer/templates/report.html`
|
|
92
|
+
|
|
93
|
+
## Scenario A: Quick Start on Any OS
|
|
94
|
+
|
|
95
|
+
Install the package and run the full autonomous cycle against the current project:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
python -m pip install .
|
|
99
|
+
speculast
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Expected outputs:
|
|
103
|
+
|
|
104
|
+
- generated test suite under `tests/`;
|
|
105
|
+
- `docker-compose.yaml` when infrastructure is required;
|
|
106
|
+
- date-grouped reports such as `reports/2026-05-14/report_131530.html`.
|
|
107
|
+
|
|
108
|
+
If you also want to keep raw pytest and coverage JSON artifacts:
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
speculast . --no-cleanup
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
If you only need the report without pytest execution:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
speculast . --no-tests
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Scenario B: Windows + Docker Desktop
|
|
121
|
+
|
|
122
|
+
Recommended stack:
|
|
123
|
+
|
|
124
|
+
- Python `3.12+`
|
|
125
|
+
- Docker Desktop
|
|
126
|
+
- PowerShell or Windows Terminal
|
|
127
|
+
|
|
128
|
+
Typical workflow:
|
|
129
|
+
|
|
130
|
+
```powershell
|
|
131
|
+
.venv\Scripts\activate
|
|
132
|
+
python -m pip install .
|
|
133
|
+
speculast
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Notes for Windows:
|
|
137
|
+
|
|
138
|
+
- `speculast` can start and stop Docker-backed infrastructure for integration scenarios.
|
|
139
|
+
- If PostgreSQL-backed tests are generated, make sure Docker Desktop is installed and available in PATH.
|
|
140
|
+
- speculast writes final diagnostics into timestamped files inside `reports/`, while terminal output stays compact.
|
|
141
|
+
|
|
142
|
+
## Scenario C: Linux / macOS Server Mode
|
|
143
|
+
|
|
144
|
+
speculast does not require a desktop UI. The report is generated as a plain HTML file
|
|
145
|
+
that can be opened locally or archived as a build artifact.
|
|
146
|
+
|
|
147
|
+
Typical workflow:
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
source .venv/bin/activate
|
|
151
|
+
python -m pip install .
|
|
152
|
+
speculast /opt/projects/my-service --lang en
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Recommended environment preparation:
|
|
156
|
+
|
|
157
|
+
- install Docker Engine or Docker Desktop for container-backed tests;
|
|
158
|
+
- ensure the current user can run `docker compose`;
|
|
159
|
+
- run inside a CI worker, VM, or server shell without GUI if needed.
|
|
160
|
+
|
|
161
|
+
For analysis-only mode on a server:
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
speculast /opt/projects/my-service --no-tests --no-viz
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## Scenario D: CI/CD Integration
|
|
168
|
+
|
|
169
|
+
The CLI is designed to be called directly from automated validation pipelines.
|
|
170
|
+
|
|
171
|
+
Minimal pipeline step:
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
python -m pip install .
|
|
175
|
+
speculast . --lang en
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Recommended artifacts to publish from the job:
|
|
179
|
+
|
|
180
|
+
- `reports/`
|
|
181
|
+
- generated `tests/` directory if you want to inspect emitted suites
|
|
182
|
+
|
|
183
|
+
If the pipeline should also retain raw pytest and coverage JSON files, run with `--no-cleanup` and publish:
|
|
184
|
+
|
|
185
|
+
- `.speculast/pytest-report.json`
|
|
186
|
+
- `.speculast/coverage.json`
|
|
187
|
+
|
|
188
|
+
Example GitHub Actions step:
|
|
189
|
+
|
|
190
|
+
```yaml
|
|
191
|
+
- name: Install framework
|
|
192
|
+
run: python -m pip install .
|
|
193
|
+
|
|
194
|
+
- name: Run semantic analysis and tests
|
|
195
|
+
run: speculast . --lang en
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Example GitLab CI job:
|
|
199
|
+
|
|
200
|
+
```yaml
|
|
201
|
+
speculast:
|
|
202
|
+
stage: test
|
|
203
|
+
script:
|
|
204
|
+
- python -m pip install .
|
|
205
|
+
- speculast . --lang en
|
|
206
|
+
artifacts:
|
|
207
|
+
when: always
|
|
208
|
+
paths:
|
|
209
|
+
- reports/
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## Project Layout
|
|
213
|
+
|
|
214
|
+
```text
|
|
215
|
+
engine/
|
|
216
|
+
analyzer/ Semantic analysis and AST visitors
|
|
217
|
+
core/ Pydantic models, i18n, protocols
|
|
218
|
+
generator/ Jinja-based pytest generation templates and engine
|
|
219
|
+
infra/ Infrastructure detection and Docker Compose helpers
|
|
220
|
+
visualizer/ HTML dashboard rendering
|
|
221
|
+
main.py CLI entry module
|
|
222
|
+
pyproject.toml Packaging metadata and script entry points
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
## Installed CLI Entry Point
|
|
226
|
+
|
|
227
|
+
The package registers:
|
|
228
|
+
|
|
229
|
+
```toml
|
|
230
|
+
[project.scripts]
|
|
231
|
+
speculast = "main:main"
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
So after installation, `speculast` runs the same autonomous CLI cycle exposed by `main.py`.
|
|
235
|
+
|
|
236
|
+
## Output Artifacts
|
|
237
|
+
|
|
238
|
+
Depending on the mode, the framework can generate:
|
|
239
|
+
|
|
240
|
+
- `tests/`
|
|
241
|
+
- `docker-compose.yaml`
|
|
242
|
+
- `reports/`
|
|
243
|
+
|
|
244
|
+
Temporary technical artifacts such as `.speculast/`, cache folders, and browser-check profiles are removed automatically unless `--no-cleanup` is used.
|
|
245
|
+
|
|
246
|
+
## Development Notes
|
|
247
|
+
|
|
248
|
+
Runtime dependencies are declared in `pyproject.toml` and include:
|
|
249
|
+
|
|
250
|
+
- `pydantic`
|
|
251
|
+
- `jinja2`
|
|
252
|
+
- `sqlalchemy`
|
|
253
|
+
- `asyncpg`
|
|
254
|
+
- `pytest`
|
|
255
|
+
- `pytest-asyncio`
|
|
256
|
+
- `pytest-cov`
|
|
257
|
+
- `pytest-json-report`
|
|
258
|
+
- `rich`
|
|
259
|
+
|
|
260
|
+
Optional development extras:
|
|
261
|
+
|
|
262
|
+
```bash
|
|
263
|
+
python -m pip install .[dev]
|
|
264
|
+
```
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"""Demo e-commerce application used by speculast."""
|
|
2
|
+
|
|
3
|
+
from .logic import (
|
|
4
|
+
calculate_discount,
|
|
5
|
+
calculate_line_total,
|
|
6
|
+
calculate_order_total,
|
|
7
|
+
validate_stock,
|
|
8
|
+
)
|
|
9
|
+
from .models import OrderCreateRequest, OrderItemRequest, OrderResult, Product
|
|
10
|
+
from .service import create_order
|
|
11
|
+
|
|
12
|
+
__all__ = [
|
|
13
|
+
"OrderCreateRequest",
|
|
14
|
+
"OrderItemRequest",
|
|
15
|
+
"OrderResult",
|
|
16
|
+
"Product",
|
|
17
|
+
"calculate_discount",
|
|
18
|
+
"calculate_line_total",
|
|
19
|
+
"calculate_order_total",
|
|
20
|
+
"create_order",
|
|
21
|
+
"validate_stock",
|
|
22
|
+
]
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"""SQLAlchemy models and helpers for the demo shop."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
from decimal import Decimal
|
|
7
|
+
|
|
8
|
+
from sqlalchemy import ForeignKey, Numeric, String
|
|
9
|
+
from sqlalchemy.ext.asyncio import AsyncEngine, AsyncSession, async_sessionmaker, create_async_engine
|
|
10
|
+
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
DEFAULT_DATABASE_URL = "postgresql+asyncpg://app:app@127.0.0.1:55432/app"
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class Base(DeclarativeBase):
|
|
17
|
+
"""Shared SQLAlchemy declarative base."""
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class ProductRecord(Base):
|
|
21
|
+
"""Catalog inventory row."""
|
|
22
|
+
|
|
23
|
+
__tablename__ = "shop_products"
|
|
24
|
+
|
|
25
|
+
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
|
|
26
|
+
sku: Mapped[str] = mapped_column(String(64), unique=True, index=True)
|
|
27
|
+
title: Mapped[str] = mapped_column(String(255))
|
|
28
|
+
unit_price: Mapped[Decimal] = mapped_column(Numeric(10, 2))
|
|
29
|
+
stock: Mapped[int] = mapped_column()
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class OrderRecord(Base):
|
|
33
|
+
"""Order header row."""
|
|
34
|
+
|
|
35
|
+
__tablename__ = "shop_orders"
|
|
36
|
+
|
|
37
|
+
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
|
|
38
|
+
customer_email: Mapped[str] = mapped_column(String(255), index=True)
|
|
39
|
+
promo_code: Mapped[str | None] = mapped_column(String(64), nullable=True)
|
|
40
|
+
subtotal: Mapped[Decimal] = mapped_column(Numeric(10, 2))
|
|
41
|
+
discount_total: Mapped[Decimal] = mapped_column(Numeric(10, 2))
|
|
42
|
+
total: Mapped[Decimal] = mapped_column(Numeric(10, 2))
|
|
43
|
+
|
|
44
|
+
items: Mapped[list["OrderItemRecord"]] = relationship(
|
|
45
|
+
back_populates="order",
|
|
46
|
+
cascade="all, delete-orphan",
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class OrderItemRecord(Base):
|
|
51
|
+
"""Order line row."""
|
|
52
|
+
|
|
53
|
+
__tablename__ = "shop_order_items"
|
|
54
|
+
|
|
55
|
+
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
|
|
56
|
+
order_id: Mapped[int] = mapped_column(ForeignKey("shop_orders.id", ondelete="CASCADE"))
|
|
57
|
+
product_id: Mapped[int] = mapped_column(ForeignKey("shop_products.id"))
|
|
58
|
+
sku: Mapped[str] = mapped_column(String(64))
|
|
59
|
+
quantity: Mapped[int] = mapped_column()
|
|
60
|
+
unit_price: Mapped[Decimal] = mapped_column(Numeric(10, 2))
|
|
61
|
+
line_total: Mapped[Decimal] = mapped_column(Numeric(10, 2))
|
|
62
|
+
|
|
63
|
+
order: Mapped[OrderRecord] = relationship(back_populates="items")
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def resolve_database_url() -> str:
|
|
67
|
+
"""Return the connection string used by integration tests and services."""
|
|
68
|
+
|
|
69
|
+
return os.getenv("DEMO_SHOP_DATABASE_URL", DEFAULT_DATABASE_URL)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def create_engine(database_url: str | None = None) -> AsyncEngine:
|
|
73
|
+
"""Build an async SQLAlchemy engine."""
|
|
74
|
+
|
|
75
|
+
return create_async_engine(
|
|
76
|
+
database_url or resolve_database_url(),
|
|
77
|
+
future=True,
|
|
78
|
+
connect_args={"ssl": False},
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def create_session_factory(database_url: str | None = None) -> async_sessionmaker[AsyncSession]:
|
|
83
|
+
"""Build a reusable async session factory."""
|
|
84
|
+
|
|
85
|
+
return async_sessionmaker(
|
|
86
|
+
create_engine(database_url),
|
|
87
|
+
class_=AsyncSession,
|
|
88
|
+
expire_on_commit=False,
|
|
89
|
+
)
|