From ea41e26bd977e7c51df8a7465742827daf51ce63 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 5 Oct 2024 13:27:07 +0200 Subject: [PATCH 1/8] fix: bump actions/checkout from 4.1.7 to 4.2.0 (#44) Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.7 to 4.2.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v4.1.7...v4.2.0) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/schedule-update-actions.yml | 2 +- .github/workflows/template-sync.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/schedule-update-actions.yml b/.github/workflows/schedule-update-actions.yml index d8bcc8a..df8387b 100644 --- a/.github/workflows/schedule-update-actions.yml +++ b/.github/workflows/schedule-update-actions.yml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4.1.7 + - uses: actions/checkout@v4.2.0 with: # [Required] Access token with `workflow` scope. token: ${{ secrets.PAT }} diff --git a/.github/workflows/template-sync.yml b/.github/workflows/template-sync.yml index 3ca48ce..2ec662b 100644 --- a/.github/workflows/template-sync.yml +++ b/.github/workflows/template-sync.yml @@ -5,7 +5,7 @@ jobs: sync: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4.1.7 # important! + - uses: actions/checkout@v4.2.0 # important! - uses: euphoricsystems/action-sync-template-repository@v2.5.1 with: github-token: ${{ secrets.GITHUB_TOKEN }} From 5386faaffcbd1ea417bc70291c404dc91209fb9f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 5 Oct 2024 13:27:25 +0200 Subject: [PATCH 2/8] fix: bump bandit[toml] from 1.7.9 to 1.7.10 (#43) Bumps [bandit[toml]](https://github.com/PyCQA/bandit) from 1.7.9 to 1.7.10. - [Release notes](https://github.com/PyCQA/bandit/releases) - [Commits](https://github.com/PyCQA/bandit/compare/1.7.9...1.7.10) --- updated-dependencies: - dependency-name: bandit[toml] dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 7a7c854..890c6c2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,7 +36,7 @@ exd-data = [ "grpcio" ] test = [ - "bandit[toml]==1.7.9", + "bandit[toml]==1.7.10", "black==24.8.0", "check-manifest==0.49", "flake8-bugbear==24.8.19", From 3fad0415578f6539c8565d955bbd16445aea1740 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 5 Oct 2024 13:27:47 +0200 Subject: [PATCH 3/8] fix: bump pylint from 3.3.0 to 3.3.1 (#42) Bumps [pylint](https://github.com/pylint-dev/pylint) from 3.3.0 to 3.3.1. - [Release notes](https://github.com/pylint-dev/pylint/releases) - [Commits](https://github.com/pylint-dev/pylint/compare/v3.3.0...v3.3.1) --- updated-dependencies: - dependency-name: pylint dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 890c6c2..87bf85f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -45,7 +45,7 @@ test = [ "flake8", "flake8-pyproject", "pre-commit==3.8.0", - "pylint==3.3.0", + "pylint==3.3.1", "pylint_junit", "pytest-cov==5.0.0", "pytest-mock<3.14.1", From 522aace11f71d28f4eff37cd6a883406153655a7 Mon Sep 17 00:00:00 2001 From: Andreas K Date: Sat, 5 Oct 2024 13:51:23 +0200 Subject: [PATCH 4/8] feat: update workflows to have rules (#45) --- .github/dependabot.yml | 2 + .github/workflows/schedule-update-actions.yml | 4 +- .github/workflows/semantic-pr-check.yml | 13 +++++ docs/branchstrategy.md | 55 +++++++++++++++++++ docs/index.rst | 1 + 5 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 docs/branchstrategy.md diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 8cd4fb9..4ceb12e 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -13,6 +13,7 @@ updates: - dependency-type: indirect commit-message: prefix: "fix: " + target-branch: dev - package-ecosystem: "github-actions" directory: "/" schedule: @@ -20,3 +21,4 @@ updates: time: "13:00" commit-message: prefix: "fix: " + target-branch: dev diff --git a/.github/workflows/schedule-update-actions.yml b/.github/workflows/schedule-update-actions.yml index df8387b..2010cb8 100644 --- a/.github/workflows/schedule-update-actions.yml +++ b/.github/workflows/schedule-update-actions.yml @@ -15,11 +15,11 @@ jobs: - uses: actions/checkout@v4.2.0 with: # [Required] Access token with `workflow` scope. - token: ${{ secrets.PAT }} + token: ${{ secrets.GITHUB_TOKEN }} - name: Run GitHub Actions Version Updater uses: saadmk11/github-actions-version-updater@v0.8.1 with: # [Required] Access token with `workflow` scope. - token: ${{ secrets.PAT }} + token: ${{ secrets.GITHUB_TOKEN }} pull_request_title: "ci: Update GitHub Actions to Latest Version" diff --git a/.github/workflows/semantic-pr-check.yml b/.github/workflows/semantic-pr-check.yml index 7fdd599..b89c6ea 100644 --- a/.github/workflows/semantic-pr-check.yml +++ b/.github/workflows/semantic-pr-check.yml @@ -15,3 +15,16 @@ jobs: - uses: amannn/action-semantic-pull-request@v5.5.3 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + restrict-merge: + name: Restrict PR to main to dev and hotfix/* + runs-on: ubuntu-latest + steps: + - name: Check source branch + if: github.event.pull_request.base.ref == 'main' + run: | + if [[ "${{ github.event.pull_request.head.ref }}" =~ ^(dev|hotfix/.*|release/.*)$ ]]; then + echo "Branch name is valid." + else + echo "Invalid branch name. Only 'dev' or 'hotfix/*' branches can be merged into 'main'." + exit 1 + fi diff --git a/docs/branchstrategy.md b/docs/branchstrategy.md new file mode 100644 index 0000000..142b685 --- /dev/null +++ b/docs/branchstrategy.md @@ -0,0 +1,55 @@ +# Repository Rules +## Branching strategy + +### Main Branches + +- **`main`**: This branch contains the stable, production-ready code. + Only thoroughly tested and approved changes are merged here. +- **`dev`**: This is the integration branch for features and fixes. + All new development work is merged here before it goes to `main`. + +### Supporting Branches + +- **Feature Branches**: Used for developing new features. + These branches are created from `dev` and merged back into `dev` once the feature is complete. + - Naming convention: `feature/feature-name` +- **Bugfix Branches**: Used for fixing bugs. These branches are also created + from `dev` and merged back into `dev` after the fix. + - Naming convention: `bugfix/bug-name` +- **Release Branches**: When preparing for a new release, a release branch is created from `dev`. + This branch is used for final testing and minor bug fixes before merging into `main`. + - Naming convention: `release/x.y.z` +- **Hotfix Branches**: For critical fixes that need to be applied to the production code immediately. + These branches are created from `main` and merged back into both `main` and `dev`. + - Naming convention: `hotfix/x.y.z` + +### Workflow Example + +#### Feature Development + +- Create a feature branch from `dev`:
`git checkout -b feature/new-feature dev` +- Develop the feature and commit changes. +- Merge the feature branch back into `dev`:
`git checkout dev && git merge feature/new-feature` +- Delete the feature branch:
`git branch -d feature/new-feature` + +#### Release Preparation + +- Create a release branch from `dev`:
`git checkout -b release/1.0.0 dev` +- Perform final testing and bug fixes. +- Merge the release branch into `main`:
`git checkout main && git merge release/1.0.0` +- Tag the release:
`git tag -a v1.0.0 -m "Release 1.0.0"` +- Merge the release branch back into `dev`:
`git checkout dev && git merge release/1.0.0` +- Delete the release branch:
`git branch -d release/1.0.0` + +#### Hotfix + +- Create a hotfix branch from `main`:
`git checkout -b hotfix/1.0.1 main` +- Apply the hotfix and commit changes. +- Merge the hotfix branch into `main`:
`git checkout main && git merge hotfix/1.0.1` +- Tag the hotfix:
`git tag -a v1.0.1 -m "Hotfix 1.0.1"` +- Merge the hotfix branch into `dev`:
`git checkout dev && git merge hotfix/1.0.1` +- Delete the hotfix branch:
`git branch -d hotfix/1.0.1` + +## Merge Requests + +Merge request must follow the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) naming rules. \ No newline at end of file diff --git a/docs/index.rst b/docs/index.rst index 6addfd1..7785506 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -10,6 +10,7 @@ Welcome to ASAM ODSBox docs's documentation! overview odsbox + branchstrategies Indices and tables ================== From a996502a296b4eaadd8860ad2a130a2048e78dc4 Mon Sep 17 00:00:00 2001 From: Andreas K Date: Sat, 5 Oct 2024 16:14:10 +0200 Subject: [PATCH 5/8] added documentation (#46) --- .vscode/settings.json | 3 + docs/index.rst | 3 +- docs/jaquel.md | 501 ++++++++++++++++++ ...{branchstrategy.md => repository_rules.md} | 2 +- src/odsbox/jaquel.py | 3 +- tests/test_data/examples_from_jaquel_doc.json | 291 ++++++++++ tests/test_jaquel_convert.py | 17 + 7 files changed, 816 insertions(+), 4 deletions(-) create mode 100644 docs/jaquel.md rename docs/{branchstrategy.md => repository_rules.md} (97%) create mode 100644 tests/test_data/examples_from_jaquel_doc.json diff --git a/.vscode/settings.json b/.vscode/settings.json index f13c3e8..b88a4eb 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -43,6 +43,7 @@ "datamatrix", "DCOUNT", "EXTERNALREFERENCE", + "groupby", "iloc", "isort", "iterrows", @@ -55,6 +56,7 @@ "noqa", "NOTINSET", "NOTLIKE", + "notnull", "odsbox", "Oneof", "pycln", @@ -64,6 +66,7 @@ "rowskip", "seqlimit", "seqskip", + "stddev", "STORAGETYPE", "submatrix", "TESTSTEP", diff --git a/docs/index.rst b/docs/index.rst index 7785506..118ea3c 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -10,7 +10,8 @@ Welcome to ASAM ODSBox docs's documentation! overview odsbox - branchstrategies + jaquel + repository_rules Indices and tables ================== diff --git a/docs/jaquel.md b/docs/jaquel.md new file mode 100644 index 0000000..3f986f9 --- /dev/null +++ b/docs/jaquel.md @@ -0,0 +1,501 @@ +# JAQueL + +**IMPORTANT**: It is always possible to use application or base names for entity, relations, attributes. + +The lookup order is: + +1. **application name** +2. **base name**
+ If base name is not uniquely assigned in the model just one is picked. + This is important for writing generic code without having to analyze + the complete application model. Be aware that application name can + always be used to access any element or attribute. + +*Almost all examples use base names to make they work on any application model.* + +## Examples + +### Get all AoTest instances + +```json +{ + "AoTest": {} +} +``` + +### Access instances using id only + +Get measurement with id 4711 + +```json +{ + "AoMeasurement": 4711 +} +``` + +```json +{ + "AoMeasurement": "4711" +} +``` + +```json +{ + "AoMeasurement": { + "id": 4711 + } +} +``` + +Using application names. + +```json +{ + "MeaResult": { + "Id": 4711 + } +} +``` + + +### Get children of a given SubTest + + +```json +{ + "AoMeasurement": { + "test": 4611 + } +} +``` + +```json +{ + "AoMeasurement": { + "test.id": 4611 + } +} +``` + +TIP: `test.id` is a duplicate because the id is also stored in test column + +### Use inverse to do the same job + +```json +{ + "AoSubTest": "4611", + "$attributes": { + "children.name": 1, + "children.id": 1 + } +} +``` + +```json +{ + "AoSubTest": "4611", + "$attributes": { + "children": { + "name": 1, + "id": 1 + } + } +} +``` + +### Search for a AoTestSequence by name and version + +```json +{ + "AoTestSequence": { + "name": "MyTestSequence", + "version": "V1" + } +} +``` +### Case insensitive match + +```json +{ + "AoTest": { + "name": { + "$eq": "MyTest", + "$options": "i" + } + } +} +``` +### Case insensitive match + +```json +{ + "AoTest": { + "name": { + "$like": "My*", + "$options": "i" + } + } +} +``` + +### Resolve asam path + +```json +{ + "AoMeasurement": { + "name": "MyMea", + "version": "V1", + "test.name": "MySubTest2", + "test.version": "V1", + "test.parent_test.name": "MySubTest1", + "test.parent_test.version": "V1", + "test.parent_test.parent_test.name": "MyTest", + "test.parent_test.parent_test.version": "V1" + } +} +``` + +```json +{ + "AoMeasurement": { + "name": "MyMea", + "version": "V1", + "test": { + "name": "MySubTest2", + "version": "V1", + "parent_test": { + "name": "MySubTest1", + "version": "V1", + "parent_test": { + "name": "MyTest", + "version": "V1" + } + } + } + } +} +``` + +### Use $in operator + +```json +{ + "AoMeasurement": { + "id": { + "$in": [ + 4711, + 4712, + 4713 + ] + } + } +} +``` + +### Search for a time span + +```json +{ + "AoMeasurement": { + "measurement_begin": { + "$gte": "2012-04-23T00:00:00.000Z", + "$lt": "2012-04-24T00:00:00.000Z" + } + } +} +``` + +### Use between operator + +```json +{ + "AoMeasurement": { + "measurement_begin": { + "$between": [ + "2012-04-23T00:00:00.000Z", + "2012-04-24T00:00:00.000Z" + ] + } + } +} +``` + +### Simple $and example + +```json +{ + "AoMeasurement": { + "$and": [ + { + "measurement_begin": { + "$gte": "2012-04-23T00:00:00.000Z", + "$lt": "2012-04-24T00:00:00.000Z" + } + }, + { + "measurement_end": { + "$gte": "2012-04-23T00:00:00.000Z", + "$lt": "2012-04-24T00:00:00.000Z" + } + } + ] + } +} +``` + +### Simple or example + +```json +{ + "AoMeasurement": { + "$or": [ + { + "measurement_begin": { + "$gte": "2012-04-23T00:00:00.000Z", + "$lt": "2012-04-24T00:00:00.000Z" + } + }, + { + "measurement_begin": { + "$gte": "2012-05-23T00:00:00.000Z", + "$lt": "2012-05-24T00:00:00.000Z" + } + }, + { + "measurement_begin": { + "$gte": "2012-06-23T00:00:00.000Z", + "$lt": "2012-06-24T00:00:00.000Z" + } + } + ] + } +} +``` + +### Simple $not example + +```json +{ + "AoTestSequence": { + "$not": { + "$and": [ + { + "name": "MyTestSequence" + }, + { + "version": "V1" + } + ] + } + } +} +``` + +### Mixed case sensitive/insensitive + +```json +{ + "AoTest": { + "$and": [ + { + "name": { + "$like": "My*", + "$options": "i" + } + }, + { + "name": { + "$like": "??Test" + } + } + ] + } +} +``` +### Define unit for attribute to be retrieved + +```json +{ + "AoMeasurementQuantity": 4711, + "$attributes": { + "name": 1, + "id": 1, + "maximum": { + "$unit": 1234 + } + } +} +``` + +### Define unit for attribute value in condition + +```json +{ + "AoMeasurementQuantity": { + "maximum": { + "$unit": 3, + "$between": [ + 1.2, + 2.3 + ] + } + } +} +``` + +### Access $min and $max from minimum and maximum + +```json +{ + "AoMeasurementQuantity": { + "name": "Revs" + }, + "$attributes": { + "minimum": { + "$min": 1, + "$max": 1 + }, + "maximum": { + "$min": 1, + "$max": 1 + } + } +} +``` + +### Do a full query filling some query elements + +```json +{ + "AoMeasurement": { + "$or": [ + { + "measurement_begin": { + "$gte": "2012-04-23T00:00:00.000Z", + "$lt": "2012-04-24T00:00:00.000Z" + } + }, + { + "measurement_begin": { + "$gte": "2012-05-23T00:00:00.000Z", + "$lt": "2012-05-24T00:00:00.000Z" + } + }, + { + "measurement_begin": { + "$gte": "2012-06-23T00:00:00.000Z", + "$lt": "2012-06-24T00:00:00.000Z" + } + } + ] + }, + "$options": { + "$rowlimit": 1000, + "$rowskip": 500 + }, + "$attributes": { + "name": 1, + "id": 1, + "test": { + "name": 1, + "id": 1 + } + }, + "$orderby": { + "test.name": 0, + "name": 1 + }, + "$groupby": { + "id": 1 + } +} +``` + +```json +{ + "AoMeasurement": {}, + "$attributes": { + "name": { + "$distinct": 1 + } + } +} +``` + +### Use outer join to retrieve sparse set unit names + +```json +{ + "AoMeasurementQuantity": { + "measurement": 4712 + }, + "$attributes": { + "name": 1, + "id": 1, + "datatype": 1, + "unit:OUTER.name": 1 + } +} +``` + +## Special key values + +| top level | description | +|-------------|---------------------------------------------| +| $attributes | list of attributes to retrieve. | +| $orderby | order the results by this (1 ascending, 0 descending). | +| $groupby | group the results by this. | +| $options | global options. | + +| conjunctions | description | +|--------------|--------------------------------------------| +| $and | connect array elements with logical AND. Contains Array of expressions. | +| $or | connect array elements with logical OR. Contains Array of expressions. | +| $not | invert result of object. Contains single expression. | + +| operators | description | +|--------------|--------------------------------------------| +| $eq | equal | +| $neq | not equal | +| $lt | lesser than | +| $gt | greater than | +| $lte | lesser than equal | +| $gte | greater than equal | +| $in | contained in array | +| $notinset | not contained in array | +| $like | equal using wildcards *? | +| $null | is null value ("$null":1) | +| $notnull | not is null value ("$notnull":1) | +| $notlike | not equal using wildcards *? | +| $between | two values in an array. Equal to a $gte $lt pair | +| $options | string containing letters: `i` for case insensitive | +| $unit | define the unit the condition value is given in. If 0 it assumed its the default unit. | + +| aggregates | description | +|--------------|--------------------------------------------| +| $none | no aggregate | +| $count | return int containing the number of rows | +| $dcount | return int containing the number of distinct rows | +| $min | returns minimal value of the attribute | +| $max | returns maximal value of the attribute | +| $avg | returns average value of the attribute | +| $stddev | returns standard derivation value of the attribute | +| $sum | returns sum of all attribute values | +| $distinct | distinct attribute values | +| $point | used for query on bulk data. returning indices of local column values | +| $ia | Retrieve an instance attribute | +| $unit | define the unit by its id that should be used for the return values | + +| global options | description | +|----------------|--------------------------------------------| +| $rowlimit | maximal number of rows to return | +| $rowskip | number of rows to be skipped | +| $seqlimit | maximal number of entries in a single sequence | +| $seqskip | number of entries to be skipped in a single sequence | + +## Remarks + +* enum values in conditions can be given as string or number. Be aware that the string is case sensitive. +* longlong values can be given as string or number because not all longlong values can be + represented as a number in json. +* outer joins are given by adding `:OUTER` to the end of a relation name before the next dot. diff --git a/docs/branchstrategy.md b/docs/repository_rules.md similarity index 97% rename from docs/branchstrategy.md rename to docs/repository_rules.md index 142b685..626f9c0 100644 --- a/docs/branchstrategy.md +++ b/docs/repository_rules.md @@ -52,4 +52,4 @@ ## Merge Requests -Merge request must follow the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) naming rules. \ No newline at end of file +Merge request must follow the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) naming rules. diff --git a/src/odsbox/jaquel.py b/src/odsbox/jaquel.py index 2caa1dc..83e59a8 100644 --- a/src/odsbox/jaquel.py +++ b/src/odsbox/jaquel.py @@ -20,6 +20,7 @@ "$min": ods.AggregateEnum.AG_MIN, "$max": ods.AggregateEnum.AG_MAX, "$avg": ods.AggregateEnum.AG_AVG, + "$stddev": ods.AggregateEnum.AG_STDDEV, "$sum": ods.AggregateEnum.AG_SUM, "$distinct": ods.AggregateEnum.AG_DISTINCT, "$point": ods.AggregateEnum.AG_VALUES_POINT, @@ -267,8 +268,6 @@ def __parse_attributes( elif "$unit" == element: element_attribute["unit"] = element_dict[element] continue - elif "$calculated" == element: - raise SyntaxError('currently not supported "' + element + '"') elif "$options" == element: raise SyntaxError("Actually no $options defined for attributes") else: diff --git a/tests/test_data/examples_from_jaquel_doc.json b/tests/test_data/examples_from_jaquel_doc.json new file mode 100644 index 0000000..b1d975a --- /dev/null +++ b/tests/test_data/examples_from_jaquel_doc.json @@ -0,0 +1,291 @@ +[ + { + "AoTest": {} + }, + { + "AoMeasurement": 4711 + }, + { + "AoMeasurement": "4711" + }, + { + "AoMeasurement": { + "id": 4711 + } + }, + { + "MeaResult": { + "Id": 4711 + } + }, + { + "AoMeasurement": { + "test": 4611 + } + }, + { + "AoMeasurement": { + "test.id": 4611 + } + }, + { + "AoSubTest": "4611", + "$attributes": { + "children.name": 1, + "children.id": 1 + } + }, + { + "AoSubTest": "4611", + "$attributes": { + "children": { + "name": 1, + "id": 1 + } + } + }, + { + "AoTestSequence": { + "name": "MyTestSequence", + "version": "V1" + } + }, + { + "AoTest": { + "name": { + "$eq": "MyTest", + "$options": "i" + } + } + }, + { + "AoTest": { + "name": { + "$like": "My*", + "$options": "i" + } + } + }, + { + "AoMeasurement": { + "name": "MyMea", + "test.name": "MySubTest2", + "test.parent_test.name": "MySubTest1", + "test.parent_test.parent_test.name": "MyTest" + } + }, + { + "AoMeasurement": { + "name": "MyMea", + "test": { + "name": "MySubTest2", + "parent_test": { + "name": "MySubTest1", + "parent_test": { + "name": "MyTest" + } + } + } + } + }, + { + "AoMeasurement": { + "id": { + "$in": [ + 4711, + 4712, + 4713 + ] + } + } + }, + { + "AoMeasurement": { + "measurement_begin": { + "$gte": "2012-04-23T00:00:00.000Z", + "$lt": "2012-04-24T00:00:00.000Z" + } + } + }, + { + "AoMeasurement": { + "measurement_begin": { + "$between": [ + "2012-04-23T00:00:00.000Z", + "2012-04-24T00:00:00.000Z" + ] + } + } + }, + { + "AoMeasurement": { + "$and": [ + { + "measurement_begin": { + "$gte": "2012-04-23T00:00:00.000Z", + "$lt": "2012-04-24T00:00:00.000Z" + } + }, + { + "measurement_end": { + "$gte": "2012-04-23T00:00:00.000Z", + "$lt": "2012-04-24T00:00:00.000Z" + } + } + ] + } + }, + { + "AoMeasurement": { + "$or": [ + { + "measurement_begin": { + "$gte": "2012-04-23T00:00:00.000Z", + "$lt": "2012-04-24T00:00:00.000Z" + } + }, + { + "measurement_begin": { + "$gte": "2012-05-23T00:00:00.000Z", + "$lt": "2012-05-24T00:00:00.000Z" + } + }, + { + "measurement_begin": { + "$gte": "2012-06-23T00:00:00.000Z", + "$lt": "2012-06-24T00:00:00.000Z" + } + } + ] + } + }, + { + "AoTestSequence": { + "$not": { + "$and": [ + { + "name": "MyTestSequence" + }, + { + "version": "V1" + } + ] + } + } + }, + { + "AoTest": { + "$and": [ + { + "name": { + "$like": "My*", + "$options": "i" + } + }, + { + "name": { + "$like": "??Test" + } + } + ] + } + }, + { + "AoMeasurementQuantity": 4711, + "$attributes": { + "name": 1, + "id": 1, + "maximum": { + "$unit": 3 + } + } + }, + { + "AoMeasurementQuantity": { + "maximum": { + "$unit": 3, + "$between": [ + 1.2, + 2.3 + ] + } + } + }, + { + "AoMeasurementQuantity": { + "name": "Revs" + }, + "$attributes": { + "minimum": { + "$min": 1, + "$max": 1 + }, + "maximum": { + "$min": 1, + "$max": 1 + } + } + }, + { + "AoMeasurement": { + "$or": [ + { + "measurement_begin": { + "$gte": "2012-04-23T00:00:00.000Z", + "$lt": "2012-04-24T00:00:00.000Z" + } + }, + { + "measurement_begin": { + "$gte": "2012-05-23T00:00:00.000Z", + "$lt": "2012-05-24T00:00:00.000Z" + } + }, + { + "measurement_begin": { + "$gte": "2012-06-23T00:00:00.000Z", + "$lt": "2012-06-24T00:00:00.000Z" + } + } + ] + }, + "$options": { + "$rowlimit": 1000, + "$rowskip": 500 + }, + "$attributes": { + "name": 1, + "id": 1, + "test": { + "name": 1, + "id": 1 + } + }, + "$orderby": { + "test.name": 0, + "name": 1 + }, + "$groupby": { + "id": 1 + } + }, + { + "AoMeasurement": {}, + "$attributes": { + "name": { + "$distinct": 1 + } + } + }, + { + "AoMeasurementQuantity": { + "measurement": 4712 + }, + "$attributes": { + "name": 1, + "id": 1, + "datatype": 1, + "unit:OUTER.name": 1 + } + } +] \ No newline at end of file diff --git a/tests/test_jaquel_convert.py b/tests/test_jaquel_convert.py index 5d7df72..06afc55 100644 --- a/tests/test_jaquel_convert.py +++ b/tests/test_jaquel_convert.py @@ -147,3 +147,20 @@ def test_syntax_errors(): with pytest.raises(SyntaxError, match=r"Does not define a target entity."): jaquel_to_ods(model, {}) + + +def test_example_queries(): + model = __get_model("application_model.json") + + with open( + os.path.join(os.path.abspath(os.path.dirname(__file__)), "test_data", "examples_from_jaquel_doc.json"), + encoding="utf-8", + ) as fh: + example_queries = json.load(fh) + + for example_query in example_queries: + logging.getLogger().info(example_query) + + entity, select_statement = jaquel_to_ods(model, example_query) + assert entity is not None + assert select_statement is not None From 41bf429e8620b219840326dab8d7d7612c523c19 Mon Sep 17 00:00:00 2001 From: Andreas K Date: Sat, 5 Oct 2024 17:07:54 +0200 Subject: [PATCH 6/8] doc: doc version from odsbox (#47) --- docs/conf.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index 7c250e4..f0bdf7f 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -15,6 +15,8 @@ sys.path.insert(0, os.path.abspath("../src/")) +from odsbox import __version__ as odsbox_version + # -- Project information ----------------------------------------------------- @@ -23,7 +25,7 @@ author = "Peak Solution" # The full version, including alpha/beta/rc tags -release = "0.1.0" +release = odsbox_version # -- General configuration --------------------------------------------------- From 75e805f0dba7a10f189b0cdf30c4f7c85b2f6984 Mon Sep 17 00:00:00 2001 From: Andreas K Date: Sat, 5 Oct 2024 17:22:42 +0200 Subject: [PATCH 7/8] feat: set version to 1.0.0 (#48) --- pyproject.toml | 260 +++++++++++++++++------------------------ src/odsbox/__init__.py | 2 +- 2 files changed, 111 insertions(+), 151 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 87bf85f..c99a51f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,16 +3,21 @@ requires = ["flit_core >=2,<4"] build-backend = "flit_core.buildapi" [project] -name = "odsbox" -authors = [ - {name = "Andreas Krantz", email = "a.krantz@peak-solution.de"}, -] +name = "odsbox" +authors = [{ name = "Andreas Krantz", email = "a.krantz@peak-solution.de" }] description = "Toolbox for accessing ASAM ODS servers using the HTTP API" -license = {file = "LICENSE"} -keywords = ["asam", "ods", "measurement", "data access", "data science", "data analysis"] +license = { file = "LICENSE" } +keywords = [ + "asam", + "ods", + "measurement", + "data access", + "data science", + "data analysis", +] readme = "README.md" classifiers = [ - "Development Status :: 4 - Beta", + "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", @@ -21,20 +26,18 @@ classifiers = [ "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Topic :: Software Development :: Libraries :: Python Modules", - "Topic :: Scientific/Engineering :: Information Analysis" + "Topic :: Scientific/Engineering :: Information Analysis", ] requires-python = ">=3.10.14" dynamic = ["version"] -dependencies=[ - "protobuf", - "requests", - "pandas" +dependencies = [ + "protobuf>=3.20.0,<4.0.0", + "requests>=2.25.1,<3.0.0", + "pandas>=1.2.0,<2.0.0", ] [project.optional-dependencies] -exd-data = [ - "grpcio" -] +exd-data = ["grpcio>=1.38.0,<2.0.0"] test = [ "bandit[toml]==1.7.10", "black==24.8.0", @@ -53,7 +56,7 @@ test = [ "pytest==8.3.3", "pytest-github-actions-annotate-failures", "pytest-xdist", - "shellcheck-py==0.10.0.1" + "shellcheck-py==0.10.0.1", ] [project.urls] @@ -66,7 +69,7 @@ Tracker = "https://github.com/peak-solution/odsbox/issues" name = "odsbox" [tool.bandit] -exclude_dirs = ["build","dist","tests","scripts"] +exclude_dirs = ["build", "dist", "tests", "scripts"] number = 4 recursive = true targets = "src" @@ -96,21 +99,13 @@ exclude = [ "pywin32", "tests", "swagger_client", - "*_pb2*.py*" -] -ignore = [ - "E722", - "B001", - "W503", - "E203" + "*_pb2*.py*", ] +ignore = ["E722", "B001", "W503", "E203"] [tool.pyright] include = ["src"] -exclude = [ - "**/node_modules", - "**/__pycache__", -] +exclude = ["**/node_modules", "**/__pycache__"] venv = "env37" reportMissingImports = true @@ -119,15 +114,11 @@ reportMissingTypeStubs = false pythonVersion = "3.7" pythonPlatform = "Linux" -executionEnvironments = [ - { root = "src" } -] +executionEnvironments = [{ root = "src" }] [tool.pytest.ini_options] addopts = "--cov-report xml:coverage.xml --cov src --cov-fail-under 0 --cov-append -m 'not integration'" -pythonpath = [ - "src" -] +pythonpath = ["src"] testpaths = "tests" junit_family = "xunit2" markers = [ @@ -158,7 +149,7 @@ commands = """ [tool.pylint] -extension-pkg-whitelist= [ +extension-pkg-whitelist = [ "numpy", "torch", "cv2", @@ -166,151 +157,120 @@ extension-pkg-whitelist= [ "pydantic", "ciso8601", "netcdf4", - "scipy" + "scipy", ] -ignore="CVS" -ignore-patterns="test.*?py,conftest.py,*_pb2*.py*" -init-hook='import sys; sys.setrecursionlimit(8 * sys.getrecursionlimit())' -jobs=0 -limit-inference-results=100 -persistent="yes" -suggestion-mode="yes" -unsafe-load-any-extension="no" +ignore = "CVS" +ignore-patterns = "test.*?py,conftest.py,*_pb2*.py*" +init-hook = 'import sys; sys.setrecursionlimit(8 * sys.getrecursionlimit())' +jobs = 0 +limit-inference-results = 100 +persistent = "yes" +suggestion-mode = "yes" +unsafe-load-any-extension = "no" [tool.pylint.'MESSAGES CONTROL'] -enable="c-extension-no-member" +enable = "c-extension-no-member" [tool.pylint.'REPORTS'] -evaluation="10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)" -output-format="text" -reports="no" -score="yes" +evaluation = "10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)" +output-format = "text" +reports = "no" +score = "yes" [tool.pylint.'REFACTORING'] -max-nested-blocks=5 -never-returning-functions="sys.exit" +max-nested-blocks = 5 +never-returning-functions = "sys.exit" [tool.pylint.'BASIC'] -argument-naming-style="snake_case" -attr-naming-style="snake_case" -bad-names= [ - "foo", - "bar" -] -class-attribute-naming-style="any" -class-naming-style="PascalCase" -const-naming-style="UPPER_CASE" -docstring-min-length=-1 -function-naming-style="snake_case" -good-names= [ - "i", - "j", - "k", - "ex", - "Run", - "_" -] -include-naming-hint="yes" -inlinevar-naming-style="any" -method-naming-style="snake_case" -module-naming-style="any" -no-docstring-rgx="^_" -property-classes="abc.abstractproperty" -variable-naming-style="snake_case" +argument-naming-style = "snake_case" +attr-naming-style = "snake_case" +bad-names = ["foo", "bar"] +class-attribute-naming-style = "any" +class-naming-style = "PascalCase" +const-naming-style = "UPPER_CASE" +docstring-min-length = -1 +function-naming-style = "snake_case" +good-names = ["i", "j", "k", "ex", "Run", "_"] +include-naming-hint = "yes" +inlinevar-naming-style = "any" +method-naming-style = "snake_case" +module-naming-style = "any" +no-docstring-rgx = "^_" +property-classes = "abc.abstractproperty" +variable-naming-style = "snake_case" [tool.pylint.'FORMAT'] -ignore-long-lines="^\\s*(# )?.*['\"]??" -indent-after-paren=4 -indent-string=' ' -max-line-length=120 -max-module-lines=1000 -single-line-class-stmt="no" -single-line-if-stmt="no" +ignore-long-lines = "^\\s*(# )?.*['\"]??" +indent-after-paren = 4 +indent-string = ' ' +max-line-length = 120 +max-module-lines = 1000 +single-line-class-stmt = "no" +single-line-if-stmt = "no" [tool.pylint.'LOGGING'] -logging-format-style="old" -logging-modules="logging" +logging-format-style = "old" +logging-modules = "logging" [tool.pylint.'MISCELLANEOUS'] -notes= [ - "FIXME", - "XXX", - "TODO" -] +notes = ["FIXME", "XXX", "TODO"] [tool.pylint.'SIMILARITIES'] -ignore-comments="yes" -ignore-docstrings="yes" -ignore-imports="yes" -min-similarity-lines=7 +ignore-comments = "yes" +ignore-docstrings = "yes" +ignore-imports = "yes" +min-similarity-lines = 7 [tool.pylint.'SPELLING'] -max-spelling-suggestions=4 -spelling-store-unknown-words="no" +max-spelling-suggestions = 4 +spelling-store-unknown-words = "no" [tool.pylint.'STRING'] -check-str-concat-over-line-jumps="no" +check-str-concat-over-line-jumps = "no" [tool.pylint.'TYPECHECK'] -contextmanager-decorators="contextlib.contextmanager" -generated-members="numpy.*,np.*,ods*_pb2.*,collect_list" -ignore-mixin-members="yes" -ignore-none="yes" -ignore-on-opaque-inference="yes" -ignored-classes="optparse.Values,thread._local,_thread._local,numpy,torch,swagger_client" -ignored-modules="numpy,torch,swagger_client,netCDF4,scipy" -missing-member-hint="yes" -missing-member-hint-distance=1 -missing-member-max-choices=1 +contextmanager-decorators = "contextlib.contextmanager" +generated-members = "numpy.*,np.*,ods*_pb2.*,collect_list" +ignore-mixin-members = "yes" +ignore-none = "yes" +ignore-on-opaque-inference = "yes" +ignored-classes = "optparse.Values,thread._local,_thread._local,numpy,torch,swagger_client" +ignored-modules = "numpy,torch,swagger_client,netCDF4,scipy" +missing-member-hint = "yes" +missing-member-hint-distance = 1 +missing-member-max-choices = 1 [tool.pylint.'VARIABLES'] -additional-builtins="dbutils" -allow-global-unused-variables="yes" -callbacks= [ - "cb_", - "_cb" -] -dummy-variables-rgx="_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_" -ignored-argument-names="_.*|^ignored_|^unused_" -init-import="no" -redefining-builtins-modules="six.moves,past.builtins,future.builtins,builtins,io" +additional-builtins = "dbutils" +allow-global-unused-variables = "yes" +callbacks = ["cb_", "_cb"] +dummy-variables-rgx = "_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_" +ignored-argument-names = "_.*|^ignored_|^unused_" +init-import = "no" +redefining-builtins-modules = "six.moves,past.builtins,future.builtins,builtins,io" [tool.pylint.'CLASSES'] -defining-attr-methods= [ - "__init__", - "__new__", - "setUp", - "__post_init__" -] -exclude-protected= [ - "_asdict", - "_fields", - "_replace", - "_source", - "_make" -] -valid-classmethod-first-arg="cls" -valid-metaclass-classmethod-first-arg="cls" +defining-attr-methods = ["__init__", "__new__", "setUp", "__post_init__"] +exclude-protected = ["_asdict", "_fields", "_replace", "_source", "_make"] +valid-classmethod-first-arg = "cls" +valid-metaclass-classmethod-first-arg = "cls" [tool.pylint.'DESIGN'] -max-args=5 -max-attributes=7 -max-bool-expr=5 -max-branches=12 -max-locals=15 -max-parents=7 -max-public-methods=20 -max-returns=6 -max-statements=50 -min-public-methods=2 +max-args = 5 +max-attributes = 7 +max-bool-expr = 5 +max-branches = 12 +max-locals = 15 +max-parents = 7 +max-public-methods = 20 +max-returns = 6 +max-statements = 50 +min-public-methods = 2 [tool.pylint.'IMPORTS'] -allow-wildcard-with-all="no" -analyse-fallback-blocks="no" -deprecated-modules="optparse,tkinter.tix" +allow-wildcard-with-all = "no" +analyse-fallback-blocks = "no" +deprecated-modules = "optparse,tkinter.tix" [tool.pylint.'EXCEPTIONS'] -overgeneral-exceptions= [ - "BaseException", - "Exception" -] +overgeneral-exceptions = ["BaseException", "Exception"] diff --git a/src/odsbox/__init__.py b/src/odsbox/__init__.py index 704a8da..42dcd31 100644 --- a/src/odsbox/__init__.py +++ b/src/odsbox/__init__.py @@ -2,4 +2,4 @@ from __future__ import annotations -__version__ = "0.3.0" +__version__ = "1.0.0" From 2f2d60afe9d9e2cf8617563ed24a7758ac6f7d2a Mon Sep 17 00:00:00 2001 From: Andreas K Date: Sat, 5 Oct 2024 18:31:44 +0200 Subject: [PATCH 8/8] fix: update-version (#52) * fix linter * adjust versions --- docs/conf.py | 5 +---- pyproject.toml | 8 ++++---- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index f0bdf7f..0ccb328 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -15,9 +15,6 @@ sys.path.insert(0, os.path.abspath("../src/")) -from odsbox import __version__ as odsbox_version - - # -- Project information ----------------------------------------------------- project = "ASAM ODSBox docs" @@ -25,7 +22,7 @@ author = "Peak Solution" # The full version, including alpha/beta/rc tags -release = odsbox_version +release = "1.0.0" # -- General configuration --------------------------------------------------- diff --git a/pyproject.toml b/pyproject.toml index c99a51f..1c19109 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,13 +31,13 @@ classifiers = [ requires-python = ">=3.10.14" dynamic = ["version"] dependencies = [ - "protobuf>=3.20.0,<4.0.0", - "requests>=2.25.1,<3.0.0", - "pandas>=1.2.0,<2.0.0", + "protobuf>=5.27.0,<6.0.0", + "requests>=2.30.0,<3.0.0", + "pandas>=2.2.0,<3.0.0", ] [project.optional-dependencies] -exd-data = ["grpcio>=1.38.0,<2.0.0"] +exd-data = ["grpcio>=1.59.3,<2.0.0"] test = [ "bandit[toml]==1.7.10", "black==24.8.0",