python: publish sphinx docs to read the docs

Background:

This is a follow-up to the PR that adds sphinx docs.

Read the Docs is a hosting platform for documentation, primarily Python
docs. It supports builds at commit time as well as at specific git
labels to support versioned docs. I have claimed the
protobuf.readthedocs.io project and can add any Googlers who need access
to be able to configure and trigger builds.
https://readthedocs.org/projects/protobuf/builds/ It's also relatively
easy to create a new project to test the documentation builds from a
fork, such as https://readthedocs.org/projects/tswast-protobuf/builds/

About this change:

Once web hooks are configured, Read the Docs will automatically build
the docs for the latest changes on the master branch.

I needed to update `python/setup.py` to support installation from the
root of the repository because Read the Docs does not `cd python` before
installing the protobuf package with `setup.py install`. To support
this, I updated the file paths to use the absolute path to files. The
`__file__` special variable comes in handy for this, as it provides the
path to the `setup.py` file.

A banner is added to the docs when published to readthedocs. This links
to the official documentation and the future home of the stable API
reference on googleapis.dev.
This commit is contained in:
Tim Swast 2019-08-15 16:22:02 -07:00
parent ed19442270
commit 35a2bf9d90
No known key found for this signature in database
GPG Key ID: E75A8DDEB47FCD24
28 changed files with 376 additions and 14 deletions

22
.readthedocs.yml Normal file
View File

@ -0,0 +1,22 @@
# .readthedocs.yml
# Read the Docs configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
# Required
version: 2
sphinx:
configuration: python/docs/conf.py
fail_on_warning: false
# Setup build requirements for docs.
# Use conda so that we can install the latest libprotobuf package without
# having to build from scratch just for docs builds.
conda:
environment: python/docs/environment.yml
python:
version: 3.7
install:
- method: setuptools
path: python

View File

@ -41,7 +41,7 @@
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
# import os
import os
# import sys
# sys.path.insert(0, os.path.abspath('.'))
import google.protobuf
@ -69,6 +69,7 @@ release = google.protobuf.__version__
# ones.
extensions = [
"sphinx.ext.autosummary",
"sphinx.ext.ifconfig",
"sphinx.ext.intersphinx",
"sphinxcontrib.napoleon",
]
@ -237,3 +238,17 @@ autosummary_generate = True
# Example configuration for intersphinx: refer to the Python standard library.
intersphinx_mapping = {"https://docs.python.org/": None}
# -- Config values -----------------------------------------------------------
# The setup() function is needed to add configuration values to the Sphinx
# builder. We use this to show a banner when built on Read the Docs.
# https://www.sphinx-doc.org/en/master/usage/extensions/ifconfig.html
def setup(app):
app.add_config_value(
"build_env",
# Read the Docs sets a READTHEDOCS environment during builds.
# https://docs.readthedocs.io/en/stable/builds.html#build-environment
"readthedocs" if os.getenv("READTHEDOCS") else "",
"env"
)

View File

@ -95,6 +95,18 @@ TOC_TEMPLATE = """.. START REFTOC, generated by generate_docs.py.
AUTOMODULE_TEMPLATE = """.. DO NOT EDIT, generated by generate_docs.py.
.. ifconfig:: build_env == 'readthedocs'
.. warning::
You are reading the documentation for the `latest committed changes
<https://github.com/protocolbuffers/protobuf/tree/master/python>`_ of
the `Protocol Buffers package for Python
<https://developers.google.com/protocol-buffers/docs/pythontutorial>`_.
Some features may not yet be released. Read the documentation for the
latest released package at `googleapis.dev
<https://googleapis.dev/python/protobuf/latest/>`_.
{module}
{underline}

View File

@ -1,5 +1,17 @@
.. DO NOT EDIT, generated by generate_docs.py.
.. ifconfig:: build_env == 'readthedocs'
.. warning::
You are reading the documentation for the `latest committed changes
<https://github.com/protocolbuffers/protobuf/tree/master/python>`_ of
the `Protocol Buffers package for Python
<https://developers.google.com/protocol-buffers/docs/pythontutorial>`_.
Some features may not yet be released. Read the documentation for the
latest released package at `googleapis.dev
<https://googleapis.dev/python/protobuf/latest/>`_.
google.protobuf
===============

View File

