Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Converts Swagger YAML to a static HTML document (needs: pip install PyYAML)
#!/usr/bin/python
#
# Copyright 2017 Otto Seiskari
# Licensed under the Apache License, Version 2.0.
# See http://www.apache.org/licenses/LICENSE-2.0 for the full text.
#
# This file is based on
# https://github.com/swagger-api/swagger-ui/blob/4f1772f6544699bc748299bd65f7ae2112777abc/dist/index.html
# (Copyright 2017 SmartBear Software, Licensed under Apache 2.0)
#
"""
Usage:
python swagger-yaml-to-html.py < /path/to/api.yaml > doc.html
"""
import yaml, json, sys
TEMPLATE = """
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Swagger UI</title>
<link href="https://fonts.googleapis.com/css?family=Open+Sans:400,700|Source+Code+Pro:300,600|Titillium+Web:400,600,700" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/3.24.2/swagger-ui.css" >
<style>
html
{
box-sizing: border-box;
overflow: -moz-scrollbars-vertical;
overflow-y: scroll;
}
*,
*:before,
*:after
{
box-sizing: inherit;
}
body {
margin:0;
background: #fafafa;
}
</style>
</head>
<body>
<div id="swagger-ui"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/3.24.2/swagger-ui-bundle.js"> </script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/3.24.2/swagger-ui-standalone-preset.js"> </script>
<script>
window.onload = function() {
var spec = %s;
// Build a system
const ui = SwaggerUIBundle({
spec: spec,
dom_id: '#swagger-ui',
deepLinking: true,
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIStandalonePreset
],
plugins: [
SwaggerUIBundle.plugins.DownloadUrl
],
layout: "StandaloneLayout"
})
window.ui = ui
}
</script>
</body>
</html>
"""
spec = yaml.load(sys.stdin, Loader=yaml.FullLoader)
sys.stdout.write(TEMPLATE % json.dumps(spec))
@Vichoko

This comment has been minimized.

Copy link

@Vichoko Vichoko commented Feb 19, 2018

This script is perfect.
After a long day trying different openapi yaml to html applications, this is the most beautiful and easy to use i've found.

@dolzenko

This comment has been minimized.

Copy link

@dolzenko dolzenko commented May 15, 2018

Worked, thanks!

@vsawant1608

This comment has been minimized.

Copy link

@vsawant1608 vsawant1608 commented May 29, 2018

D:\convertyaml>python swagger-yaml-to-html.py < D:\convertyaml\swagger.yaml > do
c.html
Traceback (most recent call last):
File "swagger-yaml-to-html.py", line 8, in
import yaml, json, sys
ImportError: No module named yaml

Getting this error

@1jkunz1

This comment has been minimized.

Copy link

@1jkunz1 1jkunz1 commented Jun 12, 2018

Gorgeous work.

@xPlorinRolyPoly

This comment has been minimized.

Copy link

@xPlorinRolyPoly xPlorinRolyPoly commented Jun 12, 2018

Awesome! And it works 👍 Thank you very much!

@ostriandoni

This comment has been minimized.

Copy link

@ostriandoni ostriandoni commented Jun 23, 2018

This script is super awesome. Thank you very much!

@oseiskar

This comment has been minimized.

Copy link
Owner Author

@oseiskar oseiskar commented Jul 3, 2018

@vsawant1608 you need to install the PyYAML package for this to work (pip install PyYAML)

@adudiapis

This comment has been minimized.

Copy link

@adudiapis adudiapis commented Jul 3, 2018

How long will it take to generate page? Mine is running for more than couple of min.

@DjleeSB

This comment has been minimized.

Copy link

@DjleeSB DjleeSB commented Jul 16, 2018

It's Awesome!!!!

@DjleeSB

This comment has been minimized.

Copy link

@DjleeSB DjleeSB commented Jul 17, 2018

I found few flaws. Search bar at top of html page was not working...Some icon was not displayed correctly. For example close icon of Authorize layered pop-up.

@DjleeSB

This comment has been minimized.

Copy link

@DjleeSB DjleeSB commented Jul 17, 2018

Can you add this code next line of 'div id="swagger-ui"'? It would fix "missing icons" flaw.

