pdoc is my go-to documentation tool for small Python projects.
However, when they start to grow, MkDocs and the Material for MkDocs theme make the most sense — they’re easy to install and deploy, and they offer a ton of features for writing engaging documentation.
Love MkDocs* even for non-Python. But, wasn’t aware it could auto-generate from code comments like pdoc? I’d assume one would use pdoc for the API section of a hot mkdocs layout.
Had to recently document a Python library / API; it was not for public consumption. I took inspiration from pyserial [1] and made sparse docstrings which in turn reduced potential clutter making things easier to read and digest; and provide a more elaborate (hand generated) documentation in the sphinx documentation rendered as html/pdf. I quite liked this balance. The obvious trade off is the sphinx documentation may go out of sync with what is in the code, but eh if it happens it won't be the end of the world and is quickly rectified.
I would just say follow pyserial example if that is something you like; look at their source code docstrings vs the documentation including the API bits.
If that's something you like, then just lift their documentation/ wholesale and tailor it to your needs, which is how I started. I also tweaked the sphinx settings to generate a pdf as well, but that was a special thing for the customer we were delivering the library and documentation to.
I'd say neither fork as made great strides since then, but I'm also biased here as the maintainer of pdoc.
There is no pdoc-specific library for link checking as far as I'm aware. It's all plain HTML though, so you can use a more general tool like https://lychee.cli.rs/. :)
They write on documenting variable assignments which don't support pythons __doc__ string:
> To compensate, pdoc will read the abstract syntax tree (an abstract representation of the source code) and include all assignment statements immediately followed by a docstring
I can't really understand that. I am programming Python for 14 years now, and any real codebase I have ever seen documents variables above their declaration. Even if there is some technical reason for it, if I saw a python developer comment what a variable declaration means below that declaration I would at least question their taste.
To me that particular implementation is so bad, that I would prefer pdoc without it.
> I can't really understand that. I am programming Python for 14 years now, and any real codebase I have ever seen documents variables above their declaration. Even if there is some technical reason for it, if I saw a python developer comment what a variable declaration means below that declaration I would at least question their taste.
It’s standard to write docstrings below the declaration they refer to. What you are refering to are comments, not docstrings. I’ve been programming in Python for 15 years and I learnt this quite recently. This gives you in-editor documentation for class attributes and other non-functions.
Let me try to explain why it is that way: First, it's consistent with Python functions. The docstring for functions is below the signature as well. Second, consider a file with only a docstring and then a variable declaration. Here it would be ambiguous if that's the module or the variable docstring. Finally, this behavior is consistent with other tools (and failed standardization efforts) in the space. So yeah - I share your sentiment, but I think it's the most pragmatic approach for pdoc. :)
Maybe it is me, but I find that idea unhinged and aesthetically/semantically offputting to a degree you would have to force me to do it. I know that isn't rational, but hey, it is my personal taste and those may differ.
I much prefer the way Rust did it, so just a separate type of comment-prefix for docstrings. In Rust a regular comment may be
// this is a comment
foo = 1.5;
while a docstring is simply
/// this shows up in docs
foo = 1.5;
with //! for docstrings at a module level. This is elegant. This is simple. It is a pythonic solution. Treating comments below a variable declaration implicity as a docstring is not. At the beginning of class or function declarations, ok (although I also would have prefered that to be above the declaration), but this.. I need a drink.
FWIW I agree that the Rust way is nicer, but I can't impose the Rust way on Python. I guess the secret hack is to use PyO3, which pdoc supports quite well. ;)
not sure if this is a typo or a misunderstanding, but to be clear: pdoc does not treat a comment immediately below a variable declaration as a docstring, it treats an unassigned string immediately following a variable declaration as a docstring, same as how python treats an unassigned string literal immediately following a function signature as a docstring
my_var = 5
"documentation for my_var"
def my_func():
"documentation for my_func"
also worth noting, pdoc didn't invent this design pattern, sphinx did (or perhaps something preceding sphinx?)
and since sphinx is the documentation tool of choice by the python core devs to document python itself, i have to assume they've given this design pattern at least tacit approval... :shrug:
There's a workaround for this case (relevant issue has a link at the top), which is cool, but it uses an "internal" function to solve it, which is not.
pdoc is my go-to documentation tool for small Python projects.
However, when they start to grow, MkDocs and the Material for MkDocs theme make the most sense — they’re easy to install and deploy, and they offer a ton of features for writing engaging documentation.
[0] https://www.mkdocs.org/ [1] https://squidfunk.github.io/mkdocs-material/
Love MkDocs* even for non-Python. But, wasn’t aware it could auto-generate from code comments like pdoc? I’d assume one would use pdoc for the API section of a hot mkdocs layout.
*not just because my initials are MK
You can't directly but there is a plugin for this: https://mkdocstrings.github.io/
Example here: https://quarkslab.github.io/quokka/reference/python/executab...
Had to recently document a Python library / API; it was not for public consumption. I took inspiration from pyserial [1] and made sparse docstrings which in turn reduced potential clutter making things easier to read and digest; and provide a more elaborate (hand generated) documentation in the sphinx documentation rendered as html/pdf. I quite liked this balance. The obvious trade off is the sphinx documentation may go out of sync with what is in the code, but eh if it happens it won't be the end of the world and is quickly rectified.
[1]: https://pythonhosted.org/pyserial/
Hey I’m in the process of documenting a library for my startup, do you have any more thoughts about your process?
I would just say follow pyserial example if that is something you like; look at their source code docstrings vs the documentation including the API bits.
If that's something you like, then just lift their documentation/ wholesale and tailor it to your needs, which is how I started. I also tweaked the sphinx settings to generate a pdf as well, but that was a special thing for the customer we were delivering the library and documentation to.
In the 2021 thread [1] that dang linked to, there was some discussion of friendly and hostile forks. What's the status of the forks?
Are there any libraries similar to Doxylink [2] that ensure that links from Sphinx to pdoc (and vice versa) are valid?
[1] https://news.ycombinator.com/item?id=25903595
[2] https://sphinxcontrib-doxylink.readthedocs.io/en/stable/
I'd say neither fork as made great strides since then, but I'm also biased here as the maintainer of pdoc.
There is no pdoc-specific library for link checking as far as I'm aware. It's all plain HTML though, so you can use a more general tool like https://lychee.cli.rs/. :)
Pdoc is great. I love it.
But there is one blemish.
They write on documenting variable assignments which don't support pythons __doc__ string:
> To compensate, pdoc will read the abstract syntax tree (an abstract representation of the source code) and include all assignment statements immediately followed by a docstring
I can't really understand that. I am programming Python for 14 years now, and any real codebase I have ever seen documents variables above their declaration. Even if there is some technical reason for it, if I saw a python developer comment what a variable declaration means below that declaration I would at least question their taste.
To me that particular implementation is so bad, that I would prefer pdoc without it.
> I can't really understand that. I am programming Python for 14 years now, and any real codebase I have ever seen documents variables above their declaration. Even if there is some technical reason for it, if I saw a python developer comment what a variable declaration means below that declaration I would at least question their taste.
It’s standard to write docstrings below the declaration they refer to. What you are refering to are comments, not docstrings. I’ve been programming in Python for 15 years and I learnt this quite recently. This gives you in-editor documentation for class attributes and other non-functions.
Sphinx reads comments starting with #: above class variables and uses them for documentation.
I wonder why they didn’t take the same approach here and invented a new syntax.
Sphinx is the one who invented new syntax. I just used the syntax Python already had for docstrings, but extended it to variables.
Also, when I first wrote pdoc, it was at a time of immense frustration with both Sphinx and reST.
Comments are not included in the AST. Also, Sphinx does support that syntax: https://stackoverflow.com/a/31764368/735926
Both sound good, it seems like # immediately above a variable should be the first fallback.
Let me try to explain why it is that way: First, it's consistent with Python functions. The docstring for functions is below the signature as well. Second, consider a file with only a docstring and then a variable declaration. Here it would be ambiguous if that's the module or the variable docstring. Finally, this behavior is consistent with other tools (and failed standardization efforts) in the space. So yeah - I share your sentiment, but I think it's the most pragmatic approach for pdoc. :)
Maybe it is me, but I find that idea unhinged and aesthetically/semantically offputting to a degree you would have to force me to do it. I know that isn't rational, but hey, it is my personal taste and those may differ.
I much prefer the way Rust did it, so just a separate type of comment-prefix for docstrings. In Rust a regular comment may be
while a docstring is simply with //! for docstrings at a module level. This is elegant. This is simple. It is a pythonic solution. Treating comments below a variable declaration implicity as a docstring is not. At the beginning of class or function declarations, ok (although I also would have prefered that to be above the declaration), but this.. I need a drink.FWIW I agree that the Rust way is nicer, but I can't impose the Rust way on Python. I guess the secret hack is to use PyO3, which pdoc supports quite well. ;)
not sure if this is a typo or a misunderstanding, but to be clear: pdoc does not treat a comment immediately below a variable declaration as a docstring, it treats an unassigned string immediately following a variable declaration as a docstring, same as how python treats an unassigned string literal immediately following a function signature as a docstring
also worth noting, pdoc didn't invent this design pattern, sphinx did (or perhaps something preceding sphinx?)and since sphinx is the documentation tool of choice by the python core devs to document python itself, i have to assume they've given this design pattern at least tacit approval... :shrug:
pdoc maintainer here. Pleasant surprise to see us on HN again, and happy to answer any questions! :)
Any chance we could get a better solution to this problem: https://git.sr.ht/~chiefnoah/pybare/tree/master/item/pdoc_in...
There's a workaround for this case (relevant issue has a link at the top), which is cool, but it uses an "internal" function to solve it, which is not.
pdoc3 is not pdoc, see https://github.com/mitmproxy/pdoc?tab=readme-ov-file#pdoc-vs....
ah, dang I forgot about that split.
Related. Others?
Show HN: Pdoc, a lightweight Python API documentation generator - https://news.ycombinator.com/item?id=25903595 - Jan 2021 (18 comments)
Pdoc is great. I tried mkdoc and others, but pdoc was so much easier. One command and you're done. Trivial to add to a Github workflow & Github pages.
I'm a big fan of pdoc and have used it in a couple projects.
It makes really nice use of python docstrings and is overall just really easy to use!
[dead]