How to integrate Matomo? (something like google analytics)

Hi Guys,

I run a bokeh app behind a bokeh server and want to integrate now Matomo with the following script tag:

<!-- Matomo -->
<script type="text/javascript">
  console.log("I'm fireing!")
  var _paq = window._paq || [];
  /* tracker methods like "setCustomDimension" should be called before "trackPageView" */
  _paq.push(['trackPageView']);
  _paq.push(['enableLinkTracking']);
  (function() {
    var u="//someurl/matomo/";
    _paq.push(['setTrackerUrl', u+'piwik.php']);
    _paq.push(['setSiteId', '123']);
    var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
    g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s);
  })();
</script>
<!-- End Matomo Code -->

Unfortunately I don’t know how to do it.
So far I tried:

  • using a div widget with the javascript code but it seems like this is really only possible for markups
  • creating an index.html file included the script aforementioned script tag in the app dir in a templates folder. Since bokeh server is part of another 3rd Party App here, I can now at no means change the startup command to include --show

I’m running out of ideas. Any help is higly appreciated.

Best,
Alex

You can set

curdoc().template = some_jinja_template

To specify your own HTML template with whatever additional content you need. The default template (that you can use for comparison, or extend) is bokeh.core.templates.FILE

Thanks Bryan for your reply.

Unfortunately with your hint I still don’t get it to work.
curdoc().template = some_jinja_template

how should the some_jinja_template look like? I tried to reference an existing html in the current workdir as well as the content directly within “”" “”".

I tried to use core template file and included the script. I tried to just extend it and compare it with various other templates from the bokeh examples also using templates but all without success.

It only works for me when I use --show in my local environment where I have the control over the startup command, but not in the production environment which always starts without it.

Do you have any further hint for me?

@Alexander there is no way --show has any effect one way or the other. Literally all it does is cause a call to webbrowser.open(...) to the App URL so that you don’t have to do it manually. It’s for sure a red-herring.

I can’t really offer any concrete advice without more information. What does “don’t get it to work” actually mean? No output at all? Some output but not what you expect? How is it different? Errors in the server logs? Or in the browser JS console? What exactly are you using to set as the template value? You need to be much more detailed and precise about what is happening, and what you have tried.

Sorry for the vagueness Bryan.
Indeed it was a red-herring. The --show parameter and a working solution was just a coincidence as this were the trials where I executed the bokeh serve command outside of the project dir.

And this is also my issue.
I have provided some example code here https://github.com/AlexHiesch/Bokeh_Matomo

It all depends how bokeh serves is getting called:

  1. inside of the project dir with bokeh serve will end up with a blank page, no index.html was loaded and thus also not the required javascript call for Matomo

  2. Pointing directly to the python file with bokeh serve main.py will result in a new route named main: so instead of http://localhost:5006 it’s http://localhost:5006/main again without the html template
    There’s also a warning literally stating this: `UserWarning:
    It looks like you might be running the main.py of a directory app directly.
    If this is the case, to enable the features of directory style apps, you must
    call “bokeh serve” on the directory instead. For example:

    bokeh serve my_app_dir/

If this is not the case, renaming main.py will suppress this warning.`

  1. Pointing to the project dir with bokeh serve Bokeh_Matomo. Bingo! Everything works as expected. Html file was loaded, javascript was tried to get as well.

But here come’s the point. I don’t have any influence how bokeh serve is getting executed. I use a 3rd Party Tool here called Dataiku (Analytics Workbench) which offers to create Dashboards with bokeh server as a backend. By default it starts with /somepath/python/myenv/bin/python -u -m bokeh serve /projects/myproject/main.py --port 33626 --allow-websocket-origin * which I cannot change.

I hope this was more clearer now. And I also hope your answer won’t be now

Nope, there’s nothing we can do about it.

I think unfortunately you will have to take this up with Dataiku. The templates directory is a feature of [“directory-style” apps’*http://docs.bokeh.org/en/latest/docs/user_guide/server.html#directory-format). If their (and your) intent is to start a “directory-style” app, which is what has easy support for templates, static dirs, etc, then bokeh serve needs to be called with the directory, not with main.py.

Otherwise, all I can suggest is to pass an actual Jinja2 Template object as the value of curdoc().template and not a filename. The filename is only usable by a directory-style app.

Eureka!
After struggling some time I finally got it.
I was totally confused with the concept of FileSystemLoader, PackageLoader, Jinja2 Templates, FILE and its extensibility but the persistence and your great help Bryan paid finally off!

In case anyone else wanders around in the dark, I have put my final solution on github. There’s the option with the custom html outsouced in a dedicated file and commented out the option for an inline approach:

I hope it can help anyone.

Thanks a lot Bryan!

1 Like