@ -1,5 +1,17 @@
.. DO NOT EDIT, generated by generate_docs.py.
.. ifconfig:: build_env == 'readthedocs'
.. warning::
You are reading the documentation for the `latest committed changes
<https://github.com/protocolbuffers/protobuf/tree/master/python>`_ of
the `Protocol Buffers package for Python
<https://developers.google.com/protocol-buffers/docs/pythontutorial>`_.
Some features may not yet be released. Read the documentation for the
latest released package at `googleapis.dev
<https://googleapis.dev/python/protobuf/latest/>`_.
google.protobuf.any_pb2
=======================

View File

@ -1,5 +1,17 @@
.. DO NOT EDIT, generated by generate_docs.py.
.. ifconfig:: build_env == 'readthedocs'
.. warning::
You are reading the documentation for the `latest committed changes
<https://github.com/protocolbuffers/protobuf/tree/master/python>`_ of
the `Protocol Buffers package for Python
<https://developers.google.com/protocol-buffers/docs/pythontutorial>`_.
Some features may not yet be released. Read the documentation for the
latest released package at `googleapis.dev
<https://googleapis.dev/python/protobuf/latest/>`_.
google.protobuf.descriptor
==========================

View File

@ -1,5 +1,17 @@
.. DO NOT EDIT, generated by generate_docs.py.
.. ifconfig:: build_env == 'readthedocs'
.. warning::
You are reading the documentation for the `latest committed changes
<https://github.com/protocolbuffers/protobuf/tree/master/python>`_ of
the `Protocol Buffers package for Python
<https://developers.google.com/protocol-buffers/docs/pythontutorial>`_.
Some features may not yet be released. Read the documentation for the
latest released package at `googleapis.dev
<https://googleapis.dev/python/protobuf/latest/>`_.
google.protobuf.descriptor_database
===================================

View File

@ -1,5 +1,17 @@
.. DO NOT EDIT, generated by generate_docs.py.
.. ifconfig:: build_env == 'readthedocs'
.. warning::
You are reading the documentation for the `latest committed changes
<https://github.com/protocolbuffers/protobuf/tree/master/python>`_ of
the `Protocol Buffers package for Python
<https://developers.google.com/protocol-buffers/docs/pythontutorial>`_.
Some features may not yet be released. Read the documentation for the
latest released package at `googleapis.dev
<https://googleapis.dev/python/protobuf/latest/>`_.
google.protobuf.descriptor_pb2
==============================

View File

@ -1,5 +1,17 @@
.. DO NOT EDIT, generated by generate_docs.py.
.. ifconfig:: build_env == 'readthedocs'
.. warning::
You are reading the documentation for the `latest committed changes
<https://github.com/protocolbuffers/protobuf/tree/master/python>`_ of
the `Protocol Buffers package for Python
<https://developers.google.com/protocol-buffers/docs/pythontutorial>`_.
Some features may not yet be released. Read the documentation for the
latest released package at `googleapis.dev
<https://googleapis.dev/python/protobuf/latest/>`_.
google.protobuf.descriptor_pool
===============================

View File

@ -1,5 +1,17 @@
.. DO NOT EDIT, generated by generate_docs.py.
.. ifconfig:: build_env == 'readthedocs'
.. warning::
You are reading the documentation for the `latest committed changes
<https://github.com/protocolbuffers/protobuf/tree/master/python>`_ of
the `Protocol Buffers package for Python
<https://developers.google.com/protocol-buffers/docs/pythontutorial>`_.
Some features may not yet be released. Read the documentation for the
latest released package at `googleapis.dev
<https://googleapis.dev/python/protobuf/latest/>`_.
google.protobuf.duration_pb2
============================

View File

@ -1,5 +1,17 @@
.. DO NOT EDIT, generated by generate_docs.py.
.. ifconfig:: build_env == 'readthedocs'
.. warning::
You are reading the documentation for the `latest committed changes
<https://github.com/protocolbuffers/protobuf/tree/master/python>`_ of
the `Protocol Buffers package for Python
<https://developers.google.com/protocol-buffers/docs/pythontutorial>`_.
Some features may not yet be released. Read the documentation for the
latest released package at `googleapis.dev
<https://googleapis.dev/python/protobuf/latest/>`_.
google.protobuf.empty_pb2
=========================

View File

@ -1,5 +1,17 @@
.. DO NOT EDIT, generated by generate_docs.py.
.. ifconfig:: build_env == 'readthedocs'
.. warning::
You are reading the documentation for the `latest committed changes
<https://github.com/protocolbuffers/protobuf/tree/master/python>`_ of
the `Protocol Buffers package for Python
<https://developers.google.com/protocol-buffers/docs/pythontutorial>`_.
Some features may not yet be released. Read the documentation for the
latest released package at `googleapis.dev
<https://googleapis.dev/python/protobuf/latest/>`_.
google.protobuf.field_mask_pb2
==============================

