\r\n

51Degrees Device Detection Python  4.4

Device Detection services for 51Degrees Pipeline

cloud/gettingstarted_web/app.py

This example is available in full on GitHub.

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.

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 from fiftyone_devicedetection_examples.example_utils import ExampleUtils
78 from flask import Flask, request, render_template
79 from flask.helpers import make_response
80 from fiftyone_devicedetection.devicedetection_pipelinebuilder import DeviceDetectionPipelineBuilder
81 from fiftyone_pipeline_core.logger import Logger
82 from fiftyone_pipeline_core.web import *
83 import json
84 import sys
85 
86 class GettingStartedWeb():
87  app = Flask(__name__)
88 
89  def build(self, resource_key, logger):
90  # 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
91 
92  javascript_builder_settings = {
93  "endpoint": "/json",
94  "minify": True,
95  # The enable_cookies setting is needed if you want to work with results from client-side
96  # evidence on the server. For example, precise Apple models or screen dimensions.
97  # This will store the results of client-side detection scripts on the client as cookies.
98  # On subsequent requests, these cookies will be included in the payload and will be
99  # used by the device detection API when it runs.
100  "enable_cookies": True
101  }
102  GettingStartedWeb.pipeline = DeviceDetectionPipelineBuilder(
103  resource_key = resource_key,
104  javascript_builder_settings = javascript_builder_settings).add_logger(logger).build()
105 
106  return self
107 
108  def run(self):
109 
110  GettingStartedWeb.app.run()
111 
112  # First we make a JSON route that will be called from the client side and will return
113  # a JSON encoded property database using any additional evidence provided by the client
114 
115  @app.route('/json', methods=['POST'])
116  def jsonroute():
117 
118  # Create the flowdata object for the JSON route
119  flowdata = GettingStartedWeb.pipeline.create_flowdata()
120 
121  # Add any information from the request (headers, cookies and additional
122  # client side provided information)
123 
124  flowdata.evidence.add_from_dict(webevidence(request))
125 
126  # Process the flowdata
127 
128  flowdata.process()
129 
130  # Return the JSON from the JSONBundler engine
131 
132  return json.dumps(flowdata.jsonbundler.json)
133 
134  # In the main route we dynamically update the screen's device property display
135  # using the above JSON route
136 
137  @app.route('/')
138  def server():
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  response = make_response()
153 
154  # Some browsers require that extra HTTP headers are explicitly
155  # requested. So set whatever headers are required by the browser in
156  # order to return the evidence needed by the pipeline.
157  # More info on this can be found at
158  # https://51degrees.com/blog/user-agent-client-hints
159 
160  set_response_header(flowdata, response)
161 
162  # Generate the HTML
163  response.set_data(render_template(
164  'index.html',
165  data=flowdata,
166  utils=ExampleUtils,
167  response=response))
168 
169  return response
170 
171 def main(argv):
172  # Use the command line args to get the resource key if present.
173  # Otherwise, get it from the environment variable.
174  resource_key = argv[0] if len(argv) > 0 else ExampleUtils.get_resource_key()
175 
176  # Configure a logger to output to the console.
177  logger = Logger(min_level="info")
178 
179  if (resource_key):
180  GettingStartedWeb().build(resource_key, logger).run()
181 
182  else:
183  logger.log("error",
184  "No resource key specified in environment variable " +
185  f"'{ExampleUtils.RESOURCE_KEY_ENV_VAR}'. The 51Degrees " +
186  "cloud service is accessed using a 'ResourceKey'. " +
187  "For more detail see " +
188  "http://51degrees.com/documentation/4.3/_info__resource_keys.html. " +
189  "A resource key with the properties required by this " +
190  "example can be created for free at " +
191  "https://configure.51degrees.com/g3gMZdPY. " +
192  "Once complete, populated the environment variable " +
193  "mentioned at the start of this message with the key.")
194 
195 if __name__ == "__main__":
196  main(sys.argv[1:])