# netosecret.py - Python class and CLI

{% stepper %}
{% step %}

### CLI usage: python netosecret.py --help

You can run this as a standalone CLI for encoding and decoding netosecret values, or use the NetoSecret class in your Python.

```python
"""Encode/Decode netosecret format for Netography API.
usage: netosecret.py [-h] [--url URL] [--appkey APPKEY] [--sharedsecret SHAREDSECRET] [--save SAVE] [--envname ENVNAME] [--print] [--decode] [--env] [--envfile ENVFILE] [shortname] [appname]
Encode/Decode netosecret format for Netography API.
positional arguments:
  shortname             Set the shortname
  appname               Set the appname
options:
  -h, --help            show this help message and exit
  --url URL             Set a custom API URL
  --appkey APPKEY       Set the appkey (prompt if not provided)
  --sharedsecret SHAREDSECRET
                        Set the sharedsecret (prompt if not provided)
  --save SAVE           Save to env file
  --envname ENVNAME     Variable name to write to in envfile
  --print               Print the encoded netosecret
  --decode              Decode NETOSECRET and print the JSON (contains secrets)
  --env                 Read all variables from environment
  --envfile ENVFILE     Read environment variables from the file

Example:
% python netosecret.py --appkey myappkey --sharedsecret mysharedsecret myshortname myappname
netosecret saved to netosecret.env
% python netosecret.py --decode --envfile netosecret.env
{
  "url": "https://api.netography.com/api/v1",
  "shortname": "myshortname",
  "appname": "myappname",
  "sharedsecret": "mysharedsecret",
  "appkey": "myappkey"
}
% python netosecret.py --help
"""
```

{% endstep %}

{% step %}

### class NetoSecret definition

These 11 lines are all you need to replace setting the 5 individual authentication fields used by the Fusion APi with the netosecret.

NetoSecret.encode()

```python
import argparse
import base64
import json
import os
from getpass import getpass
from typing import Dict

class NetoSecret:
    @staticmethod
    def encode(api_key: Dict[str, str]) -> str:
        api_key_json = json.dumps(api_key)
        api_key_base64 = base64.b64encode(api_key_json.encode()).decode()
        return api_key_base64

    @staticmethod
    def decode(api_key_base64: str) -> Dict[str, str]:
        api_key_json = base64.b64decode(api_key_base64).decode()
        api_key = json.loads(api_key_json)
        return api_key
```

{% endstep %}

{% step %}

### NetoSecret.encode() takes Python Dict in this format and returns netosecret string.

{ "url":"",\
"shortname":"",\
"appname":"",\
"sharedsecret":"",\
"appkey":""\
}

```python
    @staticmethod
    def encode(api_key: Dict[str, str]) -> str:
        api_key_json = json.dumps(api_key)
        api_key_base64 = base64.b64encode(api_key_json.encode()).decode()
        return api_key_base64
```

{% endstep %}

{% step %}

### NetoSecret.decode()

NetoSecret.decode() takes a netosecret string as argument and returns a Python Dict in format below:

{ "url":"",\
"shortname":"",\
"appname":"",\
"sharedsecret":"",\
"appkey":""\
}

```python
    @staticmethod
    def decode(api_key_base64: str) -> Dict[str, str]:
        api_key_json = base64.b64decode(api_key_base64).decode()
        api_key = json.loads(api_key_json)
        return api_key

```

{% endstep %}

{% step %}

### CLI argument parsing

Parses command line arguments when running this file

