Metadata-Version: 2.4
Name: robotframework-jmespath
Version: 0.1.0
Summary: A Robot Framework library for JMESPath-based JSON querying, providing high-performance alternative to JSONPath
Project-URL: homepage, https://github.com/netascode/robotframework-jmespath
Project-URL: repository, https://github.com/netascode/robotframework-jmespath
Project-URL: documentation, https://github.com/netascode/robotframework-jmespath
Project-URL: issues, https://github.com/netascode/robotframework-jmespath/issues
Author-email: Oliver Boehmer <oboehmer@cisco.com>
Maintainer-email: Oliver Boehmer <oboehmer@cisco.com>
License: MPL-2.0
License-File: LICENSE
Keywords: jmespath,json,query,robot,robotframework,testing
Classifier: Development Status :: 4 - Beta
Classifier: Framework :: Robot Framework
Classifier: Framework :: Robot Framework :: Library
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Quality Assurance
Classifier: Topic :: Software Development :: Testing
Requires-Python: >=3.10
Requires-Dist: jmespath>=1.0.1
Requires-Dist: robotframework>=5.0
Provides-Extra: dev
Requires-Dist: bandit[toml]>=1.8.6; extra == 'dev'
Requires-Dist: mypy>=1.17.1; extra == 'dev'
Requires-Dist: pre-commit>=4.3.0; extra == 'dev'
Requires-Dist: pytest-cov>=6.2.1; extra == 'dev'
Requires-Dist: pytest-mock>=3.15.0; extra == 'dev'
Requires-Dist: pytest>=8.4.2; extra == 'dev'
Requires-Dist: robotframework>=5.0; extra == 'dev'
Requires-Dist: ruff>=0.12.12; extra == 'dev'
Description-Content-Type: text/markdown

# Robot Framework JMESPath Library

