Sphinx: the simplest usage scenario, how to? [duplicate] - python

I am running Sphinx on a rst file containing automodule but it does not seem to have any effect.
Here are the details: I have a Python project with a file agent.py containing a class Agent in it. I also have a subdirectory apidoc with a file agent.rst in it (generated by sphinx-apidoc):
agent module
============
.. automodule:: agent
:members:
:undoc-members:
:show-inheritance:
I run sphinx with sphinx-build -b html apidoc apidoc/_build with the project's directory as the current working directory.
To make sure the Python files are found, I've included the following in apidoc/conf.py:
import os
import sys
sys.path.insert(0, os.path.abspath('.'))
It runs without errors but when I open the resulting HTML file it only shows "agent module" and everything is blank. Why isn't it showing the class Agent and its members?
Update: the original problem was likely caused by the fact that I had not included sphinx.ext.autodoc in conf.py. Now that I did, though, I get warnings like:
WARNING: invalid signature for automodule ('My Project.agent')
WARNING: don't know which module to import for autodocumenting 'My Project.agent' (try placing a "module" or "currentmodule" directive in the document, or giving an explicit module name)
WARNING: autodoc: failed to import module 'agent'; the following exception was raised:
No module named 'agent'

I'll try answering by putting the "canonical" approach side-by-side with your case.
The usual "getting started approach" follows these steps:
create a doc directory in your project directory (it's from this directory the commands in the following steps are executed).
sphinx-quickstart (choosing separate source from build).
sphinx-apidoc -o ./source ..
make html
This would yield the following structure:
C:\Project
|
| agent.py
|
|---docs
| | make.bat
| | Makefile
| |
| |---build
| |
| |---source
| | conf.py
| | agent.rst
| | index.rst
| | modules.rst
In your conf.py you'd add (after step 2):
sys.path.insert(0, os.path.abspath(os.path.join('..', '..')))
and in index.rst you'd link modules.rst:
Welcome to Project's documentation!
================================
.. toctree::
:maxdepth: 2
:caption: Contents:
modules
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
Now compare the above with what you have - from what you shared in your question:
C:\Project
|
| agent.py
|
|---apidoc
| | agent.rst
| | conf.py
| |
| |-- _build
You ran:
sphinx-build -b html apidoc apidoc/_build
and in your conf.py:
sys.path.insert(0, os.path.abspath('.'))
Your error stacktrace says it couldn't find the module agent. That's probably because you didn't go 1 level down in your conf.py (it's pointing to the path with .rst, not the path with .py), this should work:
sys.path.insert(0, os.path.abspath('..')). Also, if you didn't manually edit/connect your modules.rst in your index.rst you are likely to only see that module.
You may care to notice the signatures of the sphinx commands at play:
sphinx-apidoc [OPTIONS] -o <OUTPUT_PATH> <MODULE_PATH>
sphinx-build [options] <sourcedir> <outputdir> [filenames …]
<sourcedir> refers to where .rst are, and <MODULE_PATH> to where .py are. <OUTPUT_PATH> to where .rst are placed, and <outputdir> to where .html are placed.
Please also notice, you mentioned: "the project's directory as the current working directory." I've seen "working directory" mentioned in sphinx threads on stackoverflow, interchangeably as both the Project base directory, or the docs directory. However, if you search the Sphinx documentation for "working directory" you'll find no mention of it.
Finally, there is an advantage to using the file/directory structure of the "getting started approach". It basically "puts you on the same page" with most threads on the Sphinx tag, and that way alleviates the mental work of mapping the cases to different directory/file structures.
I hope this helps.

Related

Can you autodoc only submodules using sphinx-apidoc?

