21

I've locally built static Sphinx documentations (using make html).

I wish now to integrate the Sphinx files into my webapp that runs with Flask. From the Flask running application, I simply mean to include an hyperlink towards the Sphinx documentation, that will serve as help for the application.

Websupport seems the way to follow, but it's not clear to me how I should bridge the Flask framework to the Sphinx files.

Thanks for any help,

Regards

barryhunter
  • 20,886
  • 3
  • 30
  • 43
mannaia
  • 860
  • 2
  • 11
  • 27

6 Answers6

13

Other solutions nicely omit the Flask object initialization, which lead me to bang my head against the wall for a while.

Without touching the Sphinx project structure at all, here's the solution that worked for me:

from flask import Flask

app = Flask(__name__, static_url_path='/', static_folder='_build/html/')


@app.route('/')
@app.route('/<path:path>')
def serve_sphinx_docs(path='index.html'):
    return app.send_static_file(path)


if __name__ == '__main__':
    app.run(debug=True)

And below is the file structure of the project, where <doc> represents the rst files I actually wrote for the documentation, and app.py is the file containing the Flask app code above.

.
├── Makefile
├── _build
│   ├── doctrees
│   │   ├── index.doctree
│   │   ├── <doc>.doctree
│   │   ├── ...
│   │   └── <doc>.doctree
│   └── html
│       ├── _images
│       ├── _modules
│       │   ├── index.html
│       │   └── <package name>
│       │       └── ...
│       ├── _sources
│       │   ├── <doc>.rst.txt
│       │   ├── ...
│       │   └── <doc>.rst.txt
│       ├── _static
│       │   ├── ajax-loader.gif
│       │   ├── alabaster.css
│       │   └── ...
│       ├── genindex.html
│       ├── index.html
│       ├── objects.inv
│       ├── py-modindex.html
│       ├── search.html
│       ├── searchindex.js
│       ├── <doc>.html
│       ├── ...
│       └── <doc>.html
├── _static
│   ├── custom.css
│   └── <myimage>.gif
├── _templates
├── app.py
├── conf.py
├── index.rst
├── make.bat
├── <doc>.rst
├── ...
└── <doc>.rst
Gustavo Bezerra
  • 9,984
  • 4
  • 40
  • 48
8

You could just handle it with your web server, the same way you handle the /static directory in Flask. For example if you used Apache as your production web server, you might add

Alias /documentation /location/of/sphinx/html
<Directory /location/of/sphinx/html>
    Order deny,allow
    Allow from all
</Directory>

to your Apache site configuration, so then you could just link directly to http://yoursite.com/documentation to access the Sphinx files, avoiding Flask altogether.

Doobeh
  • 9,280
  • 39
  • 32
3

You can copy the _build/html folder from your docs to a doc folder in your flask static directory, and serve them with the following rule:

@app.route('/doc/<dir>/<filename>', defaults={'static': True})
def doc(dir='',filename='index.html'):
    path = join(dir,filename)
    return app.send_static_file(path)
user545424
  • 15,713
  • 11
  • 56
  • 70
2

In some cases you do not want to expose your docs to all users so configuring at the Apache or Nginx level is not an option. The following worked for me:

@app.route('/docs', defaults = {'filename': 'index.html'})
@app.route('/docs/<path:filename>')
@login_required
def web_docs(filename):
    path = os.path.join('docs/html', filename)
    return app.send_static_file(path)
spitz
  • 658
  • 1
  • 8
  • 19
  • 1
    This works for me using sphinx. However, the page does not have any of the CSS styling when I use the '/docs' route, but when I use the full path to index.html directly I do get the CSS. Wondering if you have any ideas on this.. all the style files are in 'docs/html/_static' – Carlos G. Oliver Aug 27 '21 at 17:31
1

As far as I've seen the Flask.send_static_file method requires that the file resides within the static directory. Sub directories are not supported using this method.

To serve a file from any location use the Flask.send_from_directory method.

Example:

import flask
from flask import send_from_directory


app = Flask(
    import_name=__name__
    )


@app.route('/docs/', defaults={'filename': 'index.html'})
@app.route('/docs/<path:filename>')
def docs(filename) -> flask.send_from_directory:
    docs_dir = os.path.join(os.path.dirname(__file__), 'docs', 'build', 'html')

    return send_from_directory(directory=docs_dir, path=filename)

The example assumes docs\build\html\ exists in the same directory as the python file. Change docs_dir as needed.

Additionally, without appending a trailing backslash to the default route, the page did not render properly, therefore I changed the default route to /docs/.

0

Set the BUILDDIR path in sphinx Makefile

BUILDDIR      = app/static/docs

add flask routes

@app.get('/docs/')
@app.get('/docs/<path:filename>')
def get_docs(filename='index.html'):
    path = os.path.join('docs/html', filename)
    return app.send_static_file(path)

Build the sphinx documentation.

$ make html

You can browse to http://127.0.0.1:5000/docs for sphinx documentation page. All the sphinx docs static files will be served under this route. You can also add Flask Authentication to the route if needed.

Test Versions:

  • Flask: 2.0.2
  • Sphinx: 4.3.1