View File

@ -1,5 +1,17 @@
.. DO NOT EDIT, generated by generate_docs.py.
.. ifconfig:: build_env == 'readthedocs'
.. warning::
You are reading the documentation for the `latest committed changes
<https://github.com/protocolbuffers/protobuf/tree/master/python>`_ of
the `Protocol Buffers package for Python
<https://developers.google.com/protocol-buffers/docs/pythontutorial>`_.
Some features may not yet be released. Read the documentation for the
latest released package at `googleapis.dev
<https://googleapis.dev/python/protobuf/latest/>`_.
google.protobuf.json_format
===========================

View File

@ -1,5 +1,17 @@
.. DO NOT EDIT, generated by generate_docs.py.
.. ifconfig:: build_env == 'readthedocs'
.. warning::
You are reading the documentation for the `latest committed changes
<https://github.com/protocolbuffers/protobuf/tree/master/python>`_ of
the `Protocol Buffers package for Python
<https://developers.google.com/protocol-buffers/docs/pythontutorial>`_.
Some features may not yet be released. Read the documentation for the
latest released package at `googleapis.dev
<https://googleapis.dev/python/protobuf/latest/>`_.
google.protobuf.message
=======================

View File

@ -1,5 +1,17 @@
.. DO NOT EDIT, generated by generate_docs.py.
.. ifconfig:: build_env == 'readthedocs'
.. warning::
You are reading the documentation for the `latest committed changes
<https://github.com/protocolbuffers/protobuf/tree/master/python>`_ of
the `Protocol Buffers package for Python
<https://developers.google.com/protocol-buffers/docs/pythontutorial>`_.
Some features may not yet be released. Read the documentation for the
latest released package at `googleapis.dev
<https://googleapis.dev/python/protobuf/latest/>`_.
google.protobuf.message_factory
===============================

View File

@ -1,5 +1,17 @@
.. DO NOT EDIT, generated by generate_docs.py.
.. ifconfig:: build_env == 'readthedocs'
.. warning::
You are reading the documentation for the `latest committed changes
<https://github.com/protocolbuffers/protobuf/tree/master/python>`_ of
the `Protocol Buffers package for Python
<https://developers.google.com/protocol-buffers/docs/pythontutorial>`_.
Some features may not yet be released. Read the documentation for the
latest released package at `googleapis.dev
<https://googleapis.dev/python/protobuf/latest/>`_.
google.protobuf.proto_builder
=============================

View File

@ -1,5 +1,17 @@
.. DO NOT EDIT, generated by generate_docs.py.
.. ifconfig:: build_env == 'readthedocs'
.. warning::
You are reading the documentation for the `latest committed changes
<https://github.com/protocolbuffers/protobuf/tree/master/python>`_ of
the `Protocol Buffers package for Python
<https://developers.google.com/protocol-buffers/docs/pythontutorial>`_.
Some features may not yet be released. Read the documentation for the
latest released package at `googleapis.dev
<https://googleapis.dev/python/protobuf/latest/>`_.
google.protobuf.reflection
==========================

View File

@ -1,5 +1,17 @@
.. DO NOT EDIT, generated by generate_docs.py.
.. ifconfig:: build_env == 'readthedocs'
.. warning::
You are reading the documentation for the `latest committed changes
<https://github.com/protocolbuffers/protobuf/tree/master/python>`_ of
the `Protocol Buffers package for Python
<https://developers.google.com/protocol-buffers/docs/pythontutorial>`_.
Some features may not yet be released. Read the documentation for the
latest released package at `googleapis.dev
<https://googleapis.dev/python/protobuf/latest/>`_.
google.protobuf.service
=======================

View File

@ -1,5 +1,17 @@
.. DO NOT EDIT, generated by generate_docs.py.
.. ifconfig:: build_env == 'readthedocs'
.. warning::
You are reading the documentation for the `latest committed changes
<https://github.com/protocolbuffers/protobuf/tree/master/python>`_ of
the `Protocol Buffers package for Python
<https://developers.google.com/protocol-buffers/docs/pythontutorial>`_.
Some features may not yet be released. Read the documentation for the
latest released package at `googleapis.dev
<https://googleapis.dev/python/protobuf/latest/>`_.
google.protobuf.service_reflection
==================================

View File