I use sphinx-click extension for my click application, and i want to use sphinx-apidoc to generate .rst files for only submodules.
I've been working with pythons Sphinx documentation library for about a year now, and I have a usecase... I cannot quite figure out.. maybe I'm just blind right now.
Anyways, I have a cli tool structured something like
my_tool/
+-- __init__.py
+-- cli_entry.py
+-- utils
| +-- __init__.py
| +-- foo.py
| +-- bar.py
Where cli_entry is a click application, and it imports my_tool.utils.foo and my_tools.utils.bar
Since this is using the Click library. I've decided to use the sphinx_click extension to document any command that is in cli_entry.py (which documents all the commands great).
But heres the issue, I want to use sphinx-apidoc to generate the .rst files for everything that is in the ./my_tool/utils/ modules.
When I use the command as sphinx-apidoc -o ../docs/utils my_tool/utils the output files that I get include
docs/
+-- utils
| +-- module.rst
| +-- utils.rst
Which looks great at first, but upon opening utils.rst the file looks something like
utils package
=============
Submodules
----------
utils.foo module
----------------------
.. automodule:: utils.foo
:members:
:undoc-members:
:show-inheritance:
utils.bar module
----------------------
.. automodule:: utils.bar
:members:
:undoc-members:
:show-inheritance:
Then when I build the documentation using make html (from sphinx generated makefile) I get an error saying Failed to import 'utils.foo': no module named utils.foo thats because the import should exist as my_tool.utils.foo
How can I use sphinx-apidoc to generate only submodules and include the correct import paths?? Maybe its something I'm missing in the conf.py.. maybe it's an option I'm missing from sphinx-apidoc?
EDIT: I should mention that I could use the exclude_pattern argument... but I would prefer to not have to specify each cli file in my root. ex. In the case that I have cli_entry.py, cli_commandgroup1.py... cli_commandgroupN.py. I want this solution to be dynamic enough to just support only submodules.
EDIT: I tried using sphinx-apidoc -o ../docs/utils my_tool/ and this creates the following output
docs/
+-- utils
| +-- module.rst
| +-- my_tool.cli_entry.rst
| +-- my_tool.utils.rst
Now in the my_tool.utils.rst file, the imports are correct, and the docs can be generated.
my_tool.utils.foo module
----------------------
.. automodule:: my_tool.utils.foo
:members:
:undoc-members:
:show-inheritance:
The issue with specifying my_tool/ is that my_tool.cli_entry.rst gets created, when this .rst file would already be created using the click-sphinx extension.

Python Sphinx Autosummary: failed to import module

I am trying to create autosummary using sphinx-autosummary for my python code which looks like as follows:
main
├───modA
| ├───__init__.py
| ├───modA.py
├───modB
| ├───__init__.py
| ├───modB.py
├───docs
| ├───build
| └───source
| ├───refs
| | |───_autosummary
| | |───index.rst
| | |───modA.rst
| | |───modB.rst
| ├───index.rst
| ├───conf.py
As mentioned in Sphinx documentation, I inserted the abspath of my working directory, added sphinx.ext.autodoc to the list of extensions, and set autosummary_generate to True in conf.py.
import os
import sys
sys.path.insert(0, os.path.abspath('../..'))
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.autodoc',
"sphinx.ext.autosummary",
'sphinx.ext.coverage',
'sphinx.ext.napoleon'
]
autosummary_generate = True
Next, within docs/index.rst, I added a reference to the refs/ folder.
.. toctree::
:maxdepth: 2
refs/index
The refs/index.rst has reference to modA.rst and modB.rst.
.. toctree::
:maxdepth: 2
modA
modB
In modA.rst and modB.rst, I am trying to create autosummaries.
modA.rst
Attributes
~~~~~~~~~~
.. autosummary::
:toctree: _autosummary
modA.modA.create_job
modB.rst
Attributes
~~~~~~~~~~
.. autosummary::
:toctree: _autosummary
modB.modB.get_jobs
While the code is working for modA.rst, it fails for modB.rst. The error says,
failed to import 'modB.modB.get_jobs': no module named modB.modB.get_jobs
I tried putting .. currentmodule::modB and .. currentmodule::main before the autosummary, but with no success. I even tried putting .. module::modB and .. module::main before autosummary, but even that is not working. I searched a lot on the internet, but unable to understand why it's not working.
Edit-1: Added __init__.py in both the folders.
I had similar issue in using Sphinx.
After some experiments, I suspect that the error message like failed to import XXX: no module named XXX does not necessarily mean the module XXX cannot be found. Instead, in my experiment, there is some error in importing XXX.
In my case, the module XXX itself is importing some package YYY that has not been installed. Since Sphinx import XXX in order to extract docstring, it found an error in this import attempt. After I removed that import YYY statement, I can successfully build the documentation.
I had a similar issue.
My reason of failed import error was that the module modA.modA, specified under .. autosummary:: directive, had imports of not installed libraries.
Attributes
~~~~~~~~~~
.. autosummary::
:toctree: _autosummary
modA.modA.create_job
But in general your reason for failed to import error can be different, because the function that imports modules from .. autosummary:: directive catches all errors and autosummary prints to output the same error message.
Here is the related issue on github https://github.com/sphinx-doc/sphinx/issues/7989
I suggest to import your modules modA.modA, modB.modB and see if there are any errors during importing.
It seems that when Sphinx can't handle a python import it will show the generic module import warning (".. no module named ...") as you mentioned. It seems that this warning can even occur when all imported python package are correctly installed in the environment and it just means that something could not be imported.
A workaround to get rid of this warnings is to mock external python libraries by using the autodoc_mock_imports in the conf.py file of Sphinx.
For example:
import flask
import mongoengine
...
# your python code
Example conf.py with mocking flask:
autodoc_mock_imports = ["flask", "mongoengine"]
In this case Sphinx will ignore these imports and autosummary may be able to build the summary correctly without any errors.
To be more specific to your case: It could be that your python file 'modB.modB' contains an import statement that Sphinx can't handle and that you either need to install the python package correctly or to mock the specific libraries imported in the modB.modB file.

