Metadata-Version: 2.4
Name: testbench-requirement-service
Version: 1.0.0a2
Summary: # TestBench Requirement Service
Author-email: René Rohner <rene.rohner@imbus.de>
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-Expression: Apache-2.0
License-File: LICENSE
Requires-Dist: sanic>=24.12,<25.0
Requires-Dist: sanic-ext>=23.12,<25.0
Requires-Dist: pydantic>=2.10.6,<3.0.0
Requires-Dist: click>=8.1.8,<9.0.0
Requires-Dist: pandas>=2.2.3,<3.0.0
Requires-Dist: openpyxl>=3.1.5,<4.0.0
Requires-Dist: xlrd>=2.0.1,<3.0.0
Requires-Dist: javaproperties>=0.8.2,<1.0.0
Requires-Dist: ruff>=0.9.6 ; extra == "dev"
Requires-Dist: pre-commit>=4.1.0 ; extra == "dev"
Requires-Dist: invoke>=2.2.0 ; extra == "dev"
Requires-Dist: mypy>=1.15.0 ; extra == "dev"
Requires-Dist: flit>=3.10.1 ; extra == "dev"
Requires-Dist: wheel>=0.45.1 ; extra == "dev"
Requires-Dist: robotframework>=7.2.2 ; extra == "test"
Requires-Dist: robotframework-robocop>=5.8.1 ; extra == "test"
Requires-Dist: robotframework-tidy>=4.16.0 ; extra == "test"
Requires-Dist: requests>=2.32.3 ; extra == "test"
Project-URL: Home, https://github.com/imbus/testbench-requirement-service
Provides-Extra: dev
Provides-Extra: test

# TestBench Requirement Service - Python

A simple CLI tool to start and configure a TestBench Requirement Service.

## Table of contents

