jbms / sphinx-immaterial

Adaptation of the popular mkdocs-material material design theme to the sphinx documentation system
https://jbms.github.io/sphinx-immaterial/
Other
203 stars 32 forks source link

Does a Python piece of software need to be a package to use python.apigen? #237

Closed claytonEtillman closed 1 year ago

claytonEtillman commented 1 year ago

First off, great package! The generated docs from your example and the galois package (the author of which pointed me here from StackOverflow; thanks mhostetter!) look fantastic.

Now if I could just get the python.apigen to work for me to get started on using the package to create similarly great docs. Before I spend another day trying to get it to work, does the Python code set I'm trying to document need to use setuptools (or distutils) to create a package for this to work?

I keep getting error messages no matter how I try to emulate the two libraries' setup:

python-apigen-group:: logic -> source/index.rst.rst:13: WARNING: No top-level Python API group named: 'XXXXX', valid groups are: []

python-apigen-entity-summary:: predict_lgc -> source/index.rst.rst:13: WARNING: No Python entity named: 'predict_lgc'

If not, cool. I'll then update with more details on how I've set it up so we can figure out my idiocy together. I got it to work with automodule. I'd just like to know if I need to implement setuptools before spending more time on it.

jbms commented 1 year ago

No, there is no need to use setuptools or any other packaging requirements to use it.

2bndy5 commented 1 year ago

does the Python code set I'm trying to document need to use setuptools (or distutils) to create a package for this to work?

No. Our docs' sample pkg (tensorstore_demo) is just a couple modules located in our docs/tensorestaore_demo folder. it does not require an install script to document.

Please read the docs about using the python.apigen extension: https://jbms.github.io/sphinx-immaterial/apidoc/python/apigen.html#directive-python-apigen-entity-summary

claytonEtillman commented 1 year ago

Wow, thanks for the quick responses! I'm using numpy format for the docstrings and put in a

    Group:
        logic

while including the extension sphinx.ext.napoleon.

Still, even if I messed that up, wouldn't they be available through the default groups?

Give me about an hour, and I'll give you more details. Thanks, y'all!

2bndy5 commented 1 year ago

I misread the error. You can document entire groups or individual entities. It looks like your trying to do the later without specifying the entity's namespace (the module name), but I don't know for sure without seeing the src that you're trying to document.

claytonEtillman commented 1 year ago

Here's more context:

I'm using the two folder (source & build) format for Sphinx. Here's the folder skeleton of my code:

- api
  - predict
      - logic
           - predict_lgc.py
      - docs3
           - source
                  - conf..py
                  - index.rst
           - build

Here is the way I set up conf.py:

sys.path.insert(0, os.path.abspath('../../..'))
import predict
print(sys.path) <this prints "['my_folder/api', ...]">

extensions = [
    'sphinx.ext.autodoc',
    'sphinx.ext.napoleon',
    'sphinx_immaterial',
    'sphinx_immaterial.apidoc.python.apigen',
]

source_suffix = [".rst"]

html_theme = 'sphinx_immaterial'

python_apigen_modules = {'predict.logic': 'python_apigen_generated/predict.'}
python_apigen_default_groups = [
    ("class:.*", "Classes"),
    ("data:.*", "Variables"),
    ("function:.*", "Functions"),
    ("classmethod:.*", "Class methods"),
    ("method:.*", "Methods"),
    (r"method:.*\.[A-Z][A-Za-z,_]*", "Constructors"),
    (r"method:.*\.__[A-Za-z,_]*__", "Special methods"),
    (r"method:.*\.__(init|new)__", "Constructors"),
    (r"method:.*\.__(str|repr)__", "String representation"),
    ("property:.*", "Properties"),
    (r".*:.*\.is_[a-z,_]*", "Attributes"),
]
python_apigen_show_base_classes = True

Then in `api.predict.logic.predict_lgc.py:

class ParamSet(Enum):
    """Testing autodoc.

    Group:
        logic
    """
    TRAINING_DATA = 'training_data'
    TRAINED_MODEL = 'trained_model'

Then in index.rst:

.. Predict API documentation master file, created by
   sphinx-quickstart on Mon Mar 27 20:38:52 2023.
   You can adapt this file completely to your liking, but it should at least
   contain the root `toctree` directive.

Welcome to Predict API's documentation!
============================================

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

.. python-apigen-entity-summary:: predict_lgc

..
    python-apigen-group:: logic

..
    automodule:: predict.logic.predict_lgc
   :members:

Indices and tables
==================

* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
claytonEtillman commented 1 year ago

If I "uncomment" the automodule section of index.rst, I get all the autodocs, but neither the entity-summary nor the apigen-group produce results without an error.

jbms commented 1 year ago

The first thing to check is whether anything is getting written to the python_apigen_generated directory of your source directory.

claytonEtillman commented 1 year ago

The folder is generated, but there is nothing in it. I get this error message: api/predict/docs3/source/index.rst.rst:13: WARNING: No Python entity named: 'predict_lgc'

... after running: make clean, make html

2bndy5 commented 1 year ago

You might need a blank __init__.py for each folder in your pkg. Without this, python might not be recognizing the predict folder (& any of its subfolders) as an installed pkg (or sub-pkg).

jbms commented 1 year ago

Yes, __init__.py is required. If that doesn't fix it, can you provide a self-contained example in a zip file that reproduces the issue?

claytonEtillman commented 1 year ago

Ok, I think I have fixed the first problem. api.predict.logic is not a module, so obviously that would not work. When I change it to api.predict.logic.predict_lgc, it then outputs to the python_apigen_generated directory (many, many files - including submodules of each module imported including 3rd party). However, I now get 123 errors instead of 1. Let me take a look at what's going on here now for a bit. I really appreciate the assistance. Sometimes you just need to "speak" the logic to see what's not 💯.

Thanks, @2bndy5, I have __init__.py files in each directory.

claytonEtillman commented 1 year ago

A small sample of files now in the python_apigen_generated directory:

predict.OrderedDict.__reduce__.rst
predict.OrderedDict.__repr__.rst
predict.OrderedDict.__ror__.rst
predict.OrderedDict.__setitem__.rst
predict.OrderedDict.clear.rst
predict.OrderedDict.copy.rst
predict.OrderedDict.fromkeys.rst
predict.OrderedDict.items.rst
predict.OrderedDict.keys.rst
predict.OrderedDict.move_to_end.rst
...
predict.Baseline.cuda.rst
jbms commented 1 year ago

If you define an __all__ variable in your module, that will limit what gets documented.

claytonEtillman commented 1 year ago

Thanks, @jbms, I'll try that and let you all know the outcome.

2bndy5 commented 1 year ago

Looks like the python.apigen is trying to document stdlib stuff again (see discussion in #152).

2bndy5 commented 1 year ago

I'm closing this as it was more of a question that ended with reference to #152