@ -1,5 +1,17 @@
.. DO NOT EDIT, generated by generate_docs.py.
.. ifconfig:: build_env == 'readthedocs'
.. warning::
You are reading the documentation for the `latest committed changes
<https://github.com/protocolbuffers/protobuf/tree/master/python>`_ of
the `Protocol Buffers package for Python
<https://developers.google.com/protocol-buffers/docs/pythontutorial>`_.
Some features may not yet be released. Read the documentation for the
latest released package at `googleapis.dev
<https://googleapis.dev/python/protobuf/latest/>`_.
google.protobuf.struct_pb2
==========================

View File

@ -1,5 +1,17 @@
.. DO NOT EDIT, generated by generate_docs.py.
.. ifconfig:: build_env == 'readthedocs'
.. warning::
You are reading the documentation for the `latest committed changes
<https://github.com/protocolbuffers/protobuf/tree/master/python>`_ of
the `Protocol Buffers package for Python
<https://developers.google.com/protocol-buffers/docs/pythontutorial>`_.
Some features may not yet be released. Read the documentation for the
latest released package at `googleapis.dev
<https://googleapis.dev/python/protobuf/latest/>`_.
google.protobuf.symbol_database
===============================

View File

@ -1,5 +1,17 @@
.. DO NOT EDIT, generated by generate_docs.py.
.. ifconfig:: build_env == 'readthedocs'
.. warning::
You are reading the documentation for the `latest committed changes
<https://github.com/protocolbuffers/protobuf/tree/master/python>`_ of
the `Protocol Buffers package for Python
<https://developers.google.com/protocol-buffers/docs/pythontutorial>`_.
Some features may not yet be released. Read the documentation for the
latest released package at `googleapis.dev
<https://googleapis.dev/python/protobuf/latest/>`_.
google.protobuf.text_encoding
=============================

View File

@ -1,5 +1,17 @@
.. DO NOT EDIT, generated by generate_docs.py.
.. ifconfig:: build_env == 'readthedocs'
.. warning::
You are reading the documentation for the `latest committed changes
<https://github.com/protocolbuffers/protobuf/tree/master/python>`_ of
the `Protocol Buffers package for Python
<https://developers.google.com/protocol-buffers/docs/pythontutorial>`_.
Some features may not yet be released. Read the documentation for the
latest released package at `googleapis.dev
<https://googleapis.dev/python/protobuf/latest/>`_.
google.protobuf.text_format
===========================

View File

@ -1,5 +1,17 @@
.. DO NOT EDIT, generated by generate_docs.py.
.. ifconfig:: build_env == 'readthedocs'
.. warning::
You are reading the documentation for the `latest committed changes
<https://github.com/protocolbuffers/protobuf/tree/master/python>`_ of
the `Protocol Buffers package for Python
<https://developers.google.com/protocol-buffers/docs/pythontutorial>`_.
Some features may not yet be released. Read the documentation for the
latest released package at `googleapis.dev
<https://googleapis.dev/python/protobuf/latest/>`_.
google.protobuf.timestamp_pb2
=============================

View File

@ -1,5 +1,17 @@
.. DO NOT EDIT, generated by generate_docs.py.
.. ifconfig:: build_env == 'readthedocs'
.. warning::
You are reading the documentation for the `latest committed changes
<https://github.com/protocolbuffers/protobuf/tree/master/python>`_ of
the `Protocol Buffers package for Python
<https://developers.google.com/protocol-buffers/docs/pythontutorial>`_.
Some features may not yet be released. Read the documentation for the
latest released package at `googleapis.dev
<https://googleapis.dev/python/protobuf/latest/>`_.
google.protobuf.type_pb2
========================

View File

@ -1,5 +1,17 @@
.. DO NOT EDIT, generated by generate_docs.py.
.. ifconfig:: build_env == 'readthedocs'
.. warning::
You are reading the documentation for the `latest committed changes
<https://github.com/protocolbuffers/protobuf/tree/master/python>`_ of
the `Protocol Buffers package for Python
<https://developers.google.com/protocol-buffers/docs/pythontutorial>`_.
Some features may not yet be released. Read the documentation for the
latest released package at `googleapis.dev
<https://googleapis.dev/python/protobuf/latest/>`_.
google.protobuf.wrappers_pb2
============================

View File

@ -3,6 +3,18 @@
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
.. ifconfig:: build_env == 'readthedocs'
.. warning::
You are reading the documentation for the `latest committed changes
<https://github.com/protocolbuffers/protobuf/tree/master/python>`_ of
the `Protocol Buffers package for Python
<https://developers.google.com/protocol-buffers/docs/pythontutorial>`_.
Some features may not yet be released. Read the documentation for the
latest released package at `googleapis.dev
<https://googleapis.dev/python/protobuf/latest/>`_.
Protocol Buffers Python API Reference
=====================================

