In this section we'll see how to generate documentation from docstrings. 

This tutorial is going to show you how to write files so that Sphinx's `autodoc` reads the relevant source code and generate the documentation from the docstrings. 

!!! note
    You may use any other Sphinx module/package/functionality as long as `make html` works and the built code is in `your_project/build`.

# Initialize the project's docs

Say your project is called `awesome_project` -> make it a Sphinx project with:

1. `cd ./awesome_project`
2. `sphinx-quickstart ./`
    * **say yes to `> Separate source and build directories (y/n)`**, 
    * keep default for the next one, 
    * fill in the Project's name, author and release then 
    * keep defaults for everything until you 
    * **say yes to `> autodoc: automatically insert [...]`** and then you can 
    * keep defaults until the end (you may want to **say no** to the creation of a Windows executable)
3. Copy your project in there, alongside `source` and `build`

Ok so now you have a new `build` directory, a new `source` directory and a new `Makefile`. 

!!! note
    To (manually) build the documentation from the docstrings run `make html` from the project's root. You can also just use `mkinx build` as explained [here](/#building-the-documentations).

But before that, let's configure a couple things:

# Edit `conf.py`

In the `source` directory, edit the `conf.py` file as follows:

* uncomment lines 15 to 17 and add `sys.path.insert(0, os.path.abspath('..'))`. This allows for two things: future documentation files (`.rst` files in the `source` directory) will be in `conf.py`'s scope (`abspath('.')`) and so will packages alongside it's parent folder (_i.e._ your project's code) (`abspath('..')`):
```python
import os
import sys
sys.path.insert(0, os.path.abspath('.'))
sys.path.insert(0, os.path.abspath('..'))
```

* In order to understand Google Style docstrings, `sphinx` needs an extension. Add `'sphinx.ext.napoleon'` to the `extensions` list (around line 42)

* Change the theme to Read The Docs's template: `html_theme = 'sphinx_rtd_theme'` (around line 80)

That's it! Notice that you can change the `author`, `version`, `realease` and `project` values in this file.

# Generate the Documentation

Sphinx's `autodoc` will do most of the work but you still have to do some of it. Basically you'll write the skeletton of each package's doc and list those in the `index` file. Pretty easy!

## index

In the `index.rst` file generated by `sphinx-quickstart` you'll list the packages that need to be documented:

```
.. toctree::
   :maxdepth: 2
   :caption: Contents:

   matching
   classif
   datasets
```
!!! important
    Notice that there is a _mandatory_ blank line and that there are _exactly_ 3 spaces on the left. 

The above code lists 3 files which should be alongside `index.rst`: `matching.rst`, `classif.rst` and `datasets.rst`.


## Package documentation

Now one of these files, documenting the package `datasets`, may look like this (`datasets.rst`):

```
*************************
``classif`` Documentation
*************************


Here is the autodocumentation of a package. You may write anything you like as in Markdown


Inference
=========

.. automodule:: classif.inference
   :members:

Models
======

.. automodule:: classif.models
   :members:

```

`***` are for title 1, `===` for title 2 and so on, have a look at some [`.rst` cheatsheet](https://github.com/ralsina/rst-cheatsheet/blob/master/rst-cheatsheet.rst)

Basically this file says: put some titles ("classif Documentation", "Inference", "Models") and generate the documentations (`.. automodule::`) for the modules `classif.inference` and `classif.models`. 

These `automodule` are used by `autodoc` which is run by `mkinx` using `make html` in your project.


# Docstrings

IDEs like Visual Code or PyCharm have plugins to automatically generate docstrings.

For instance, Visual Code with the Python Docstring extension would do this:

From
```python
def f(a, b=None):
    return a+b if b else a
```

It would generate 

```python
def f(a, b=None):
    """[summary]
    
    Args:
        a ([type]): [description]
        b ([type], optional): Defaults to None. [description]
    
    Returns:
        [type]: [description]
    """

    return a+b if b else a
```

 Otherwise, here is an example Google style docstring: 

```python
def function_with_types_in_docstring(param1, param2):
    """Example function with types documented in the docstring.

    Args:
        param1 (int): The first parameter.
        param2 (str): The second parameter.

    Returns:
        bool: The return value. True for success, False otherwise.

    

    """


def function_with_pep484_type_annotations(param1: int, param2: str) -> bool:
    """Example function with PEP 484 type annotations.

     `PEP 484`_ type annotations are supported. If attribute, parameter, and
    return types are annotated according to `PEP 484`_, they do not need to be
    included in the docstring:
    .. _PEP 484:
        https://www.python.org/dev/peps/pep-0484/

    Args:
        param1: The first parameter.
        param2: The second parameter.

    Returns:
        The return value. True for success, False otherwise.

    """

```