Last Updated: December 23, 2020
·
25.77K
· OiNutter

Use Markdown README's in Python modules

If, like me, you regularly use Markdown to give your GitHub projects nice pretty README's, but are trying to submit your new swanky Python module to the Python Package Index, you may have hit a bit of a snag. To get your nicely formatted README on your module's PyPi page, you need to use reStructuredTxt. Now you could admit defeat and change your README, or you could do this:

Install Pandoc

Install pyandoc python module

pip install pyandoc

Create a file called register.py and add the following code:

import pandoc
import os

pandoc.core.PANDOC_PATH = '/path/to/pandoc'

doc = pandoc.Document()
doc.markdown = open('README.md').read()
f = open('README.txt','w+')
f.write(doc.rst)
f.close()
os.system("setup.py register")
os.remove('README.txt')

Now add the following code to the top of your setup.py file:

import os
long_description = 'Add a fallback short description here'
if os.path.exists('README.txt'):
    long_description = open('README.txt').read()

and set the longdescription arg equal to `longdescription`

Now just register your module using

python register.py

and your Pypi page should have it's own nicely formatted instructions.

Basically all your doing is creating a temporary reStructeredTxt file for setup.py to read in, but avoiding trying to do any pandoc conversion in setup.py like I originally had, which caused issues for installing on other systems.

12 Responses
Add your response

Here's what I ended up doing:

# I really prefer Markdown to reStructuredText.  PyPi does not.  This allows me
# to have things how I'd like, but not throw complaints when people are trying
# to install the package and they don't have pypandoc or the README in the
# right place.
try:
   import pypandoc
   description = pypandoc.convert('README.md', 'rst')
except (IOError, ImportError):
   description = ''

and then using description in setup() as you'd expect.

over 1 year ago ·

Typo: Seems like "pyandoc" should actually say "pypandoc".

over 1 year ago ·

Unfortunately, on Python 2.7 the command "pypandoc.convert()" can't cope with non-ASCII characters. Is this an issue of restructured text, pypandoc or pandoc?

over 1 year ago ·

Hi, that isn't actually a typo. There is also a module called pyandoc. I'm unaware as to whether that has the same issue with non-ASCII characters though.

over 1 year ago ·

Thanks for making this!

over 1 year ago ·

@xiongchiamiov: I too preferred to use pypandoc instead of pyandoc. However, I modified your code so that if pypandoc had problems, the description would just be the README.md as markdown.

try:
   import pypandoc
   description = pypandoc.convert('README.md', 'rst')
except (IOError, ImportError):
   description = open('README.md').read()
over 1 year ago ·

Following some of the suggestions above, but using the software described in this article, here's a gist of my solution.

https://gist.github.com/aubricus/9184003#file-setup_snippet-py

I went this way mostly because I was also encountering the non-ASCII character issues while using pypandoc (in lieu of pyandoc, which was suggested by some of the commenters).

Also for those interested in sort of managing Pandoc through Homebrew: Install Pandoc With Homebrew

over 1 year ago ·

Clever workaround, but the best solution would be to petition PyPI to support Markdown (as well as Restructured Text). It's a pervasive format, used on Github and StackOverflow. It shouldn't be necessary to learn a new markup language or rewrite your documentation to publish a Python package.

Npm (the Nodejs) package manager and its registry support Markdown readmes. See, for example, https://www.npmjs.org/package/yargs

over 1 year ago ·

If you would like PyPI to support Markdown readmes, please comment on the feature request at https://bitbucket.org/pypa/pypi/issue/148/support-markdown-for-readmes

over 1 year ago ·

Done! Would definitely be better if they supported Markdown without all the faff!

over 1 year ago ·

For those of you using pypandoc to convert, you may encounter an issue, like me, where only the first line of the original readme appears on pypi. You need to add one line to fix that :

try:
    long_description = pypandoc.convert('README.md', 'rst')
    long_description = long_description.replace("\r","") # YOU  NEED THIS LINE
except OSError:
    print("Pandoc not found. Long_description conversion failure.")
    import io
    # pandoc is not installed, fallback to using raw contents
    with io.open('README.md', encoding="utf-8") as f:
        long_description = f.read()

(This piece of code comes from pypandoc repo itself in case you're not convinced)

over 1 year ago ·

Useful, but I prefer rst > <

over 1 year ago ·