<div id="swagger-ui"></div>
 <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="position:absolute;width:0;height:0">
  <defs>
    <symbol viewBox="0 0 20 20" id="unlocked">
          <path d="M15.8 8H14V5.6C14 2.703 12.665 1 10 1 7.334 1 6 2.703 6 5.6V6h2v-.801C8 3.754 8.797 3 10 3c1.203 0 2 .754 2 2.199V8H4c-.553 0-1 .646-1 1.199V17c0 .549.428 1.139.951 1.307l1.197.387C5.672 18.861 6.55 19 7.1 19h5.8c.549 0 1.428-.139 1.951-.307l1.196-.387c.524-.167.953-.757.953-1.306V9.199C17 8.646 16.352 8 15.8 8z"></path>
    </symbol>

    <symbol viewBox="0 0 20 20" id="locked">
      <path d="M15.8 8H14V5.6C14 2.703 12.665 1 10 1 7.334 1 6 2.703 6 5.6V8H4c-.553 0-1 .646-1 1.199V17c0 .549.428 1.139.951 1.307l1.197.387C5.672 18.861 6.55 19 7.1 19h5.8c.549 0 1.428-.139 1.951-.307l1.196-.387c.524-.167.953-.757.953-1.306V9.199C17 8.646 16.352 8 15.8 8zM12 8H8V5.199C8 3.754 8.797 3 10 3c1.203 0 2 .754 2 2.199V8z"/>
    </symbol>

    <symbol viewBox="0 0 20 20" id="close">
      <path d="M14.348 14.849c-.469.469-1.229.469-1.697 0L10 11.819l-2.651 3.029c-.469.469-1.229.469-1.697 0-.469-.469-.469-1.229 0-1.697l2.758-3.15-2.759-3.152c-.469-.469-.469-1.228 0-1.697.469-.469 1.228-.469 1.697 0L10 8.183l2.651-3.031c.469-.469 1.228-.469 1.697 0 .469.469.469 1.229 0 1.697l-2.758 3.152 2.758 3.15c.469.469.469 1.229 0 1.698z"/>
    </symbol>

    <symbol viewBox="0 0 20 20" id="large-arrow">
      <path d="M13.25 10L6.109 2.58c-.268-.27-.268-.707 0-.979.268-.27.701-.27.969 0l7.83 7.908c.268.271.268.709 0 .979l-7.83 7.908c-.268.271-.701.27-.969 0-.268-.269-.268-.707 0-.979L13.25 10z"/>
    </symbol>

    <symbol viewBox="0 0 20 20" id="large-arrow-down">
      <path d="M17.418 6.109c.272-.268.709-.268.979 0s.271.701 0 .969l-7.908 7.83c-.27.268-.707.268-.979 0l-7.908-7.83c-.27-.268-.27-.701 0-.969.271-.268.709-.268.979 0L10 13.25l7.418-7.141z"/>
    </symbol>


    <symbol viewBox="0 0 24 24" id="jump-to">
      <path d="M19 7v4H5.83l3.58-3.59L8 6l-6 6 6 6 1.41-1.41L5.83 13H21V7z"/>
    </symbol>

    <symbol viewBox="0 0 24 24" id="expand">
      <path d="M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z"/>
    </symbol>
  </defs>
 </svg>
@yousan

This comment has been minimized.

Copy link

@yousan yousan commented Aug 24, 2018

Thank you very much 👍

I made a Docker container from this Python script.

docker run -i yousan/swagger-yaml-to-html < petstore.yaml > petstore.html

https://github.com/yousan/swagger-yaml-to-html

@gennamon

This comment has been minimized.

Copy link

@gennamon gennamon commented Nov 9, 2018

Perfect! Thanks

@oseiskar

This comment has been minimized.

Copy link
Owner Author

@oseiskar oseiskar commented Nov 10, 2018

How long will it take to generate page? Mine is running for more than couple of min.

@adudiapis you probably forgot to pipe the input to file to the script (notice the <)

python swagger-yaml-to-html.py < /path/to/api.yaml > doc.html
@bunyk

This comment has been minimized.

Copy link

@bunyk bunyk commented Nov 14, 2018

Awesome, it helped a lot.

But I just realised that I could just paste your template as static html, paste openapi spec in the same folder, and then instead of spec argument, provide url argument with path to my yaml spec. Swagger UI will parse and load YAML by itself, no need for additional library.

