# Python SDK Configuration

**Python SDK** allows implementing licensing:

* using the **License** and **LicenseManager** classes

The License object is responsible for managing **license operations**, while the **LicenseManager** handles license activation and retrieval of the License object.

In the following examples, we will demonstrate SDK usage with only the **LicenseManager** and **License** classes.

### Configuration

To initialize the SDK you will need to fill in your application, LicenseSpring API key, shared key and product code.

Both the API key and shared key can be found on your LicenseSpring account under Settings->Keys:

![API and Shared Key Location](https://content.gitbook.com/content/gLzurdfXUuKr9IziZWLz/blobs/sWDKqjOcUe9JhYjZkPF0/E8UhHrENKuF%20RQw50B4nn_screenshotkeys.png)

Your product code is located in your product list under Configure Products:

![Product CoProduct Code Location Location](https://content.gitbook.com/content/gLzurdfXUuKr9IziZWLz/blobs/EolKdpns3yY2tQ2a4EtS/LGlB_ERjJM0YF_0EHtMt2_screenshotproduct.png)

Please, keep in mind that the product code field is case-sensitive.

### Configuration

To use licensefile inside a python SDK you should first setup your key and IV. This process is only required once at the setup.

{% tabs %}
{% tab title="Key derivation" %}

```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()
```

{% endtab %}

{% tab title="Create Configuration" %}
When you have the necessary values, create the [**configuration**](https://docs.licensespring.com/sdks/tutorials/getting-started/python/broken-reference).

```python
from licensespring.licensefile.config import Configuration

conf = Configuration(product="your_product_key",api_key="your_api_key",
                   shared_key="your_shared_key",file_key=key,file_iv=iv)
```

{% endtab %}

{% tab title="Initialize LicenseManager" %}
Now you can initialize [**License Manager**](https://docs.licensespring.com/sdks/tutorials/getting-started/python/broken-reference) using configuration object.

```python
from licensespring.licensefile.license_manager import LicenseManager

manager = LicenseManager(conf)
```

{% endtab %}
{% endtabs %}

### License Activation

The license keys are located in Licenses section:

![License Key Location](https://content.gitbook.com/content/gLzurdfXUuKr9IziZWLz/blobs/KJaeAEnp277mz6m5TqVz/xUdyMD7vPArcHnhvLlQxY_screenshotlicense.png)

To implement user-based licensing please refer to: [**User-Based Licensing**](https://docs.licensespring.com/sdks/tutorials/getting-started/python/broken-reference).

To activate a license, create a **LicenseID** using the given key and call [**activation**](https://docs.licensespring.com/sdks/tutorials/getting-started/python/broken-reference) method.

{% tabs %}
{% tab title="Key Based" %}

```python
manager = LicenseManager(conf)

license_id = LicenseID.from_key("H6QM-6H5R-ZENJ-VBLK")

license = manager.activate_license(license_id)
```

{% endtab %}

{% tab title="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)
```

{% endtab %}
{% endtabs %}

The process of activating a license refers to binding a device to a license. On the LicenseSpring platform, activating the license increments the total activations counter within the license.

### Local License

The local license is a copy of the license information that is saved on the end user's local computer. Users who have not activated the license on their end before will not have a local license. By default, the local license is stored: %USERPROFILE%\AppData\Local\LicenseSpring\”Product Code”\License.key.

See [**Local License File**](https://docs.licensespring.com/sdks/tutorials/getting-started/python/broken-reference) for more information.

### License Check

It is recommended to perform a local license check at application start to confirm that the local license file belongs to the current device and has not been transferred.

It is also useful to check whether the local license file has been tampered with and whether the local license is still valid.

{% tabs %}
{% tab title="Local check" %}

```python
manager = LicenseManager(conf)

license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")

license = manager.activate_license(license_id)
    
license.local_check()
```

{% endtab %}
{% endtabs %}

The local check can produce the following errors:

| Exception                | Error code                                                                                                      | Reason                                                      |
| ------------------------ | --------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------- |
| `LicenseStateException`  | <p><code>LICENSE\_NOT\_ENABLED</code><br><code>LICENSE\_NOT\_ACTIVE</code><br><code>LICENSE\_EXPIRED</code></p> | License is in invalid state (disabled, expired or inactive) |
| `ConfigurationMismatch`  | `PRODUCT_MISMATCH`                                                                                              | License does not belong to configured product               |
| `ConfigurationMismatch`  | `HARDWARE_ID_MISMATCH`                                                                                          | License does not belong to current device                   |
| `ClockTamperedException` | `CLOCK_TAMPERED`                                                                                                | Detected cheating with system clock                         |

Online license check refreshes the local license with the data from LicenseSpring backend:

{% tabs %}
{% tab title="Online check" %}

```python
manager = LicenseManager(conf)

license_id = LicenseID.from_key("H7G3-F4PJ-4AEJ-UKYL")

license = manager.activate_license(license_id)
    
response = license.check()
```

{% endtab %}
{% endtabs %}

The online check can produce the following errors:

| Exception          | Error code                                                                                                      | Reason                                                                                 |
| ------------------ | --------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
| `ClientError`      | <p><code>LICENSE\_NOT\_ACTIVE</code><br><code>LICENSE\_NOT\_ENABLED</code><br><code>LICENSE\_EXPIRED</code></p> | License disabled, expired or not active                                                |
| `RequestException` |                                                                                                                 | Connection-related errors: if there's no Internet or an internal server error occured. |

This method also returns full **response**.

For more information about managing software updates, see [**Handling Product Versions**](https://docs.licensespring.com/sdks/tutorials/getting-started/python/broken-reference).

You can also check for active, valid, enabled, and expired licenses using `license_active`, `is_valid`, `license_enabled`, and `is_expired` methods respectively.

{% hint style="warning" %}
Note that an **active license** does not necessarily mean a license is **valid**. A valid license means the license is **active**, **enabled**, and **not expired**. An active license means that the license is bound to a device, but may also be **disabled** or **expired**.
{% endhint %}

### Full Code Sample

Below you can find a code sample that initializes the SDK, retrieves a local license or activates a new one, and performs the necessary checks.

{% tabs %}
{% tab title="LicenseManager" %}

```python
from licensespring.licensefile.config import Configuration
from licensespring.licensefile.license_manager import LicenseID
from licensespring.licensefile.license_manager import LicenseManager

conf = Configuration(product="your_product_key",api_key="your_api_key",
                   shared_key="your_shared_key",file_key=key,file_iv=iv)
     

manager = LicenseManager(conf)

license_id = LicenseID.from_key("your_license_key")

try:
    license = manager.activate_license(license_id)

    license.local_check()

    license.check()
    
except Exception as ex:
    print("LicenseSpring exception encountered:", ex)
```

{% endtab %}
{% endtabs %}

### License Deactivation

Deactivating a license unbinds the device from the license, and decrements the number of total activations. Depending on the license transfer policy, this usually means that the license is freed up to be activated onto a new device. Deactivating is done using the following method:

{% tabs %}
{% tab title="License" %}

```python
license.deactivate()
```

{% endtab %}
{% endtabs %}

The `license.deactivate()` method allows to specify whether you want to remove the local license file after the deactivation. Set the `delete_license` parameter to `true` if you want the local files to be removed.
