Metadata-Version: 2.4
Name: guardx
Version: 0.2.2
Summary: A Python library for code analysis and sandboxing
License-File: LICENSE
Author: IBM Research
Requires-Python: >=3.10
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: Programming Language :: Python :: 3.14
Requires-Dist: docker (>=7.1.0,<8.0.0)
Requires-Dist: pydantic (>=2.13.1,<3.0.0)
Requires-Dist: pyelftools (>=0.31,<0.32)
Requires-Dist: pyseccomp (>=0.1.2,<0.2.0)
Requires-Dist: pyyaml (>=6.0.1,<7.0.0)
Requires-Dist: requests (==2.33.1)
Requires-Dist: urllib3 (==2.6.3)
Description-Content-Type: text/markdown

# GuardX

A Python package for code analysis and sandbox.

This library can be used to create pipelines that filter code generated by GenAI code models, and for guarding the execution of generated code.

[Design](docs/arch.rst)

[Static Code Analysis](docs/analysis.rst)

[Sandbox via seccomp](docs/seccomp.rst)

## Quick start

### Create a python virtual env

```bash
python -m venv .venv
source .venv/bin/activate
```

**Note:** Depending on your system, you may need to run as `sudo .venv/bin/guardx init`.

**Podman:** GuardX uses the docker python package to communicate with containers.
Hence, if you are using Podman, you will need to set the env variable DOCKER\_HOST to point
to the unix socket used by Podman. See docs/container.rst.

```bash
podman machine inspect --format '{{.ConnectionInfo.PodmanSocket.Path}}'
export DOCKER_HOST=unix://<your_podman_socket_location>
```

### Method 1: via CLI

```
pip install guardx

```

**git+https** (using a [github personal access token](https://help.github.com/articles/creating-an-access-token-for-command-line-use/)):
```bash
pip install git+https://github.com/ibm/guardx.git@{branch/tag}
```

**git+ssh**:

```bash
pip install git+ssh://git@github.com/ibm/guardx.git@${branch/tag}
```

The library container images must be built before importing and using the library.

```bash
guardx init
```
#### Test using provided example

```bash
python example.py --file example_gen_code.py
```

### Method 2: for development 

#### Install pre-requisites

```bash
git clone git@github.com:ibm/guardx.git
cd guardx
make init
```
**Note:** This installs Poetry. Make sure to configure your PATH to access poetry.

#### Install dependencies

To install the dev dependencies (editable mode):

```bash
make install/dev
```

**Note:** To add additional dependencies, use `poetry add "package"`. For help, `poetry add -h`.

#### Build the library container images

```bash
make containers/docker

OR

make containers/podman
```

**Note:** Fresh build takes 5-10 minutes. Make sure to update the GuardX config file 
in resources/config.yaml to match built image name and tag.

#### Testing

Test modules are created under the `tests` directory.

To run all tests, use the following command:

```bash
make test
```

**Note:** To enable logging, set `log_cli = true` in `tests/pytest.ini`.

#### Code Linting

Before checking in any code for the project, please lint the code.  This can be done using:

```bash
make lint
```

### Precommit Hooks
We are currently using [detect-secrets](https://www.google.com/search?q=code+scanning+detect+secrets) in 
our precommit hooks. Refer to [this repo](https://github.com/ibm/detect-secrets)  for configuration instructions

### Docs config & build

```bash
cd docs
make html
```

## Library Usage

Here is an example of how to use this library in your code.

```python
from guardx import Guardx
from guardx.analysis import AnalysisType

python_code = """<your code here>"""

g = Guardx(config_path="./resources/config.yaml")

# To analyze code
result = g.analyze(python_code, {AnalysisType.DETECT_SECRET, AnalysisType.UNSAFE_CODE})
print(result)

# To execute code in sandbox with a default security policy
result = g.execute(python_code).get_docker_result()
print(result)

# To execute code with global variables passed into the sandbox
globals_dict = {"x": 10, "y": 20}
result = g.execute(python_code, globals=globals_dict).get_docker_result()
print(result)
```

### Passing Global Variables to Sandbox Execution

You can pass global variables into the sandbox execution environment using the `globals` parameter. This is useful for:
- Providing prior execution state
- Passing configuration or context data
- Simulating stateful execution across multiple code snippets

```python
# Example: Using globals for stateful execution
code1 = "counter = 1"
result1 = g.execute(code1)

# Continue with prior state
code2 = "counter += 1; print(counter)"
result2 = g.execute(code2, globals={"counter": 1})

# Example: Passing complex data structures
code = "result = sum(numbers) * multiplier"
globals_dict = {
    "numbers": [1, 2, 3, 4, 5],
    "multiplier": 2
}
result = g.execute(code, globals=globals_dict)

# Example: Passing configuration
code = "result = data['value'] * config['multiplier']"
globals_dict = {
    "data": {"value": 100},
    "config": {"multiplier": 2.5, "threshold": 10}
}
result = g.execute(code, globals=globals_dict)
```

**Important Notes:**
- Global variables must be **JSON-serializable** (strings, numbers, lists, dicts, booleans, None)
- **Do NOT include `__builtins__`** - it is automatically provided by the executor
- Non-serializable objects (functions, classes, modules, file handles) will be automatically filtered out with a warning
- Only the serializable values will be passed to the sandbox

