Metadata-Version: 2.3
Name: nitlsconfig
Version: 1.0.0a4
Summary: Python API for reading nitlsconfig configurations and creating NI gRPC Device client channels from them
License: MIT
Keywords: nitlsconfig,tls,mtls,grpc,configuration
Author: NI
Author-email: opensource@ni.com
Maintainer: Philip Thong
Maintainer-email: philip.thong@emerson.com
Requires-Python: >=3.9
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: POSIX
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
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
Provides-Extra: grpc
Requires-Dist: grpcio (>=1.49.0,<2.0) ; extra == "grpc"
Requires-Dist: pywin32 (>=306) ; (sys_platform == "win32") and (extra == "grpc")
Project-URL: Documentation, https://nitlsconfig-python.readthedocs.io
Project-URL: Repository, https://github.com/ni/nitlsconfig-python
Description-Content-Type: text/markdown

# nitlsconfig

Python API that reads nitlsconfig configurations through the `nitlsconfig` command line,
and builds NI gRPC Device client channels from them.

Installed and imported as `nitlsconfig`; developed at
[ni/nitlsconfig-python](https://github.com/ni/nitlsconfig-python).

## Runtime dependencies

- nitlsconfig executable, discoverable.

## Install

Reading NI TLS configuration is pure Python and has no third-party dependencies:

- `pip install nitlsconfig`

The gRPC channel factory additionally needs grpcio, which is an optional extra:

- `pip install nitlsconfig[grpc]`

Neither install provides the `nitlsconfig` runtime itself. This package reads
configuration by invoking the `nitlsconfig` command line interface, which ships with NI
driver software products that support NI TLS. Install a driver that provides it before using
this package; without it, calls raise `ExecutableNotFoundError`.

## Creating a gRPC channel

`create_grpc_device_channel` reads the local NI TLS client configuration for the NI
gRPC Device Server and returns a `grpc.Channel` secured accordingly. The
`server_address` hostname or address is used to select matching target-specific NI TLS
settings. Pass the channel straight to any NI gRPC Python API:

```python
import nidcpower
import nitlsconfig

with nitlsconfig.create_grpc_device_channel("localhost", 31763) as channel:
    options = nidcpower.GrpcSessionOptions(channel, "")
    with nidcpower.Session("Dev1", grpc_options=options) as session:
        ...
```

NI driver software provides the NI TLS configuration. Using `create_grpc_device_channel`
opts into mTLS.

Before `create_grpc_device_channel` can succeed, use NI Hardware Manager to perform a
certificate exchange with the remote system. See
[Managing mTLS](https://www.ni.com/docs/en-US/bundle/hardwaremanager/page/mtls-manage.html)
for details.

Weakening the security posture to one-way TLS or to an insecure connection
requires explicitly changing that configuration in NI Hardware Manager. Either way, no
code change is needed.

The channel is owned by the caller - NI driver APIs never close it.

Retries are opt-in:

```python
channel = nitlsconfig.create_grpc_device_channel(
    "localhost", 31763, retry_policy=nitlsconfig.RetryPolicy()
)
```

`TlsConfigurationError` is raised when TLS is enabled but the configuration is
unusable. It is always importable, since handling it does not require grpcio.

`create_grpc_device_channel` and `RetryPolicy` do require grpcio; accessing them
without the `grpc` extra installed raises `ImportError` telling you which extra
to install.

## Reading configurations
```python
import nitlsconfig

# List configured services
clients = nitlsconfig.ClientConfig.list_services()
servers = nitlsconfig.ServerConfig.list_services()

if clients:
    # Read one client configuration
    client_info = nitlsconfig.ClientConfig(clients[0])
    print(client_info.service_name)
    print(client_info.certificate_mode)
    print(client_info.certificate_chain_location.scheme)
    print(client_info.certificate_chain_location.path)
    print(client_info.certificate_chain_contents)

    # Inspect target-specific configurations
    for known_server in client_info.known_servers:
        print(known_server.server_name)
        print(known_server.server_mode)
        print(known_server.trusted_certificates_location)

if servers:
    # Read one server configuration
    server_info = nitlsconfig.ServerConfig(servers[0])
    print(server_info.service_name)
    print(server_info.certificate_mode)
    print(server_info.client_mode)
    print(server_info.certificate_chain_location.scheme)
    print(server_info.certificate_key_location.scheme)
    print(server_info.trusted_certificates_location.scheme)
    print(server_info.trusted_certificates_contents)

    # Enumerate trusted certificates
    for cert in server_info.trusted_certificates:
        print(cert.display_name)
        print(cert.trusted_certificate_location.path)
        print(cert.trusted_certificate_contents)
```



