blob: 7996592f2feae4cde818fcd050e28bb9e4c561b5 [file] [log] [blame]
#!/usr/bin/env python
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
# This script generates notebooks for all the files defined in `docs.yaml`.
# It has to be run manually if the docs or code snippets are updated.
#
# To run, you have to install `md2ipynb`.
# pip install -U md2ipynb
#
# Then it can be run without any arguments.
# python website/notebooks/generate.py
#
# This creates the output notebooks in the `examples/notebooks` directory.
# You have to commit the generated notebooks after generating them.
import logging
import md2ipynb
import nbformat
import os
import sys
import yaml
docs_logo_url = 'https://beam.apache.org/images/logos/full-color/name-bottom/beam-logo-full-color-name-bottom-100.png'
def run(docs, root_dir, variables=None,
inputs_dir='.', outputs_dir='.', imports_dir='.', include_dir='.'):
errors = []
for basename, doc in docs.items():
languages=doc.get('languages', 'py java go').split()
for lang in languages:
# Read the imports defined in the docs.yaml.
imports = {
i: [os.path.join(imports_dir, path) for path in imports]
for i, imports in doc.get('imports', {}).items()
}
# Make sure the first import in section 0 is the license.md.
if 0 not in imports:
imports[0] = []
imports[0].insert(0, os.path.join(imports_dir, 'license.md'))
# Create a new notebook from the Markdown file contents.
input_file = basename + '.md'
ipynb_file = '/'.join([outputs_dir, '{}-{}.ipynb'.format(basename, lang)])
try:
notebook = md2ipynb.new_notebook(
input_file=os.path.join(inputs_dir, input_file),
variables=variables,
imports=imports,
notebook_title=doc.get('title', os.path.basename(basename).replace('-', ' ')),
keep_classes=['language-' + lang, 'shell-sh'],
filter_classes='notebook-skip',
docs_url='https://beam.apache.org/' + basename.replace('-', ''),
docs_logo_url=docs_logo_url,
github_ipynb_url='https://github.com/apache/beam/blob/master/'
+ os.path.relpath(ipynb_file, root_dir),
include_dir=include_dir,
)
logging.info('{} succeeded'.format(input_file))
# Write the notebook to file.
output_dir = os.path.dirname(ipynb_file)
if not os.path.exists(output_dir):
os.makedirs(output_dir)
with open(ipynb_file, 'w') as f:
nbformat.write(notebook, f)
except Exception as e:
logging.error('{} failed: {}'.format(input_file, e))
errors.append((input_file, e))
if errors:
import traceback
sys.stdout.flush()
sys.stderr.flush()
print('')
print('=' * 60)
print(' Errors')
for input_file, e in errors:
print('')
print(input_file)
print('-' * len(input_file))
traceback.print_exception(type(e), e, e.__traceback__)
print('')
print('{} files processed ({} succeeded, {} failed)'.format(
len(docs), len(docs) - len(errors), len(errors)))
if __name__ == '__main__':
logging.basicConfig(level=logging.INFO)
script_dir = os.path.dirname(os.path.realpath(__file__))
root_dir = os.path.realpath(os.path.join(script_dir, '..', '..'))
docs_file = os.path.join(script_dir, 'docs.yaml')
with open(docs_file) as f:
docs = yaml.load(f.read())
variables_file = os.path.join(root_dir, 'website', '_config.yml')
with open(variables_file) as f:
variables = {'site': yaml.load(f.read())}
variables['site']['baseurl'] = variables['site']['url']
run(
docs=docs,
root_dir=root_dir,
variables=variables,
inputs_dir=os.path.join(root_dir, 'website', 'src'),
outputs_dir=os.path.join(root_dir, 'examples', 'notebooks'),
imports_dir=os.path.join(script_dir, 'imports'),
include_dir=os.path.join(root_dir, 'website', 'src', '_includes'),
)