How to import modules from adjacent package without setting PYTHONPATH

I have a python 2.7 project which I have structured as below:
project
|
|____src
| |
| |__pkg
| |
| |__ __init__.py
|
|____test
|
|__test_pkg
| |
| |__ __init__.py
|
|__helpers
| |
| |__ __init__.py
|
|__ __init__.py
I am setting the src folder to the PYTHONPATH, so importing works nicely in the packages inside src. I am using eclipse, pylint inside eclipse and nosetests in eclipse as well as via bash and in a make file (for project). So I have to satisfy lets say every stakeholder!
The problem is importing some code from the helpers package in test. Weirdly enough, my test is also a python package with __init__.py containing some top level setUp and tearDown method for all tests. So when I try this:
import helpers
from helpers.blaaa import Blaaa
in some module inside test_pkg, all my stakeholders are not satisfied. I get the ImportError: No module named ... and pylint also complains about not finding it. I can live with pylint complaining in test folders but nosetests is also dying if I run it in the project directory and test directory. I would prefer not to do relative imports with dot (.).
The problem is that you can not escape the current directory by importing from ..helpers.
But if you start your test code inside the test directory with
python3 -m test_pkg.foo
the current directory will be the test directory and importing helpers will work. On the minus side that means you have to import from . inside test_pkg.

Sphinx autodoc in Flask ImportError: no module named

I'm trying to set Sphinx autodoc for my Flask project.
Here is schema of my project:
Folder
|--docs
| |--build
| |--source
| conf.py
| index.rst
| mod_ololo.rst
| ....
|--flask_app
| |--celery_worker.py
| |--config.py
| |--run.py
| |--app
| |--__init__.py
| |--temp.py
| |--mod_search
| ....
| |--mod_files
| |--__init__.py
| ....
and so on.
In conf.py I already set:
sys.path.insert(0, os.path.abspath("../.."))
I'm trying to add content of temp.py to my documentation.
Here is content of mod_ololo.rst:
*******************************************
OLOLO module
*******************************************
Ololololo
======
.. automodule:: flask_app.app.temp
:members:
And when I run make html for separate scripts - Sphinx autodoc works, but in case of my flask project it doesn't and shows me the following error:
ImportError: No module named 'config'
Where config is config.py
Purely a guess, but the config module that your sphinx builder isn't finding is probably the config.py module in your flask_app folder. There's likely an import config statement somewhere in your flask_app/app/temp.py file, so when sphinx tries to run the automodule procedure on it, it gets a failure on that import.
From your directory structure it looks like your flask_app folder is not a python package, so you might have to add that folder rather than (or in addition to) its parent folder to the path in your conf.py file:
sys.path.insert(0, os.path.abspath('../../flask_app'))
Also, you'll likely have to change your automodule statement in mod_ololo.rst not to reference flask_app as a package:
.. automodule:: app.temp
If you actually do intend to use flask_app as a package, then you need an __init__.py file in that folder, and your import statements within your project should be absolute from the top flask_app package, i.e.:
from flask_app import config
rather than
import config

Sphinx autodoc not importing anything?

I'm trying to use sphinx (in conjunction with autodoc and numpydoc) to document my module, but after the basic setup, running make html produces just the basic html with nothing from the docstrings included. I'm running Python 3.3, the outline of the project structure is as follows:
Kineticlib
|--docs
| |--build
| |--source
| | |--conf.py
|--src
| |--kineticmulti
| | |--__init__.py
| | |--file1.py
| | |--file2.py
|--setup.py
__init__.py is empty, and in conf.py in the docs/source directory I've added sys.path.insert(0, os.path.abspath('../..'))
Running make html in the docs directory gives the following output:
sphinx-build -b html -d build/doctrees source build/html
Running Sphinx v1.2.2
loading pickled environment... done
building [html]: targets for 0 source files that are out of date
updating environment: 0 added, 0 changed, 0 removed
looking for now-outdated files... none found
no targets are out of date.
Build finished. The HTML pages are in build/html.
So, what am I doing wrong?
Did you run sphinx-apidoc in the docs/source directory? This will generate the .rst files used to make the html. From man sphinx-apidoc,
sphinx-apidoc [options] -o <outputdir> <sourcedir> [pathnames ...]
You'll need to include (at a minimum) the outputdir (where the .rst files will go, ./ should work) and the sourcedir which should point to your package (looks like ../../src/kineticmulti should work)
As it is being said you should do:
sphinx-apidoc [options] -o <outputdir> <sourcedir> [pathnames ...]
Sometime modifying your conf.py to import some source modules are also needed. As well as adding some docs to class in order to load its method docs (can be true only for private classed, but I've been stuck on that).

Categories