> ## Documentation Index
> Fetch the complete documentation index at: https://help.cryptolens.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Python 3: Helpers

> Compute machine codes and check individual license properties.

Python 3 package `licensing 0.54`. [Reviewed source revision](https://github.com/Cryptolens/cryptolens-python/tree/8f38b5a37580f2aba1c9374f581cdc85e251950f).

```python theme={null}
from licensing.methods import Helpers
```

<a id="licensing.methods.Helpers.GetMachineCode" />

## GetMachineCode

Compute this device's machine code.

```python theme={null}
Helpers.GetMachineCode(v=1)
```

### Parameters

| Parameter | Default | Meaning |
| - | - | - |
| `v` | `1` | The machine-code algorithm version. The default is `1`; `2` supports the documented .NET-compatible Windows machine code. |

### Result

Returns a machine-code string, or `None` when the implementation cannot obtain a usable identifier.

Operating-system commands or unavailable system information can also raise exceptions; handle a missing identifier before activating.

### Checks

Computes an identifier only. It does not contact the licensing API or verify a license.

### Example

The Python 3 examples use version 2. Keep the same version when comparing the returned activations.

```python theme={null}
machine_code = Helpers.GetMachineCode(v=2)
if machine_code is None:
    print("Could not read a machine code.")
else:
    print(machine_code)
```

<a id="licensing.methods.Helpers.IsOnRightMachine" />

## IsOnRightMachine

Check whether the license contains the expected device or process identifier.

```python theme={null}
Helpers.IsOnRightMachine(
    license_key,
    is_floating_license=False,
    allow_overdraft=False,
    v=1,
    custom_machine_code=None
)
```

### Parameters

| Parameter | Default | Meaning |
| - | - | - |
| `license_key` | Required | A successfully loaded `LicenseKey` object. |
| `is_floating_license` | `False` | Use the floating-activation form of the machine-code comparison. |
| `allow_overdraft` | `False` | Also accept the overdraft form of a floating activation. This does not enable overdraft on the server. |
| `v` | `1` | The machine-code algorithm version. The default is `1`; `2` supports the documented .NET-compatible Windows machine code. |
| `custom_machine_code` | `None` | The identifier already used for activation. Supply it when using a custom device ID or a random floating-process ID; this skips local machine-code generation. |

### Result

Returns `True` when an activation matches, otherwise `False`.

A missing license object or a failure while computing its machine code can raise an exception. Check that license loading or activation succeeded first.

### Checks

Compares machine identifiers, with the requested floating and overdraft modes. It does not verify the signature, expiry, blocking, features or the floating deadline. This check assumes **Maximum Number of Machines is greater than 0**.

<a id="licensing.methods.Helpers.GetMACAddress" />

## GetMACAddress

Obtain a MAC-address-style identifier using Python's `uuid.getnode()`.

```python theme={null}
Helpers.GetMACAddress()
```

### Result

Returns a colon-separated hexadecimal string.

The underlying Python and operating-system calls determine how a node identifier is obtained.

### Checks

This is an identifier helper, not a license check. Do not assume that it always identifies the same physical network adapter.

<a id="licensing.methods.Helpers.HasNotExpired" />

## HasNotExpired

Compare the license's expiry with the device clock.

```python theme={null}
Helpers.HasNotExpired(license_key, allow_usage_on_expiry_date=True)
```

### Parameters

| Parameter | Default | Meaning |
| - | - | - |
| `license_key` | Required | A successfully loaded `LicenseKey` object. |
| `allow_usage_on_expiry_date` | `True` | Keep the default `True` in version 0.54. The `False` branch has the TypeError described below. |

### Result

With the default `allow_usage_on_expiry_date=True`, returns whether the remaining duration is greater than or equal to zero. Returns `False` for `None`.

In version 0.54, setting `allow_usage_on_expiry_date=False` raises `TypeError` for a non-null license because that branch compares a duration with a number. Avoid that option until it is fixed.

### Checks

Checks only expiry using the device clock. Despite the parameter's name, the default comparison does not extend the expiry to the end of its calendar day.

<a id="licensing.methods.Helpers.HasFeature" />

## HasFeature

Look up a feature path in the `cryptolens_features` data object.

```python theme={null}
Helpers.HasFeature(license_key, feature_name)
```

### Parameters

| Parameter | Default | Meaning |
| - | - | - |
| `license_key` | Required | A successfully loaded `LicenseKey` object. |
| `feature_name` | Required | The path in the feature hierarchy, for example `f2.voice.all`. |

### Result

Returns `True` or `False`; missing or empty feature data returns `False`.

Malformed feature JSON or a missing license object can raise an exception.

### Checks

Reads the JSON feature hierarchy in the data object's `StringValue`. It does not check the eight Boolean flags (`f1` to `f8`), signature or expiry.

## FAQ

<AccordionGroup>
  <Accordion title="Why Is the Machine Check False After Successful Activation?" id="why-is-the-machine-check-false-after-successful-activation">
    Check that **Maximum Number of Machines is greater than 0**. With a value of `0`, activation does not register machine codes. Also use the same identifier and algorithm version for activation and the machine check.
  </Accordion>

  <Accordion title="Can I Use a Process ID for Floating Licenses?" id="can-i-use-a-process-id-for-floating-licenses">
    Yes. Generate one random identifier when the process starts, send it as `machine_code` on activation, and pass it as `custom_machine_code` to the machine check with `is_floating_license=True`. Reuse that identifier for renewals and deactivation. See the [floating guide](/licensing-models/floating).
  </Accordion>
</AccordionGroup>

[Python SDK Reference](/libraries/python-api)