View File

@ -19,17 +19,23 @@ from distutils.command.build_py import build_py as _build_py
from distutils.command.clean import clean as _clean
from distutils.spawn import find_executable
current_dir = os.path.dirname(__file__)
current_dir_relative = os.path.relpath(current_dir)
src_dir = os.path.abspath(os.path.join(current_dir, "..", "src"))
vsprojects_dir = os.path.abspath(os.path.join(current_dir, "..", "vsprojects"))
# Find the Protocol Compiler.
if 'PROTOC' in os.environ and os.path.exists(os.environ['PROTOC']):
protoc = os.environ['PROTOC']
elif os.path.exists("../src/protoc"):
protoc = "../src/protoc"
elif os.path.exists("../src/protoc.exe"):
protoc = "../src/protoc.exe"
elif os.path.exists("../vsprojects/Debug/protoc.exe"):
protoc = "../vsprojects/Debug/protoc.exe"
elif os.path.exists("../vsprojects/Release/protoc.exe"):
protoc = "../vsprojects/Release/protoc.exe"
elif os.path.exists(os.path.join(src_dir, "protoc")):
protoc = os.path.join(src_dir, "protoc")
elif os.path.exists(os.path.join(src_dir, "protoc.exe")):
protoc = os.path.join(src_dir, "protoc.exe")
elif os.path.exists(os.path.join(vsprojects_dir, "Debug", "protoc.exe")):
protoc = os.path.join(vsprojects_dir, "Debug", "protoc.exe")
elif os.path.exists(os.path.join(vsprojects_dir, "Release", "protoc.exe")):
protoc = os.path.join(vsprojects_dir, "Release", "protoc.exe")
else:
protoc = find_executable("protoc")
@ -40,7 +46,7 @@ def GetVersion():
Do not import google.protobuf.__init__ directly, because an installed
protobuf library may be loaded instead."""
with open(os.path.join('google', 'protobuf', '__init__.py')) as version_file:
with open(os.path.join(current_dir, 'google', 'protobuf', '__init__.py')) as version_file:
exec(version_file.read(), globals())
global __version__
return __version__
@ -51,15 +57,21 @@ def generate_proto(source, require = True):
.proto file. Does nothing if the output already exists and is newer than
the input."""
original_source = source
source = source.replace("../src", src_dir)
if not require and not os.path.exists(source):
return
output = source.replace(".proto", "_pb2.py").replace("../src/", "")
output = os.path.join(
current_dir,
original_source.replace(".proto", "_pb2.py").replace("../src/", "")
)
if (not os.path.exists(output) or
(os.path.exists(source) and
os.path.getmtime(source) > os.path.getmtime(output))):
print("Generating %s..." % output)
print("Generating %s..." % os.path.relpath(output))
if not os.path.exists(source):
sys.stderr.write("Can't find required file: %s\n" % source)
@ -71,7 +83,13 @@ def generate_proto(source, require = True):
"or install the binary package.\n")
sys.exit(-1)
protoc_command = [ protoc, "-I../src", "-I.", "--python_out=.", source ]
protoc_command = [
protoc,
"-I{}".format(src_dir),
"-I{}".format(current_dir),
"--python_out={}".format(current_dir),
source,
]
if subprocess.call(protoc_command) != 0:
sys.exit(-1)
@ -116,7 +134,7 @@ def GenerateUnittestProtos():
class clean(_clean):
def run(self):
# Delete generated files in the code tree.
for (dirpath, dirnames, filenames) in os.walk("."):
for (dirpath, dirnames, filenames) in os.walk(current_dir):
for filename in filenames:
filepath = os.path.join(dirpath, filename)
if filepath.endswith("_pb2.py") or filepath.endswith(".pyc") or \
@ -269,7 +287,14 @@ if __name__ == '__main__':
"Programming Language :: Python :: 3.7",
],
namespace_packages=['google'],
# package_dir is required when setup.py is not run from the python/
# directory (such as from the ReadTheDocs build). See
# https://setuptools.readthedocs.io/en/latest/setuptools.html#using-find-packages
# package_dir must be a relative path. See:
# https://stackoverflow.com/a/53547931/101923
package_dir={"": current_dir_relative},
packages=find_packages(
where=current_dir,
exclude=[
'import_test_package',
],