@james-jjj

This comment has been minimized.

Copy link

@james-jjj james-jjj commented Feb 18, 2019

Thanks !!!

@roberso

This comment has been minimized.

Copy link

@roberso roberso commented Feb 20, 2019

Please update the level of swagger-ui used in the template. The current one has issues with complex (recursive response definitions) and makes the input fields readonly.

@Maxvien

This comment has been minimized.

Copy link

@Maxvien Maxvien commented Mar 22, 2019

Gorgeous work.

@hestellez

This comment has been minimized.

Copy link

@hestellez hestellez commented Apr 9, 2019

I have some datetime examples in my YAML; I was getting some parse errors:

TypeError: Object of type datetime is not JSON serializable

I add some code I got from stackoverflow...

class NoDatesSafeLoader(yaml.SafeLoader):
    @classmethod
    def remove_implicit_resolver(cls, tag_to_remove):
        """
        Remove implicit resolvers for a particular tag

        Takes care not to modify resolvers in super classes.

        We want to load datetimes as strings, not dates, because we
        go on to serialise as json which doesn't have the advanced types
        of yaml, and leads to incompatibilities down the track.
        """
        if not 'yaml_implicit_resolvers' in cls.__dict__:
            cls.yaml_implicit_resolvers = cls.yaml_implicit_resolvers.copy()

        for first_letter, mappings in cls.yaml_implicit_resolvers.items():
            cls.yaml_implicit_resolvers[first_letter] = [(tag, regexp) 
                                                         for tag, regexp in mappings
                                                         if tag != tag_to_remove]

NoDatesSafeLoader.remove_implicit_resolver('tag:yaml.org,2002:timestamp')

spec = yaml.load(sys.stdin, Loader=NoDatesSafeLoader)
sys.stdout.write(TEMPLATE % json.dumps(spec))
@chenlujjj

This comment has been minimized.

Copy link

@chenlujjj chenlujjj commented Apr 30, 2019

PPPPerfect script !!! Thanks

@lputcha

This comment has been minimized.

Copy link

@lputcha lputcha commented Apr 30, 2019

Hi,
The script generates the HTML in a jiffy. But the alignment of objects is not inline with the input YAML file.
How can we retain the order of objects in the output HTML file to be same as the input YAML file.

Thanks in advance,
Lak.

@Rikusor

This comment has been minimized.

Copy link

@Rikusor Rikusor commented May 14, 2019

This script is 10/10. Thanks for sharing! 👍

@jkilgrow

This comment has been minimized.

Copy link

@jkilgrow jkilgrow commented May 30, 2019

This is absolute GOLD!!

@yanf820

This comment has been minimized.

Copy link

@yanf820 yanf820 commented Jun 25, 2019

Thank you! It works.

@Creat1veM1nd

This comment has been minimized.

Copy link

@Creat1veM1nd Creat1veM1nd commented Jul 17, 2019

Absolute awesome!

The only thing which does not work for me are Umlauts. They are shown as "ü" instead of "ü" - how to solve ?

Beside that, I also get this warning:
../swagger-to-html.py:81: YAMLLoadWarning: calling yaml.load() without Loader=... is deprecated, as the default Loader is unsafe. Please read https://msg.pyyaml.org/load for full details. spec = yaml.load(sys.stdin)

Thanks in advance for any help!

@oseiskar

This comment has been minimized.

Copy link
Owner Author

@oseiskar oseiskar commented Jul 17, 2019

@Creat1veM1nd The umlauts are likely a problem with your terminal's (or text editor's) locale settings (try typing locale, does it say "UTF-8" somewhere?). When everything is correctly set up as UTF-8, umlauts work fine too.

@Creat1veM1nd

This comment has been minimized.

Copy link

@Creat1veM1nd Creat1veM1nd commented Jul 17, 2019

@oseiskar
my file is UTF-8 encoded, I just doublechecked it (I am editing with Visual Code). Also UTF-8 BOM did not work. Strangely switching to ISO8859-1 gave me the proper Umlauts in the generated file.

Edit: If setting the encoding to ISO in Visual Code I do get a proper HTML when running the python script, but on the other side, the preview in Visual Code does not show proper Umlauts. Switching the encoding is a workaround but not really a solution. So, any other suggestions ?

