Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

show_in_browser() method for folium.folium.Map #953

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 110 additions & 0 deletions folium/_server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# -*- coding: utf-8 -*-

"""
Simple HTTP server so we are able to show Maps in browser.
"""

import sys
if sys.version_info[0] >= 3:
from http.server import BaseHTTPRequestHandler, HTTPServer
else:
from SimpleHTTPServer import SimpleHTTPRequestHandler as BaseHTTPRequestHandler
from SocketServer import TCPServer as HTTPServer

import webbrowser

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

E402 module level import not at top of file

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that seems to be the case for most of the other files in the repo, so I chose consistency over purity.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

E402 module level import not at top of file

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as before this seems to be a convention in the repo

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

E402 module level import not at top of file

from textwrap import dedent

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

E402 module level import not at top of file

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that seems to be the case for most of the other files in the repo, so I chose consistency over purity.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please follow the liner cues here. We are cleaning up the code and new code should be compliant from the start.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

E402 module level import not at top of file

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as before this seems to be a convention in the repo

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

E402 module level import not at top of file



# Based on https://stackoverflow.com/a/38945907/3494126
class TemporaryHTTPServer:
"""
A simple, temporary http web server on the pure Python 3.

Parameters
----------
host: str
Local address on which the page will be hosted, default is '127.0.0.1'
port: int
Corresponding port, default 7000
"""
def __init__(self, host=None, port=None):
self.host = host or '127.0.0.1'
self.port = port or 7000

self.server_address = '{host}:{port}'.format(host=self.host, port=self.port)
self.full_server_address = 'http://' + self.server_address

def serve(self, html_data):
"""
Serve html content in a suitable for us manner: allow to gracefully exit using ctrl+c and re-serve some other
content on the same host:port
"""

# we need a request handler with a method `do_GET` which somehow is not provided in the baseline
class HTTPServerRequestHandler(BaseHTTPRequestHandler):

def do_GET(self):
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
if sys.version_info[0] >= 3:
self.wfile.write(bytes(html_data, encoding='utf'))
else:
self.wfile.write(bytes(html_data))

return

# run a temporary server
HTTPServer.allow_reuse_address = True
httpd = HTTPServer((self.host, self.port), HTTPServerRequestHandler)

try:
httpd.serve_forever()
except KeyboardInterrupt:
print('\n Closing the server.')
httpd.server_close()
except Exception:
raise

def open_html_in_browser(self, html_data=None):
"""
Opens a browser window showing the html content

Parameters
----------
html_data: str
Should be a valid html code

Examples
--------

Demetrio92 marked this conversation as resolved.
Show resolved Hide resolved
html_data = '''
<!DOCTYPE html>
<html>
<head>
<title> Test Page </title>
</head>
<body>
<p> Seems to be working. Now give the function `open_html_in_browser` some content! </p>
</body>
</html>
'''

srvr = TemporaryHTTPServer()
srvr.open_html_in_browser(html_data)

"""

# open the URL in a browser (if possible, in a new window)
webbrowser.open(self.full_server_address, new=2)

# print a user-friendly message
msg = '''
Your map is available at {link}.
Demetrio92 marked this conversation as resolved.
Show resolved Hide resolved
It should have been opened in your browser automatically.
Press ctrl+c to return.
'''.format(link=self.full_server_address)
print(dedent(msg))

# run server (this blocks the console!)
self.serve(html_data)
34 changes: 34 additions & 0 deletions folium/folium.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import os
import tempfile
import time
import sys
Demetrio92 marked this conversation as resolved.
Show resolved Hide resolved
Demetrio92 marked this conversation as resolved.
Show resolved Hide resolved

from branca.colormap import StepColormap
from branca.element import CssLink, Element, Figure, JavascriptLink, MacroElement
Expand All @@ -19,6 +20,7 @@
from folium.map import FitBounds
from folium.raster_layers import TileLayer
from folium.utilities import _validate_location
from folium._server import TemporaryHTTPServer

from jinja2 import Environment, PackageLoader, Template

Expand Down Expand Up @@ -387,6 +389,38 @@ def render(self, **kwargs):

super(Map, self).render(**kwargs)

def show_in_browser(self, host='127.0.0.1', port=7000):
"""
Displays the Map in the default web browser.

Parameters
----------
host: str
Local address on which the Map will be hosted, default is '127.0.0.1'
port: int
Corresponding port, default 7000

Examples
--------
import numpy as np
import folium
from folium.plugins import HeatMap

# create a dummy map
data = (np.random.normal(size=(100, 3)) *
np.array([[1, 1, 1]]) +
np.array([[48, 5, 1]])).tolist()
folium_map = folium.Map([48., 5.], tiles='stamentoner', zoom_start=6)
HeatMap(data).add_to(folium_map)

# open in in browser
folium_map.show_in_browser()


"""
srvr = TemporaryHTTPServer(host, port)
srvr.open_html_in_browser(self._repr_html_())

def fit_bounds(self, bounds, padding_top_left=None,
padding_bottom_right=None, padding=None, max_zoom=None):
"""Fit the map to contain a bounding box with the
Expand Down
4 changes: 4 additions & 0 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
altair
cartopy
descartes
flake8
flake8-builtins
flake8-comprehensions
Expand All @@ -12,6 +13,7 @@ geopandas
gpxpy
ipykernel
jupyter_client
matplotlib
mplleaflet
nbconvert
nbsphinx
Expand All @@ -20,7 +22,9 @@ pillow
pycodestyle
pytest
selenium
scipy
sphinx
twine
owslib
vega_datasets
vincent