Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
86 commits
Select commit Hold shift + click to select a range
307389c
Add abstract storage interface to support multiple backends in HardPy
rici4kubicek Dec 8, 2025
4b5e48f
Add StorageFactory to support configurable storage backends (JSON, Co…
rici4kubicek Dec 8, 2025
c71fac7
Add JSON file-based storage implementation for HardPy
rici4kubicek Dec 8, 2025
8e10875
Refactor storage system to support multiple backends (JSON, CouchDB) …
rici4kubicek Dec 8, 2025
5b06726
Add API endpoints to fetch storage type and retrieve JSON storage data
rici4kubicek Dec 8, 2025
4c35cec
frontend: Switch to `useStorageData` hook and integrate backend-drive…
rici4kubicek Dec 8, 2025
4708e24
frontend: Add `useStorageData` hook to support dynamic storage type d…
rici4kubicek Dec 8, 2025
e4522d2
examples: Add demo for JSON storage usage
rici4kubicek Dec 8, 2025
7164911
examples: Simplify comment on storage type in demo config
rici4kubicek Dec 8, 2025
5d4b392
docs: Update hardpy_config.md to document `storage_type` option for J…
rici4kubicek Dec 8, 2025
0182643
examples: Remove unnecessary comments from demo_json_storage conftest…
rici4kubicek Dec 8, 2025
1d4d6af
examples: Remove copyright comments from test modules in demo_json_st…
rici4kubicek Dec 8, 2025
898a8df
api: Use `logger.exception` for better error trace in JSON storage ha…
rici4kubicek Dec 8, 2025
76fe2b0
db: Improve logging for JSONDecodeError and suppress noqa warning
rici4kubicek Dec 8, 2025
8a67a97
db: Suppress specific noqa warning in runstore schema assignment
rici4kubicek Dec 8, 2025
78593a4
db: Suppress specific noqa warning in runstore schema assignment
rici4kubicek Dec 8, 2025
a6e7ae3
db: Add type checking for IStorage import, improve exception messages…
rici4kubicek Dec 8, 2025
677c829
docs: Adjust storage_interface docstring formatting for clarity
rici4kubicek Dec 8, 2025
751baa9
db: Refactor logging and return paths in tempstore; suppress addition…
rici4kubicek Dec 8, 2025
0d680a1
config: Add `storage_path` attribute for JSON storage type
rici4kubicek Dec 9, 2025
0c76685
Revert "Auxiliary commit to revert individual files from 0d680a1c6270…
rici4kubicek Dec 9, 2025
667a4f6
db: Update JSON storage directory to use `storage_path` from config
rici4kubicek Dec 9, 2025
58c9a00
examples: Add `storage_path` to hardpy.toml in demo_json_storage
rici4kubicek Dec 9, 2025
a8cb417
docs: Update hardpy_config with `storage_path` details and usage
rici4kubicek Dec 9, 2025
2bfc282
docs: Update JsonFileStore docstring to reflect `storage_path` usage
rici4kubicek Dec 9, 2025
14aec64
db: Reformat `_storage_dir` assignment for improved readability
rici4kubicek Dec 9, 2025
0db3faa
db: Replace `ModelMetaclass` with `BaseModel` across database modules
rici4kubicek Dec 9, 2025
8c2a194
db: Introduce TempStoreInterface and implement JsonTempStore and Couc…
rici4kubicek Dec 9, 2025
04ef085
db: Rename `base_store` to `couchdb_store` for clarity and consistency
rici4kubicek Dec 9, 2025
c6cde7a
db: Replace BaseStore with CouchDBStore and remove backward compatibi…
rici4kubicek Dec 9, 2025
bcb3359
docs: Fix typo in hardpy_config `storage_path` section
rici4kubicek Dec 9, 2025
a44804b
db: Rename `IStorage` to `Storage` across database modules for clarit…
rici4kubicek Dec 9, 2025
51b40c4
db: Replace `ModelMetaclass` with `BaseModel` in `statestore` module …
rici4kubicek Dec 9, 2025
6faecc9
db: Introduce `RunStoreInterface` and implement `JsonRunStore`, `Couc…
rici4kubicek Dec 9, 2025
d4c220d
db: Replace string-based storage type with `StorageType` enum across …
rici4kubicek Dec 9, 2025
538b9b2
db: Update imports for improved type-checking compatibility and remov…
rici4kubicek Dec 9, 2025
466ecc9
db: Add schema-based validation to storage modules and refactor initi…
rici4kubicek Dec 9, 2025
1c03e84
db: Ensure `id` field is always set in temp store reports
rici4kubicek Dec 9, 2025
feb4390
db: Handle missing `id` field in temp store reports gracefully
rici4kubicek Dec 9, 2025
9fb1098
db: Consolidate document initialization logic with `_create_default_d…
rici4kubicek Dec 9, 2025
df29ae2
Apply suggestions from code review
rici4kubicek Dec 11, 2025
98761dd
gitignore: Add `.hardpy` to ignored files
rici4kubicek Dec 15, 2025
70d8184
db: Handle missing paths in document access and ensure safe updates w…
rici4kubicek Dec 15, 2025
05aa0e9
db: Add `_rev` field to default document structure for CouchDB compat…
rici4kubicek Dec 15, 2025
ba2a981
db: Ensure storage directory exists before persisting JSON file
rici4kubicek Dec 15, 2025
9388882
reporter: Use `set_doc_value` for setting stop times in modules and c…
rici4kubicek Dec 15, 2025
e926403
reporter: Fix stop time key generation formatting for consistency
rici4kubicek Dec 15, 2025
0046b36
db: Replace interface-based run store implementation with storage fac…
rici4kubicek Dec 15, 2025
15296d7
db: Introduce abstract state store interface with JSON and CouchDB im…
rici4kubicek Dec 15, 2025
0f966aa
db: Refactor state store to use factory pattern and remove redundant …
rici4kubicek Dec 15, 2025
be77fd7
db: Refactor temp store to use factory pattern and remove unused methods
rici4kubicek Dec 15, 2025
4e05e59
refactor(db): consolidate storage implementations and remove redundan…
rici4kubicek Dec 15, 2025
b0d7fa8
refactor(db): extract `_create_default_doc_structure` into shared fun…
rici4kubicek Dec 15, 2025
a085ab2
Apply suggestions from code review
rici4kubicek Dec 15, 2025
66a5b00
refactor(db): improve exception imports and simplify storage type han…
rici4kubicek Dec 15, 2025
d72efab
refactor(db): clean up exception imports and streamline storage type …
rici4kubicek Dec 15, 2025
8885b3a
refactor(db): simplify storage type conditional checks in temp store
rici4kubicek Dec 15, 2025
ce51ae3
refactor(db): reformat multiline statements for improved readability
rici4kubicek Dec 15, 2025
05b974c
refactor(db): add type annotations, clean up unused imports, and impr…
rici4kubicek Dec 15, 2025
f1b0d0f
refactor(db): handle relative storage paths for better flexibility
rici4kubicek Dec 24, 2025
18cc74d
refactor(db): include `store_name` in storage path and use `doc_id` f…
rici4kubicek Dec 24, 2025
b351dea
fix(plugin): correct argument for `set_module_stop_time` and `set_cas…
rici4kubicek Dec 25, 2025
6b70ba9
Merge pull request #243 from rici4kubicek/bug/pluginValidateStopTime
xorialexandrov Dec 26, 2025
e910325
Merge branch 'develop' into feature/json_storage
xorialexandrov Dec 29, 2025
0bc8bb3
Update hardpy/pytest_hardpy/plugin.py
xorialexandrov Dec 29, 2025
807acd5
Merge pull request #239 from rici4kubicek/feature/json_storage
xorialexandrov Dec 29, 2025
8251765
Merge remote-tracking branch 'origin/main' into feature/json_support_doc
Alexandroviliav Dec 29, 2025
a3dbe7c
Update package to 0.20.0
Alexandroviliav Dec 29, 2025
5c8791b
Add JSON info
Alexandroviliav Dec 29, 2025
bdd9ae6
[documentation] Add storage type info
Alexandroviliav Dec 29, 2025
64b231f
[hardpy] Add storage_type
Alexandroviliav Dec 29, 2025
f51036b
[test_cli] Add storage_type test
Alexandroviliav Dec 29, 2025
9b40b64
[examples] Add storage_type
Alexandroviliav Dec 29, 2025
95bf5b9
[common] Add storage_type docstring
Alexandroviliav Dec 29, 2025
a4e527f
[test_config] Add storage_type
Alexandroviliav Dec 29, 2025
cfa42ed
Add uuid6 for uuid7 using
Alexandroviliav Dec 29, 2025
d863684
[pytest_hardpy] Fix JSON tempstore usage
Alexandroviliav Dec 29, 2025
d1293cb
[.vscode] Add JSON storage example
Alexandroviliav Dec 29, 2025
527cb28
Add json_storage.md
Alexandroviliav Dec 29, 2025
cb39cee
Add example without a database
Alexandroviliav Dec 29, 2025
6563164
[docs] Fix link
Alexandroviliav Dec 29, 2025
c514ecd
[docs] Add JSON features
Alexandroviliav Dec 29, 2025
49582e9
[json_storage] Mv json storage example
Alexandroviliav Dec 29, 2025
79a6de6
[hardpy] Add JsonLoader
Alexandroviliav Dec 29, 2025
9f6a2a5
[test_plugin] Add JSON tests
Alexandroviliav Dec 29, 2025
d01fca3
Merge pull request #244 from everypinio/feature/json_support_doc
xorialexandrov Dec 29, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ dist
.mypy_cache
__pycache__/
node_modules/
.hardpy
11 changes: 11 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,17 @@
"examples/minute_parity"
]
},
{
"name": "Python: Example JSON storage",
"type": "debugpy",
"request": "launch",
"module": "hardpy.cli.cli",
"console": "integratedTerminal",
"args": [
"run",
"examples/json_storage"
]
},
{
"name": "Python: Example Multiple configs",
"type": "debugpy",
Expand Down
18 changes: 16 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ HardPy is a python library for creating a test bench for devices.
[![pytest versions](https://img.shields.io/badge/pytest-%3E%3D7.0-blue)](https://docs.pytest.org/en/latest/)
[![Documentation](https://img.shields.io/badge/Documentation%20-Overview%20-%20%23007ec6)](https://everypinio.github.io/hardpy/)
[![Reddit](https://img.shields.io/badge/-Reddit-FF4500?style=flat&logo=reddit&logoColor=white)](https://www.reddit.com/r/HardPy)
[![Discord](https://img.shields.io/discord/1304494076799877172?color=7389D8&label&logo=discord&logoColor=ffffff)](https://discord.com/invite/3kBG9CbS)
[![Discord](https://img.shields.io/discord/1304494076799877172?color=7389D8&label&logo=discord&logoColor=ffffff)](https://discord.gg/98bWadmG8J)
[![Telegram](https://img.shields.io/badge/-Telegram-2CA5E0?style=flat&logo=telegram&logoColor=white)](https://t.me/everypin)

</div>
Expand All @@ -26,7 +26,7 @@ HardPy allows you to:

* Create test benches for devices using [pytest](https://docs.pytest.org/);
* Use a browser to view, start, stop, and interact with tests;
* Store test results in the [CouchDB](https://couchdb.apache.org/) database;
* Store test results in the [CouchDB](https://couchdb.apache.org/) database or to simple JSON files;
* Store test results on the [StandCloud](https://standcloud.io/) analytics platform.

<h1 align="center">
Expand All @@ -41,6 +41,8 @@ pip install hardpy

## Getting Started

### With CouchDB

1. Create your first test bench.
```bash
hardpy init
Expand All @@ -59,6 +61,18 @@ hardpy run

Login and password: **dev**, database - **runstore**.

### Without a database

1. Create your first test bench.
```bash
hardpy init --no-create-database --storage-type json
```
2. Launch HardPy operator panel.
```bash
hardpy run
```
3. View operator panel in browser: http://localhost:8000/

## Examples

For more examples of using **HardPy**, see the [examples](https://github.com/everypinio/hardpy/tree/main/examples) folder and the [documentation](https://everypinio.github.io/hardpy/examples/).
Expand Down
7 changes: 6 additions & 1 deletion docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

Versions follow [Semantic Versioning](https://semver.org/): `<major>.<minor>.<patch>`.

## 0.20.0

* Add JSON file storage support as alternative to CouchDB.
[[PR-239](https://github.com/everypinio/hardpy/pull/239)]

## 0.19.1

* Add a `stop_time` validator function. If a case or module has a start time,
Expand All @@ -19,7 +24,7 @@ Versions follow [Semantic Versioning](https://semver.org/): `<major>.<minor>.<pa
tests to run via UI checkboxes.
[[PR-224](https://github.com/everypinio/hardpy/pull/224)]
* Add multiple test plan configurations.
[[PR-225]](https://github.com/everypinio/hardpy/pull/225)
[[PR-225](https://github.com/everypinio/hardpy/pull/225)]

## 0.18.3

Expand Down
1 change: 1 addition & 0 deletions docs/documentation/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ More info in [hardpy config](./hardpy_config.md).
| [default: no-sc-autosync] │
| [default: check-stand-cloud] │
│ --sc-api-key TEXT Specify a StandCloud API key. │
│ --storage-type TEXT Specify a storage type. [default: couchdb] |
│ --help Show this message and exit. │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
```
Expand Down
23 changes: 23 additions & 0 deletions docs/documentation/hardpy_config.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ tests_name = "My tests"
current_test_config = ""

[database]
storage_type = "couchdb"
user = "dev"
password = "dev"
host = "localhost"
Expand Down Expand Up @@ -81,6 +82,28 @@ An example of its use can be found on page [Multiple configs](./../examples/mult

Database settings.

#### storage_type

Storage type. The default is `couchdb`.

- `couchdb`: Stores test results and measurements in a CouchDB database. Requires a running CouchDB instance.
- `json`: Stores test results and measurements in local JSON files. No external database required.

Files are stored in the `.hardpy` directory in the root of the project.
The user can change this value with the `hardpy init --storage-type` option.

#### storage_path

Path to the storage directory. The default is `.hardpy` in the root of the project.
The user can change this value in the hardpy.toml file using the `storage_path` option.
Both relative and absolute paths are supported.

```toml
[database]
storage_type = "json"
storage_path = "result"
```

#### user

Database user name. The default is `dev`.
Expand Down
29 changes: 29 additions & 0 deletions docs/documentation/pytest_hardpy.md
Original file line number Diff line number Diff line change
Expand Up @@ -911,6 +911,35 @@ def fill_actions_after_test(post_run_functions: list):
yield
```

#### JsonLoader

Used to write reports to the JSON.

**Arguments:**

- `storage_dir` *(Path | None)*: JSON file directory.

**Functions:**

- `load` *(ResultRunStore, new_report_id)*: Load report to the JSON file.

**Example:**

```python
# conftest
def save_report_to_dir():
report = get_current_report()
if report:
loader = JsonLoader(Path.cwd() / "reports")
loader.load(report)


@pytest.fixture(scope="session", autouse=True)
def fill_actions_after_test(post_run_functions: list):
post_run_functions.append(save_report_to_dir)
yield
```

#### StandCloudLoader

Used to write reports to the **StandCloud**.
Expand Down
Loading