@Creat1veM1nd

This comment has been minimized.

Copy link

@Creat1veM1nd Creat1veM1nd commented Jul 23, 2019

I got it working. No matter if the file is UTF-8 or not, the encoding which is chosen by python when reading from sys.stdin is set automatically. You can change it with a commandline option.

As for the warning: solved that, too.

@Abhijot

This comment has been minimized.

Copy link

@Abhijot Abhijot commented Jul 30, 2019

when I run this python file, from cmd I only see YAMLLoadWarning: calling yaml.load() without Loader=... is deprecated, as the default Loader is unsafe. Please read https://msg.pyyaml.org/load for full details.
spec = yaml.load(sys.stdin). I know this is just warning but how can I see the html page on browser, I mean I don't see any thing popping up on browser. Please help I want to see the doc.html showing up.

@oseiskar

This comment has been minimized.

Copy link
Owner Author

@oseiskar oseiskar commented Jul 30, 2019

I now fixed the PyYAML warning introduced by a recent-ish PyYAML update.

@Abhijot the warning did prevent the script from producing any output. Please check that you pipe the input and output correctly when running the script (see this comment).

@Abhijot

This comment has been minimized.

Copy link

@Abhijot Abhijot commented Jul 30, 2019

@oseiskar It still hangs at "spec = yaml.load(sys.stdin)" with the same warning "swagger-yaml-to-html.py:161: YAMLLoadWarning: " . I have specified the input and output correctly " python swagger-yaml-to-html.py < /C:/Users/amann/Downloads/swagger.yaml > doc.html " in my case. I do not know what is the issue here in python script file. Please give me some inputs as it is urgent work and we are stuck.

@jkilgrow

This comment has been minimized.

Copy link

@jkilgrow jkilgrow commented Jul 30, 2019

@Abhijot , The usage of the script is:
python swagger-yaml-to-html.py < file.yaml > file.html
You have to feed the script a yaml file and tell it to redirect to an html file. Then, you open up that html file in your browser.

Untitled

Does that help?

@Abhijot

This comment has been minimized.

Copy link

@Abhijot Abhijot commented Jul 30, 2019

@jkilgrow got the point. Thank you very much. Its working now

@Abhijot

This comment has been minimized.

Copy link

@Abhijot Abhijot commented Aug 5, 2019

i am trying to use this script as a python script maven plugin inside my pom.xml file. Can somebody help how can I put it. I tried something as shown in my code below, but i am getting error. Below is my code. I tried to follow https://www.bswen.com/2018/04/maven-Execute-python-scripts-in-maven-projects

    <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>exec-maven-plugin</artifactId>
        <version>1.6.0</version>
        <executions>
            <execution>
                <configuration>
                    <executable>python</executable>
                    <workingDirectory>${basedir}</workingDirectory>
                    <arguments>
                        <argument>/swagger-yaml-to-html.py</argument>  
                      <argument>/swagger.yaml</argument>
                       <argument>/out/doc.html</argument>
                     
                    </arguments>
                   
                </configuration>
                <id>python_build</id>
                <phase>generate-resources</phase>
                <goals>
                    <goal>exec</goal>
                </goals>
            </execution>
        </executions>
    </plugin>
@Tehau

This comment has been minimized.

Copy link

@Tehau Tehau commented Aug 9, 2019

Thank you, i was looking for a YAML to HTML to look like my swagger and this is awesome.

@CZDiego

This comment has been minimized.

Copy link

@CZDiego CZDiego commented Aug 16, 2019

image
I deleted the search bar by adding

window.ui = ui

var elements = document.getElementsByClassName("topbar");
while(elements.length > 0){
    elements[0].parentNode.removeChild(elements[0]);
}

right after the part of window.ui = ui

@diego3

This comment has been minimized.

Copy link

@diego3 diego3 commented Sep 10, 2019

Amazing

@vinamraagrawal

This comment has been minimized.

Copy link

@vinamraagrawal vinamraagrawal commented Oct 15, 2019

First of all thank you so much for the script. However, when I am trying to use it, it is working perfectly except it is not able to include (Authorise) in the html. Can you please let me know how this thing could be done?

@vnation

