51Degrees Device Detection Python  4.2

Device Detection services for 51Degrees Pipeline

cloud/web.py

This example demonstrates how to enhance results by incorporating evidence from client-side JavaScript. This approach is required to perform certain tasks such as identify iPhone and iPad models or get the screen resolution for a desktop device.

Properties containing JavaScript snippets are populated by engines in the Pipeline and these are then bundled together into a single JavaScript block by the 'JsonBuilder' and 'JavaScriptBuilder' elements. This JavaScript is then used to obtain the additional evidence from the client and pass it back to the server. The updated results can then be used immediately on the client-side or on subsequent requests to the server.

To run this example, you will need to create a resource key. The resource key is used as shorthand to store the particular set of properties you are interested in as well as any associated license keys that entitle you to increased request limits and/or paid-for properties.

You can create a resource key using the 51Degrees Configurator.

1 # *********************************************************************
2 # This Original Work is copyright of 51 Degrees Mobile Experts Limited.
3 # Copyright 2019 51 Degrees Mobile Experts Limited, 5 Charlotte Close,
4 # Caversham, Reading, Berkshire, United Kingdom RG4 7BY.
5 #
6 # This Original Work is licensed under the European Union Public Licence (EUPL)
7 # v.1.2 and is subject to its terms as set out below.
8 #
9 # If a copy of the EUPL was not distributed with this file, You can obtain
10 # one at https://opensource.org/licenses/EUPL-1.2.
11 #
12 # The 'Compatible Licences' set out in the Appendix to the EUPL (as may be
13 # amended by the European Commission) shall be deemed incompatible for
14 # the purposes of the Work and the provisions of the compatibility
15 # clause in Article 5 of the EUPL shall not apply.
16 #
17 # If using the Work as, or as part of, a network application, by
18 # including the attribution notice(s) required under Article 5 of the EUPL
19 # in the end user terms of the application under an appropriate heading,
20 # such notice(s) shall fulfill the requirements of that article.
21 # ********************************************************************
22 
23 
24 
29 
30 from fiftyone_devicedetection_cloud.devicedetection_cloud_pipelinebuilder import DeviceDetectionCloudPipelineBuilder
31 from fiftyone_pipeline_core.web import webevidence
32 import json
33 
34 # First create the device detection pipeline with the desired settings.
35 
36 # You need to create a resource key at https://configure.51degrees.com
37 # and paste it into the code, replacing !!YOUR_RESOURCE_KEY!! below.
38 # Alternatively, add a resource_key environment variable
39 import os
40 if "resource_key" in os.environ:
41  resource_key = os.environ["resource_key"]
42 else:
43  resource_key = "!!YOUR_RESOURCE_KEY!!"
44 
45 if resource_key == "!!YOUR_RESOURCE_KEY!!":
46  print("""
47  You need to create a resource key at
48  https://configure.51degrees.com and paste it into the code,
49  'replacing !!YOUR_RESOURCE_KEY!!
50  make sure to include the HardwareName, HardwareProfile and HardwareVendor, DeviceType,
51  PlatformVendor, PlatformName, BrowserVendor, BrowserName, BrowserVersion, ScreenWidth
52  and ScreenHeight properties used by this example
53  """)
54 else:
55 
56  # Here we add some callback settings for the page to make a request with extra evidence from the client side, in this case the Flask /json route we will make below
57 
58  javascript_builder_settings = {
59  "endpoint": "/json"
60  }
61 
62  pipeline = DeviceDetectionCloudPipelineBuilder({
63  "resource_key": resource_key,
64  "javascript_builder_settings": javascript_builder_settings
65  }).build()
66 
67  from flask import Flask, request
68 
69  app = Flask(__name__)
70 
71  # First we make a JSON route that will be called from the client side and will return
72  # a JSON encoded property database using any additional evidence provided by the client
73 
74  @app.route('/json', methods=['POST'])
75  def jsonroute():
76 
77  # Create the flowdata object for the JSON route
78  flowdata = pipeline.create_flowdata()
79 
80  # Add any information from the request (headers, cookies and additional
81  # client side provided information)
82 
83  flowdata.evidence.add_from_dict(webevidence(request))
84 
85  # Process the flowdata
86 
87  flowdata.process()
88 
89  # Return the JSON from the JSONBundler engine
90 
91  return json.dumps(flowdata.jsonbundler.json)
92 
93  # Helper function to get a property value if it exists and return
94  # the reason why if it doesn't
95  def get_value_helper(flowdata, engine, property_key):
96 
97  engine_properties = getattr(flowdata, engine)
98 
99  property_value = getattr(engine_properties, property_key)
100 
101  if property_value.has_value():
102  return property_value.value()
103  else:
104  return property_value.no_value_message()
105 
106  # In the main route we dynamically update the screen's device property display
107  # using the above JSON route
108 
109  @app.route('/')
110  def server():
111 
112  # Create the flowdata object for the JSON route
113  flowdata = pipeline.create_flowdata()
114 
115  # Add any information from the request (headers, cookies and additional
116  # client side provided information)
117 
118  flowdata.evidence.add_from_dict(webevidence(request))
119 
120  # Process the flowdata
121 
122  flowdata.process()
123 
124  # Generate the HTML
125 
126  output = "<h1>Client side evidence</h1>"
127 
128  # Add the JavaScript created by the pipeline
129  output += "<script>"
130  output += flowdata.javascriptbuilder.javascript
131  output += "</script>"
132 
133  # Print results from server side processing
134  output += "<p><b>The following values are determined by sever-side device detection on the first request:</b></p>"
135 
136  output += "<b>Hardware Vendor:</b> " + get_value_helper(flowdata, "device", "hardwarevendor")
137  output += "<br />"
138  output += "<b>Hardware Name:</b> " + str(get_value_helper(flowdata, "device", "hardwarename"))
139  output += "<br />"
140  output += "<b>Device Type:</b> " + get_value_helper(flowdata, "device", "devicetype")
141  output += "<br />"
142  output += "<b>Platform Vendor:</b> " + get_value_helper(flowdata, "device", "platformvendor")
143  output += "<br />"
144  output += "<b>Platform Name:</b> " + get_value_helper(flowdata, "device", "platformname")
145  output += "<br />"
146  output += "<b>Browser Vendor:</b> " + get_value_helper(flowdata, "device", "browservendor")
147  output += "<br />"
148  output += "<b>Browser Name:</b> " + get_value_helper(flowdata, "device", "browsername")
149  output += "<br />"
150  output += "<b>Browser Version:</b> " + get_value_helper(flowdata, "device", "browserversion")
151  output += "<br />"
152  output += "<b>Screen width (pixels):</b> " + str(get_value_helper(flowdata, "device", "screenpixelswidth"))
153  output += "<br />"
154  output += "<b>Screen height (pixels):</b> " + str(get_value_helper(flowdata, "device", "screenpixelsheight"))
155 
156 
157  output += """
158 
159  <p>The information shown below is determined from JavaScript running on the client-side that is able to obtain additional evidence. If no additional information appears then it may indicate an external problem such as JavaScript being disabled in your browser.</p>
160 
161  <p>Note that the 'Hardware Name' field is intended to illustrate detection of Apple device models as this cannot be determined server-side. This can be tested to some extent using most emulators such as those in the 'developer tools' menu in Google Chrome. However, using real devices will result in more precise model numbers.</p>
162 
163  <p id=hardwarename></p>
164  <p id=screenpixelwidth></p>
165  <p id=screenpixelheight></p>
166  <script>
167  window.onload = function(){
168  fod.complete(function (data) {
169  if(data.device["hardwarename"]){
170  document.getElementById('hardwarename').innerHTML = "<strong>Updated Hardware Name from client-side evidence:</strong> " + data.device["hardwarename"];
171  }
172  document.getElementById('screenpixelwidth').innerHTML = "<strong>Screen width (pixels): " + data.device.screenpixelswidth + "</strong>"
173  document.getElementById('screenpixelheight').innerHTML = "<strong>Screen height (pixels): " + data.device.screenpixelsheight + "</strong>"
174  });
175  }
176  </script>
177  """
178 
179  return output