```python
def get_env_value(is_secret: bool, *keys: str) -> str:
    for key in keys:
        value = os.getenv(key)
        if value:
            if is_secret:
                print(f"Read from env {key}=******", file=os.stderr)
            else:
                print(f"Read from env {key}={value}", file=os.stderr)
            return value
    return ""

def main():
    parser = argparse.ArgumentParser(
        description="Encode/Decode netosecret format for Netography API."
    )

    parser.add_argument("shortname", nargs="?", help="Set the shortname")
    parser.add_argument("appname", nargs="?", help="Set the appname")
    parser.add_argument(
        "--url",
        help="Set a custom API URL",
        default="https://api.netography.com/api/v1",
    )
    parser.add_argument("--appkey", help="Set the appkey (prompt if not provided)")
    parser.add_argument(
        "--sharedsecret", help="Set the sharedsecret (prompt if not provided)"
    )
    parser.add_argument("--save", help="Save to env file", default="netosecret.env")
    parser.add_argument(
        "--envname", help="Variable name to write to in envfile", default="NETOSECRET"
    )
    parser.add_argument(
        "--print", action="store_true", help="Print the encoded netosecret"
    )
    parser.add_argument(
        "--decode",
        action="store_true",
        help="Decode NETOSECRET and print the JSON (contains secrets)",
    )
    parser.add_argument(
        "--env", action="store_true", help="Read all variables from environment"
    )
    parser.add_argument("--envfile", help="Read environment variables from the file")

    args = parser.parse_args()

    if args.envfile:
        with open(args.envfile) as f:
            for line in f:
                if not line.startswith("#") and "=" in line:
                    key, value = line.strip().split("=", 1)
                    os.environ[key] = value
```

{% endstep %}

{% step %}

### CLI: decode

Decodes netosecret to JSON

```python
    if args.decode:
        netosecret_to_decode = os.getenv(args.envname)
        if not netosecret_to_decode:
            netosecret_to_decode = getpass("Enter netosecret: ")
        decoded = NetoSecret.decode(netosecret_to_decode)
        print(json.dumps(decoded, indent=2))
        return
```

{% endstep %}

{% step %}

### CLI: encode

Encodes individual authentication fields to netosecret string

```python
    if args.env or args.envfile:
        args.url = (
            get_env_value(False, "NETO__API__URL", "NETO_URL", "NETO__URL") or args.url
        )
        args.appname = (
            get_env_value(False, "NETO__API__APP_NAME", "NETO_APP_NAME", "NETO_APPNAME")
            or args.appname
        )
        args.shortname = (
            get_env_value(
                False, "NETO__API__SHORTNAME", "NETO_SHORTNAME", "NETO__SHORTNAME"
            )
            or args.shortname
        )
        args.sharedsecret = (
            get_env_value(
                True,
                "NETO__API__CREDENTIALS__SHARED_SECRET",
                "NETO_SHAREDSECRET",
                "NETO__SHAREDSECRET",
                "NETO_SHARED_SECRET",
            )
            or args.sharedsecret
        )
        args.appkey = (
            get_env_value(
                True,
                "NETO__API__CREDENTIALS__APP_KEY",
                "NETO__APPKEY",
                "NETO__APP_KEY",
                "NETO_APPKEY",
            )
            or args.appkey
        )

    if not args.shortname:
        args.shortname = input("Enter shortname: ")
    if not args.appname:
        args.appname = input("Enter appname: ")
    if not args.appkey:
        args.appkey = getpass("Enter appkey: ")
    if not args.sharedsecret:
        args.sharedsecret = getpass("Enter sharedsecret: ")

    if not all([args.shortname, args.appname, args.appkey, args.sharedsecret]):
        parser.error(
            "All fields (shortname, appname, appkey, sharedsecret) must be provided."
        )

    api_key = {
        "url": args.url,
        "shortname": args.shortname,
        "appname": args.appname,
        "sharedsecret": args.sharedsecret,
        "appkey": args.appkey,
    }

    encoded = NetoSecret.encode(api_key)

    if args.print:
        print(encoded)
    else:
        with open(args.save, "w") as f:
            f.write(f"{args.envname}={encoded}\n")
        print(f"netosecret saved to {args.save}")


if __name__ == "__main__":
    main()
```

{% endstep %}
{% endstepper %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.fusion.vectra.ai/api-recipes/recipes/netosecret.py-python-class-and-cli.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
