\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:

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 2023 51 Degrees Mobile Experts Limited, Davidson House,
4 # Forbury Square, Reading, Berkshire, United Kingdom RG1 3EU.
5 #
6 # This Original Work is licensed under the European Union Public Licence
7 # (EUPL) 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 
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 webevidence, set_response_header
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  @staticmethod
116  @app.route('/json', methods=['POST'])
117  def jsonroute():
118 
119  # Create the flowdata object for the JSON route
120  flowdata = GettingStartedWeb.pipeline.create_flowdata()
121 
122  # Add any information from the request (headers, cookies and additional
123  # client side provided information)
124 
125  flowdata.evidence.add_from_dict(webevidence(request))
126 
127  # Process the flowdata
128 
129  flowdata.process()
130 
131  # Return the JSON from the JSONBundler engine
132 
133  return json.dumps(flowdata.jsonbundler.json)
134 
135  # In the main route we dynamically update the screen's device property display
136  # using the above JSON route
137 
138  @staticmethod
139  @app.route('/')
140  def server():
141 
142  # Create the flowdata object for the JSON route
143  flowdata = GettingStartedWeb.pipeline.create_flowdata()
144 
145  # Add any information from the request (headers, cookies and additional
146  # client side provided information)
147 
148  flowdata.evidence.add_from_dict(webevidence(request))
149 
150  # Process the flowdata
151 
152  flowdata.process()
153 
154  response = make_response()
155 
156  # Some browsers require that extra HTTP headers are explicitly
157  # requested. So set whatever headers are required by the browser in
158  # order to return the evidence needed by the pipeline.
159  # More info on this can be found at
160  # https://51degrees.com/blog/user-agent-client-hints
161 
162  set_response_header(flowdata, response)
163 
164  # Generate the HTML
165  response.set_data(render_template(
166  'index.html',
167  data=flowdata,
168  utils=ExampleUtils,
169  response=response))
170 
171  return response
172 
173 def main(argv):
174  # Use the command line args to get the resource key if present.
175  # Otherwise, get it from the environment variable.
176  resource_key = argv[0] if len(argv) > 0 else ExampleUtils.get_resource_key()
177 
178  # Configure a logger to output to the console.
179  logger = Logger(min_level="info")
180 
181  if (resource_key):
182  GettingStartedWeb().build(resource_key, logger).run()
183 
184  else:
185  logger.log("error",
186  "No resource key specified in environment variable " +
187  f"'{ExampleUtils.RESOURCE_KEY_ENV_VAR}'. The 51Degrees " +
188  "cloud service is accessed using a 'ResourceKey'. " +
189  "For more detail see " +
190  "http://51degrees.com/documentation/4.3/_info__resource_keys.html. " +
191  "A resource key with the properties required by this " +
192  "example can be created for free at " +
193  "https://configure.51degrees.com/g3gMZdPY. " +
194  "Once complete, populated the environment variable " +
195  "mentioned at the start of this message with the key.")
196 
197 if __name__ == "__main__":
198  main(sys.argv[1:])