51Degrees Device Detection Python  4.2

Device Detection services for 51Degrees Pipeline

hash/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_onpremise.devicedetection_onpremise_pipelinebuilder import DeviceDetectionOnPremisePipelineBuilder
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 data_file = "../../fiftyone_devicedetection_onpremise/device-detection-cxx/device-detection-data/51Degrees-LiteV4.1.hash"
37 
38 # 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
39 
40 javascript_builder_settings = {
41  "endpoint": "/json"
42 }
43 
44 pipeline = DeviceDetectionOnPremisePipelineBuilder(
45  data_file_path = data_file,
46  licence_keys = "",
47  performance_profile = 'MaxPerformance',
48  update_on_start=False,
49  javascript_builder_settings=javascript_builder_settings).build()
50 
51 from flask import Flask, request
52 
53 app = Flask(__name__)
54 
55 # First we make a JSON route that will be called from the client side and will
56 # return a JSON encoded property database using any additional evidence provided
57 # by the client
58 
59 @app.route('/json', methods=['POST'])
60 def jsonroute():
61 
62  # Create the flowdata object for the JSON route
63  flowdata = pipeline.create_flowdata()
64 
65  # Add any information from the request (headers, cookies and additional
66  # client side provided information)
67 
68  flowdata.evidence.add_from_dict(webevidence(request))
69 
70  # Process the flowdata
71 
72  flowdata.process()
73 
74  # Return the JSON from the JSONBundler engine
75 
76  return json.dumps(flowdata.jsonbundler.json)
77 
78 # Helper function to get a property value if it exists and return
79 # the reason why if it doesn't
80 def get_value_helper(flowdata, engine, property_key):
81 
82  engine_properties = getattr(flowdata, engine)
83 
84  try:
85  property_value = getattr(engine_properties, property_key)
86 
87  if property_value.has_value():
88  return property_value.value()
89  else:
90  return property_value.no_value_message()
91  except:
92  return "Not found in datafile"
93 
94 # In the main route we dynamically update the screen's device property display
95 # using the above JSON route
96 
97 @app.route('/')
98 def server():
99 
100  # Create the flowdata object for the JSON route
101  flowdata = pipeline.create_flowdata()
102 
103  # Add any information from the request (headers, cookies and additional
104  # client side provided information)
105 
106  flowdata.evidence.add_from_dict(webevidence(request))
107 
108  # Process the flowdata
109 
110  flowdata.process()
111 
112  # Generate the HTML
113 
114  output = "<h1>Client side evidence</h1>"
115 
116  # Add the JavaScript created by the pipeline
117  output += "<script>"
118  output += flowdata.javascriptbuilder.javascript
119  output += "</script>"
120 
121  # Print results from server side processing
122  output += "<p><b>The following values are determined by sever-side device"
123  "detection on the first request:</b></p>"
124 
125  output += "<b>Hardware Name:</b> " + str(get_value_helper(flowdata, "device", "hardwarename"))
126  output += "<br />"
127  output += "<b>Screen width (pixels):</b> " + str(get_value_helper(flowdata, "device", "screenpixelswidth"))
128  output += "<br />"
129  output += "<b>Screen height (pixels):</b> " + str(get_value_helper(flowdata, "device", "screenpixelsheight"))
130 
131 
132  output += """
133 
134  <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>
135 
136  <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>
137 
138  <p id=hardwarename></p>
139  <p id=screenpixelwidth></p>
140  <p id=screenpixelheight></p>
141  <script>
142  window.onload = function(){
143  fod.complete(function (data) {
144  if(data.device["hardwarename"]){
145  document.getElementById('hardwarename').innerHTML = "<strong>Updated Hardware Name from client-side evidence:</strong> " + data.device["hardwarename"];
146  }
147  document.getElementById('screenpixelwidth').innerHTML = "<strong>Screen width (pixels): " + data.device.screenpixelswidth + "</strong>"
148  document.getElementById('screenpixelheight').innerHTML = "<strong>Screen height (pixels): " + data.device.screenpixelsheight + "</strong>"
149  });
150  }
151  </script>
152  """
153 
154  return output