Token in secret, is that correct? (newbie!)

Hello all

This is a newbie here, both in Anvil, but also in web apps.

Quickly, I am a Geologist by education, and have worked over 10 years in the oil/gas field in Norway. My last position (9 years) was Geoscience Data Manager, seismic. I left my work last summer to study full time from home (edX, Coursera), firstly Python coding and also ML and now web app. A friend recommended me to use Anvil. I also have a background in GIS and relational databases (SQL ‘general knowledge’).

Ok, I am working with a public datasets which can be pointsets (wells) or polygons (fields).

I am going to use Mapbox. I have worked with it a bit, and I really like it.

I got help from Shaun. So I understand better, but of course I have to to try myself to do stuff.

I have a token from Mapbox and I tried now to display my map with Anvil.

So I created a secret, named it ‘Mapbox_token’, and pasted my token in there.

Then in my map form (called MapBoxMap), I have the following:

<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.52.0/mapbox-gl.css' rel='stylesheet' />

<div id='mapBoxMap' style="width: 100%; height: 1000px;"></div>

<script>
  mapboxgl.accessToken = 'Mapbox_token';
  var map = new mapboxgl.Map({
    container: 'mapBoxMap',
    style: 'mapbox://styles/annee/cjqsbbdsrafaz2tpakytjdxze',
    
    center: [6.0, 70.0],
    zoom: 3
  });

  function addMarker(lng, lat) {
    var marker = new mapboxgl.Marker()
      .setLngLat([lng, lat])
      .addTo(map);
  };
</script>

My map is now blank (no error message telling me something is wrongly set).

Have I called my token the proper way in the code above?

Thanks a lot in advance for help,

Cheers
Anne

Hi Anne!

mapboxgl.accessToken expects the literal token, so let’s say your token was

pk.eyJ2Ijoic3RtLWFudmlsIiwiYSI6ImNqcXA1a2FsNTBoOHo0Mm13YjJuN3IydGQifQ.RJ3divudCfU2qoDZ8CmELh

you would use it like so:

mapboxgl.accessToken = 'pk.eyJ2Ijoic3RtLWFudmlsIiwiYSI6ImNqcXA1a2FsNTBoOHo0Mm13YjJuN3IydGQifQ.RJ3divudCfU2qoDZ8CmELh';
// ... and the rest of the inialisation code ...

But as you point out, it is more secure to store the token in a Secret. To do this, you need to pass it into the JavsScript from the Python, so your initialisation needs to go into a function:

  function initMap(token) {
    mapboxgl.accessToken = token;
    map = new mapboxgl.Map({
      container: 'mapBoxMap',
      style: 'mapbox://styles/annee/cjqsbbdsrafaz2tpakytjdxze',
      center: [6.0, 70.0],
      zoom: 3
    });
  }

This can be called from the show event of the Form using call_js:

# On the client side, in MapBoxMap

  def form_show(self, **event_args):
    """This method is called when the HTML panel is shown on the screen"""
    # Get the token from the server
    token = anvil.server.call_s('get_mapbox_token')

    # Call the JavaScript function to initialise MapBox
    self.call_js('initMap', token)

Remember to bind the form_show method to the show event on the Form! Like so:

50

That’s not the end of the story - the anvil.server.call_s is there because Secrets can only be accessed on the server side, for security reasons. So we have a server function to access the token and return it to the client:

# In a Server module

@anvil.server.callable
def get_mapbox_token():
  return anvil.secrets.get_secret('Mapbox_token')

Let me know whether you get this working, do ask more questions if anything’s not clear.

3 Likes

Thanks Shaun

Yes, I think I got it quite right, then I could compare with the updated clone you sent me, and it seems right from what I see. Still, I have this error message in the Output:

So I think there is something else which is not set up properly.

Thanks for explaining everything with a fork and a knife. I am in the process of putting the pieces together, slowly :grinning:

Cheer
Anne

1 Like

That error means the Python 3 runtime isn’t available because you’re on the free plan, but the Server Module has been set to use it.

In the Server Module, select Restricted (Python 2) and it should work fine.

(The function that subsamples the data uses random.choices, which is only available in Python 3, but this has already been run so you don’t really need to run it again. Also, you could rewrite this function not to need random.choices.)

1 Like

Yes cool that is working now!

Ok there are one more thing for now:

What is the form ‘MapBoxLib’ form for?
And where on Earth did you get all the HTML code which is in there from?

I am going to present shortly next week the work I am doing now with Anvil. It’s about data integration.
It’s just a couple of slides in a presentation that a company here in Stavanger is organising. Let me know if it is ok that I show a screenshot with the anvil logo on it?

Next step in the app is to add again the map with the well markers.
Then I will have one layer with the discovery fields and one with the well. I can use the menus on the left for that.
I will change to the NPD dataset ‘exploration’, which has only exploration wells.

We have beautiful sunshine here today, so I’ll go for a walk now :slight_smile:

Thanks for all the help, really! :+1:

Snakkes (talk to you later in Norwegian)

1 Like

Hope you enjoyed your walk - it’s snowing here in the UK, we’re not used to it over here!

What is the form ‘MapBoxLib’ form for?
And where on Earth did you get all the HTML code which is in there from?

That’s the Mapbox GL library, and I had included it as a CustomHTML Form.

The good news is, we’ve just added a feature that lets you depend on external JavaScript APIs more elegantly. Look for Native Libraries under Theme. It allows you to add <script> tags to pull in Javascript libraries from external sources.

So for Mapbox GL, you would put these lines in there (following the Mapbox Quickstart):

<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.52.0/mapbox-gl.js'></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.52.0/mapbox-gl.css' rel='stylesheet' />

Here’s a version of the Oil Wells app that has the MapBoxLib component replaced with those two lines in Native Libraries:

2 Likes

Hello Shaun and thanks for your help. I am in the middle of a ML class on Coursera, it’s a bit intensive for me, but it I should be finished with it in a couple of weeks. Then I can come back to Anvil.

It’s great to see that it is constantly evolving and having new features. It sounds great with Native Libraries!

Cheers :slight_smile:
Anne

1 Like