51Degrees Location Python  4.1Newer Version 4.2

Reverse Geo-Location 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 
28 
29 from fiftyone_location.location_pipelinebuilder import LocationPipelineBuilder
30 from fiftyone_pipeline_core.web import webevidence
31 import json
32 
33 # First create the location pipeline with the desired settings.
34 
35 # You need to create a resource key at https://configure.51degrees.com
36 # and paste it into the code, replacing !!YOUR_RESOURCE_KEY!! below.
37 
38 resourceKey = "!!YOUR_RESOURCE_KEY!!"
39 
40 if resourceKey == "!!YOUR_RESOURCE_KEY!!":
41  print("""
42  You need to create a resource key at
43  https://configure.51degrees.com and paste it into the code,
44  'replacing !!YOUR_RESOURCE_KEY!!
45  To get a resourcekey with the properties used in this example go to https://configure.51degrees.com/GCrtGh1L
46  """)
47 else:
48 
49  # 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
50 
51  javascriptBuilderSettings = {
52  "endpoint": "/json"
53  }
54 
55  pipeline = LocationPipelineBuilder({"resourceKey": resourceKey, "javascriptBuilderSettings": javascriptBuilderSettings}).build()
56 
57  from flask import Flask, request
58 
59  app = Flask(__name__)
60 
61  # First we make a JSON route that will be called from the client side and will return
62  # a JSON encoded property database using any additional evidence provided by the client
63 
64  @app.route('/json', methods=['POST'])
65  def jsonroute():
66 
67  # Create the flowData object for the JSON route
68  flowData = pipeline.create_flowdata()
69 
70  # Add any information from the request (headers, cookies and additional
71  # client side provided information)
72 
73  flowData.evidence.add_from_dict(webevidence(request))
74 
75  # Process the flowData
76  flowData.process()
77 
78  # Return the JSON from the JSONBundler engine
79  return json.dumps(flowData.jsonbundler.json)
80 
81  # Helper function to get a property value if it exists and return
82  # the reason why if it doesn't
83  def getValueHelper(flowdata, engine, propertyKey):
84 
85  engineProperties = getattr(flowdata, engine)
86 
87  propertyValue = getattr(engineProperties, propertyKey)
88 
89  if propertyValue.hasValue():
90  return propertyValue.value()
91  else:
92  return propertyValue.no_value_message()
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  output = ""
114 
115  # Add the JavaScript created by the pipeline
116  output += "<script>"
117  output += flowData.javascriptbuilder.javascript
118  output += "</script>"
119 
120 
121  output += "<h1>Client side evidence</h1>"
122 
123  # Print a button which gets the user's location information
124  # This is then sent to the previously specified json endpoint
125  # Data comes back from the request and populates the country in the HTML
126 
127  output += """
128 
129  <p>After you select the "use my location" button below, client side JavaScript will
130  update the country field using this information.</p>
131 
132  <p>Country: <span id=country></span></p>
133 
134  <button type="button" onclick="getLocation()">Use my location</button>
135 
136  <script>
137 
138  let getLocation = function() {
139  fod.complete(function (data) {
140  document.getElementById("country").innerHTML = data.location.country
141  }, 'location');
142  }
143 
144  </script>
145 
146 
147  """
148 
149  return output