infuze python module user guide

WURFL InFuze for Python: User Guide

This is a Python module wrapping the WURFL C API and encapsulating it in an object oriented manner, to provide a fast, intuitive interface.

Installing libwurfl

In order for the Module to work it is ESSENTIAL that the libwurfl library is installed on your system. libwurfl is provided in your Customer Vault/FileX.

If you have not already installed libwurfl, instructions can be found here. Release notes for each API can be found here.

Setup

WURFL InFuze for Python is built/installed using the Python virtualenv utility. The requirements.txt and setup.py files contain relevant setup code.

Requirements

The C libwurfl library must be installed and usable by C as #include <wurfl/wurfl.h>.

Python development headers and setuptools must also be installed. On Debian this is done by:

$ apt-get install python-dev python-setuptools

On CentOS this is done by:

$ yum install python-dev python-virtualenv

Installation

WURFL InFuze for Python is distributed as Python egg and can be installed using easy_install.

Once you have obtained the egg from your file manager and installed the InFuze WURFL library, you can run:

$ easy_install pywurfl-<version>-py<version>-<architecture>-x86_64.egg

Usage

Once installed, WURFL InFuze for Python can immediately be used in Python using a simple import pywurfl. For pre-installation testing purposes, the bootstrapped bin/python interpreter can be used.

>>> import pywurfl

The pyWurfl functionality is encapsulated in an object representing a connection to a WURFL DB. It must be initialized with the path to a valid wurfl data file. Only two lines are needed to import the library and load the file:

>>> from pywurfl.wurfl import Wurfl, CACHE_PROVIDERS
>>> wurfl = Wurfl("/usr/share/wurfl/wurfl.zip")

The constructor can also be called with the keyword arguments patches and capabs. Both are lists of strings, specifying the location of WURFL patches and capabilities to load.

>>> wurfl = Wurfl("/usr/share/wurfl/wurfl.zip",
...   capabs = ["brand_name", "model_name", "is_tablet",
...   "pointing_method", "resolution_width", "device_os_version",
...   "device_os", "mobile_browser", "is_smartphone",
...   ],
...   patches = [<path(s) to your patch file(s)>])

The argument high_accuracy (a True/False flag) can also be provided in order to switch WURFL from high performance mode (in which desktop browsers are not distinguished from each other) to high accuracy mode.

The last arguments that can be provided to the WURFL constructor are cache_provider and cache_extra_config. The value of cache_provider must be one of the values provided in the CACHE_PROVIDERS dictionary in the module, while cache_extra_config is expected to be a string containing configuration for the selected cache mechanism. Consult the Infuze C API documentation. for more details on possible cache configuration.

>>> wurfl = Wurfl("/usr/share/wurfl/wurfl.zip",
...   capabs = ["brand_name", "model_name", "is_tablet",
...   "pointing_method", "resolution_width", "device_os_version",
...   "device_os", "mobile_browser", "is_smartphone",
...   ],
...   patches = [<path(s) to your patch file(s)>],
...   high_accuracy = True,
...   cache_provider = CACHE_PROVIDERS["DOUBLE_LRU"],
...   cache_extra_config="10000, 3000")

The most common and simple way to use this WURFL object is to parse browser user agents with it. To do so, let's first define some UA's to use for testing.

>>> nexus = "Mozilla/5.0 (Linux; Android 4.3; Nexus 7 Build/JWR66Y) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.72 Safari/537.36"
>>> iphone = "Mozilla/5.0 (iPhone; CPU iPhone OS 9_2_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Mobile/13D15 (370315264)"

Next, let's parse them into WURFL devices.

>>> nexus_dev = wurfl.parse_useragent(nexus)
>>> iphone_dev = wurfl.parse_useragent(iphone)

These WURFL devices are used to query information about their particular user agents.

>>> print (nexus_dev.id)
google_nexus7_ver1_suban43

>>> print (iphone_dev.id)
apple_iphone_ver9_2

They also have several different ways to retrieve their browser capabilities:

>>> print (nexus_dev.get_capability("brand_name"))
Google

>>> print (nexus_dev.get_capability("model_name"))
Nexus 7

