Skip to main content

Generic Python framework for mobile user agent detection

Project description

Introduction

mobile.sniffer is Python framework for abstracting mobile handset databases.

When rendering web pages for mobile phones one must deal with varying handset features: different screen sizes and shapes, different supported file formats, different sets of web browser features. Information about mobile phones is collected to databases and there are several databases available (Wurfl, DeviceAtlas, etc). mobile.sniffer framework aims to provide generic interface that you can easily plug-in different mobile handset databases without need to change your code.

Features

  • Able to source data from multiple sniffing backends leading better handset coverage

  • Automatically download, parse and cache complex RDF based WAP profiles

  • Very convenient Python API designed by professionals

  • Open source

  • Unit test coverage

The library is Django, WSGI and Zope/Plone compatible.

Supported sniffing backends

  • Wurfl

  • ApexVertex. Commercially available from mFabrik.

  • DeviceAtlas. Commercially available.

  • WAP profiles. User agents post a link to their WAP profile data, which is an XML file and maintained by the handset manufacturer. (note: as WAP is deprecating protocol these are not supported on newer smartphones)

Installation

mobile.sniffer is distributed as Python egg in PyPi repository. The usual method to install Python eggs is easy_install command.

Simple (Unix version):

sudo easy_install mobile.sniffer

Dependencies

You might need to install additional libraries depending on what handset database you use

Usage examples

There is no single standard to name properties queried from the handset database. For legacy reasons, we use DeviceAtlas database column names (keys) and then map them to database-dependent keys.

Simple example

This example will work out of the box with the included pywurlf database.

Example:

try:
    from mobile.sniffer.wurlf.sniffer import WurlfSniffer

    # Wrapper sniffer instance
    # All start-up delay goes on this line
    sniffer = WurlfSniffer()
except ImportError, e:
    import traceback
    traceback.print_exc()
    logger.exception(e)
    logger.error("Could not import Wurlf sniffer... add pywurfl and python-Lehvenstein to buildout.cfg eggs section")
    sniffer = None

def sniff_request(request):
    """
    @param request: Request can be Django, WSGI or Zope HTTPRequest object
    """

    if not sniffer:
        # We failed to initialize Wurfl
        return None

    user_agent = sniffer.sniff(request)

    if user_agent == None:
        # No match in the handset database,
        return None
    else:
        return user_agent # mobile.sniffer.wurlf.sniffer.UserAgent object


def web_or_mobile(request)
        ua = sniff_request(request)

        # How certain we must be about UA
        # match to make decisions
        # float 0...1, the actual value is UA search algorithm specific
        # We use JaroWinkler as the default algorithm
        certainty_threshold = 0.7

        if ua.get("is_wireless_device") and ua.getCertainty() > certainty_threshold:
                # Mobile code
                pass
        else:
                # Webby code
                pass

Match-making process for Wurfl

Since Wurfl is the default backend the process of finding UA record is explained more carefully

  • Wurlf database is usually loaded during the start-up (slow operation) - it is possible to make this to use lazy initialization pattern

  • The search algorithm is initialized with certain match threshold - all matches below this threshold will be ignored. The default search algorithm is JaroWinkler from Lehvenstein Python package.

  • When the user agent is searched

    • Take in HTTP request User-Agent header

    • Go through all entries in database

    • Match this entry against incoming User-Agent using the search algorithm

      • First search pass is doing using exact string matches (no algorithm involved). In this case exposed certainty will be 1.1.

      • If there was no match in the first pass, do the second pass using the search algorithm

    • If match is found and threshold is exceed return this user agent record

      • User agent record is retrofitted with the information how accurate the match was (ua.getCertainty() method exposes this)

Chained example

Use all available handset information sources to accurately get device data. Matching is done on property level - if one data source lacks the property information the next data source is tried. Finally if the handset is unknown, but it publishes WAP profile information, the profile is downloaded and analyzed and saved for further requests.

Example:

from mobile.sniffer.chain import ChainedSniffer
from mobile.sniffer.apexvertex.sniffer import ApexVertexSniffer
from mobile.sniffer.wapprofile.sniffer import WAPProfileSniffer
from mobile.sniffer.deviceatlas.sniffer import DeviceAtlasSniffer

# Create all supported sniffers
da = DeviceAtlasSniffer(da_api_file)
apex = ApexVertexSniffer()
wap = WAPProfileSniffer()

# Preferred order of sniffers
sniffer = ChainedSniffer([apex, da, wap])

ua = sniffer.sniff(request) # Sniff HTTP_USER_AGENT, HTTP_PROFILE and many other fields
property = ua.get("usableDisplayWidth") # This will look up data from all the databases in the chain

Automatic database installers

Proprietary handset databases do not publicly distribute their APIs or data. mobile.sniffer deals with the problem by automatic installation wrappers. Also, these handset database APIs are not open source compatible which makes it further difficult to use them in open source projects. Instead of manually download and set up bunch of files each time you deploy your code on a new server, just make call to one magical Python function which will take care of all of this for you.

Source code

Source code is available via Google Code.

Beta software

This software is still in much development and aimed for advanced Python developers only.

Author

mFabrik Research Oy - Python and Plone professionals for hire.

Changelog

0.1

  • Initial release

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mobile.sniffer-0.1dev-r63.tar.gz (727.5 kB view details)

Uploaded Source

File details

Details for the file mobile.sniffer-0.1dev-r63.tar.gz.

File metadata

File hashes

Hashes for mobile.sniffer-0.1dev-r63.tar.gz
Algorithm Hash digest
SHA256 0d2afae8fb01e8c9079332a5db3c74431b52d8b569912e8e8fb5d9cba773fcac
MD5 fe9c87a9c260a7312697a72c066268b5
BLAKE2b-256 ec58a9698cb3ed726a4224b8d546997618b019f7ff538fa016c48b0856d8481b

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page