\r\n

51Degrees Device Detection Python  4.3Newer Version 4.4

Device Detection services for 51Degrees Pipeline

onpremise/gettingstarted_web/app.py

This example is available in full on GitHub.

This example requires a local data file. The free 'Lite' data file can be acquired by pulling the git submodules under this repository (run `git submodule update --recursive`) or from the device-detection-data GitHub repository.

The Lite data file is only used for illustration, and has limited accuracy and capabilities. Find out about the more capable data files that are available on our pricing page

Required PyPi Dependencies:

  • fiftyone_devicedetection
  • flask

Overview

The DeviceDetectionPipelineBuilder class is used to create a Pipeline instance from the configuration that is supplied. The fiftyone_pipeline_core.web module contains helpers which deal with automatically populating evidence from a web request.

1 flowdata.evidence.add_from_dict(webevidence(request))
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 
45 
46 # The module can also handling setting response headers (e.g. Accept-CH for User-Agent
47 # Client Hints) and serving requests for client-side JavaScript and JSON resources.
48 # ```{py}
49 # set_response_header(flowdata, response)
50 # ```
51 #
52 # The results of detection can be accessed by through the flowdata object once
53 # processed. This can then be used to interrogate the data.
54 # ```{py}
55 # flowdata.process()
56 # device = flowdata.device
57 # hardware_vendor = device.hardwarevendor
58 # ```
59 #
60 # Results can also be accessed in client-side code by using the `fod` object. See the
61 # [JavaScriptBuilderElementBuilder](https://51degrees.com/pipeline-python/4.3/classpipeline-python_1_1fiftyone__pipeline__core_1_1fiftyone__pipeline__core_1_1javascriptbuilde778a9036818b19ab55d981a40be4a4d7.html)
62 # for details on available settings such as changing the `fod` name.
63 # ```{js}
64 # window.onload = function () {
65 # fod.complete(function(data) {
66 # var hardwareName = data.device.hardwarename;
67 # alert(hardwareName.join(", "));
68 # }
69 # }
70 # ```
71 #
72 # ## View
73 # @include templates/index.html
74 #
75 # ## App
76 
77 import logging
78 import sys
79 from fiftyone_devicedetection_examples.example_utils import ExampleUtils
80 from flask.helpers import make_response
81 from flask import Flask, request, render_template
82 from fiftyone_devicedetection.devicedetection_pipelinebuilder import DeviceDetectionPipelineBuilder
83 from fiftyone_pipeline_core.web import *
84 import json
85 
86 # In this example, by default, the 51degrees "Lite" file needs to be
87 # somewhere in the project space.
88 #
89 # Note that the Lite data file is only used for illustration, and has
90 # limited accuracy and capabilities.
91 # Find out about the Enterprise data file on our pricing page:
92 # https://51degrees.com/pricing
93 LITE_V_4_1_HASH = "51Degrees-LiteV4.1.hash";
94 
95 
96 class GettingStartedWeb():
97  app = Flask(__name__)
98 
99  def build(self, data_file):
100  # 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
101 
102  javascript_builder_settings = {
103  "endpoint": "/json",
104  "minify": True,
105  # The enable_cookies setting is needed if you want to work with results from client-side
106  # evidence on the server. For example, precise Apple models or screen dimensions.
107  # This will store the results of client-side detection scripts on the client as cookies.
108  # On subsequent requests, these cookies will be included in the payload and will be
109  # used by the device detection API when it runs.
110  "enable_cookies": True
111  }
112 
113  GettingStartedWeb.pipeline = DeviceDetectionPipelineBuilder(
114  data_file_path = data_file,
115  # We use the low memory profile as its performance is
116  # sufficient for this example. See the documentation for
117  # more detail on this and other configuration options:
118  # http://51degrees.com/documentation/4.3/_device_detection__features__performance_options.html
119  # http://51degrees.com/documentation/4.3/_features__automatic_datafile_updates.html
120  # http://51degrees.com/documentation/4.3/_features__usage_sharing.html
121  performance_profile = "LowMemory",
122  # inhibit sharing usage for this test, usually this
123  # should be set "true"
124  auto_update = False,
125  licence_keys = "",
126  javascript_builder_settings = javascript_builder_settings).build()
127 
128  return self
129 
130  def run(self):
131 
132  GettingStartedWeb.app.run()
133 
134  # First we make a JSON route that will be called from the client side and will return
135  # a JSON encoded property database using any additional evidence provided by the client
136 
137  @app.route('/json', methods=['POST'])
138  def jsonroute():
139 
140  # Create the flowdata object for the JSON route
141  flowdata = GettingStartedWeb.pipeline.create_flowdata()
142 
143  # Add any information from the request (headers, cookies and additional
144  # client side provided information)
145 
146  flowdata.evidence.add_from_dict(webevidence(request))
147 
148  # Process the flowdata
149 
150  flowdata.process()
151 
152  # Return the JSON from the JSONBundler engine
153 
154  return json.dumps(flowdata.jsonbundler.json)
155 
156  # In the main route we dynamically update the screen's device property display
157  # using the above JSON route
158 
159  @app.route('/')
160  def server():
161 
162  # Create the flowdata object for the JSON route
163  flowdata = GettingStartedWeb.pipeline.create_flowdata()
164 
165  # Add any information from the request (headers, cookies and additional
166  # client side provided information)
167 
168  flowdata.evidence.add_from_dict(webevidence(request))
169 
170  # Process the flowdata
171 
172  flowdata.process()
173 
174  response = make_response()
175 
176  # Some browsers require that extra HTTP headers are explicitly
177  # requested. So set whatever headers are required by the browser in
178  # order to return the evidence needed by the pipeline.
179  # More info on this can be found at
180  # https://51degrees.com/blog/user-agent-client-hints
181 
182  set_response_header(flowdata, response)
183 
184  # Generate the HTML
185  response.set_data(render_template(
186  'index.html',
187  data=flowdata,
188  utils=ExampleUtils,
189  response=response))
190 
191  return response
192 
193 def main(argv):
194  # Use the supplied path for the data file or find the lite
195  # file that is included in the repository.
196  data_file = argv[0] if len(argv) > 0 else ExampleUtils.find_file(LITE_V_4_1_HASH)
197 
198  # Configure a logger to output to the console.
199  logger = logging.getLogger("Getting Started")
200  logger.setLevel(logging.INFO)
201 
202  if (data_file != None):
203  GettingStartedWeb().build(data_file).run()
204  else:
205  logger.error("Failed to find a device detection " +
206  "data file. Make sure the device-detection-data " +
207  "submodule has been updated by running " +
208  "`git submodule update --recursive`.")
209 
210 if __name__ == "__main__":
211  main(sys.argv[1:])