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
Related
I moved my tests to a separate subfolder in the project, and now testing my classes does not work anymore.
|-- project
| |main.py
| |-- lib
| | |__init__.py
| | |myclass.py
| |-- tests
| | |__init__.py
| | |test_myclass.py
Both init files are empty.
but when I run the test (i'm in the tests folder and typing python -m unittest) I get the following error:
ModuleNotFoundError: No module named 'lib'
at the line from lib.myclass import Myclass
I also saw that one could use sys and os to add the parent folder to the path, but each time that I do it, the code that adds it is automatically going under all the imports in vscode (I guess due to some automatic formatting?) and therefore is not ran on time.
That's because once you are in tests folder your working directory dir is:
.\
.\test_mycalss.py
You should run tests from project so your working directory will cover whole tree:
.\
.\main.py
.\lib\
and so on
Your project cannot view lib.myclass because in folder tests there is no folder lib.
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.
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.
I get a directory like the following:
__init__.py
common
| \
| __init__.py
| util.py
|
sites
\
__init__.py
site_a.py
The folder where 'common' and 'sites' locat is named 'father'
I'd like to import common/util.py from inside sites/site_a.py.
I tried to use: from father.common import util
But pycharm reports: unsolved reference 'father'
How shall I import util.py from inside site_a.py?
PS: I don't want to change my PYTHONPATH setting, so please use correct python codes only.
How would I organize my python imports so that I can have a directory like this.
project
| \
| __init__.py
|
src
| \
| __init__.py
| classes.py
|
test
\
__init__.py
tests.py
And then inside /project/test/tests.py be able to import classes.py
I've got code looking like this in tests.py
from .. src.classes import(
scheduler
db
)
And am getting errors of
SystemError: Parent module '' not loaded, cannot perform relative import
Anyone know what to do?
Python adds the folder containing the script you launch to the PYTHONPATH, so if you run
python test/tests.py
Only the folder test is added to the path (not the base dir that you're executing the command in).
Instead run your tests like so:
python -m test.tests
This will add the base dir to the python path, and then classes will be accessible via a non-relative import:
from src.classes import etc
If you really want to use the relative import style, then your 3 dirs need to be added to a package directory
package
* __init__.py
* project
* src
* test
And you execute it from above the package dir with
python -m package.test.tests
See also:
https://docs.python.org/2/using/cmdline.html
http://www.stereoplex.com/blog/understanding-imports-and-pythonpath