- [Installation](#installation)
- [Setup](#setup)
- [Usage](#usage)
- [API Documentation](#api-documentation)
- [Built-in FileReader](#built-in-filereader)
- [Custom FileReader Classes](#custom-filereader-classes)
- [Contributing](#contributing)
- [License](#license)

## Installation

This tool requires Python ≥ 3.10 with pip installed.

If you already have Python ≥ 3.10 with pip installed, you can simply run:

```powershell
pip install testbench-requirement-service
```
Once installed, verify the installation by checking the version:

```powershell
testbench-requirement-service --version
```
If the installation was successful, this should output the installed version of the tool.

## Setup

Before starting the service, you need to configure it.

### Step 1: Set up your service credentials

First, you need to set the credentials for your service in a configuration file. Use the integrated command `set-credentials`, which will automatically create a `config.py` in your current working directory. This file stores your credentials as a hashed password with a salt.

The server will verify requests using *Basic Auth*, comparing the username and password in incoming requests with the hash and salt stored in the `config.py` file.

If you'd like to store the configuration file elsewhere, you can specify the path with the `--config` option. However, remember that this config file is required for your service, and you will need to provide this path when starting the service if you change the default location.

You can run the following command without options, which will prompt you to enter your username and password:

```powershell
testbench-requirement-service set-credentials
```
Alternatively, you can specify the username and password directly in the command:

```powershell
testbench-requirement-service set-credentials --username USERNAME --password PASSWORD
```
If successful, a `config.py` file will be created with `PASSWORD_HASH` and `SALT` as the content.

### Step 2: Set up the file reader configuration

You will also need to configure the file reader that the service will use.

Create a `reader_config.py` file in your current working directory and define the necessary settings for the file reader. If you prefer to store the configuration file elsewhere, you can specify a custom path, but remember to provide this path when starting the service.

The file reader will receive the path to this configuration file as a parameter in its constructor, allowing it to load and work with your settings.

For the default file reader, `JsonlFileReader`, you must define at least the `BASE_DIR` setting in your `reader_config.py`. This should be the path to the directory containing the requirement files for your service.

Here’s an example of the minimum configuration for `JsonlFileReader`:

```python
# reader_config.py

BASE_DIR = "requirements/"
```

Once the configuration is complete, you're ready to start the service.

## Usage

Now that your service is set up, you can start the service through the command-line interface.

### Start the Service

The basic command to start the service is:

```powershell
testbench-requirement-service start
```

By default, the service will run locally on `127.0.0.1:8000`. If you'd like to run it on a different host or port, use the following options:

```powershell
testbench-requirement-service start --host HOST --port PORT
```
For example, to run the service on host `127.0.0.2` and port `8002`:

```powershell
testbench-requirement-service start --host 127.0.0.2 --port 8002
```

### Available Options

| Option            | Description | Default |
| ----------------- | ----------- | --------|
| `--config`        | Path to the app configuration file  | `config.py` |
| `--reader-class`  | Path or module string to the reader class | `testbench_requirement_service.readers.JsonlFileReader` |
| `--reader-config` | Path to the reader configuration file | `reader_config.py` |
| `--host`          | Host to run the service on | `127.0.0.1` |
| `--port`          | Port to run the service on | `8000` |
| `--dev`           | Run the service in dev mode (debug + auto reload) | Not set |

You can also see the available options and their descriptions by running:

```powershell
testbench-requirement-service start --help
```

### Example Usage

- **Start the service with custom host and port**
    ```powershell
    testbench-requirement-service start --host 127.0.0.2 --port 8001
    ```
- **Start the service in dev mode (debug + auto reload)**
    ```powershell
    testbench-requirement-service start --dev
    ```
- **Use a custom config path**
    ```powershell
    testbench-requirement-service start --config path/to/config.py
    ```
- **Use a custom reader class**
    ```powershell
    testbench-requirement-service start --reader-class custom_readers/CustomFileReader.py
    ```

## API Documentation

Once your service is running, you can explore the available API documentation and OpenAPI specification using built-in endpoints.

### Interactive API Docs

The interactive API documentation is available at `/docs` and is powered by **Swagger UI**.
If the server is running locally with default settings, you can access it at: [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs)

Swagger UI allows you to test API endpoints directly, including authentication using the "Authorize" button.

### OpenAPI Specification

For the raw OpenAPI JSON schema, use the built-in endpoint `/docs/openapi.json`: [http://127.0.0.1:8000/docs/openapi.json](http://127.0.0.1:8000/docs/openapi.json)

## Built-in FileReader

The service includes built-in file reader classes that handle different file formats. Below is a list of the currently available readers:

### [JsonlFileReader](src/testbench_requirement_service/readers/JsonlFileReader.py) *(Default)*

- **Description**: Reads requirement data from `.jsonl` (JSON Lines) files.
- **Required Configuration**:
    - `BASE_DIR`: Path to the directory containing the requirement files.
- **Required Schema**:
    - ***Projects*** are directories located at the top level inside `BASE_DIR`.
    - ***Baselines*** are `.jsonl` files stored within a project directory.
    - ***Requirements*** are JSON objects, each represented as a separate line in a baseline `.jsonl` file.
    A requirement follows this Schema:
        ```json
        {
            "name": "string",
            "extendedID": "string",
            "key": {
                "id": "string",
                "version": {
                    "name": "string",
                    "date": "string <date-time>",
                    "author": "string",
                    "comment": "string"
                }
            },
            "owner": "string",
            "status": "string",
            "priority": "string",
            "requirement": boolean,
            "description": "string",
            "documents": ["string"],
            "parent": "string" | null,
            "userDefinedAttributes": [
                {
                    "name": "string",
                    "valueType": "STRING" | "ARRAY" | "BOOLEAN",
                    "stringValue": "string",
                    "stringValues": ["string"],
                    "booleanValue": boolean
                }
            ]
        }
        ```
        If the `"requirement"` attribute is set to `true`, the object represents an actual requirement. Otherwise, it serves only as a node in the requirements tree structure.
        Root requirement objects have their `"parent"` attribute set to `null`.
    - ***UserDefinedAttributes*** are specified in the `UserDefinedAttributes.json` file, located at the top level in `BASE_DIR`.
    This file follows the Schema below:
        ```json
        [
            {
                "name": "string", 
                "valueType": "STRING" | "ARRAY" | "BOOLEAN"
            }
        ]
        ```

## Custom FileReader Classes

If you want to implement your own custom file reader, you need to create a subclass of the abstract [FileReader](src/testbench_requirement_service/readers/FileReader.py) class and implement all its abstract methods.

## Steps to create a custom FileReader class

**1. Create a new class**
- Subclass the abstract [FileReader](src/testbench_requirement_service/readers/FileReader.py) class.
    ```python
    # CustomFileReader.py

    from testbench_requirement_service.readers.FileReader import FileReader

    class CustomFileReader(FileReader):
        def __init__(self, config_path: str):
            ...
        
        ...
    ```
- Implement all required abstract methods.

**2. Ensure compatibility**
- Your custom FileReader class **must implement** all required abstract methods.
- Make sure your import paths are **correct** based on your project structure.

**3. Start the service with your custom reader**
- To use your custom file reader, start the service with the `--reader-class` option, specifying the **import path** (module path) to the class.
    ```powershell
    testbench-requirement-service start --reader-class path/to/CustomFileReader.py
    ```

## Contributing

We welcome contributions! See [CONTRIBUTING](CONTRIBUTING.md) for details.

## License

This project is licensed under the ... License – see the [LICENSE](LICENSE) file for details.

