blob: f9349f4677869571b80e44be4a56b17ea56eb97b [file] [log] [blame]
<!DOCTYPE html>
<html class="writer-html5" lang="en" >
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Timestamps &mdash; Apache Arrow v2.0.0</title>
<link rel="stylesheet" href="../_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<!--[if lt IE 9]>
<script src="../_static/js/html5shiv.min.js"></script>
<![endif]-->
<script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
<script src="../_static/jquery.js"></script>
<script src="../_static/underscore.js"></script>
<script src="../_static/doctools.js"></script>
<script src="../_static/language_data.js"></script>
<script type="text/javascript" src="../_static/js/theme.js"></script>
<link rel="canonical" href="https://arrow.apache.org/docs/python/timestamps.html" />
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Reading CSV files" href="csv.html" />
<link rel="prev" title="Pandas Integration" href="pandas.html" />
<!-- Matomo -->
<script>
var _paq = window._paq = window._paq || [];
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
_paq.push(["setDoNotTrack", true]);
_paq.push(["disableCookies"]);
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
var u="https://analytics.apache.org/";
_paq.push(['setTrackerUrl', u+'matomo.php']);
_paq.push(['setSiteId', '20']);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
})();
</script>
<!-- End Matomo Code -->
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search" >
<a href="../index.html" class="icon icon-home" alt="Documentation Home"> Apache Arrow
</a>
<div class="version">
2.0.0
</div>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="../search.html" method="get">
<input type="text" name="q" placeholder="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
<p class="caption"><span class="caption-text">Specifications and Protocols</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../format/Versioning.html">Format Versioning and Stability</a></li>
<li class="toctree-l1"><a class="reference internal" href="../format/Columnar.html">Arrow Columnar Format</a></li>
<li class="toctree-l1"><a class="reference internal" href="../format/Flight.html">Arrow Flight RPC</a></li>
<li class="toctree-l1"><a class="reference internal" href="../format/Integration.html">Integration Testing</a></li>
<li class="toctree-l1"><a class="reference internal" href="../format/CDataInterface.html">The Arrow C data interface</a></li>
<li class="toctree-l1"><a class="reference internal" href="../format/CStreamInterface.html">The Arrow C stream interface</a></li>
<li class="toctree-l1"><a class="reference internal" href="../format/Other.html">Other Data Structures</a></li>
</ul>
<p class="caption"><span class="caption-text">Libraries</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../status.html">Implementation Status</a></li>
<li class="toctree-l1"><a class="reference external" href="https://arrow.apache.org/docs/c_glib/">C/GLib</a></li>
<li class="toctree-l1"><a class="reference internal" href="../cpp/index.html">C++</a></li>
<li class="toctree-l1"><a class="reference external" href="https://github.com/apache/arrow/blob/master/csharp/README.md">C#</a></li>
<li class="toctree-l1"><a class="reference external" href="https://godoc.org/github.com/apache/arrow/go/arrow">Go</a></li>
<li class="toctree-l1"><a class="reference internal" href="../java/index.html">Java</a></li>
<li class="toctree-l1"><a class="reference external" href="https://arrow.apache.org/docs/js/">JavaScript</a></li>
<li class="toctree-l1"><a class="reference external" href="https://github.com/apache/arrow/blob/master/matlab/README.md">MATLAB</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="index.html">Python</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="install.html">Installing PyArrow</a></li>
<li class="toctree-l2"><a class="reference internal" href="memory.html">Memory and IO Interfaces</a></li>
<li class="toctree-l2"><a class="reference internal" href="data.html">Data Types and In-Memory Data Model</a></li>
<li class="toctree-l2"><a class="reference internal" href="compute.html">Compute Functions</a></li>
<li class="toctree-l2"><a class="reference internal" href="ipc.html">Streaming, Serialization, and IPC</a></li>
<li class="toctree-l2"><a class="reference internal" href="filesystems.html">Filesystem Interface</a></li>
<li class="toctree-l2"><a class="reference internal" href="filesystems_deprecated.html">Filesystem Interface (legacy)</a></li>
<li class="toctree-l2"><a class="reference internal" href="plasma.html">The Plasma In-Memory Object Store</a></li>
<li class="toctree-l2"><a class="reference internal" href="numpy.html">NumPy Integration</a></li>
<li class="toctree-l2"><a class="reference internal" href="pandas.html">Pandas Integration</a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#">Timestamps</a><ul>
<li class="toctree-l3"><a class="reference internal" href="#arrow-pandas-timestamps">Arrow/Pandas Timestamps</a></li>
<li class="toctree-l3"><a class="reference internal" href="#timestamp-conversions">Timestamp Conversions</a><ul>
<li class="toctree-l4"><a class="reference internal" href="#pandas-arrow-spark">Pandas/Arrow ⇄ Spark</a></li>
</ul>
</li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="csv.html">Reading CSV files</a></li>
<li class="toctree-l2"><a class="reference internal" href="feather.html">Feather File Format</a></li>
<li class="toctree-l2"><a class="reference internal" href="json.html">Reading JSON files</a></li>
<li class="toctree-l2"><a class="reference internal" href="parquet.html">Reading and Writing the Apache Parquet Format</a></li>
<li class="toctree-l2"><a class="reference internal" href="dataset.html">Tabular Datasets</a></li>
<li class="toctree-l2"><a class="reference internal" href="cuda.html">CUDA Integration</a></li>
<li class="toctree-l2"><a class="reference internal" href="extending_types.html">Extending pyarrow</a></li>
<li class="toctree-l2"><a class="reference internal" href="extending.html">Using pyarrow from C++ and Cython Code</a></li>
<li class="toctree-l2"><a class="reference internal" href="api.html">API Reference</a></li>
<li class="toctree-l2"><a class="reference internal" href="getting_involved.html">Getting Involved</a></li>
<li class="toctree-l2"><a class="reference internal" href="benchmarks.html">Benchmarks</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference external" href="https://arrow.apache.org/docs/r/">R</a></li>
<li class="toctree-l1"><a class="reference external" href="https://github.com/apache/arrow/blob/master/ruby/README.md">Ruby</a></li>
<li class="toctree-l1"><a class="reference external" href="https://docs.rs/crate/arrow/">Rust</a></li>
</ul>
<p class="caption"><span class="caption-text">Development</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../developers/contributing.html">Contributing to Apache Arrow</a></li>
<li class="toctree-l1"><a class="reference internal" href="../developers/cpp/index.html">C++ Development</a></li>
<li class="toctree-l1"><a class="reference internal" href="../developers/python.html">Python Development</a></li>
<li class="toctree-l1"><a class="reference internal" href="../developers/archery.html">Daily Development using Archery</a></li>
<li class="toctree-l1"><a class="reference internal" href="../developers/crossbow.html">Packaging and Testing with Crossbow</a></li>
<li class="toctree-l1"><a class="reference internal" href="../developers/docker.html">Running Docker Builds</a></li>
<li class="toctree-l1"><a class="reference internal" href="../developers/benchmarks.html">Benchmarks</a></li>
<li class="toctree-l1"><a class="reference internal" href="../developers/documentation.html">Building the Documentation</a></li>
</ul>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
<nav class="wy-nav-top" aria-label="top navigation">
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="../index.html">Apache Arrow</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="breadcrumbs navigation">
<ul class="wy-breadcrumbs">
<li><a href="../index.html" class="icon icon-home"></a> &raquo;</li>
<li><a href="index.html">Python bindings</a> &raquo;</li>
<li>Timestamps</li>
<li class="wy-breadcrumbs-aside">
<a href="../_sources/python/timestamps.rst.txt" rel="nofollow"> View page source</a>
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<div class="section" id="timestamps">
<h1>Timestamps<a class="headerlink" href="#timestamps" title="Permalink to this headline"></a></h1>
<div class="section" id="arrow-pandas-timestamps">
<h2>Arrow/Pandas Timestamps<a class="headerlink" href="#arrow-pandas-timestamps" title="Permalink to this headline"></a></h2>
<p>Arrow timestamps are stored as a 64-bit integer with column metadata to
associate a time unit (e.g. milliseconds, microseconds, or nanoseconds), and an
optional time zone. Pandas (<cite>Timestamp</cite>) uses a 64-bit integer representing
nanoseconds and an optional time zone.
Python/Pandas timestamp types without a associated time zone are referred to as
“Time Zone Naive”. Python/Pandas timestamp types with an associated time zone are
referred to as “Time Zone Aware”.</p>
</div>
<div class="section" id="timestamp-conversions">
<h2>Timestamp Conversions<a class="headerlink" href="#timestamp-conversions" title="Permalink to this headline"></a></h2>
<div class="section" id="pandas-arrow-spark">
<h3>Pandas/Arrow ⇄ Spark<a class="headerlink" href="#pandas-arrow-spark" title="Permalink to this headline"></a></h3>
<p>Spark stores timestamps as 64-bit integers representing microseconds since
the UNIX epoch. It does not store any metadata about time zones with its
timestamps.</p>
<p>Spark interprets timestamps with the <em>session local time zone</em>, (i.e.
<code class="docutils literal notranslate"><span class="pre">spark.sql.session.timeZone</span></code>). If that time zone is undefined, Spark turns to
the default system time zone. For simplicity’s sake below, the session
local time zone is always defined.</p>
<p>This implies a few things when round-tripping timestamps:</p>
<ol class="arabic simple">
<li><p>Timezone information is lost (all timestamps that result from
converting from spark to arrow/pandas are “time zone naive”).</p></li>
<li><p>Timestamps are truncated to microseconds.</p></li>
<li><p>The session time zone might have unintuitive impacts on
translation of timestamp values.</p></li>
</ol>
<div class="section" id="spark-to-pandas-through-apache-arrow">
<h4>Spark to Pandas (through Apache Arrow)<a class="headerlink" href="#spark-to-pandas-through-apache-arrow" title="Permalink to this headline"></a></h4>
<p>The following cases assume the Spark configuration
<code class="docutils literal notranslate"><span class="pre">spark.sql.execution.arrow.enabled</span></code> is set to <code class="docutils literal notranslate"><span class="pre">&quot;true&quot;</span></code>.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">pdf</span> <span class="o">=</span> <span class="n">pd</span><span class="o">.</span><span class="n">DataFrame</span><span class="p">({</span><span class="s1">&#39;naive&#39;</span><span class="p">:</span> <span class="p">[</span><span class="n">datetime</span><span class="p">(</span><span class="mi">2019</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">)],</span>
<span class="gp">... </span> <span class="s1">&#39;aware&#39;</span><span class="p">:</span> <span class="p">[</span><span class="n">Timestamp</span><span class="p">(</span><span class="n">year</span><span class="o">=</span><span class="mi">2019</span><span class="p">,</span> <span class="n">month</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">day</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span>
<span class="gp">... </span> <span class="n">nanosecond</span><span class="o">=</span><span class="mi">500</span><span class="p">,</span> <span class="n">tz</span><span class="o">=</span><span class="n">timezone</span><span class="p">(</span><span class="n">timedelta</span><span class="p">(</span><span class="n">hours</span><span class="o">=-</span><span class="mi">8</span><span class="p">)))]})</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">pdf</span>
<span class="go"> naive aware</span>
<span class="go"> 0 2018-10-01 2018-10-01 00:00:00.000000500-08:00</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">spark</span><span class="o">.</span><span class="n">conf</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;spark.sql.session.timeZone&quot;</span><span class="p">,</span> <span class="s2">&quot;UTC&quot;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">utc_df</span> <span class="o">=</span> <span class="n">sqlContext</span><span class="o">.</span><span class="n">createDataFrame</span><span class="p">(</span><span class="n">pdf</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">utf_df</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
<span class="go">+-------------------+-------------------+</span>
<span class="go">| naive| aware|</span>
<span class="go">+-------------------+-------------------+</span>
<span class="go">|2019-01-01 00:00:00|2019-01-01 08:00:00|</span>
<span class="go">+-------------------+-------------------+</span>
</pre></div>
</div>
<p>Note that conversion of the aware timestamp is shifted to reflect the time
assuming UTC (it represents the same instant in time). For naive
timestamps, Spark treats them as being in the system local
time zone and converts them UTC. Recall that internally, the schema
for spark dataframe’s does not store any time zone information with
timestamps.</p>
<p>Now if the session time zone is set to US Pacific Time (PST) we don’t
see any shift in the display of the aware time zone (it
still represents the same instant in time):</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">spark</span><span class="o">.</span><span class="n">conf</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;spark.sql.session.timeZone&quot;</span><span class="p">,</span> <span class="s2">&quot;US/Pacific&quot;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">pst_df</span> <span class="o">=</span> <span class="n">sqlContext</span><span class="o">.</span><span class="n">createDataFrame</span><span class="p">(</span><span class="n">pdf</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">pst_df</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
<span class="go">+-------------------+-------------------+</span>
<span class="go">| naive| aware|</span>
<span class="go">+-------------------+-------------------+</span>
<span class="go">|2019-01-01 00:00:00|2019-01-01 00:00:00|</span>
<span class="go">+-------------------+-------------------+</span>
</pre></div>
</div>
<p>Looking again at utc_df.show() we see one of the impacts of the session time
zone. The naive timestamp was initially converted assuming UTC, the instant it
reflects is actually earlier than the naive time zone from the PST converted
data frame:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">utc_df</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
<span class="go">+-------------------+-------------------+</span>
<span class="go">| naive| aware|</span>
<span class="go">+-------------------+-------------------+</span>
<span class="go">|2018-12-31 16:00:00|2019-01-01 00:00:00|</span>
<span class="go">+-------------------+-------------------+</span>
</pre></div>
</div>
</div>
<div class="section" id="spark-to-pandas">
<h4>Spark to Pandas<a class="headerlink" href="#spark-to-pandas" title="Permalink to this headline"></a></h4>
<p>We can observe what happens when converting back to Arrow/Pandas. Assuming the
session time zone is still PST:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">pst_df</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
<span class="go">+-------------------+-------------------+</span>
<span class="go">| naive| aware|</span>
<span class="go">+-------------------+-------------------+</span>
<span class="go">|2019-01-01 00:00:00|2019-01-01 00:00:00|</span>
<span class="go">+-------------------+-------------------+</span>
<span class="go"> &gt;&gt;&gt; pst_df.toPandas()</span>
<span class="go"> naive aware</span>
<span class="go"> 0 2019-01-01 2019-01-01</span>
<span class="go"> &gt;&gt;&gt; pst_df.toPandas().info()</span>
<span class="go"> &lt;class &#39;pandas.core.frame.DataFrame&#39;&gt;</span>
<span class="go"> RangeIndex: 1 entries, 0 to 0</span>
<span class="go"> Data columns (total 2 columns):</span>
<span class="go"> naive 1 non-null datetime64[ns]</span>
<span class="go"> aware 1 non-null datetime64[ns]</span>
<span class="go"> dtypes: datetime64[ns](2)</span>
<span class="go"> memory usage: 96.0 bytes</span>
</pre></div>
</div>
<p>Notice that, in addition to being a “time zone naive” timestamp, the ‘aware’
value will now differ when converting to an epoch offset. Spark does the conversion
by first converting to the session time zone (or system local time zone if
session time zones isn’t set) and then localizes to remove the time zone
information. This results in the timestamp being 8 hours before the original
time:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">pst_df</span><span class="o">.</span><span class="n">toPandas</span><span class="p">()[</span><span class="s1">&#39;aware&#39;</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span>
<span class="go">Timestamp(&#39;2019-01-01 00:00:00&#39;)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">pdf</span><span class="p">[</span><span class="s1">&#39;aware&#39;</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span>
<span class="go">Timestamp(&#39;2019-01-01 00:00:00.000000500-0800&#39;, tz=&#39;UTC-08:00&#39;)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="p">(</span><span class="n">pst_df</span><span class="o">.</span><span class="n">toPandas</span><span class="p">()[</span><span class="s1">&#39;aware&#39;</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">timestamp</span><span class="p">()</span><span class="o">-</span><span class="n">pdf</span><span class="p">[</span><span class="s1">&#39;aware&#39;</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">timestamp</span><span class="p">())</span><span class="o">/</span><span class="mi">3600</span>
<span class="go">-8.0</span>
</pre></div>
</div>
<p>The same type of conversion happens with the data frame converted while
the session time zone was UTC. In this case both naive and aware
represent different instants in time (the naive instant is due to
the change in session time zone between creating data frames):</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">utc_df</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
<span class="go">+-------------------+-------------------+</span>
<span class="go">| naive| aware|</span>
<span class="go">+-------------------+-------------------+</span>
<span class="go">|2018-12-31 16:00:00|2019-01-01 00:00:00|</span>
<span class="go">+-------------------+-------------------+</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">utc_df</span><span class="o">.</span><span class="n">toPandas</span><span class="p">()</span>
<span class="go">naive aware</span>
<span class="go">0 2018-12-31 16:00:00 2019-01-01</span>
</pre></div>
</div>
<p>Note that the surprising shift for aware doesn’t happen
when the session time zone is UTC (but the timestamps
still become “time zone naive”):</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">spark</span><span class="o">.</span><span class="n">conf</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;spark.sql.session.timeZone&quot;</span><span class="p">,</span> <span class="s2">&quot;UTC&quot;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">pst_df</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
<span class="go">+-------------------+-------------------+</span>
<span class="go">| naive| aware|</span>
<span class="go">+-------------------+-------------------+</span>
<span class="go">|2019-01-01 08:00:00|2019-01-01 08:00:00|</span>
<span class="go">+-------------------+-------------------+</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">pst_df</span><span class="o">.</span><span class="n">toPandas</span><span class="p">()[</span><span class="s1">&#39;aware&#39;</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span>
<span class="go">Timestamp(&#39;2019-01-01 08:00:00&#39;)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">pdf</span><span class="p">[</span><span class="s1">&#39;aware&#39;</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span>
<span class="go">Timestamp(&#39;2019-01-01 00:00:00.000000500-0800&#39;, tz=&#39;UTC-08:00&#39;)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="p">(</span><span class="n">pst_df</span><span class="o">.</span><span class="n">toPandas</span><span class="p">()[</span><span class="s1">&#39;aware&#39;</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">timestamp</span><span class="p">()</span><span class="o">-</span><span class="n">pdf</span><span class="p">[</span><span class="s1">&#39;aware&#39;</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">timestamp</span><span class="p">())</span><span class="o">/</span><span class="mi">3600</span>
<span class="go">0.0</span>
</pre></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<footer>
<div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
<a href="csv.html" class="btn btn-neutral float-right" title="Reading CSV files" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right"></span></a>
<a href="pandas.html" class="btn btn-neutral float-left" title="Pandas Integration" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left"></span> Previous</a>
</div>
<hr/>
<div role="contentinfo">
<p>
&copy; Copyright 2016-2019 Apache Software Foundation
</p>
</div>
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a
<a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a>
provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
</div>
</div>
</section>
</div>
<script type="text/javascript">
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
<script type="text/javascript" src="/docs/_static/versionwarning.js"></script></body>
</html>