A Robot Framework library providing high-performance JSON querying using [JMESPath](https://jmespath.org/) expressions.

[![PyPI version](https://badge.fury.io/py/robotframework-jmespath.svg)](https://badge.fury.io/py/robotframework-jmespath)
[![Python versions](https://img.shields.io/pypi/pyversions/robotframework-jmespath.svg)](https://pypi.org/project/robotframework-jmespath/)
[![License](https://img.shields.io/badge/License-MPL%202.0-brightgreen.svg)](https://opensource.org/licenses/MPL-2.0)

## Why JMESPath?

JMESPath offers significant advantages over JSONPath for Robot Framework testing:

- **Better Performance**: Native Python implementation with superior performance
- **More Powerful**: Rich filtering, projections, and transformations
- **Better Maintained**: Active development and strong community support
- **Simpler Syntax**: Cleaner, more intuitive query expressions
- **Standardized**: Well-defined specification and behavior

## Installation

```bash
pip install robotframework-jmespath
```

## Quick Start

```robot
*** Settings ***
Library    JMESPathLibrary

*** Test Cases ***
Query JSON Data
    ${json}=    Evaluate    {"users": [{"name": "Alice", "age": 30}, {"name": "Bob", "age": 25}]}
    ${name}=    JSON Search String    ${json}    users[0].name
    Should Be Equal    ${name}    Alice

    ${names}=    JSON Search List    ${json}    users[*].name
    Should Contain    ${names}    Alice
    Should Contain    ${names}    Bob
```

## Keywords

### JSON Search String

Execute a JMESPath query and return a single string result.

**Arguments:**
- `data`: JSON data to query (dict, list, or JSON string)
- `expression`: JMESPath expression

**Returns:** String value (first result if multiple matches), or empty string if no match

**Examples:**
```robot
${tenant}=    JSON Search String    ${response}    imdata[0].fvTenant.attributes.name
${ip}=        JSON Search String    ${response}    imdata[0].fvBD.children[?fvSubnet] | [0].fvSubnet.attributes.ip
```

### JSON Search List

Execute a JMESPath query and return results as a list.

**Arguments:**
- `data`: JSON data to query (dict, list, or JSON string)
- `expression`: JMESPath expression

**Returns:** List of results, or empty list if no matches

**Examples:**
```robot
${names}=    JSON Search List    ${response}    imdata[0].fvTenant.children[*].fvAp.attributes.name
${ips}=      JSON Search List    ${response}    imdata[0].fvBD.children[*].fvSubnet.attributes.ip
```

## JMESPath Syntax Overview

### Basic Operations

| Operation | Example | Description |
|-----------|---------|-------------|
| **Object access** | `foo.bar` | Access nested object |
| **Array access** | `foo[0]` | Access array element |
| **Array slice** | `foo[0:2]` | Slice array |
| **Wildcard** | `foo[*].bar` | All array elements |
| **Filter** | `foo[?bar=='value']` | Filter array |
| **Pipe** | `foo \| [0]` | Chain expressions |

### Common Patterns

**Access nested object:**
```
imdata[0].fvTenant.attributes.name
```

**Filter array by attribute:**
```
imdata[0].fvTenant.children[?fvAp.attributes.name=='AP1'] | [0]
```

**Get all names from array:**
```
imdata[0].fvTenant.children[*].fvAp.attributes.name
```

**Filter with multiple conditions:**
```
users[?age > `25` && active == `true`]
```

## Comparison with JSONPath

| Feature | JSONPath | JMESPath |
|---------|----------|----------|
| Root | `$` | (implicit) |
| Child access | `$.foo.bar` | `foo.bar` |
| Recursive descent | `$..field` | Not supported* |
| Array filter | `$[?(@.age > 25)]` | `[?age > \`25\`]` |
| Wildcard | `$.*` | `*` or `[*]` |
| Pipe/Chain | Not supported | `foo \| [0]` |

*For recursive descent, use explicit paths: `children[?fvAp]`

## Usage with REST API Testing

### Example: Cisco ACI API Testing

```robot
*** Settings ***
Library    RequestsLibrary
Library    JMESPathLibrary

*** Test Cases ***
Verify Tenant Configuration
    # Make API call
    ${response}=    GET On Session    apic    /api/mo/uni/tn-TENANT1.json    params=rsp-subtree=full
    ${json}=        Set Variable    ${response.json()}

    # Query with JMESPath
    ${tenant_name}=    JSON Search String    ${json}    imdata[0].fvTenant.attributes.name
    Should Be Equal    ${tenant_name}    TENANT1

    # Query nested objects
    ${ap_name}=    JSON Search String    ${json}
    ...    imdata[0].fvTenant.children[?fvAp.attributes.name=='AP1'] | [0].fvAp.attributes.name
    Should Be Equal    ${ap_name}    AP1

    # Get all subnet IPs
    ${subnets}=    JSON Search List    ${json}
    ...    imdata[0].fvTenant.children[*].fvBD.children[*].fvSubnet.attributes.ip
    Should Contain    ${subnets}    10.0.0.1/24
```

## Development

### Setup Development Environment

```bash
# Clone repository
git clone https://github.com/netascode/robotframework-jmespath.git
cd robotframework-jmespath

# Install in development mode
pip install -e ".[dev]"

# Install pre-commit hooks
pre-commit install
```

### Running Tests

```bash
# Run all tests (unit tests + robot tests via pytest wrapper)
pytest tests/

# Run unit tests only
pytest tests/test_unit.py

# Run robot acceptance tests directly
robot tests/acceptance.robot

# Run acceptance tests via pytest wrapper
pytest tests/test_acceptance.py

# Run with coverage
pytest --cov=JMESPathLibrary tests/

# Run linters
ruff check .
mypy .
bandit -r JMESPathLibrary/
```

### Code Quality

This project uses:
- **ruff** for linting and formatting
- **mypy** for type checking
- **bandit** for security analysis
- **pytest** for testing
- **pre-commit** for git hooks

## Contributing

Contributions are welcome! Please:

1. Fork the repository
2. Create a feature branch
3. Make your changes with tests
4. Run the test suite
5. Submit a pull request

## Resources

- [JMESPath Tutorial](https://jmespath.org/tutorial.html)
- [JMESPath Specification](https://jmespath.org/specification.html)
- [Robot Framework Documentation](https://robotframework.org/)

## License

This project is licensed under the Mozilla Public License 2.0 - see the [LICENSE](LICENSE) file for details.

## Authors

- Oliver Boehmer ([@oboehmer](https://github.com/oboehmer))

## Acknowledgments

- Inspired by the need for high-performance JSON querying in network automation testing
- Built on the excellent [jmespath.py](https://github.com/jmespath/jmespath.py) library
- Part of the [Network-as-Code](https://github.com/netascode) ecosystem