This comment has been minimized.

Copy link

@vnation vnation commented Nov 1, 2019

you need python3 to successfully run this script.

Selection_023

Also, I deleted the search bar by adding

window.ui = ui

var elements = document.getElementsByClassName("download-url-wrapper");
while(elements.length > 0){
    elements[0].parentNode.removeChild(elements[0]);
}

after window.ui = ui

@blimey74

This comment has been minimized.

Copy link

@blimey74 blimey74 commented Nov 6, 2019

Thanks a million for this script. Is anyone else getting "Cannot read property '0' of undefined" in Chrome and knows how to remove this error?

@oseiskar

This comment has been minimized.

Copy link
Owner Author

@oseiskar oseiskar commented Nov 13, 2019

you need python3 to successfully run this script.

@vnation: That is not true. I can run this just fine with Python 2.7. However, you do need a rather recent version (5.1+) of PyYAML, for example version 3.2 does not work. Can be fixed with pip install -U PyYAML

@pedr0-fr

This comment has been minimized.

Copy link

@pedr0-fr pedr0-fr commented Nov 15, 2019

Have been using this script with no problems, it's awesome. @CZDiego an easier way to remove the top bar is replacing 'StandaloneLayout' by 'BaseLayout'.

Does anyone know of a similar file but that works with Open API 3?

@ranggabimantika

This comment has been minimized.

Copy link

@ranggabimantika ranggabimantika commented Mar 12, 2020

its 2020 now, and this awesome work is still works
thank you!!

@nigredo13

This comment has been minimized.

Copy link

@nigredo13 nigredo13 commented Mar 27, 2020

Hi, really great !!!
But how do I use it with jwt auth (Bearer etc) ?
it is defined in the yaml and with swagger editor works...

@ezeholz

This comment has been minimized.

Copy link

@ezeholz ezeholz commented Apr 11, 2020

Hi there, so I was looking out why the auth isn't working. You just have to update the CDN.
Right after <div id="swagger-ui"></div> you should change the two script lines by

<script src="https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/3.24.2/swagger-ui-bundle.js"> </script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/3.24.2/swagger-ui-standalone-preset.js"> </script>

And that's all, your page will be render with the auth box.

Tagging people who ask for it:
@vinamraagrawal
@nigredo13

@oseiskar

This comment has been minimized.

Copy link
Owner Author

@oseiskar oseiskar commented Apr 11, 2020

@ezeholtz Thanks. I now applied those changes and also updated the CSS.

@ezeholz

This comment has been minimized.

Copy link

@ezeholz ezeholz commented Apr 11, 2020

@oseiskar You can also use the io library to force the encoding in UTF-8, it's just a few more lines to be sure that anyone can use it.

import yaml, json, sys, io

input_stream = io.TextIOWrapper(sys.stdin.buffer, encoding='utf-8')

spec = yaml.load(input_stream, Loader=yaml.FullLoader)
sys.stdout.write(TEMPLATE % json.dumps(spec))
@friderikceljski

This comment has been minimized.

Copy link

@friderikceljski friderikceljski commented Apr 18, 2020

Thanks!! :) No idea why swagger editor doesn't have an option to export as html by default...

@ngohieutp

This comment has been minimized.

Copy link

@ngohieutp ngohieutp commented Apr 27, 2020

Great! Many thanks.

@AlefCS

This comment has been minimized.

Copy link

@AlefCS AlefCS commented Jul 4, 2020

image
I deleted the search bar by adding

window.ui = ui

var elements = document.getElementsByClassName("topbar");
while(elements.length > 0){
    elements[0].parentNode.removeChild(elements[0]);
}

right after the part of window.ui = ui

It could also be done by removing SwaggerUIStandalonePreset and layout: "StandaloneLayout" as mentioned in this comment in SwaggerUI repo.

@ShreyaKarmakar

This comment has been minimized.

Copy link

@ShreyaKarmakar ShreyaKarmakar commented Aug 23, 2020

D:\convertyaml>python swagger-yaml-to-html.py < D:\convertyaml\swagger.yaml > do
c.html
Traceback (most recent call last):
File "swagger-yaml-to-html.py", line 8, in
import yaml, json, sys
ImportError: No module named yaml

Getting this error

installing pyyaml works fine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.