>>> print (iphone_dev.get_capability("brand_name"))
Apple

>>> print (iphone_dev.get_capability("model_name"))
iPhone

>>> caps = nexus_dev.get_capabilities(["brand_name", "model_name"])
>>> caps == {'brand_name': 'Google', 'model_name': 'Nexus 7'}
True

>>> caps_all = nexus_dev.get_all_capabilities()
>>> all(item in caps_all.items() for item in
...     [('brand_name', 'Google'), ('model_name', 'Nexus 7')])
True

When a particular capability is not found, the API should return None as a value.

>>> print (nexus_dev.get_capability("not_a_capability"))
None

Virtual capabilities are abstracted through this API, which means they can be accessed using the exact same method calls.

>>> print (nexus_dev.get_capability("is_android"))
true

Once a device is no longer needed, it should be released to avoid memory leaks.

>>> iphone_dev.release()
>>> iphone_dev.get_all_capabilities()
Traceback (most recent call last):
AssertionError: This handle was released!

Here is an example program to get started using InFuze for Python:

from pywurfl.wurfl import Wurfl
WURFL = Wurfl("/usr/share/wurfl/wurfl.zip")

dev = WURFL.parse_useragent("Mozilla/5.0 (Linux; Android 4.4; Nexus 5 Build/KRT16M) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0 Mobile Safari/537.36")

# Get deviceid
print(dev.id)

# Get one capability
print(dev.get_capability("is_mobile"))

# Get many capabilities
print(dev.get_capabilities(["brand_name", "model_name"]))

# Get all capabilities
dev.get_all_capabilities()

# Release the device
dev.release()

WURFL Updater

If you want to keep your wurfl.zip up-to-date with the ScientiaMobile data release schedule, then you might want to use the Updater features, available in Python WURFL as follows:

After creating your WURFL engine, set your personal WURFL Snapshot URL (in the form "https://data.scientiamobile.com/xxxxx/wurfl.zip", with "xxxxx" replaced with your personal access token, located in your license account page):

try:
    WURFL.set_updater_data_url("https://data.scientiamobile.com/<your access token>/wurfl.zip")
except Exception as exception:
    print("Error while setting updater data URL: ")
    print(exception)

Optionally, specify at which frequency you want to check for updates: (DAILY or WEEKLY, default is DAILY):

WURFL.set_updater_data_frequency(wurfl.UPDATER_FREQUENCIES['DAILY'])

Then start the updater:

try:
    WURFL.updater_start()
except Exception as exception:
    print("Error while starting the updater: ")
    print(exception)

Updater will run a periodic check for the latest release of the wurfl.zip file, download it, and update the running engine to the latest version - all during normal application operations.

The internal updater also supports simple file logging, useful in debugging network problems and the like:

WURFL.set_updater_log_path("updater.log")

Please note also:

  • The WURFL data file and the path where it resides, specified in the WURFL engine construction,

    MUST
    have write/rename access: the old data file will be replaced (i.e. a rename operation will be performed) with the updated version upon successful update operation completion, and the directory will be used for temp file creation, etc.

  • ScientiaMobile does not distribute uncompressed XML data files via updater. This means that, if you plan to use the updater, you

    MUST
    use the compressed (i.e. a ZIP or a XML.GZ) data file in the engine construction call..

Please note that set_updater_data_frequency() sets how often the updater

checks
for an updated data file, not how often the engine data file is actually updated.

The WURFL InFuze Updater functionality relies on availability and features of the well-known and widely available curl command-line utility. A check for curl availability is done in the set_updater_data_url() call.

License

2017 ScientiaMobile Incorporated All Rights Reserved.

NOTICE: All information contained herein is, and remains the property of ScientiaMobile Incorporated and its suppliers, if any. The intellectual and technical concepts contained herein are proprietary to ScientiaMobile Incorporated and its suppliers and may be covered by U.S. and Foreign Patents, patents in process, and are protected by trade secret or copyright law. Dissemination of this information or reproduction of this material is strictly forbidden unless prior written permission is obtained from ScientiaMobile Incorporated.include('layouts.partials.license-footer')