# LicenseSpring Python Library
The LicenseSpring Python Library provides convenient access to the LicenseSpring API from
applications written in the Python language.
## Installation
Install `licensespring` library:
```
pip install licensespring
```
Requires: Python >=3.9
## Hardware (Device) IDs
This library provides preconfigured hardware identity providers:
- `HardwareIdProvider` (default)
- `PlatformIdProvider`
- `HardwareIdProviderSource` (recommended)
You can set the desired hardware identity provider when initializing the APIClient:
```python
from licensespring.hardware import PlatformIdProvider
api_client = APIClient(api_key="_your_api_key_", shared_key="_your_shared_key_", hardware_id_provider=PlatformIdProvider)
```
It also supports their customization and creation of your own hardware id provider.
### HardwareIdProvider
Uses [uuid.getnode()](https://docs.python.org/3/library/uuid.html#uuid.getnode) to generate unique ID per device as described:
> Get the hardware address as a 48-bit positive integer. The first time this runs, it may launch a separate program, which could be quite slow. If all attempts to obtain the hardware address fail, we choose a random 48-bit number with the multicast bit (least significant bit of the first octet) set to 1 as recommended in RFC 4122. “Hardware address” means the MAC address of a network interface. On a machine with multiple network interfaces, universally administered MAC addresses (i.e. where the second least significant bit of the first octet is unset) will be preferred over locally administered MAC addresses, but with no other ordering guarantees.
All of the methods exposed by `HardwareIdProvider`:
```python
class HardwareIdProvider:
def get_id(self):
return str(uuid.getnode())
def get_os_ver(self):
return platform.platform()
def get_hostname(self):
return platform.node()
def get_ip(self):
return socket.gethostbyname(self.get_hostname())
def get_is_vm(self):
return False
def get_vm_info(self):
return None
def get_mac_address(self):
return ":".join(("%012X" % uuid.getnode())[i : i + 2] for i in range(0, 12, 2))
def get_request_id(self):
return str(uuid.uuid4())
```
### HardwareIdProviderSource
Utilizes a proprietary in-house algorithm for our SDKs **(recommended algorithm)** [Hardware ID Algorithm](https://pypi.org/project/licensespring-hardware-id-generator/).
```python
class HardwareIdProviderSource(HardwareIdProvider):
def get_id(self):
hardware_id = get_hardware_id(HardwareIdAlgorithm.Default)
if logging.getLogger().hasHandlers():
logs = get_logs()
version = get_version()
logging.info("Version: ",version)
logging.info("Hardware ID:",hardware_id)
for log_line in logs:
logging.info(log_line)
return hardware_id
```
### PlatformIdProvider
Uses [sys.platform](https://docs.python.org/3/library/sys.html#sys.platform) and OS queries to find the raw GUID of the device.
Extends the `HardwareIdProvider` and overwrites only the `get_id` method:
```python
class PlatformIdProvider(HardwareIdProvider):
def get_id(self):
id = None
if sys.platform == 'darwin':
id = execute("ioreg -d2 -c IOPlatformExpertDevice | awk -F\\\" '/IOPlatformUUID/{print $(NF-1)}'")
if sys.platform == 'win32' or sys.platform == 'cygwin' or sys.platform == 'msys':
id = read_win_registry('HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography', 'MachineGuid')
if not id:
id = execute('wmic csproduct get uuid').split('\n')[2].strip()
if sys.platform.startswith('linux'):
id = read_file('/var/lib/dbus/machine-id')
if not id:
id = read_file('/etc/machine-id')
if sys.platform.startswith('openbsd') or sys.platform.startswith('freebsd'):
id = read_file('/etc/hostid')
if not id:
id = execute('kenv -q smbios.system.uuid')
if not id:
id = super().get_id()
return id
```
### Customization
Extend any of the preconfigured hardware identity providers, overwrite the methods you want and provide it when initializing the APIClient:
```python
class CustomHardwareIdProvider(HardwareIdProvider):
def get_id(self):
return "_my_id_"
api_client = APIClient(api_key="_your_api_key_", shared_key="_your_shared_key_", hardware_id_provider=CustomHardwareIdProvider)
```
## APIClient Usage Examples
### Set app version
```python
import licensespring
licensespring.app_version = "MyApp 1.0.0"
```
### Create APIClient
```python
from licensespring.api import APIClient
api_client = APIClient(api_key="_your_api_key_", shared_key="_your_shared_key_")
```
### Activate key based license
```python
product = "lkprod1"
license_key = "GPB7-279T-6MNK-CQLK"
license_data = api_client.activate_license(product=product, license_key=license_key)
print(license_data)
```
### Activate user based license
```python
product = "uprod1"
username = "user1@email.com"
password = "nq64k1!@"
license_data = api_client.activate_license(
product=product, username=username, password=password
)
print(license_data)
```
### Deactivate key based license
```python
product = "lkprod1"
license_key = "GPUB-J4PH-CGNK-C7LK"
api_client.deactivate_license(product=product, license_key=license_key)
```
### Deactivate user based license
```python
product = "uprod1"
username = "user1@email.com"
api_client.deactivate_license(
product=product, username=username
)
```
### Check key based license
```python
product = "lkprod1"
license_key = "GPBQ-DZCP-E9SK-CQLK"
license_data = api_client.check_license(product=product, license_key=license_key)
print(license_data)
```
### Check user based license
```python
product = "uprod1"
username = "user2@email.com"
password = "1l48y#!b"
license_data = api_client.check_license(product=product, username=username)
print(license_data)
```
### Add consumption
```python
product = "lkprod1"
license_key = "GPSU-QTKQ-HSSK-C9LK"
# Add 1 consumption
consumption_data = api_client.add_consumption(
product=product, license_key=license_key
)
print(consumption_data)
# Add 3 consumptions
consumption_data = api_client.add_consumption(
product=product, license_key=license_key, consumptions=3
)
print(consumption_data)
# Add 1 consumption, allow overages and define max overages
consumption_data = api_client.add_consumption(
product=product, license_key=license_key, allow_overages=True, max_overages=10
)
print(consumption_data)
```
### Add feature consumption
```python
product = "lkprod1"
license_key = "GPTJ-LSYZ-USEK-C8LK"
feature = "lkprod1cf1"
# Add 1 consumption
feature_consumption_data = api_client.add_feature_consumption(
product=product, license_key=license_key, feature=feature
)
# Add 3 consumptions
feature_consumption_data = api_client.add_feature_consumption(
product=product, license_key=license_key, feature=feature, consumptions=3
)
print(feature_consumption_data)
```
### Trial key
```python
product = "lkprod2"
trial_license_data = api_client.trial_key(product=product)
print(trial_license_data)
```
### Product details
```python
product = "lkprod1"
product_data = api_client.product_details(product=product)
print(product_data)
```
### Track device variables
```python
product = "lkprod1"
license_key = "GPUB-SZF9-AB2K-C7LK"
variables = {"variable_1_key": "variable_1_value", "variable_2_key": "variable_2_value"}
device_variables = api_client.track_device_variables(product=product, license_key=license_key, variables=variables)
print(device_variables)
```
### Get device variables
```python
product = "lkprod1"
license_key = "GPUB-SZF9-AB2K-C7LK"
device_variables = api_client.get_device_variables(product=product, license_key=license_key)
print(device_variables)
```
### Floating borrow
```python
product = "lkprod1"
license_key = "GPUC-NGWU-3NJK-C7LK"
# Borrow for 2 hours
borrowed_until = (datetime.utcnow() + timedelta(hours=2)).isoformat()
floating_borrow_data = api_client.floating_borrow(product=product, license_key=license_key, borrowed_until=borrowed_until)
print(floating_borrow_data)
```
### Floating release
```python
product = "lkprod1"
license_key = "GPUC-NGWU-3NJK-C7LK"
api_client.floating_release(product=product, license_key=license_key)
```
### Change password
```python
username = "user4@email.com"
password = "_old_password_"
new_password = "_new_password_"
is_password_changed = api_client.change_password(username=username, password=password, new_password=new_password)
print(is_password_changed)
```
### Versions
```python
product = "lkprod1"
license_key = "GPB7-279T-6MNK-CQLK"
# Get versions for all environments
versions_data = api_client.versions(product=product, license_key=license_key)
# Get versions for mac environment
mac_versions_data = api_client.versions(
product=product, license_key=license_key, env="mac"
)
print(versions_data)
```
### Installation file
```python
product = "lkprod1"
license_key = "GPB7-279T-6MNK-CQLK"
# Get the latest installation file
installation_file_data = api_client.installation_file(
product=product, license_key=license_key
)
# Get the latest installation file for linux environment
installation_file_data = api_client.installation_file(
product=product, license_key=license_key, env="linux"
)
# Get the latest installation file for version 1.0.0
installation_file_data = api_client.installation_file(
product=product, license_key=license_key, version="1.0.0"
)
print(installation_file_data)
```
### Customer license users
```python
product = "uprod1"
customer = 'c1@c.com'
customer_license_users_data = api_client.customer_license_users(
product=product, customer=customer
)
print(customer_license_users_data)
```
### SSO URL
```python
product = "uprod1"
customer_account_code = "ccorp"
sso_url_data = api_client.sso_url(
product=product, customer_account_code=customer_account_code
)
print(sso_url_data)
```
### SSO URL with `code` response type
```python
product = "uprod1"
customer_account_code = "ccorp"
sso_url_data = api_client.sso_url(
product=product,
customer_account_code=customer_account_code,
response_type="code",
)
print(sso_url_data)
```
### Activate offline
```python
product = "lkprod1"
license_key = "GPY7-VHX9-MDSK-C3LK"
# Generate data for offline activation
activate_offline_data = api_client.activate_offline_dump(
product=product, license_key=license_key
)
# Write to file
with open('activate_offline.req', mode='w') as f:
print(activate_offline_data, file=f)
# Activate offline
license_data = api_client.activate_offline(data=activate_offline_data)
print(license_data)
```
### Activate offline load
```python
# Read from file
with open('./ls_activation.lic') as file:
ls_activation_data = file.read()
license_data = api_client.activate_offline_load(ls_activation_data)
print(license_data)
```
### Check offline load
```python
# Read from file
with open('./license_refresh.lic') as file:
license_refresh_data = file.read()
license_data = api_client.check_offline_load(license_refresh_data)
print(license_data)
```
### Deactivate offline
```python
product = "lkprod1"
license_key = "GPYC-X5J2-L5SK-C3LK"
# Generate data for offline deactivation
deactivate_offline_data = api_client.deactivate_offline_dump(
product=product, license_key=license_key
)
# Write to file
with open('deactivate_offline.req', mode='w') as f:
print(deactivate_offline_data, file=f)
# Deactivate offline
api_client.deactivate_offline(data=deactivate_offline_data)
```
### Key based license feature check
```python
product = "lkprod1"
license_key = "GPB7-279T-6MNK-CQLK"
feature = "lkprod1f1"
license_feature_data = api_client.check_license_feature(
product=product, feature=feature, license_key=license_key
)
print(license_feature_data)
```
### Key based license floating feature release
```python
product = "lkprod1"
license_key = "GPB7-279T-6MNK-CQLK"
feature = "lkprod1f1"
api_client.floating_feature_release(
product=product, feature=feature, license_key=license_key
)
```
### User licenses
```python
product = "userpr1"
username = "user123"
password = "password"
response = api_client.user_licenses(
product=product,username=username,
password=password)
print(response)
```
## Licensefile
### Licensefile setup
To use licensefile inside a python SDK you should first setup your key and IV. Key and IV are used inside Python SDK for encryption and decryption process inside licensefile. For the first setup it is essenital to chose **password** and **salt** for key generation. This process is only required **once** at the setup.
```python
from licensespring.licensefile.default_crypto import DefaultCryptoProvider
password = "YOUR_PASSWORD"
salt = "YOUR_SALT"
crypto = DefaultCryptoProvider()
key = crypto.derive_key(password=key_password,salt=key_salt)
iv = crypto.generate_random_iv()
```
### Configuration Setup
After you have successfully setup your key and IV you should setup your Configuration.
```python
from licensespring.licensefile.config import Configuration
conf = Configuration(product="your_product_short_code",
api_key="your_api_key",
shared_key="your_shared_key",
file_key=key,
file_iv=iv,
hardware_id_provider=HardwareIdProvider,
verify_license_signature=True,
signature_verifier=SignatureVerifier,
api_domain="api.licensespring.com",
api_version="v4",
filename="License",
file_path=None,
grace_period_conf=24,
air_gap_public_key="your_air_gap_public_key")
```
* **product (str)**: product short code.
* **api_key (str)**: Your unique API key used for authentication with the licensing server.
* **shared_key (str)**: A shared secret key used alongside the API key for enhanced security during the license verification process.
* **file_key (str)**: The encryption key used for securing license files on the client side.
* **file_iv (str)**: The initialization vector for the encryption algorithm. This complements the file_key for encrypting and decrypting license files.
* **hardware_id_provider (object, optional)**: The provider class used for generating a unique hardware ID. This ID helps in binding the license to specific hardware. Defaults to HardwareIdProvider.
* **verify_license_signature (bool, optional)**: A boolean flag indicating whether the license's digital signature should be verified. Defaults to True for enhanced security.
* **signature_verifier (object, optional)**: The class responsible for verifying the digital signature of licenses. Defaults to SignatureVerifier.
* **api_domain (str, optional)**: The domain name of the API server with which the licensing operations are performed. Defaults to "api.licensespring.com".
* **api_version (str, optional)**: The version of the API to use for requests. This allows for compatibility with different versions of the licensing API. Defaults to "v4".
* **filename (str, optional)**: The default filename for saved license files. This can be customized as needed. Defaults to "License".
* **file_path (str, optional)**: The path where license files should be saved on the client system. If not specified, a **[default location](https://docs.licensespring.com/sdks/tutorials/best-practices/local-license-file#W8U6X)** is used.
* **grace_period_conf (int, optional)**: The number of hours to allow as a grace period for Defaults to 24 hours.
* **air_gap_public_key (str, optional)**: Air gap public key from platform check **[here](https://docs.licensespring.com/sdks/tutorials/licensing-scenarios/air-gapped#Ws1BB)** for more
**Warning:**
* We advise for `hardware_id_provider` to use a newly developed [`HardwareIdProviderSource`](#hardwareidprovidersource) provider.
* On the next major version release [`HardwareIdProviderSource`](#hardwareidprovidersource) will be set as default `hardware_id_provider`
### LicenseID
* **from_key(cls, key)**: Class method to create a LicenseID instance for key-based activation
* **from_user(cls, username, password)**: Class method to create a LicenseID instance for user-based activation.
#### Key-based setup
```python
license_id = LicenseID.from_key("your_license_key")
```
#### User-based setup
```python
license_id = LicenseID.from_user(username="email@email.com",password="password")
```
### LicenseManager
```python
from licensespring.licensefile.license_manager import LicenseManager,LicenseID
manager = LicenseManager(conf)
```
#### Configuration parametres
conf (Configuration): **[A configuration object](#configuration-setup)**
#### activate_license
Activates a license with the license server and updates local license data. When activating user based license we advise that **unique_license_id** is set which represent **"id"** field within the [license check](https://docs.licensespring.com/license-api/check).
**Key-based**
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H6QM-6H5R-ZENJ-VBLK")
license = manager.activate_license(license_id)
```
**User-based**
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_user(username="python@gmail.com",password="7t_x3!o9")
license = manager.activate_license(license_id,unique_license_id=1723642193958949)
```
**Parameters**:
* **license_id** (LicenseID): An instance containing the license key or user credentials.
**Return**:
**License** object representing the activated license.
#### load_license
Loads the license file and sets attributes for the LicenseData instance. Returns an instance of the License class reflecting the loaded license.
```python
manager = LicenseManager(conf)
license = manager.load_license()
```
**Return**:
**License** object representing the activated license.
#### current_config
Get current configuration
```python
manager = LicenseManager(conf)
config = manager.current_config()
```
**Return** (dict): current configuration
#### reconfigure
Change the current configuration
**Parameters**:
* **conf** (Configuration): Configuration object
```python
manager = LicenseManager(conf)
manager.reconfigure(
Configuration(
product="lkprod2",
api_key="new_key",
shared_key="new_key",
file_key="file_key",
file_iv="file_iv",
file_path="bb",
grace_period_conf=12,
is_guard_file_enabled=True,
)
)
```
#### is_license_file_corrupted
Checks if licensefile is corrupted
```python
manager = LicenseManager(conf)
boolean = manager.is_license_file_corrupted()
```
**Return** (bool): If the file is corrupted return True, otherwise False
#### clear_local_storage
Clear all data from current product
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H6QM-6H5R-ZENJ-VBLK")
license = manager.activate_license(license_id)
manager.clear_local_storage()
```
#### data_location
Get licensefile location
```python
manager = LicenseManager(conf)
folder_path = manager.data_location()
```
**Return** (str): Licensefile location
#### set_data_location
Set data location
**Parameters**:
* **path** (str): new data location path
```python
manager = LicenseManager(conf)
manager.set_data_location()
```
**Return**: None
#### license_file_name
Get licensefile name
```python
manager = LicenseManager(conf)
file_name = manager.license_file_name()
```
**Return** (str): Licensefile name
#### set_license_file_name
Set licensefile name
**Parameters**:
* **name** (str): license file name
```python
manager = LicenseManager(conf)
manager.set_license_file_name()
```
**Return**: None
#### is_online
Checks if the licensing server is accessible. Returns True if online, False otherwise.
**Parameters**:
* **throw_e** (bool,optional): If True throws exception, otherwise exception won't be raised.
```python
manager = LicenseManager(conf)
license = manager.is_online()
```
#### get_air_gap_activation_code
Get activation code for air gap license
**Parameters**:
* **initialization_code** (str): initialization code
* **license_key** (str): license key
```python
initialization_code = "Q/MWfwp1NWAYARl8Q7KSo5Cg2YKqS2QLlnQ3nEeSBsk="
license_key = "UFF3-E9GA-VUJQ-GMLK"
manager = LicenseManager(conf)
activation_code = manager.get_air_gap_activation_code(initialization_code=initialization_code, license_key=license_key)
print("Activation code:",activation_code)
```
**Return** (str): activation code
#### activate_air_gap_license
Activate air gap license
**Parameters**:
* **confirmation_code** (str): confirmation code
* **policy_path** (str): policy path (file or folder)
* **license_key** (str): license_key
* **policy_id** (str): policy id
```python
confirmation = "ERbQBuE8giIjqMPj972Skipehqn0szQ8TH56INyo3OdtMHO1SuTVsoCOSnJWB6rml98PJ6SjybTPymOVZTG4hQ=="
policy_id = "998"
license_key = "UFF3-E9GA-VUJQ-GMLK"
policy_path = "path_to_air_lic"
manager = LicenseManager(conf)
license = manager.activate_air_gap_license(
confirmation_code=confirmation, policy_path=policy_path, license_key=license_key, policy_id=policy_id
)
```
**Raises**:
* **LicenseActivationException**: Signature verification failed
**Return** (License): License
#### create_offline_activation_file
Creates .req file for offline activation, including various optional parameters related to the device and software environment.
**Parameters**:
* **license_id** (LicenseID): An instance containing the license key or user credentials.
* **req_path** (str): Specify the path where to create .req file.
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H94R-S6KB-L7AJ-SXLK")
req_file_path = manager.create_offline_activation_file(license_id,'offline_files/test')
```
**Return** (str): Path of the .req file created for activation.
#### activate_license_offline
Activates a license offline using a .lic file provided via the specified path.
**Parameters**:
* **ls_activation_path** (str): Path to the activation file.
```python
file_path = 'offline_files/ls_activation.lic'
manager = LicenseManager(conf)
license = manager.activate_license_offline(file_path)
```
**Raises**:
* **LicenseActivationException**: Activation data is not valid.
* **LicenseActivationException**: Response file ID mismatch.
* **LicenseActivationException**: License does not belong to this device.
**Return**(License): Returns a License object representing the activated license.
#### get_trial_license
Creates LiceseID for trial licenses
**Parameters**:
* **customer** (Customer): Customer object
* **license_policy** (str,optional): license policy code. Defaults to None.
```python
customer = Customer(email='python_policy@gmail.com')
manager = LicenseManager(conf)
license_id = manager.get_trial_license(customer=customer,license_policy='test')
license = manager.activate_license(license_id=license_id)
```
**Return**(LicenseID): Returns a LicenseID object.
#### get_version_list
Get versions
**Parameters**:
* **license_id** (LicenseID): license id object
* **channel** (str, optional): channel of the version
* **unique_license_id** (int,optional): A unique identifier for the license.
* **env** (str,optional): Version of environment
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("3ZG2-K25B-76VN-WXLK")
response = manager.get_version_list(license_id=license_id)
```
**Return**(list): List of versions
#### get_installation_file
Get installation file
**Parameters**:
* **license_id** (LicenseID): An instance containing the license key or user credentials
* **channel** (str, optional): channel of the version
* **unique_license_id** (int, optional): A unique identifier for the license.
* **env** (str, optional): Version of environment
* **version** (str, optional): Versions
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("3ZG2-K25B-76VN-WXLK")
response = manager.get_installation_file(license_id=license_id)
```
**Return** (dict): installation file
#### get_customer_license_users
Get customer license users
**Parameters**:
* customer (Customer): customer
```python
manager = LicenseManager(conf)
customer = Customer(email="c1@c.com")
response = manager.get_customer_license_users(customer=customer)
```
**Return**(dict): customer license user
#### get_user_licenses
Get user licenses
**Parameters**:
* **license_id** (LicenseID): license_id
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_user(username="t@tt.com", password="d#2!17vi")
response = manager.get_user_licenses(license_id)
```
**Return**(list): User licenses
#### get_sso_url
Get user licenses
**Parameters**:
* account_code (str): account code
* use_auth_code (bool, optional): Use code for response_type. Defaults to True.
```python
manager = LicenseManager(conf)
response = manager.get_sso_url(account_code="your_account_code")
```
**Return**(dict): url
### License object
Object responsible for license operations
#### is_floating_expired
Determines wheter the license floating period has expired
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
license.check()
response = license.is_floating_expired()
```
**Return (bool)**: True if license floating period has expired otherwise False
#### floating_timeout
Retrieve license flaoting timeout
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
print(license.floating_timeout())
```
**Return (int)**: License floating timeout
#### is_floating
Check if license is floating (Floating Server or Floating Cloud)
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
print(license.is_floating())
```
**Return (bool)**: True if license if floating, otherwise False
#### floating_client_id
Get floating client id
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
print(license.floating_client_id())
```
**Return (str)**: Floating client id
#### is_controlled_by_floating_server
Check if license is controlled by Floating Server
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
print(license.is_controlled_by_floating_server())
```
**Return (bool)**: True if license is controlled by floating server, otherwise False
#### floating_in_use_devices
Number of floating devices in use
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
print(license.floating_in_use_devices())
```
**Return (int)**: Number of floating devices in use
#### floating_end_date
Datetime when flaoting will be released
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
print(license.floating_end_date())
```
**Return (datetime)**: Datetime when device will be released
#### max_floating_users
Number of max floating users
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
print(license.max_floating_users())
```
**Return (int)**: Number of max floating users
#### is_validity_period_expired
Determines whether the license's validity period has expired
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
response = license.is_validity_period_expired()
```
**Return (bool)**: True if license expired;False if license is valid
#### validity_period
Gets validity period of the license
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
response = license.validity_period()
```
**Return (datetime)**: Datetime in UTC
#### validity_with_grace_period
Gets the validity period with grace period of the license
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
response = license.validity_with_grace_period()
```
**Return (datetime)**: Datetime in UTC
#### license_user
Gets the license user
```python
user_data = license.license_user()
print(user_data)
```
**Return** (dict): license user
#### maintenance_days_remaining
Gets how many days are left until the maintenance ends
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
response = license.maintenance_days_remaining()
```
**Return (int)**: Maintenance days left
#### days_remaining
Gets how many days are left until the validity period ends
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
response = license.days_remaining()
```
**Return (int)**: Validity period days left
#### customer_information
Gets customer information
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
response = license.customer_information()
```
**Return (dict)**: customer information
#### id
Gets license id
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
response = license.id()
```
**Return (int)**: license id
#### max_transfers
Get the max transfers
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
response = license.max_transfers()
```
**Return (int)**: max transfers
#### transfer_count
Get the transfer count
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
response = license.transfer_count()
```
**Return (int)**: transfer count
#### is_device_transfer_allowed
Get if the device transfer is allowed
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
response = license.is_device_transfer_allowed()
```
**Return (bool)**: True if device transfer is allowed otherwise False.
#### is_device_transfer_limited
Get if the device transfer is limited
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
response = license.is_device_transfer_limited()
```
**Return (bool)**: True if device transfer is limited otherwise False.
#### days_since_last_check
Get how many days passed since last check
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
license.check()
response = license.days_since_last_check()
```
**Return (int)**: How many days have passed since last check.
#### start_date
Get the start date of the license
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
response = license.start_date()
```
**Return (datetime)**: Datetime in UTC
#### maintenance_period
Get the maintenance period of the license
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
response = license.maintenance_period()
```
**Return (datetime)**: Datetime in UTC
#### is_maintence_period_expired
Checks if maintence period has expired
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
response = license.is_maintence_period_expired()
```
**Return (bool)**: If maintence period expired returns True otherwise False
#### last_check
Gets when the last check was performed
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
response = license.last_check()
```
**Return (datetime)**: Datetime in UTC
#### last_usage
Gets when the last license usage
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
response = license.last_usage()
```
**Return (datetime)**: Datetime in UTC
#### license_type
Gets the license type
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
response = license.license_type()
```
**Return (str)**: License type
#### max_activations
Gets the license max activations
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
response = license.max_activations()
```
**Return (int)**: max activations
#### metadata
Gets the license metadata
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
response = license.metadata()
```
**Return (dict)**: metadata
#### allow_unlimited_activations
Check if unlimited activationsis allowed
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
response = license.allow_unlimited_activations()
```
**Return (bool)**: If unlimited activations is allowed returns True otherwise False
#### allow_grace_subscription_period
Check if grace subscription period is allowed
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
response = license.allow_grace_subscription_period()
```
**Return (bool)**: If grace subscription period is allowed returns True otherwise False
#### is_subscription_grace_period_started
Check if grace subscription period has started
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
response = license.is_subscription_grace_period_started()
```
**Return (bool)**: If grace subscription period has started returns True otherwise False
#### is_grace_period_started
Check if license is in grace period
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
response = license.is_grace_period_started()
```
**Return (bool)**: True if grace period has started, otherwise False
#### grace_period_hours_remaining
Get remain hours of grace period
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
response = license.grace_period_hours_remaining()
```
**Return (int)**: Number of hours left in grace period
#### get_grace_period
Get grace period
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
response = license.get_grace_period()
```
**Return (int)**: grace period
#### subscription_grace_period
Get subscription grace period
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
response = license.subscription_grace_period()
```
**Return (int)**: subscription grace period
#### is_expired
Checks if the license validity has expired
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
response = license.is_expired()
```
**Return (bool)**: True if license has expired otherwise False
#### license_enabled
Checks if the license is enabled
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
response = license.license_enabled()
```
**Return (bool)**: True if license is enabled otherwise False
#### license_active
Checks if the license is active
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
response = license.license_active()
```
**Return (bool)**: True if license is active otherwise False
#### is_valid
Checks if the license is valid (license is active, enabled and didn't expired)
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
response = license.is_valid()
```
**Return (bool)**: True if license is valid otherwise False
#### prevent_vm
Checks if the license prevents virtual machines
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
response = license.prevent_vm()
```
**Return (bool)**: True if license prevents VM's otherwise False
#### is_trial
Checks if the license is trial
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
response = license.is_trial()
```
**Return (bool)**: True if license is trial otherwise False
#### expiry_date
Get expiry date of floating license
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
response = license.expiry_date()
```
**Return (datetime)**: Expiry date in UTC
#### borrow_until
Get the date until a license is borrwed
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
response = license.borrow_until()
```
**Return (datetime)**: borrow_until in UTC
#### is_borrowed
Check if a license is borrowed
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
response = license.is_borrowed()
```
**Return (bool)**: True if license is borrowed otherwise False
#### local_consumptions
Get local consumptions
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
response = license.local_consumptions()
```
**Return (int)**: local consumptions
#### max_consumptions
Get max consumptions
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
response = license.max_consumptions()
```
**Return (int)**: max consumptions
#### total_consumptions
Get total consumptions
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
response = license.total_consumptions()
```
**Return (int)**: total consumptions
#### max_overages
Get max overages
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
response = license.max_overages()
```
**Return (int)**: max_overages
#### allow_unlimited_consumptions
Check if unlimited consumptions is allowed
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
response = license.allow_unlimited_consumptions()
```
**Return (int)**: If unlimited consumptions are allowed return True otherwise False
#### consumption_reset
Check if there is consumption reset
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
response = license.consumption_reset()
```
**Return (bool)**: If there is consumption reset returns True otherwise False
#### allow_overages
Check if overages are allowed
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
response = license.allow_overages()
```
**Return (bool)**: If overages are allowed returns True otherwise False
#### consumption_period
Get consumption period
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
response = license.allow_overages()
```
**Return (str)**: Consumption period
#### get_feature_data
Get feature data
**Parameters**:
* feature_code (str): feature code
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
feature_code = "feature1"
response = license.get_feature_data(feature_code)
```
**Return (dict)**: Feature
#### features
Get feature list
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
print(license.features())
```
**Return (list)**: Features
#### check_license_status
Verifies the current status of the license. It raises exceptions if the license is not enabled, not active, or expired
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
license.check_license_status()
```
**Raises**:
**LicenseStateException**: Raised if the license fails one of the following checks:
* License is not enabled.
* License is not active.
* License validity period has expired.
**Return**: None
#### check
Performs an online check to synchronize the license data with the backend. This includes syncing consumptions for consumption-based licenses.
**Parameters**:
* **include_expired_features (bool, optional)**: Includes expired license features in the check.
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
response=license.check()
```
**Raises**:
**ClientError**: Raised if there's an issue with the API client's request, such as invalid credentials or unauthorized access.
**RequestException**: Raised if there's a problem with the request to the licensing server, such as network issues or server unavailability.
**Return (dict)**: The updated license cache.
#### deactivate
Deactivates the license and optionally deletes the local license file.
**Parameters**:
* **delete_license (bool, optional)**: If **True**, deletes the local license file upon deactivation.
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
license.deactivate()
```
**Return**: None
#### local_check
This method ensures the integrity and consistency of the licensing information by comparing the data stored in the local license file with the predefined configurations in the **Configuration object**.
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
license.local_check()
```
**Raises**:
**ConfigurationMismatch**: Raised if the product code or hardware ID in the license file does not match the expected values provided in the Configuration
**VMIsNotAllowedException**: Raised if the license is used in a VM environment when the license explicitly disallows it.
**TimeoutExpiredException**: Raised if a floating license has expired. This is more relevant if is_floating_expired is later implemented to perform actual checks.
**ClockTamperedException**: Raised if there is evidence of tampering with the system's clock, detected by comparing the system's current time with the last usage time recorded in the license file.
**Return**: None
#### add_local_consumption
Adds local consumption records for **consumption-based licenses**.
**Parameters**:
* **consumptions (bool, optional)**: The number of consumptions to add locally
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
license.add_local_consumption()
```
**Raises**:
**LicenseSpringTypeError**: Raised if the license type does not support consumption (i.e., not a consumption-based license).
**ConsumptionError**: Raised if adding the specified number of consumptions would exceed the allowed maximum for the license.
**Return**: None
#### sync_consumption
Synchronizes local consumption data with the server, adjusting for overages if specified.
Parameters:
* **req_overages (int, optional)**: Specifies behavior for consumption overages.
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
license.add_local_consumption(5)
license.sync_consumption()
```
**Raises**:
**RequestException**: Raised if the request to synchronize consumption data with the server fails, for instance, due to network issues or server unavailability.
Return (bool): True if the consumption data was successfully synchronized; False otherwise.
#### is_grace_period
Determines if the current license state is within its grace period following a specific exception.
**Parameters**:
* **ex** (Exception): Raised Exception
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
try:
license.check()
except Exception as ex
boolean = license.is_grace_period(ex)
```
**Return (bool)**: True if the license is within its grace period, False otherwise
#### change_password
Changes password of a user
**Parameters**:
* **password** (str): Old password of license user
* **new_password**(str): New password of license user
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_user(username="python@gmail.com",password="7t_x3!o9")
license = manager.activate_license(license_id)
license.change_password(password="7t_x3!o9",new_password="12345678")
```
**Return (str)**: "password_changed"
#### setup_license_watch_dog
Initializes and starts the license watchdog with the specified callback and timeout settings.
**Parameters**:
**callback** (Callable): A callable to be executed by the watchdog in response to specific events or conditions.
**timeout** (int): The period in minutes after which the watchdog should perform its checks.
**deamon** (bool, optional): Run thread as deamon. Defaults to False.
**run_immediately** (bool,optional): run license check immediately, if False wait for timeout first.
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
license.setup_license_watch_dog(callback,timeout)
```
**Return**: None
#### stop_license_watch_dog
Stops the license watchdog if it is currently running, effectively halting its monitoring and callback activities.
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
license.setup_license_watch_dog(callback,timeout)
license.stop_license_watch_dog()
```
**Return**: None
#### setup_feature_watch_dog
Initializes and starts the feature watchdog with the specified callback and timeout.
**Parameters**:
**callback** (Callable): A callable to be executed by the watchdog in response to specific events or conditions.
**timeout** (int): The period in minutes after which the watchdog should perform its checks.
**deamon** (bool, optional): Run thread as deamon. Defaults to False.
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
license.setup_feature_watch_dog(callback,timeout)
```
**Return**: None
#### stop_feature_watch_dog
Stops the feature watchdog if it is currently running.
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
license.setup_feature_watch_dog(callback,timeout)
license.stop_feature_watch_dog()
```
**Return**: None
#### add_local_feature_consumption
Adds local consumption to the feature.
**Parameters**:
* **feature** (str): feature code.
* **consumptions** (int,optional): Number of consumptions.
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
license.add_local_feature_consumption("lkprod1cf1",3)
```
**Raises**:
* **ItemNotFoundError**: If the feature specified by `feature_code` does not exist.
* **LicenseSpringTypeError**: If the identified feature is not of the "consumption" type.
* **ConsumptionError**: If adding the specified number of consumptions would exceed the feature's consumption limits.
**Return**: None
#### sync_feature_consumption
Synchronizes local consumption data with the server.
**Parameters**:
* **feature** (str): feature code.
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
license.add_local_feature_consumption("lkprod1cf1",3)
license.sync_feature_consumption("lkprod1cf1")
```
**Return** (bool): True if the consumption data was successfully synchronized; False otherwise.
#### floating_borrow
Attempts to borrow a floating license until the specified date, updating the system status based on the outcome of the borrow attempt.
**Parameters**:
* **borrow_until** (str): A string representing the date until which the license should be borrowed.
* **password** (str,optional): Password for the license if required.
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
license.floating_borrow("2031-05-06T00:00:00Z")
```
**Return**: None
#### floating_release
Releases a borrowed floating license and updates the license status accordingly.
**Parameters**:
* **throw_e**(bool): A boolean indicating whether to raise an exception on failure.
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
license.check()
license.floating_release(False)
```
**Return**: None
#### check_feature
Checks for a specific license feature and updates the license cache accordingly.
**Parameters**:
* **feature**(str): feature code.
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
license.check_feature("lkprod1f1fc1")
```
**Return**: None
#### release_feature
Releases a borrowed license feature and updates the license cache accordingly.
**Parameters**:
* **feature**(str): feature code.
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
license.check_feature("lkprod1f1fc1")
license.release_feature("lkprod1f1fc1")
```
**Return**: None
#### update_offline
Updates license via refresh file
**Parameters**:
* **path** (str): path of the refresh file
* **reset_consumption** (bool): True resets consumption otherwise False
```python
file_path = 'path_to_lic_file/license.lic'
manager = LicenseManager(conf)
license = manager.activate_license_offline(file_path)
license.update_offline('offline_files/license_refresh.lic',False)
```
**Raises**:
* **ConfigurationMismatch**: The update file does not belong to this device
* **ConfigurationMismatch**: The update file does not belong to this product
**Return**(bool): True if license was successfully updated otherwise False
#### get_deactivation_code
Get deactivation code for air gap licenses
**Parameters**:
* **initialization_code** (str): initialization_code
```python
initialization_code="your_initialization_code"
manager = LicenseManager(conf)
#load air gap license
license = manager.load_license()
deactivation_code = license.get_deactivation_code(initialization_code)
print("Deactivation code:",deactivation_code)
```
**Return** (str): deactivation code
#### deactivate_air_gap
Deactivate air gap license and clear storage
**Parameters**:
* **confirmation_code** (str): confirmation_code
```python
confirmation_code="your_confirmation_code"
manager = LicenseManager(conf)
#load air gap license
license = manager.load_license()
license.deactivate_air_gap(confirmation_code)
```
**Raises**:
* **LicenseActivationException**: VerificationError
**Return**: None
#### deactivate_offline
Generates .req file for the offline deactivation
**Parameters**:
* **offline_path**(str): path of the .req file
```python
file_path = 'path_to_lic_file/license.lic'
manager = LicenseManager(conf)
license = manager.activate_license_offline(file_path)
license.deactivate_offline('path_where_to_create_req_file')
```
**Raises**:
* **ConfigurationMismatch**: The update file does not belong to this device
* **ConfigurationMismatch**: The update file does not belong to this product
**Return**(bool): True if license was successfully updated otherwise False
#### product_details
Update product details from LicenseSpring server
**Parameters**:
* **include_custom_fields** (bool, optional): custom fields information. Defaults to False.
* **include_latest_version** (bool, optional): Lateset version information. Defaults to False.
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H9V3-72XX-ZRAJ-S6LK")
license = manager.activate_license(license_id)
response = license.product_details()
```
**Raises**:
**Return**(dict): response
#### get_product_details
Get product details from licensefile (offline)
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")
license = manager.activate_license(license_id)
feature_code = "feature1"
response = license.get_product_details()
```
**Return (dict)**: Product details
#### get_device_variables
Get device variable if exists
**Parameters**:
* **variable_name** (str): variable name
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H9V3-72XX-ZRAJ-S6LK")
license = manager.activate_license(license_id)
device_var = license.get_device_variable('english')
```
**Raises**:
**Return**(dict): variable dictionary
#### set_device_variables
Set device variables locally
**Parameters**:
* **variables** (dict): variables dict
* **save** (bool, optional): Save cache to licensefile. Defaults to True.
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H9V3-72XX-ZRAJ-S6LK")
license = manager.activate_license(license_id)
license.set_device_variables({"english":"value"})
```
**Raises**:
**Return**: None
#### get_device_variables
Get device variables from server or locally
**Parameters**:
* **get_from_be** (bool, optional): If True collects data from LicenseSpring server. Defaults to True.
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H9V3-72XX-ZRAJ-S6LK")
license = manager.activate_license(license_id)
license.get_device_variables(get_from_be=True)
```
**Raises**:
* **RequestException** (Grace period not allowed)
**Return**(list): List of device variables
#### send_device_variables
Send device variables to LicenseSpring server. Handles GracePeriod
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H9V3-72XX-ZRAJ-S6LK")
license = manager.activate_license(license_id)
license.send_device_variables()
```
**Raises**:
* **RequestException** (Grace period not allowed)
**Return**(bool): True if new variables are sent to LicenseSpring server otherwise, False
#### custom_fields
Get custom fields from licensefile
```python
manager = LicenseManager(conf)
license_id = LicenseID.from_key("H9V3-72XX-ZRAJ-S6LK")
license = manager.activate_license(license_id)
response = license.custom_fields()
```
**Return**(list): Custom fields
## Floating Server
The user has the ability to utilize either a **Floating Client** or a **Floating Manager**:
**Floating Client**:
* This object is responsible for managing the operations on Floating Server
**Floating Manager**:
* This object is responsible for managing operations with the Floating Server, while also integrating the license file
### Floating Client
#### Intialization
To initialize a Floating Client, the user must specify the API protocol and domain.
* **api_protocol**: Defines the communication protocol between the client and the server (e.g., "http").
* **api_domain**: Specifies the domain or IP address and port of the Floating Server (e.g., "localhost:8080").
* **hardware_id_provider** (optional): Provides the client's hardware ID, which can be used to uniquely identify the client machine.
```python
from licensespring.floating_server import FloatingAPIClient
from licensespring.hardware import HardwareIdProvider
api_client = FloatingAPIClient(api_protocol="http", api_domain="localhost:8080",hardware_id_provider=HardwareIdProvider)
```
#### auth
Authenticate
**Parameters**:
* **username** (str): username
* **password** (str): password
```python
from licensespring.floating_server import FloatingAPIClient
api_client = FloatingAPIClient(api_protocol="http", api_domain="localhost:8080")
api_client.auth(username="admin",password="tetejac")
```
**Return**(dict): Response
#### register_user
Register user
**Parameters**:
* **product** (str): product short code.
* **user** (str,optional): user. Defaults uses hardware id.
* **os_hostname** (str, optional): os hostname. Defaults to None.
* **ip_local** (str, optional): ip local. Defaults to None.
* **user_info** (str, optional): user info. Defaults to None.
* **license_id** (int, optional):license id. Defaults to None.
```python
api_client = FloatingAPIClient(api_protocol="http", api_domain="localhost:8080")
response = api_client.register_user(
product="lkprod1",
user="user_1",
os_hostname="bla",
ip_local="bla",
user_info="bla",
license_id=1728377159207169
)
print(response)
```
**Return**(dict): Response
#### unregister
**Parameters**
* **product** (str): product short code.
* **user** (str,optional): user. Defaults uses hardware id.
* **license_id** (int, optional): license id. Defaults to None.
Unregister user
```python
api_client = FloatingAPIClient(api_protocol="http", api_domain="localhost:8080")
response = api_client.unregister_user(product="lkprod1",user="user_1",license_id=1728377159207169)
print(response)
```
**Return**(str): "user_unregistered"
#### unregister_all
Unregister all users
```python
api_client = FloatingAPIClient(api_protocol="http", api_domain="localhost:8080")
api_client.unregister_all()
```
#### borrow
Borrow license
**Parameters**
* **product** (str): product short code.
* **user** (str,optional): user. Defaults uses hardware id.
* **borrowed_until** (str): borrow until date
* **os_hostname** (str, optional): os hostname. Defaults to None.
* **ip_local** (str, optional): ip local. Defaults to None.
* **user_info** (str, optional): user info. Defaults to None.
* **license_id**(int, optional):license id. Defaults to None.
```python
api_client = FloatingAPIClient(api_protocol="http", api_domain="localhost:8080")
response = api_client.borrow(
product="lkprod1",
user="user_1",
borrowed_until="2029-05-06T00:00:00Z",
os_hostname="bla",
ip_local="bla",
user_info="bla",
license_id=1728377159207169,
)
```
**Return**(dict): Response
#### add_consumption
Add license consumption
**Parameters**
* **product** (str): product short code
* **consumptions** (int, optional): consumptions. Defaults to 1.
* **max_overages** (int, optional): max overages. Defaults to None.
* **allow_overages** (bool, optional): allow overages. Defaults to None.
* **user** (str, optional): user (default uses hardware id)
* **license_id** (int, optional): license id. Defaults to None.
```python
api_client = FloatingAPIClient(api_protocol="http", api_domain="localhost:8080")
response = api_client.add_consumption(product="fs", consumptions=1)
```
**Return**(dict): Response
#### add_feature_consumption
Add feature consumption
**Parameters**
* **product** (str): product short code
* **feature_code** (str): feature code
* **user** (str, optional): user (default uses hardware id)
* **consumptions** (int, optional): consumptions. Defaults to 1.
* **license_id** (int, optional): license id. Defaults to None.
```python
api_client = FloatingAPIClient(api_protocol="http", api_domain="localhost:8080")
response = api_client.add_feature_consumption(product="fs", feature_code="f2", consumptions=1)
```
**Return**(dict): Response
#### feature_register
Register feature
**Parameters**
* **product** (str): product short code
**feature_code** (str): feature short code
* **user** (str, optional): user (default uses hardware id)
* **license_id** (int, optional): license id. Defaults to None.
* **borrowed_until** (str): borrow until (e.g. 2029-05-06T00:00:00Z)
* **os_hostname** (str, optional): os hostname. Defaults to None.
* **ip_local** (str, optional): ip local. Defaults to None.
* **user_info** (str, optional): user info. Defaults to None.
```python
api_client = FloatingAPIClient(api_protocol="http", api_domain="localhost:8080")
response = api_client.feature_register(
product="fs", feature_code="f1", os_hostname="w", ip_local="1.0", user_info="info"
)
print(response)
```
**Return**(dict): Response
#### feature_release
Feature release
**Parameters**
* **product** (str): product short code
* **feature_code** (str): feature short code
* **user** (str, optional): user (default uses hardware id)
* **license_id** (int, optional): license id. Defaults to None.
```python
api_client = FloatingAPIClient(api_protocol="http", api_domain="localhost:8080")
response = api_client.feature_register(
product="fs", feature_code="f1", os_hostname="w", ip_local="1.0", user_info="info"
)
response = api_client.feature_release(product="fs", feature_code="f1")
```
**Return**(str): "feature_released"
### Floating Manager
#### Intialization
To intialize Floating Manager [Configuration](#configuration-setup) needs to be created. For Floating server you can set arbitrary values for `shared_key` and `api_key` keys.
#### auth
Authenticate
**Parameters**:
* **username** (str): username
* **password** (str): password
```python
from licensespring.licensefile.config import Configuration
from licensespring.licensefile.floating_manager import FloatingManager
fs_manager = FloatingManager(conf=conf)
fs_manager.auth(username="admin",password="tetejac")
```
**Return**(dict): Response
#### register
Register license
**Parameters**:
* **os_hostname** (str, optional): os hostname. Defaults to None.
* **ip_local** (str, optional): ip local. Defaults to None.
* **user_info** (str, optional): user info. Defaults to None.
* **license_id** (int, optional):license id. Defaults to None.
```python
from licensespring.licensefile.config import Configuration
from licensespring.licensefile.floating_manager import FloatingManager
conf = Configuration(
product=product,
api_key="arbitrary",
shared_key="arbitrary",
file_key="your_file_key",
file_iv="your_file_iv",
api_domain="api_domain",
api_protocol="http/https",
)
fs_manager = FloatingManager(conf=conf)
license = fs_manager.register()
```
**Return**(License): License object
#### unregister
**Parameters**
* license_id (int, optional): license id. Defaults to None.
Unregister license
```python
fs_manager = FloatingManager(conf=conf)
# There are multiple options to unregister a license
# 1. floating client -> this one is documanted
fs_manager.unregister()
# 2.1. license object -> deactivate method
license.deactivate()
#2.2 license object -> floating release
license.floating_release(False)
```
**Return**(str): "user_unregistered"
#### unregister_all
Unregister all users
```python
fs_manager = FloatingManager(conf=conf)
fs_manager.unregister_all()
```
#### borrow_license
Borrow license
**Parameters**
* **borrowed_until** (str): borrow until date
* **os_hostname** (str, optional): os hostname. Defaults to None.
* **ip_local** (str, optional): ip local. Defaults to None.
* **user_info** (str, optional): user info. Defaults to None.
* **license_id**(int, optional):license id. Defaults to None.
```python
fs_manager = FloatingManager(conf=conf)
license = fs_manager.borrow("2031-05-06T00:00:00Z")
# borrow can be also used within the License object
license.floating_borrow("2031-05-06T00:00:00Z")
```
**Return**(License): License object
#### is_online
Checks if floating server is online
**Parameters**
* **throw_e** (bool, optional): True if you want raise exception. Defaults to False.
```python
fs_manager = FloatingManager(conf=conf)
response = fs_manager.is_online()
```
**Raises**:
* **ex**: Exception
**Return**(bool): True if server is online, otherwise False
### Methods supported inside License object
[License consumptions](#add-consumption), [feature consumptions](#add-feature-consumption), [register feature](#check_feature), [release feature](#release_feature) are supported within `License` object for Floating Server
## License
LicenseSpring SDK Source Code License (LSSCL)
Preamble:
This LicenseSpring SDK Source Code License (LSSCL) governs the use, distribution, and modification of the source code for this LicenseSpring SDKs. This SDK is designed to facilitate the integration of LicenseSpring's license management service into your applications. By accessing, using, or modifying the SDK, you agree to the terms and conditions set forth in this license.
1. Permissions:
* You are permitted to access, read, and modify the source code of this LicenseSpring SDK.
* You may create derivative works that include this SDK, provided all derivative works are used solely as part of the LicenseSpring service.
2. Distribution:
* You may distribute the original or modified versions of software that incorporates the SDK, provided that all distributed versions retain this LSSCL license.
* Distributed versions, including modifications, must be used to facilitate the integration of LicenseSpring’s service and may not be:
* Provided as part of a hosted or cloud-based service that allows others to access the SDK’s functionality without interacting directly with the LicenseSpring service.
* Integrated into other services which compete with or do not use the LicenseSpring service.
3. Usage Restrictions:
* The SDK, in its original or modified form, may only be used as part of the LicenseSpring service, whether on a free or paid plan.
* You are prohibited from using the SDK independently or as part of any service that does not interact with the LicenseSpring service.
4. Prohibited Actions:
* You may not circumvent or disable any technical measures that control access to the SDK.
* You must not remove, alter, or obscure any license notices, copyright notices, or other proprietary notices from the SDK.
5. Termination:
* Any violation of these terms will result in the automatic termination of your rights under this license.
* Upon termination, you must cease all use and distribution of the SDK and destroy all copies in your possession.
6. Disclaimer of Warranty and Liability:
THE SOFTWARE IS PROVIDED "AS IS" AND LICENSESPRING DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. LICENSESPRING SHALL NOT BE LIABLE FOR ANY DAMAGES ARISING OUT OF OR RELATED TO THE USE OR PERFORMANCE OF THE SOFTWARE.
Copyright 2024 Cense Data Inc DBA LicenseSpring
Contact: support@licensespring.com
### Dependency licenses
| Name | Version | License | URL |
|--------------------|-----------|-----------------------------------------------------|----------------------------------------------------------|
| certifi | 25.1.0 | Mozilla Public License 2.0 (MPL 2.0) | https://github.com/certifi/python-certifi |
| charset-normalizer | 3.4.1 | MIT License | https://github.com/Ousret/charset_normalizer |
| idna | 3.10 | BSD License | https://github.com/kjd/idna |
| pycryptodome | 3.21.0 | Apache Software License; BSD License; Public Domain | https://www.pycryptodome.org |
| requests | 2.32.3 | Apache Software License | https://requests.readthedocs.io |
| urllib3 | 2.3.0 | MIT License | https://github.com/urllib3/urllib3/blob/main/CHANGES.rst |
| winregistry | 2.1.0 | UNKNOWN | https://github.com/shpaker/winregistry |
Raw data
{
"_id": null,
"home_page": "https://licensespring.com/",
"name": "licensespring",
"maintainer": null,
"docs_url": null,
"requires_python": "<4.0,>=3.9",
"maintainer_email": null,
"keywords": null,
"author": "Toni Sredanovi\u0107",
"author_email": "toni@licensespring.com",
"download_url": "https://files.pythonhosted.org/packages/5b/68/0ecb029bad936417ac603b6f08c23d2011536140d3fbcfc19873ef3871c3/licensespring-3.3.0.tar.gz",
"platform": null,
"description": "# LicenseSpring Python Library\n\nThe LicenseSpring Python Library provides convenient access to the LicenseSpring API from\napplications written in the Python language.\n\n## Installation\n\nInstall `licensespring` library:\n\n```\npip install licensespring\n```\n\nRequires: Python >=3.9\n\n## Hardware (Device) IDs\n\nThis library provides preconfigured hardware identity providers:\n- `HardwareIdProvider` (default)\n- `PlatformIdProvider`\n- `HardwareIdProviderSource` (recommended)\n\nYou can set the desired hardware identity provider when initializing the APIClient:\n```python\nfrom licensespring.hardware import PlatformIdProvider\n\napi_client = APIClient(api_key=\"_your_api_key_\", shared_key=\"_your_shared_key_\", hardware_id_provider=PlatformIdProvider)\n```\n\nIt also supports their customization and creation of your own hardware id provider.\n\n### HardwareIdProvider\n\nUses [uuid.getnode()](https://docs.python.org/3/library/uuid.html#uuid.getnode) to generate unique ID per device as described:\n\n> Get the hardware address as a 48-bit positive integer. The first time this runs, it may launch a separate program, which could be quite slow. If all attempts to obtain the hardware address fail, we choose a random 48-bit number with the multicast bit (least significant bit of the first octet) set to 1 as recommended in RFC 4122. \u201cHardware address\u201d means the MAC address of a network interface. On a machine with multiple network interfaces, universally administered MAC addresses (i.e. where the second least significant bit of the first octet is unset) will be preferred over locally administered MAC addresses, but with no other ordering guarantees.\n\nAll of the methods exposed by `HardwareIdProvider`:\n```python\nclass HardwareIdProvider:\n def get_id(self):\n return str(uuid.getnode())\n\n def get_os_ver(self):\n return platform.platform()\n\n def get_hostname(self):\n return platform.node()\n\n def get_ip(self):\n return socket.gethostbyname(self.get_hostname())\n\n def get_is_vm(self):\n return False\n\n def get_vm_info(self):\n return None\n\n def get_mac_address(self):\n return \":\".join((\"%012X\" % uuid.getnode())[i : i + 2] for i in range(0, 12, 2))\n\n def get_request_id(self):\n return str(uuid.uuid4())\n```\n### HardwareIdProviderSource\nUtilizes a proprietary in-house algorithm for our SDKs **(recommended algorithm)** [Hardware ID Algorithm](https://pypi.org/project/licensespring-hardware-id-generator/).\n```python \n\nclass HardwareIdProviderSource(HardwareIdProvider):\n def get_id(self): \n hardware_id = get_hardware_id(HardwareIdAlgorithm.Default)\n \n if logging.getLogger().hasHandlers():\n logs = get_logs()\n version = get_version()\n logging.info(\"Version: \",version)\n logging.info(\"Hardware ID:\",hardware_id)\n for log_line in logs:\n logging.info(log_line)\n \n return hardware_id\n```\n### PlatformIdProvider\n\nUses [sys.platform](https://docs.python.org/3/library/sys.html#sys.platform) and OS queries to find the raw GUID of the device.\n\nExtends the `HardwareIdProvider` and overwrites only the `get_id` method:\n```python\nclass PlatformIdProvider(HardwareIdProvider):\n def get_id(self):\n id = None\n\n if sys.platform == 'darwin':\n id = execute(\"ioreg -d2 -c IOPlatformExpertDevice | awk -F\\\\\\\" '/IOPlatformUUID/{print $(NF-1)}'\")\n\n if sys.platform == 'win32' or sys.platform == 'cygwin' or sys.platform == 'msys':\n id = read_win_registry('HKEY_LOCAL_MACHINE\\\\SOFTWARE\\\\Microsoft\\\\Cryptography', 'MachineGuid')\n if not id:\n id = execute('wmic csproduct get uuid').split('\\n')[2].strip()\n\n if sys.platform.startswith('linux'):\n id = read_file('/var/lib/dbus/machine-id')\n if not id:\n id = read_file('/etc/machine-id')\n\n if sys.platform.startswith('openbsd') or sys.platform.startswith('freebsd'):\n id = read_file('/etc/hostid')\n if not id:\n id = execute('kenv -q smbios.system.uuid')\n\n if not id:\n id = super().get_id()\n\n return id\n```\n\n### Customization\n\nExtend any of the preconfigured hardware identity providers, overwrite the methods you want and provide it when initializing the APIClient:\n```python\nclass CustomHardwareIdProvider(HardwareIdProvider):\n def get_id(self):\n return \"_my_id_\"\n\napi_client = APIClient(api_key=\"_your_api_key_\", shared_key=\"_your_shared_key_\", hardware_id_provider=CustomHardwareIdProvider)\n```\n\n## APIClient Usage Examples\n\n### Set app version\n```python\nimport licensespring\n\nlicensespring.app_version = \"MyApp 1.0.0\"\n```\n\n### Create APIClient\n```python\nfrom licensespring.api import APIClient\n\napi_client = APIClient(api_key=\"_your_api_key_\", shared_key=\"_your_shared_key_\")\n```\n\n### Activate key based license\n```python\nproduct = \"lkprod1\"\nlicense_key = \"GPB7-279T-6MNK-CQLK\"\nlicense_data = api_client.activate_license(product=product, license_key=license_key)\n\nprint(license_data)\n```\n\n### Activate user based license\n```python\nproduct = \"uprod1\"\nusername = \"user1@email.com\"\npassword = \"nq64k1!@\"\n\nlicense_data = api_client.activate_license(\n product=product, username=username, password=password\n)\n\nprint(license_data)\n```\n\n### Deactivate key based license\n```python\nproduct = \"lkprod1\"\nlicense_key = \"GPUB-J4PH-CGNK-C7LK\"\napi_client.deactivate_license(product=product, license_key=license_key)\n```\n\n### Deactivate user based license\n```python\nproduct = \"uprod1\"\nusername = \"user1@email.com\"\n\napi_client.deactivate_license(\n product=product, username=username\n)\n```\n\n### Check key based license\n```python\nproduct = \"lkprod1\"\nlicense_key = \"GPBQ-DZCP-E9SK-CQLK\"\n\nlicense_data = api_client.check_license(product=product, license_key=license_key)\n\nprint(license_data)\n```\n\n### Check user based license\n```python\nproduct = \"uprod1\"\nusername = \"user2@email.com\"\npassword = \"1l48y#!b\"\n\nlicense_data = api_client.check_license(product=product, username=username)\n\nprint(license_data)\n```\n\n### Add consumption\n```python\nproduct = \"lkprod1\"\nlicense_key = \"GPSU-QTKQ-HSSK-C9LK\"\n\n# Add 1 consumption\nconsumption_data = api_client.add_consumption(\n product=product, license_key=license_key\n)\n\nprint(consumption_data)\n\n# Add 3 consumptions\nconsumption_data = api_client.add_consumption(\n product=product, license_key=license_key, consumptions=3\n)\n\nprint(consumption_data)\n\n# Add 1 consumption, allow overages and define max overages\nconsumption_data = api_client.add_consumption(\n product=product, license_key=license_key, allow_overages=True, max_overages=10\n)\n\nprint(consumption_data)\n```\n\n### Add feature consumption\n```python\nproduct = \"lkprod1\"\nlicense_key = \"GPTJ-LSYZ-USEK-C8LK\"\nfeature = \"lkprod1cf1\"\n\n# Add 1 consumption\nfeature_consumption_data = api_client.add_feature_consumption(\n product=product, license_key=license_key, feature=feature\n)\n\n# Add 3 consumptions\nfeature_consumption_data = api_client.add_feature_consumption(\n product=product, license_key=license_key, feature=feature, consumptions=3\n)\n\nprint(feature_consumption_data)\n```\n\n### Trial key\n```python\nproduct = \"lkprod2\"\n\ntrial_license_data = api_client.trial_key(product=product)\n\nprint(trial_license_data)\n```\n\n### Product details\n```python\nproduct = \"lkprod1\"\n\nproduct_data = api_client.product_details(product=product)\n\nprint(product_data)\n```\n\n### Track device variables\n```python\nproduct = \"lkprod1\"\nlicense_key = \"GPUB-SZF9-AB2K-C7LK\"\nvariables = {\"variable_1_key\": \"variable_1_value\", \"variable_2_key\": \"variable_2_value\"}\n\ndevice_variables = api_client.track_device_variables(product=product, license_key=license_key, variables=variables)\n\nprint(device_variables)\n```\n\n### Get device variables\n```python\nproduct = \"lkprod1\"\nlicense_key = \"GPUB-SZF9-AB2K-C7LK\"\n\ndevice_variables = api_client.get_device_variables(product=product, license_key=license_key)\n\nprint(device_variables)\n```\n\n### Floating borrow\n```python\nproduct = \"lkprod1\"\nlicense_key = \"GPUC-NGWU-3NJK-C7LK\"\n\n# Borrow for 2 hours\nborrowed_until = (datetime.utcnow() + timedelta(hours=2)).isoformat()\nfloating_borrow_data = api_client.floating_borrow(product=product, license_key=license_key, borrowed_until=borrowed_until)\n\nprint(floating_borrow_data)\n```\n\n### Floating release\n```python\nproduct = \"lkprod1\"\nlicense_key = \"GPUC-NGWU-3NJK-C7LK\"\n\napi_client.floating_release(product=product, license_key=license_key)\n```\n\n### Change password\n```python\nusername = \"user4@email.com\"\npassword = \"_old_password_\"\nnew_password = \"_new_password_\"\n\nis_password_changed = api_client.change_password(username=username, password=password, new_password=new_password)\n\nprint(is_password_changed)\n```\n\n### Versions\n```python\nproduct = \"lkprod1\"\nlicense_key = \"GPB7-279T-6MNK-CQLK\"\n\n# Get versions for all environments\nversions_data = api_client.versions(product=product, license_key=license_key)\n\n# Get versions for mac environment\nmac_versions_data = api_client.versions(\n product=product, license_key=license_key, env=\"mac\"\n)\n\nprint(versions_data)\n```\n\n### Installation file\n```python\nproduct = \"lkprod1\"\nlicense_key = \"GPB7-279T-6MNK-CQLK\"\n\n# Get the latest installation file\ninstallation_file_data = api_client.installation_file(\n product=product, license_key=license_key\n)\n\n# Get the latest installation file for linux environment\ninstallation_file_data = api_client.installation_file(\n product=product, license_key=license_key, env=\"linux\"\n)\n\n# Get the latest installation file for version 1.0.0\ninstallation_file_data = api_client.installation_file(\n product=product, license_key=license_key, version=\"1.0.0\"\n)\n\nprint(installation_file_data)\n```\n\n### Customer license users\n```python\nproduct = \"uprod1\"\ncustomer = 'c1@c.com'\n\ncustomer_license_users_data = api_client.customer_license_users(\n product=product, customer=customer\n)\n\nprint(customer_license_users_data)\n```\n\n### SSO URL\n```python\nproduct = \"uprod1\"\ncustomer_account_code = \"ccorp\"\n\nsso_url_data = api_client.sso_url(\n product=product, customer_account_code=customer_account_code\n)\n\nprint(sso_url_data)\n```\n\n\n### SSO URL with `code` response type\n```python\nproduct = \"uprod1\"\ncustomer_account_code = \"ccorp\"\n\nsso_url_data = api_client.sso_url(\n product=product,\n customer_account_code=customer_account_code,\n response_type=\"code\",\n)\n\nprint(sso_url_data)\n```\n\n### Activate offline\n```python\nproduct = \"lkprod1\"\nlicense_key = \"GPY7-VHX9-MDSK-C3LK\"\n\n# Generate data for offline activation\nactivate_offline_data = api_client.activate_offline_dump(\n product=product, license_key=license_key\n)\n\n# Write to file\nwith open('activate_offline.req', mode='w') as f:\n print(activate_offline_data, file=f)\n\n# Activate offline\nlicense_data = api_client.activate_offline(data=activate_offline_data)\n\nprint(license_data)\n```\n\n### Activate offline load\n```python\n# Read from file\nwith open('./ls_activation.lic') as file:\n ls_activation_data = file.read()\n\nlicense_data = api_client.activate_offline_load(ls_activation_data)\n\nprint(license_data)\n```\n\n### Check offline load\n```python\n# Read from file\nwith open('./license_refresh.lic') as file:\n license_refresh_data = file.read()\n\nlicense_data = api_client.check_offline_load(license_refresh_data)\n\nprint(license_data)\n```\n\n\n### Deactivate offline\n```python\nproduct = \"lkprod1\"\nlicense_key = \"GPYC-X5J2-L5SK-C3LK\"\n\n# Generate data for offline deactivation\ndeactivate_offline_data = api_client.deactivate_offline_dump(\n product=product, license_key=license_key\n)\n\n# Write to file\nwith open('deactivate_offline.req', mode='w') as f:\n print(deactivate_offline_data, file=f)\n\n# Deactivate offline\napi_client.deactivate_offline(data=deactivate_offline_data)\n```\n\n### Key based license feature check\n```python\nproduct = \"lkprod1\"\nlicense_key = \"GPB7-279T-6MNK-CQLK\"\nfeature = \"lkprod1f1\"\n\nlicense_feature_data = api_client.check_license_feature(\n product=product, feature=feature, license_key=license_key\n)\n\nprint(license_feature_data)\n```\n\n### Key based license floating feature release\n```python\nproduct = \"lkprod1\"\nlicense_key = \"GPB7-279T-6MNK-CQLK\"\nfeature = \"lkprod1f1\"\n\napi_client.floating_feature_release(\n product=product, feature=feature, license_key=license_key\n)\n```\n### User licenses\n```python\nproduct = \"userpr1\"\nusername = \"user123\"\npassword = \"password\"\n\nresponse = api_client.user_licenses(\n product=product,username=username,\n password=password)\n\nprint(response)\n```\n\n## Licensefile\n\n### Licensefile setup \nTo use licensefile inside a python SDK you should first setup your key and IV. Key and IV are used inside Python SDK for encryption and decryption process inside licensefile. For the first setup it is essenital to chose **password** and **salt** for key generation. This process is only required **once** at the setup. \n```python\nfrom licensespring.licensefile.default_crypto import DefaultCryptoProvider\n\npassword = \"YOUR_PASSWORD\"\nsalt = \"YOUR_SALT\"\n\n\ncrypto = DefaultCryptoProvider()\n\nkey = crypto.derive_key(password=key_password,salt=key_salt)\niv = crypto.generate_random_iv()\n```\n### Configuration Setup\nAfter you have successfully setup your key and IV you should setup your Configuration.\n```python\nfrom licensespring.licensefile.config import Configuration\n\nconf = Configuration(product=\"your_product_short_code\",\n api_key=\"your_api_key\",\n shared_key=\"your_shared_key\",\n file_key=key,\n file_iv=iv,\n hardware_id_provider=HardwareIdProvider,\n verify_license_signature=True,\n signature_verifier=SignatureVerifier,\n api_domain=\"api.licensespring.com\",\n api_version=\"v4\",\n filename=\"License\",\n file_path=None,\n grace_period_conf=24,\n air_gap_public_key=\"your_air_gap_public_key\")\n```\n\n* **product (str)**: product short code. \n* **api_key (str)**: Your unique API key used for authentication with the licensing server. \n* **shared_key (str)**: A shared secret key used alongside the API key for enhanced security during the license verification process. \n* **file_key (str)**: The encryption key used for securing license files on the client side. \n* **file_iv (str)**: The initialization vector for the encryption algorithm. This complements the file_key for encrypting and decrypting license files. \n* **hardware_id_provider (object, optional)**: The provider class used for generating a unique hardware ID. This ID helps in binding the license to specific hardware. Defaults to HardwareIdProvider. \n* **verify_license_signature (bool, optional)**: A boolean flag indicating whether the license's digital signature should be verified. Defaults to True for enhanced security. \n* **signature_verifier (object, optional)**: The class responsible for verifying the digital signature of licenses. Defaults to SignatureVerifier. \n* **api_domain (str, optional)**: The domain name of the API server with which the licensing operations are performed. Defaults to \"api.licensespring.com\". \n* **api_version (str, optional)**: The version of the API to use for requests. This allows for compatibility with different versions of the licensing API. Defaults to \"v4\". \n* **filename (str, optional)**: The default filename for saved license files. This can be customized as needed. Defaults to \"License\". \n* **file_path (str, optional)**: The path where license files should be saved on the client system. If not specified, a **[default location](https://docs.licensespring.com/sdks/tutorials/best-practices/local-license-file#W8U6X)** is used. \n* **grace_period_conf (int, optional)**: The number of hours to allow as a grace period for Defaults to 24 hours. \n* **air_gap_public_key (str, optional)**: Air gap public key from platform check **[here](https://docs.licensespring.com/sdks/tutorials/licensing-scenarios/air-gapped#Ws1BB)** for more\n\n**Warning:** \n* We advise for `hardware_id_provider` to use a newly developed [`HardwareIdProviderSource`](#hardwareidprovidersource) provider.\n* On the next major version release [`HardwareIdProviderSource`](#hardwareidprovidersource) will be set as default `hardware_id_provider`\n \n### LicenseID\n\n* **from_key(cls, key)**: Class method to create a LicenseID instance for key-based activation \n* **from_user(cls, username, password)**: Class method to create a LicenseID instance for user-based activation.\n\n#### Key-based setup\n```python\nlicense_id = LicenseID.from_key(\"your_license_key\") \n```\n#### User-based setup\n```python\nlicense_id = LicenseID.from_user(username=\"email@email.com\",password=\"password\") \n```\n### LicenseManager \n```python\nfrom licensespring.licensefile.license_manager import LicenseManager,LicenseID\n\nmanager = LicenseManager(conf)\n```\n#### Configuration parametres\n\nconf (Configuration): **[A configuration object](#configuration-setup)**\n\n#### activate_license \nActivates a license with the license server and updates local license data. When activating user based license we advise that **unique_license_id** is set which represent **\"id\"** field within the [license check](https://docs.licensespring.com/license-api/check). \n\n**Key-based**\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H6QM-6H5R-ZENJ-VBLK\")\n\nlicense = manager.activate_license(license_id)\n```\n**User-based**\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_user(username=\"python@gmail.com\",password=\"7t_x3!o9\")\n\nlicense = manager.activate_license(license_id,unique_license_id=1723642193958949)\n```\n**Parameters**: \n* **license_id** (LicenseID): An instance containing the license key or user credentials. \n\n**Return**:\n**License** object representing the activated license.\n\n#### load_license \nLoads the license file and sets attributes for the LicenseData instance. Returns an instance of the License class reflecting the loaded license.\n\n```python\nmanager = LicenseManager(conf)\n\nlicense = manager.load_license()\n```\n**Return**:\n**License** object representing the activated license.\n \n#### current_config\nGet current configuration\n```python\nmanager = LicenseManager(conf)\n\nconfig = manager.current_config()\n```\n\n**Return** (dict): current configuration\n\n#### reconfigure\nChange the current configuration \n\n**Parameters**:\n* **conf** (Configuration): Configuration object \n\n```python\nmanager = LicenseManager(conf)\n\nmanager.reconfigure(\n Configuration(\n product=\"lkprod2\",\n api_key=\"new_key\",\n shared_key=\"new_key\",\n file_key=\"file_key\",\n file_iv=\"file_iv\",\n file_path=\"bb\",\n grace_period_conf=12,\n is_guard_file_enabled=True,\n )\n )\n```\n#### is_license_file_corrupted\nChecks if licensefile is corrupted \n\n```python\nmanager = LicenseManager(conf)\nboolean = manager.is_license_file_corrupted()\n```\n**Return** (bool): If the file is corrupted return True, otherwise False\n\n#### clear_local_storage\nClear all data from current product\n\n```python\nmanager = LicenseManager(conf)\nlicense_id = LicenseID.from_key(\"H6QM-6H5R-ZENJ-VBLK\") \nlicense = manager.activate_license(license_id) \nmanager.clear_local_storage()\n```\n\n#### data_location\nGet licensefile location \n\n```python\nmanager = LicenseManager(conf)\nfolder_path = manager.data_location()\n```\n**Return** (str): Licensefile location \n\n#### set_data_location\nSet data location\n\n**Parameters**:\n* **path** (str): new data location path\n\n```python\nmanager = LicenseManager(conf)\nmanager.set_data_location()\n```\n**Return**: None\n\n#### license_file_name\nGet licensefile name \n\n```python\nmanager = LicenseManager(conf)\nfile_name = manager.license_file_name()\n```\n**Return** (str): Licensefile name \n\n#### set_license_file_name\n\nSet licensefile name \n\n**Parameters**:\n* **name** (str): license file name\n\n```python\nmanager = LicenseManager(conf)\nmanager.set_license_file_name()\n```\n**Return**: None \n\n#### is_online \nChecks if the licensing server is accessible. Returns True if online, False otherwise. \n\n**Parameters**: \n* **throw_e** (bool,optional): If True throws exception, otherwise exception won't be raised. \n\n```python\nmanager = LicenseManager(conf)\n\nlicense = manager.is_online()\n```\n\n#### get_air_gap_activation_code\nGet activation code for air gap license\n\n**Parameters**:\n\n* **initialization_code** (str): initialization code \n* **license_key** (str): license key \n```python\ninitialization_code = \"Q/MWfwp1NWAYARl8Q7KSo5Cg2YKqS2QLlnQ3nEeSBsk=\"\nlicense_key = \"UFF3-E9GA-VUJQ-GMLK\"\n\nmanager = LicenseManager(conf)\nactivation_code = manager.get_air_gap_activation_code(initialization_code=initialization_code, license_key=license_key)\n\nprint(\"Activation code:\",activation_code)\n```\n**Return** (str): activation code\n\n#### activate_air_gap_license\nActivate air gap license\n\n**Parameters**:\n\n* **confirmation_code** (str): confirmation code\n* **policy_path** (str): policy path (file or folder)\n* **license_key** (str): license_key\n* **policy_id** (str): policy id\n\n```python\nconfirmation = \"ERbQBuE8giIjqMPj972Skipehqn0szQ8TH56INyo3OdtMHO1SuTVsoCOSnJWB6rml98PJ6SjybTPymOVZTG4hQ==\"\npolicy_id = \"998\"\nlicense_key = \"UFF3-E9GA-VUJQ-GMLK\"\npolicy_path = \"path_to_air_lic\"\n\nmanager = LicenseManager(conf)\nlicense = manager.activate_air_gap_license(\n confirmation_code=confirmation, policy_path=policy_path, license_key=license_key, policy_id=policy_id\n )\n```\n**Raises**:\n* **LicenseActivationException**: Signature verification failed\n\n**Return** (License): License\n\n#### create_offline_activation_file\nCreates .req file for offline activation, including various optional parameters related to the device and software environment. \n\n**Parameters**:\n\n* **license_id** (LicenseID): An instance containing the license key or user credentials. \n* **req_path** (str): Specify the path where to create .req file.\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H94R-S6KB-L7AJ-SXLK\")\n\nreq_file_path = manager.create_offline_activation_file(license_id,'offline_files/test') \n```\n**Return** (str): Path of the .req file created for activation.\n\n#### activate_license_offline\nActivates a license offline using a .lic file provided via the specified path.\n\n**Parameters**:\n\n* **ls_activation_path** (str): Path to the activation file.\n\n```python\nfile_path = 'offline_files/ls_activation.lic'\n\nmanager = LicenseManager(conf)\n\nlicense = manager.activate_license_offline(file_path)\n```\n**Raises**:\n\n* **LicenseActivationException**: Activation data is not valid.\n* **LicenseActivationException**: Response file ID mismatch.\n* **LicenseActivationException**: License does not belong to this device.\n\n**Return**(License): Returns a License object representing the activated license.\n\n#### get_trial_license\nCreates LiceseID for trial licenses\n\n**Parameters**:\n\n* **customer** (Customer): Customer object\n* **license_policy** (str,optional): license policy code. Defaults to None.\n\n```python\ncustomer = Customer(email='python_policy@gmail.com') \n\nmanager = LicenseManager(conf)\n\nlicense_id = manager.get_trial_license(customer=customer,license_policy='test')\n \nlicense = manager.activate_license(license_id=license_id)\n```\n\n**Return**(LicenseID): Returns a LicenseID object.\n\n#### get_version_list\nGet versions\n\n**Parameters**:\n\n* **license_id** (LicenseID): license id object\n* **channel** (str, optional): channel of the version \n* **unique_license_id** (int,optional): A unique identifier for the license.\n* **env** (str,optional): Version of environment\n\n```python\n\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"3ZG2-K25B-76VN-WXLK\")\n\nresponse = manager.get_version_list(license_id=license_id)\n```\n\n**Return**(list): List of versions\n\n#### get_installation_file\nGet installation file\n\n**Parameters**:\n\n* **license_id** (LicenseID): An instance containing the license key or user credentials \n* **channel** (str, optional): channel of the version \n* **unique_license_id** (int, optional): A unique identifier for the license. \n* **env** (str, optional): Version of environment\n* **version** (str, optional): Versions\n\n```python\n\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"3ZG2-K25B-76VN-WXLK\")\n\nresponse = manager.get_installation_file(license_id=license_id)\n```\n\n**Return** (dict): installation file\n\n#### get_customer_license_users\nGet customer license users\n\n**Parameters**:\n* customer (Customer): customer\n```python\n\nmanager = LicenseManager(conf)\n\ncustomer = Customer(email=\"c1@c.com\")\n\nresponse = manager.get_customer_license_users(customer=customer)\n```\n**Return**(dict): customer license user\n\n#### get_user_licenses\n\nGet user licenses\n\n**Parameters**:\n* **license_id** (LicenseID): license_id\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_user(username=\"t@tt.com\", password=\"d#2!17vi\")\n\nresponse = manager.get_user_licenses(license_id)\n```\n\n**Return**(list): User licenses\n\n#### get_sso_url\n\nGet user licenses\n\n**Parameters**:\n* account_code (str): account code\n* use_auth_code (bool, optional): Use code for response_type. Defaults to True.\n\n```python\nmanager = LicenseManager(conf)\n\nresponse = manager.get_sso_url(account_code=\"your_account_code\")\n```\n\n**Return**(dict): url\n\n### License object\n\nObject responsible for license operations\n\n#### is_floating_expired\n\nDetermines wheter the license floating period has expired\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nlicense.check()\n\nresponse = license.is_floating_expired() \n```\n**Return (bool)**: True if license floating period has expired otherwise False\n\n#### floating_timeout\n\nRetrieve license flaoting timeout\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nprint(license.floating_timeout())\n```\n**Return (int)**: License floating timeout\n\n#### is_floating\n\nCheck if license is floating (Floating Server or Floating Cloud)\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nprint(license.is_floating())\n```\n\n**Return (bool)**: True if license if floating, otherwise False\n\n#### floating_client_id\nGet floating client id\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nprint(license.floating_client_id())\n```\n\n**Return (str)**: Floating client id\n\n#### is_controlled_by_floating_server\nCheck if license is controlled by Floating Server\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nprint(license.is_controlled_by_floating_server())\n```\n\n**Return (bool)**: True if license is controlled by floating server, otherwise False\n\n#### floating_in_use_devices\nNumber of floating devices in use\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nprint(license.floating_in_use_devices())\n```\n\n**Return (int)**: Number of floating devices in use\n\n#### floating_end_date\nDatetime when flaoting will be released\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nprint(license.floating_end_date())\n```\n\n**Return (datetime)**: Datetime when device will be released\n\n#### max_floating_users\nNumber of max floating users\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nprint(license.max_floating_users())\n```\n\n**Return (int)**: Number of max floating users\n\n#### is_validity_period_expired\n\nDetermines whether the license's validity period has expired\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n \nresponse = license.is_validity_period_expired() \n```\n**Return (bool)**: True if license expired;False if license is valid\n\n#### validity_period\n\nGets validity period of the license\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n \nresponse = license.validity_period() \n```\n**Return (datetime)**: Datetime in UTC\n\n#### validity_with_grace_period\n\nGets the validity period with grace period of the license\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n \nresponse = license.validity_with_grace_period() \n```\n**Return (datetime)**: Datetime in UTC\n\n#### license_user\nGets the license user\n\n```python\nuser_data = license.license_user()\n \nprint(user_data) \n```\n**Return** (dict): license user\n\n\n#### maintenance_days_remaining\n\nGets how many days are left until the maintenance ends\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n \nresponse = license.maintenance_days_remaining() \n```\n**Return (int)**: Maintenance days left\n\n#### days_remaining\n\nGets how many days are left until the validity period ends\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n \nresponse = license.days_remaining() \n```\n**Return (int)**: Validity period days left\n\n#### customer_information\n\nGets customer information\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n \nresponse = license.customer_information() \n```\n**Return (dict)**: customer information\n\n#### id\nGets license id\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n \nresponse = license.id() \n```\n**Return (int)**: license id\n\n#### max_transfers\n\nGet the max transfers\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n \nresponse = license.max_transfers() \n```\n**Return (int)**: max transfers\n\n#### transfer_count\n\nGet the transfer count\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n \nresponse = license.transfer_count() \n```\n**Return (int)**: transfer count\n\n#### is_device_transfer_allowed\n\nGet if the device transfer is allowed\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n \nresponse = license.is_device_transfer_allowed() \n```\n**Return (bool)**: True if device transfer is allowed otherwise False.\n\n#### is_device_transfer_limited\n\nGet if the device transfer is limited\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n \nresponse = license.is_device_transfer_limited() \n```\n**Return (bool)**: True if device transfer is limited otherwise False.\n\n#### days_since_last_check\n\nGet how many days passed since last check\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nlicense.check()\n \nresponse = license.days_since_last_check() \n```\n**Return (int)**: How many days have passed since last check. \n\n#### start_date\n\nGet the start date of the license\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nresponse = license.start_date() \n```\n**Return (datetime)**: Datetime in UTC\n\n#### maintenance_period\n\nGet the maintenance period of the license\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nresponse = license.maintenance_period() \n```\n**Return (datetime)**: Datetime in UTC\n\n#### is_maintence_period_expired\nChecks if maintence period has expired\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nresponse = license.is_maintence_period_expired() \n```\n**Return (bool)**: If maintence period expired returns True otherwise False\n\n#### last_check\nGets when the last check was performed\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nresponse = license.last_check() \n```\n**Return (datetime)**: Datetime in UTC\n\n#### last_usage\nGets when the last license usage\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nresponse = license.last_usage() \n```\n**Return (datetime)**: Datetime in UTC\n\n#### license_type\nGets the license type\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nresponse = license.license_type() \n```\n**Return (str)**: License type\n\n#### max_activations\nGets the license max activations\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nresponse = license.max_activations() \n```\n**Return (int)**: max activations\n\n#### metadata\nGets the license metadata\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nresponse = license.metadata() \n```\n**Return (dict)**: metadata\n\n#### allow_unlimited_activations\nCheck if unlimited activationsis allowed\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nresponse = license.allow_unlimited_activations() \n```\n**Return (bool)**: If unlimited activations is allowed returns True otherwise False\n\n#### allow_grace_subscription_period\nCheck if grace subscription period is allowed\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nresponse = license.allow_grace_subscription_period() \n```\n**Return (bool)**: If grace subscription period is allowed returns True otherwise False\n\n#### is_subscription_grace_period_started\nCheck if grace subscription period has started\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nresponse = license.is_subscription_grace_period_started() \n```\n**Return (bool)**: If grace subscription period has started returns True otherwise False\n\n#### is_grace_period_started\nCheck if license is in grace period\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nresponse = license.is_grace_period_started() \n```\n**Return (bool)**: True if grace period has started, otherwise False\n\n#### grace_period_hours_remaining\n\nGet remain hours of grace period\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nresponse = license.grace_period_hours_remaining() \n```\n**Return (int)**: Number of hours left in grace period\n\n\n#### get_grace_period\nGet grace period \n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nresponse = license.get_grace_period() \n```\n**Return (int)**: grace period\n\n#### subscription_grace_period\nGet subscription grace period \n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nresponse = license.subscription_grace_period() \n```\n**Return (int)**: subscription grace period\n\n#### is_expired\nChecks if the license validity has expired\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nresponse = license.is_expired() \n```\n**Return (bool)**: True if license has expired otherwise False\n\n#### license_enabled\nChecks if the license is enabled\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nresponse = license.license_enabled() \n```\n**Return (bool)**: True if license is enabled otherwise False\n\n#### license_active\nChecks if the license is active\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nresponse = license.license_active() \n```\n**Return (bool)**: True if license is active otherwise False\n\n#### is_valid\nChecks if the license is valid (license is active, enabled and didn't expired)\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nresponse = license.is_valid() \n```\n**Return (bool)**: True if license is valid otherwise False\n\n\n#### prevent_vm\nChecks if the license prevents virtual machines\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nresponse = license.prevent_vm() \n```\n**Return (bool)**: True if license prevents VM's otherwise False\n\n#### is_trial\nChecks if the license is trial \n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nresponse = license.is_trial() \n```\n**Return (bool)**: True if license is trial otherwise False\n\n#### expiry_date\nGet expiry date of floating license\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nresponse = license.expiry_date() \n```\n**Return (datetime)**: Expiry date in UTC\n\n#### borrow_until\nGet the date until a license is borrwed\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nresponse = license.borrow_until() \n```\n**Return (datetime)**: borrow_until in UTC\n\n#### is_borrowed\nCheck if a license is borrowed\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nresponse = license.is_borrowed() \n```\n**Return (bool)**: True if license is borrowed otherwise False\n\n#### local_consumptions\nGet local consumptions\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nresponse = license.local_consumptions() \n```\n**Return (int)**: local consumptions\n\n#### max_consumptions\nGet max consumptions\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nresponse = license.max_consumptions() \n```\n**Return (int)**: max consumptions\n\n#### total_consumptions\nGet total consumptions\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nresponse = license.total_consumptions() \n```\n**Return (int)**: total consumptions\n\n#### max_overages\nGet max overages\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nresponse = license.max_overages() \n```\n**Return (int)**: max_overages\n\n#### allow_unlimited_consumptions\nCheck if unlimited consumptions is allowed\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nresponse = license.allow_unlimited_consumptions() \n```\n**Return (int)**: If unlimited consumptions are allowed return True otherwise False\n\n#### consumption_reset\nCheck if there is consumption reset\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nresponse = license.consumption_reset() \n```\n**Return (bool)**: If there is consumption reset returns True otherwise False\n\n#### allow_overages\nCheck if overages are allowed\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nresponse = license.allow_overages() \n```\n**Return (bool)**: If overages are allowed returns True otherwise False\n\n#### consumption_period\nGet consumption period\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nresponse = license.allow_overages() \n```\n**Return (str)**: Consumption period\n\n#### get_feature_data\nGet feature data\n\n**Parameters**:\n* feature_code (str): feature code\n\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nfeature_code = \"feature1\"\n\nresponse = license.get_feature_data(feature_code) \n```\n**Return (dict)**: Feature\n\n#### features\nGet feature list\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nprint(license.features()) \n```\n**Return (list)**: Features\n\n#### check_license_status\n\nVerifies the current status of the license. It raises exceptions if the license is not enabled, not active, or expired\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n \nlicense.check_license_status() \n```\n**Raises**: \n**LicenseStateException**: Raised if the license fails one of the following checks:\n* License is not enabled.\n* License is not active.\n* License validity period has expired. \n\n**Return**: None\n\n#### check\n\nPerforms an online check to synchronize the license data with the backend. This includes syncing consumptions for consumption-based licenses.\n\n**Parameters**:\n\n* **include_expired_features (bool, optional)**: Includes expired license features in the check.\n\n \n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n \nresponse=license.check() \n```\n**Raises**:\n\n**ClientError**: Raised if there's an issue with the API client's request, such as invalid credentials or unauthorized access.\n\n**RequestException**: Raised if there's a problem with the request to the licensing server, such as network issues or server unavailability.\n\n**Return (dict)**: The updated license cache.\n\n#### deactivate\n\nDeactivates the license and optionally deletes the local license file.\n\n**Parameters**:\n\n* **delete_license (bool, optional)**: If **True**, deletes the local license file upon deactivation.\n\n \n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n \nlicense.deactivate() \n```\n\n**Return**: None\n\n\n#### local_check\n\nThis method ensures the integrity and consistency of the licensing information by comparing the data stored in the local license file with the predefined configurations in the **Configuration object**.\n\n \n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n \nlicense.local_check() \n```\n**Raises**:\n\n**ConfigurationMismatch**: Raised if the product code or hardware ID in the license file does not match the expected values provided in the Configuration \n**VMIsNotAllowedException**: Raised if the license is used in a VM environment when the license explicitly disallows it. \n**TimeoutExpiredException**: Raised if a floating license has expired. This is more relevant if is_floating_expired is later implemented to perform actual checks.\n**ClockTamperedException**: Raised if there is evidence of tampering with the system's clock, detected by comparing the system's current time with the last usage time recorded in the license file.\n\n**Return**: None\n\n#### add_local_consumption\n\nAdds local consumption records for **consumption-based licenses**.\n**Parameters**:\n\n* **consumptions (bool, optional)**: The number of consumptions to add locally\n \n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n \nlicense.add_local_consumption() \n```\n\n**Raises**: \n**LicenseSpringTypeError**: Raised if the license type does not support consumption (i.e., not a consumption-based license). \n**ConsumptionError**: Raised if adding the specified number of consumptions would exceed the allowed maximum for the license.\n\n**Return**: None\n\n#### sync_consumption\n\nSynchronizes local consumption data with the server, adjusting for overages if specified.\n\nParameters:\n* **req_overages (int, optional)**: Specifies behavior for consumption overages.\n \n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nlicense.add_local_consumption(5)\n \nlicense.sync_consumption()\n```\n**Raises**: \n**RequestException**: Raised if the request to synchronize consumption data with the server fails, for instance, due to network issues or server unavailability.\n\nReturn (bool): True if the consumption data was successfully synchronized; False otherwise.\n\n#### is_grace_period\n\nDetermines if the current license state is within its grace period following a specific exception.\n\n**Parameters**:\n\n* **ex** (Exception): Raised Exception\n \n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\ntry:\n license.check()\n\nexcept Exception as ex\n boolean = license.is_grace_period(ex)\n```\n\n**Return (bool)**: True if the license is within its grace period, False otherwise\n\n#### change_password\n\nChanges password of a user\n\n**Parameters**:\n\n* **password** (str): Old password of license user\n* **new_password**(str): New password of license user\n\n \n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_user(username=\"python@gmail.com\",password=\"7t_x3!o9\")\n\nlicense = manager.activate_license(license_id)\n\nlicense.change_password(password=\"7t_x3!o9\",new_password=\"12345678\") \n```\n**Return (str)**: \"password_changed\"\n\n\n#### setup_license_watch_dog\n\nInitializes and starts the license watchdog with the specified callback and timeout settings.\n\n**Parameters**:\n\n**callback** (Callable): A callable to be executed by the watchdog in response to specific events or conditions. \n**timeout** (int): The period in minutes after which the watchdog should perform its checks.\n**deamon** (bool, optional): Run thread as deamon. Defaults to False. \n**run_immediately** (bool,optional): run license check immediately, if False wait for timeout first.\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nlicense.setup_license_watch_dog(callback,timeout) \n```\n\n**Return**: None\n\n#### stop_license_watch_dog\n\nStops the license watchdog if it is currently running, effectively halting its monitoring and callback activities.\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nlicense.setup_license_watch_dog(callback,timeout)\n \nlicense.stop_license_watch_dog() \n```\n**Return**: None\n\n#### setup_feature_watch_dog\n\nInitializes and starts the feature watchdog with the specified callback and timeout.\n\n**Parameters**:\n\n**callback** (Callable): A callable to be executed by the watchdog in response to specific events or conditions. \n**timeout** (int): The period in minutes after which the watchdog should perform its checks. \n**deamon** (bool, optional): Run thread as deamon. Defaults to False.\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nlicense.setup_feature_watch_dog(callback,timeout) \n```\n\n**Return**: None\n\n#### stop_feature_watch_dog\n\nStops the feature watchdog if it is currently running.\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nlicense.setup_feature_watch_dog(callback,timeout)\n \nlicense.stop_feature_watch_dog() \n```\n**Return**: None\n\n\n#### add_local_feature_consumption\nAdds local consumption to the feature.\n\n**Parameters**:\n* **feature** (str): feature code.\n* **consumptions** (int,optional): Number of consumptions.\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nlicense.add_local_feature_consumption(\"lkprod1cf1\",3) \n``` \n\n**Raises**:\n\n* **ItemNotFoundError**: If the feature specified by `feature_code` does not exist.\n\n* **LicenseSpringTypeError**: If the identified feature is not of the \"consumption\" type.\n\n* **ConsumptionError**: If adding the specified number of consumptions would exceed the feature's consumption limits.\n\n\n\n**Return**: None\n\n\n#### sync_feature_consumption\nSynchronizes local consumption data with the server.\n**Parameters**:\n\n* **feature** (str): feature code.\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nlicense.add_local_feature_consumption(\"lkprod1cf1\",3)\n\nlicense.sync_feature_consumption(\"lkprod1cf1\")\n``` \n\n**Return** (bool): True if the consumption data was successfully synchronized; False otherwise.\n\n\n#### floating_borrow\nAttempts to borrow a floating license until the specified date, updating the system status based on the outcome of the borrow attempt.\n\n**Parameters**:\n\n* **borrow_until** (str): A string representing the date until which the license should be borrowed.\n* **password** (str,optional): Password for the license if required.\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nlicense.floating_borrow(\"2031-05-06T00:00:00Z\") \n``` \n**Return**: None\n\n#### floating_release\nReleases a borrowed floating license and updates the license status accordingly.\n\n**Parameters**:\n\n* **throw_e**(bool): A boolean indicating whether to raise an exception on failure.\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nlicense.check()\n\nlicense.floating_release(False) \n``` \n\n**Return**: None\n\n#### check_feature\nChecks for a specific license feature and updates the license cache accordingly.\n\n**Parameters**:\n\n* **feature**(str): feature code.\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nlicense.check_feature(\"lkprod1f1fc1\") \n``` \n\n**Return**: None\n\n#### release_feature\nReleases a borrowed license feature and updates the license cache accordingly.\n\n**Parameters**:\n\n* **feature**(str): feature code.\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nlicense.check_feature(\"lkprod1f1fc1\")\n\nlicense.release_feature(\"lkprod1f1fc1\") \n``` \n\n**Return**: None\n\n#### update_offline\nUpdates license via refresh file\n\n**Parameters**:\n\n* **path** (str): path of the refresh file\n* **reset_consumption** (bool): True resets consumption otherwise False\n\n\n```python\nfile_path = 'path_to_lic_file/license.lic'\n\nmanager = LicenseManager(conf)\n\nlicense = manager.activate_license_offline(file_path)\n\nlicense.update_offline('offline_files/license_refresh.lic',False) \n``` \n**Raises**:\n\n* **ConfigurationMismatch**: The update file does not belong to this device\n* **ConfigurationMismatch**: The update file does not belong to this product \n\n**Return**(bool): True if license was successfully updated otherwise False\n\n#### get_deactivation_code\n\nGet deactivation code for air gap licenses\n\n**Parameters**:\n* **initialization_code** (str): initialization_code\n\n```python\ninitialization_code=\"your_initialization_code\"\nmanager = LicenseManager(conf)\n#load air gap license\nlicense = manager.load_license()\n\ndeactivation_code = license.get_deactivation_code(initialization_code)\n\nprint(\"Deactivation code:\",deactivation_code)\n``` \n\n**Return** (str): deactivation code\n\n#### deactivate_air_gap\n\nDeactivate air gap license and clear storage\n\n**Parameters**:\n* **confirmation_code** (str): confirmation_code\n\n\n```python\nconfirmation_code=\"your_confirmation_code\"\nmanager = LicenseManager(conf)\n#load air gap license\nlicense = manager.load_license()\nlicense.deactivate_air_gap(confirmation_code)\n```\n**Raises**:\n* **LicenseActivationException**: VerificationError\n\n**Return**: None\n#### deactivate_offline\nGenerates .req file for the offline deactivation\n\n**Parameters**:\n\n* **offline_path**(str): path of the .req file\n\n\n```python\nfile_path = 'path_to_lic_file/license.lic'\n\nmanager = LicenseManager(conf)\n\nlicense = manager.activate_license_offline(file_path)\n\nlicense.deactivate_offline('path_where_to_create_req_file') \n``` \n**Raises**:\n\n* **ConfigurationMismatch**: The update file does not belong to this device\n* **ConfigurationMismatch**: The update file does not belong to this product \n\n**Return**(bool): True if license was successfully updated otherwise False\n\n#### product_details\nUpdate product details from LicenseSpring server\n\n**Parameters**:\n\n* **include_custom_fields** (bool, optional): custom fields information. Defaults to False.\n* **include_latest_version** (bool, optional): Lateset version information. Defaults to False.\n \n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H9V3-72XX-ZRAJ-S6LK\")\n\nlicense = manager.activate_license(license_id)\n \nresponse = license.product_details() \n``` \n**Raises**:\n \n\n**Return**(dict): response\n\n#### get_product_details\nGet product details from licensefile (offline)\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H7G3-F4PJ-4AEJ-UKYL\")\n\nlicense = manager.activate_license(license_id)\n\nfeature_code = \"feature1\"\n\nresponse = license.get_product_details() \n```\n**Return (dict)**: Product details\n\n#### get_device_variables\nGet device variable if exists\n\n**Parameters**:\n\n* **variable_name** (str): variable name \n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H9V3-72XX-ZRAJ-S6LK\")\n\nlicense = manager.activate_license(license_id)\n \ndevice_var = license.get_device_variable('english') \n``` \n**Raises**:\n \n\n**Return**(dict): variable dictionary\n\n#### set_device_variables\nSet device variables locally \n\n**Parameters**:\n\n* **variables** (dict): variables dict\n* **save** (bool, optional): Save cache to licensefile. Defaults to True.\n \n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H9V3-72XX-ZRAJ-S6LK\")\n\nlicense = manager.activate_license(license_id)\n \nlicense.set_device_variables({\"english\":\"value\"}) \n``` \n**Raises**:\n \n\n**Return**: None\n\n#### get_device_variables\nGet device variables from server or locally\n\n**Parameters**:\n\n* **get_from_be** (bool, optional): If True collects data from LicenseSpring server. Defaults to True.\n \n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H9V3-72XX-ZRAJ-S6LK\")\n\nlicense = manager.activate_license(license_id)\n \nlicense.get_device_variables(get_from_be=True) \n``` \n**Raises**:\n * **RequestException** (Grace period not allowed)\n\n**Return**(list): List of device variables\n\n#### send_device_variables\nSend device variables to LicenseSpring server. Handles GracePeriod\n \n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H9V3-72XX-ZRAJ-S6LK\")\n\nlicense = manager.activate_license(license_id)\n \nlicense.send_device_variables() \n``` \n**Raises**:\n * **RequestException** (Grace period not allowed)\n\n**Return**(bool): True if new variables are sent to LicenseSpring server otherwise, False\n\n#### custom_fields\nGet custom fields from licensefile\n\n```python\nmanager = LicenseManager(conf)\n\nlicense_id = LicenseID.from_key(\"H9V3-72XX-ZRAJ-S6LK\")\n\nlicense = manager.activate_license(license_id)\n \nresponse = license.custom_fields() \n``` \n**Return**(list): Custom fields\n\n## Floating Server\n\nThe user has the ability to utilize either a **Floating Client** or a **Floating Manager**:\n\n**Floating Client**:\n* This object is responsible for managing the operations on Floating Server\n\n**Floating Manager**:\n* This object is responsible for managing operations with the Floating Server, while also integrating the license file\n\n### Floating Client\n\n#### Intialization\n\nTo initialize a Floating Client, the user must specify the API protocol and domain.\n\n* **api_protocol**: Defines the communication protocol between the client and the server (e.g., \"http\").\n* **api_domain**: Specifies the domain or IP address and port of the Floating Server (e.g., \"localhost:8080\").\n* **hardware_id_provider** (optional): Provides the client's hardware ID, which can be used to uniquely identify the client machine.\n\n```python\nfrom licensespring.floating_server import FloatingAPIClient\nfrom licensespring.hardware import HardwareIdProvider\n\napi_client = FloatingAPIClient(api_protocol=\"http\", api_domain=\"localhost:8080\",hardware_id_provider=HardwareIdProvider)\n```\n#### auth\nAuthenticate\n\n**Parameters**:\n* **username** (str): username\n* **password** (str): password\n\n```python\nfrom licensespring.floating_server import FloatingAPIClient\n\napi_client = FloatingAPIClient(api_protocol=\"http\", api_domain=\"localhost:8080\")\napi_client.auth(username=\"admin\",password=\"tetejac\")\n```\n**Return**(dict): Response\n\n#### register_user\n\nRegister user\n\n**Parameters**:\n\n* **product** (str): product short code.\n* **user** (str,optional): user. Defaults uses hardware id.\n* **os_hostname** (str, optional): os hostname. Defaults to None.\n* **ip_local** (str, optional): ip local. Defaults to None.\n* **user_info** (str, optional): user info. Defaults to None.\n* **license_id** (int, optional):license id. Defaults to None.\n\n```python\napi_client = FloatingAPIClient(api_protocol=\"http\", api_domain=\"localhost:8080\")\n\nresponse = api_client.register_user(\n product=\"lkprod1\",\n user=\"user_1\",\n os_hostname=\"bla\",\n ip_local=\"bla\",\n user_info=\"bla\",\n license_id=1728377159207169\n)\n\nprint(response)\n```\n**Return**(dict): Response\n\n#### unregister\n\n**Parameters**\n\n* **product** (str): product short code.\n* **user** (str,optional): user. Defaults uses hardware id.\n* **license_id** (int, optional): license id. Defaults to None.\n\n\nUnregister user\n\n```python\n\napi_client = FloatingAPIClient(api_protocol=\"http\", api_domain=\"localhost:8080\")\n\nresponse = api_client.unregister_user(product=\"lkprod1\",user=\"user_1\",license_id=1728377159207169)\n\nprint(response)\n```\n\n**Return**(str): \"user_unregistered\"\n\n#### unregister_all\n\nUnregister all users\n\n```python\napi_client = FloatingAPIClient(api_protocol=\"http\", api_domain=\"localhost:8080\")\n\napi_client.unregister_all()\n```\n\n#### borrow \n\nBorrow license\n\n**Parameters**\n\n* **product** (str): product short code.\n* **user** (str,optional): user. Defaults uses hardware id.\n* **borrowed_until** (str): borrow until date\n* **os_hostname** (str, optional): os hostname. Defaults to None.\n* **ip_local** (str, optional): ip local. Defaults to None.\n* **user_info** (str, optional): user info. Defaults to None.\n* **license_id**(int, optional):license id. Defaults to None.\n\n```python\napi_client = FloatingAPIClient(api_protocol=\"http\", api_domain=\"localhost:8080\")\n\nresponse = api_client.borrow(\n product=\"lkprod1\",\n user=\"user_1\",\n borrowed_until=\"2029-05-06T00:00:00Z\",\n os_hostname=\"bla\",\n ip_local=\"bla\",\n user_info=\"bla\",\n license_id=1728377159207169,\n )\n```\n\n**Return**(dict): Response\n\n#### add_consumption\n\nAdd license consumption\n\n**Parameters**\n\n* **product** (str): product short code\n* **consumptions** (int, optional): consumptions. Defaults to 1.\n* **max_overages** (int, optional): max overages. Defaults to None.\n* **allow_overages** (bool, optional): allow overages. Defaults to None.\n* **user** (str, optional): user (default uses hardware id)\n* **license_id** (int, optional): license id. Defaults to None.\n\n\n```python\napi_client = FloatingAPIClient(api_protocol=\"http\", api_domain=\"localhost:8080\")\n\nresponse = api_client.add_consumption(product=\"fs\", consumptions=1)\n```\n\n**Return**(dict): Response\n\n#### add_feature_consumption\n\nAdd feature consumption\n\n**Parameters**\n* **product** (str): product short code\n* **feature_code** (str): feature code\n* **user** (str, optional): user (default uses hardware id)\n* **consumptions** (int, optional): consumptions. Defaults to 1.\n* **license_id** (int, optional): license id. Defaults to None.\n\n```python\napi_client = FloatingAPIClient(api_protocol=\"http\", api_domain=\"localhost:8080\")\n\nresponse = api_client.add_feature_consumption(product=\"fs\", feature_code=\"f2\", consumptions=1)\n```\n\n**Return**(dict): Response\n\n#### feature_register\n\nRegister feature\n\n**Parameters**\n\n* **product** (str): product short code\n**feature_code** (str): feature short code\n* **user** (str, optional): user (default uses hardware id)\n* **license_id** (int, optional): license id. Defaults to None.\n* **borrowed_until** (str): borrow until (e.g. 2029-05-06T00:00:00Z) \n* **os_hostname** (str, optional): os hostname. Defaults to None.\n* **ip_local** (str, optional): ip local. Defaults to None.\n* **user_info** (str, optional): user info. Defaults to None.\n\n```python\napi_client = FloatingAPIClient(api_protocol=\"http\", api_domain=\"localhost:8080\")\n\nresponse = api_client.feature_register(\n product=\"fs\", feature_code=\"f1\", os_hostname=\"w\", ip_local=\"1.0\", user_info=\"info\"\n )\nprint(response)\n```\n\n**Return**(dict): Response\n\n#### feature_release\n\nFeature release\n\n**Parameters**\n* **product** (str): product short code\n* **feature_code** (str): feature short code\n* **user** (str, optional): user (default uses hardware id)\n* **license_id** (int, optional): license id. Defaults to None.\n\n```python\napi_client = FloatingAPIClient(api_protocol=\"http\", api_domain=\"localhost:8080\")\n\nresponse = api_client.feature_register(\n product=\"fs\", feature_code=\"f1\", os_hostname=\"w\", ip_local=\"1.0\", user_info=\"info\"\n )\n\nresponse = api_client.feature_release(product=\"fs\", feature_code=\"f1\")\n```\n\n**Return**(str): \"feature_released\"\n\n### Floating Manager\n\n#### Intialization\n\nTo intialize Floating Manager [Configuration](#configuration-setup) needs to be created. For Floating server you can set arbitrary values for `shared_key` and `api_key` keys.\n\n\n#### auth\nAuthenticate\n\n**Parameters**:\n* **username** (str): username\n* **password** (str): password\n\n```python\nfrom licensespring.licensefile.config import Configuration\nfrom licensespring.licensefile.floating_manager import FloatingManager\n\nfs_manager = FloatingManager(conf=conf)\nfs_manager.auth(username=\"admin\",password=\"tetejac\")\n```\n**Return**(dict): Response\n\n#### register \n\nRegister license\n\n**Parameters**:\n\n* **os_hostname** (str, optional): os hostname. Defaults to None.\n* **ip_local** (str, optional): ip local. Defaults to None.\n* **user_info** (str, optional): user info. Defaults to None.\n* **license_id** (int, optional):license id. Defaults to None.\n\n```python\nfrom licensespring.licensefile.config import Configuration\nfrom licensespring.licensefile.floating_manager import FloatingManager\n\nconf = Configuration(\n product=product,\n api_key=\"arbitrary\",\n shared_key=\"arbitrary\",\n file_key=\"your_file_key\",\n file_iv=\"your_file_iv\",\n api_domain=\"api_domain\",\n api_protocol=\"http/https\",\n)\n\nfs_manager = FloatingManager(conf=conf)\nlicense = fs_manager.register()\n```\n**Return**(License): License object\n\n#### unregister\n\n**Parameters**\n\n* license_id (int, optional): license id. Defaults to None.\n\nUnregister license\n\n```python\nfs_manager = FloatingManager(conf=conf)\n# There are multiple options to unregister a license\n# 1. floating client -> this one is documanted\nfs_manager.unregister()\n# 2.1. license object -> deactivate method\nlicense.deactivate() \n#2.2 license object -> floating release\nlicense.floating_release(False)\n```\n\n**Return**(str): \"user_unregistered\"\n\n\n#### unregister_all\n\nUnregister all users\n\n```python\nfs_manager = FloatingManager(conf=conf)\nfs_manager.unregister_all()\n```\n\n#### borrow_license\n\nBorrow license\n\n**Parameters**\n\n* **borrowed_until** (str): borrow until date\n* **os_hostname** (str, optional): os hostname. Defaults to None.\n* **ip_local** (str, optional): ip local. Defaults to None.\n* **user_info** (str, optional): user info. Defaults to None.\n* **license_id**(int, optional):license id. Defaults to None.\n\n```python\nfs_manager = FloatingManager(conf=conf)\nlicense = fs_manager.borrow(\"2031-05-06T00:00:00Z\")\n# borrow can be also used within the License object\nlicense.floating_borrow(\"2031-05-06T00:00:00Z\")\n```\n\n**Return**(License): License object\n\n#### is_online\n\nChecks if floating server is online\n\n**Parameters**\n\n* **throw_e** (bool, optional): True if you want raise exception. Defaults to False.\n\n```python\nfs_manager = FloatingManager(conf=conf)\nresponse = fs_manager.is_online()\n```\n\n**Raises**:\n* **ex**: Exception\n\n**Return**(bool): True if server is online, otherwise False\n\n### Methods supported inside License object\n[License consumptions](#add-consumption), [feature consumptions](#add-feature-consumption), [register feature](#check_feature), [release feature](#release_feature) are supported within `License` object for Floating Server\n \n## License\n\nLicenseSpring SDK Source Code License (LSSCL)\n\nPreamble:\nThis LicenseSpring SDK Source Code License (LSSCL) governs the use, distribution, and modification of the source code for this LicenseSpring SDKs. This SDK is designed to facilitate the integration of LicenseSpring's license management service into your applications. By accessing, using, or modifying the SDK, you agree to the terms and conditions set forth in this license.\n\n1. Permissions:\n\n\t* You are permitted to access, read, and modify the source code of this LicenseSpring SDK.\n\t* You may create derivative works that include this SDK, provided all derivative works are used solely as part of the LicenseSpring service.\n\n2. Distribution:\n\n\t* You may distribute the original or modified versions of software that incorporates the SDK, provided that all distributed versions retain this LSSCL license.\n\t* Distributed versions, including modifications, must be used to facilitate the integration of LicenseSpring\u2019s service and may not be:\n\t\t* Provided as part of a hosted or cloud-based service that allows others to access the SDK\u2019s functionality without interacting directly with the LicenseSpring service.\n\t\t* Integrated into other services which compete with or do not use the LicenseSpring service.\n\n3. Usage Restrictions:\n\n\t* The SDK, in its original or modified form, may only be used as part of the LicenseSpring service, whether on a free or paid plan.\n\t* You are prohibited from using the SDK independently or as part of any service that does not interact with the LicenseSpring service.\n\n4. Prohibited Actions:\n\n\t* You may not circumvent or disable any technical measures that control access to the SDK.\n\t* You must not remove, alter, or obscure any license notices, copyright notices, or other proprietary notices from the SDK.\n\n5. Termination:\n\n\t* Any violation of these terms will result in the automatic termination of your rights under this license.\n\t* Upon termination, you must cease all use and distribution of the SDK and destroy all copies in your possession.\n\n6. Disclaimer of Warranty and Liability:\n\n\tTHE SOFTWARE IS PROVIDED \"AS IS\" AND LICENSESPRING DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. LICENSESPRING SHALL NOT BE LIABLE FOR ANY DAMAGES ARISING OUT OF OR RELATED TO THE USE OR PERFORMANCE OF THE SOFTWARE.\n\nCopyright 2024 Cense Data Inc DBA LicenseSpring\nContact: support@licensespring.com\n\n### Dependency licenses\n\n| Name | Version | License | URL |\n|--------------------|-----------|-----------------------------------------------------|----------------------------------------------------------|\n| certifi | 25.1.0 | Mozilla Public License 2.0 (MPL 2.0) | https://github.com/certifi/python-certifi |\n| charset-normalizer | 3.4.1 | MIT License | https://github.com/Ousret/charset_normalizer |\n| idna | 3.10 | BSD License | https://github.com/kjd/idna |\n| pycryptodome | 3.21.0 | Apache Software License; BSD License; Public Domain | https://www.pycryptodome.org |\n| requests | 2.32.3 | Apache Software License | https://requests.readthedocs.io |\n| urllib3 | 2.3.0 | MIT License | https://github.com/urllib3/urllib3/blob/main/CHANGES.rst |\n| winregistry | 2.1.0 | UNKNOWN | https://github.com/shpaker/winregistry |\n",
"bugtrack_url": null,
"license": "LicenseSpring SDK Source Code License (LSSCL)",
"summary": "LicenseSpring Python Library",
"version": "3.3.0",
"project_urls": {
"Documentation": "https://docs.licensespring.com/sdks/python",
"Homepage": "https://licensespring.com/"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "964efa64698ede6175fab9e0c23a00e420b4ea2012d2eb766cf50902298a7015",
"md5": "632789f9fa67e4207949f58158e061f2",
"sha256": "8ca956bbc348c5a938deb0880a382bcd0990ecadfb3923b9a86473c95b5195af"
},
"downloads": -1,
"filename": "licensespring-3.3.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "632789f9fa67e4207949f58158e061f2",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<4.0,>=3.9",
"size": 621771,
"upload_time": "2025-02-14T10:36:59",
"upload_time_iso_8601": "2025-02-14T10:36:59.962828Z",
"url": "https://files.pythonhosted.org/packages/96/4e/fa64698ede6175fab9e0c23a00e420b4ea2012d2eb766cf50902298a7015/licensespring-3.3.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "5b680ecb029bad936417ac603b6f08c23d2011536140d3fbcfc19873ef3871c3",
"md5": "e43959fa61c8755a0920fc16b446dcd3",
"sha256": "e5a7f4f8dae2e151abf4cd10a63b807172654d76c688803f17f3a3d95802306a"
},
"downloads": -1,
"filename": "licensespring-3.3.0.tar.gz",
"has_sig": false,
"md5_digest": "e43959fa61c8755a0920fc16b446dcd3",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4.0,>=3.9",
"size": 382010,
"upload_time": "2025-02-14T10:37:02",
"upload_time_iso_8601": "2025-02-14T10:37:02.565247Z",
"url": "https://files.pythonhosted.org/packages/5b/68/0ecb029bad936417ac603b6f08c23d2011536140d3fbcfc19873ef3871c3/licensespring-3.3.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-02-14 10:37:02",
"github": false,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"lcname": "licensespring"
}