This article will give step-by-step instructions on how to add floating-licensing to your Python app. There's also a full example app that you can download and play with without needing to add licensing to your app.
By the end of this article you'll have working floating-licensing integrated with your application, and thus the ability to sell individual copies of your software.
This article shows you how to add floating-licensing to your Python app using TurboFloat. To add hardware-locked licensing to your app see the "Using TurboActivate with Python " article.
Before you can do anything, you need to login to your LimeLM account (or sign up). Then download TurboFloat for Windows, macOS, Linux, or BSD. It contains the native library and source code examples needed to integrate floating-licensing in your Python app:
After you've created a new product, go to the version page of the product you will be adding licensing to. You will need to do 2 things:
You'll be including the TurboActivate.dat file in the same folder as the TurboFloat.dll file and you'll use the Version GUID in your code as part of integrating TurboFloat within your app.
We're going to walk you through adding floating licensing to your app by using our Python example application. If you haven't downloaded it already you can get the example app inside the TurboFloat Library package.
Before you can continue, you need to start a TurboFloat Server instance. We recommend spinning-up a TurboFloat Server instance on our infrastructure using LicenseChest. Alternatively, your customers can host the TurboFloat Server on their own infrastructure by activating and installing the TurboFloat Server locally.
We recommend using our hosted TurboFloat Server option because it's fast, stable, up-to-date, and incredibly easy to deploy.
After you've created your account, download the TurboFloat library and extract it anywhere. After you extract it, inside the extracted folder you'll find 2 folders: the "API
" directory and the the "bin-*
" directory (for example, bin-windows
, for the Windows TurboFloat package).
Now you need to add TurboFloat to your app. You can do this one of 2 ways, either add "turbofloat" directory from from the "API/Python" project you extracted from the TurboFloat library main package. Or you can install the TurboFloat Python class to be used globally:
pip install turbofloat
Or, to update the downloaded pip package do it like so:
pip install --upgrade turbofloat
In the example Python application the "example.py" file's if __name__ == "__main__":
line is the entry point for the application. And because it's the entry point of the application it's where we'll be requesting the "license lease" from the TurboFloat Server.
First, create the TurboFloat instance and paste the Version GUID you copied from earlier:
try:
# TODO: go to the version page at LimeLM and
# paste this GUID here
tf = TurboFloat("PASTE-VERSION-GUID-HERE", leasecallback)
Next, we'll actually request the lease from the TurboFloat Server:
try:
# TODO: go to the version page at LimeLM and
# paste this GUID here
tf = TurboFloat("PASTE-VERSION-GUID-HERE", leasecallback)
try:
tf.request_lease()
The native TurboFloat library handles all the details about renewing leases, retrying, etc. All you have to do is handle the cases where TurboFloat talks to your app and tells it something has changed (license lease failing to be renewed or new license field data). To do this you need to create the callback function that you set when creating the TurboFloat() object instance:
def leasecallback(status):
if status == TF_CB_FEATURES_CHANGED:
print("TODO: reload any features using TF_GetFeatureValue()")
elif status == TF_CB_LEASE_DROPPED_SLEEP:
# TODO: prompt the user to re-connect -- hide this prompt upon receipt of TF_CB_LEASE_REGAINED
print("The lease has been dropped due to computer sleeping.")
elif status == TF_CB_LEASE_REGAINED:
# TODO: hide a prompt to the user if shown during TF_CB_LEASE_DROPPED_SLEEP
print("The lease has been successfully regained after a sleep.")
else:
# TODO: disable any features in your app.
print("The lease expired or has been dropped: ", status)
'''
After disabling the user's access to your app, we recommend
you do 3 things:
1. Give the user the option to save their progress.
2. Give the user the option to save their progress to a
separate file (i.e. "Save as" in case the work they were
doing was incomplete).
3. Give the user the option to retry. For example a
"Try again" button that calls TF_RequestLease(tfHandle).
Don't just exit the app without warning or without giving the user ptions.
For example, this behavior right here is a terrible example to be etting:
'''
print("The app is exiting. In your app you shouldn't just abruptly exit! That's bad. See the comments in the example app.")
quit()
In the example, notice how we're handling the case where the end-user hasn't already specified the floating license server (the TurboFloatServerError
). Instead of just hardcoding the server and port (like we show in the example), you should prompt the user to enter the details. Then you can call the tf.save_server()
function to save the details.
You should also give your customers the ability to easily choose using TFS instances hosted on our infrastructure using LicenseChest by simply prompting them to enter the server UUID (a small string that uniquely identifies their TFS instance). Then it's simply a matter of calling tf.save_server()
and appending the user-entered UUID to the hosted TFS address like so:
tf.save_server("floating.wyday.com/?server=UUID_HERE", 443, TF_USER | TF_REQUEST_OVER_HTTPS)
After you've successfully requested a lease from the TurboFloat Server, the TurboFloat library integrated in your app takes care of renewing the leases automatically and silently. You'll only ever get a notification of something going wrong in the callback function that we covered in Step 3.
When your app is closing you should "drop" the lease using the tf.drop_lease()
function, and cleanup the memory using the tf.cleanup()
function::
# Drop the floating license, wait for the response,
# then exit your app.
if tf.has_lease():
tf.drop_lease()
What this does is tell the TurboFloat Server that you're through using the lease in this instance of your app, and another instance of your app on another computer or another session can now use that "free slot".
If you can't drop the lease (because your app can't connect to the internet, or for any other reason), and you choose to exit your app anyway, then the "lease" on the TurboFloat Server will be a "zombie". The lease will expire eventually on the TurboFloat Server, and thus the free slot will open back up.
Testing requesting leases, dropping them, and everything else in the TurboFloat Library is intuitive: just call the function and it does the thing you want it to do. Testing the lease callback function is, however, slightly less intuitive. Here's how you can test the callback function:
If your app is open and has a lease, close your app and make sure it drops the license lease from the TurboFloat Server.
Stop the TurboFloat Server instance.
Open the TurboFloat Server config file, and edit <lease .../>
element and set it to "30". This will set the lease length to 30 seconds.
Save the changes you made to the configuration file.
Start your TurboFloat Server instance again.
Start your app again, and make sure it successfully gets a license lease from the TurboFloat Server.
Now, stop the TurboFloat Server instance, but leave your app running.
Within the next 30 seconds the lease callback function will be called because the TurboFloat Library was not able to renew the license lease automatically.
You should also test the "TF_CB_LEASE_DROPPED_SLEEP
" and "TF_CB_LEASE_REGAINED
" callback types. These callbacks are raised when your app has a lease and the device your app is running on goes to sleep and then eventually wakes up. To test these scenarios:
Run a TurboFloat Server on a separate computer than the one you're running the test from (or spin up a TurboFloat Server instance on our infrastructure).
Start your app and acquire a lease from that TFS instance.
Put the computer which your app is running on to sleep.
After the computer has gone to sleep, wake it up.
Your app should handle both of those events seamlessly. Namely, prompting the user to reconnect when the computer goes to sleep, and if the lease is regained automatically, hiding that prompt from the user.