1+ import json
2+
3+
14class APIDocUI :
25 """
36 This class describes an api document ui.
@@ -19,6 +22,7 @@ def generate_section(
1922 summary_post : str ,
2023 get_responses : dict ,
2124 post_responses : dict ,
25+ value : dict ,
2226 ) -> str :
2327 """
2428 generate section
@@ -45,19 +49,21 @@ def generate_section(
4549 <span class="collapse-icon">➡️</span>
4650 </div>
4751 <div class="section-content">
52+ <pre><code class="language-json">{ json .dumps (value , indent = 2 )} </code></pre>
4853 <div class="method">
4954 <strong>GET</strong>
50- <p>{ summary_get } </p>
55+ <p class='summary'>{ summary_get } </p>
56+
5157 <div class="responses">
52- { "" .join ([f"<div class='response-item'>{ key } : { value ["description" ]} .</div>" for key , value in get_responses .items ()])}
58+ { "" .join ([f"<div class='response-item'><span class='span-key'> { key } </span> : { value ["description" ]} .</div>" for key , value in get_responses .items ()])}
5359 </div>
5460 </div>
5561 <div class="method">
5662 <strong>POST</strong>
57- <p>{ summary_post } </p>
63+ <p class='summary' >{ summary_post } </p>
5864 <div class="responses">
5965 <div class="responses">
60- { "" .join ([f"<div class='response-item'>{ key } : { value ["description" ]} .</div>" for key , value in post_responses .items ()])}
66+ { "" .join ([f"<div class='response-item'><span class='span-key'> { key } </span> : { value ["description" ]} .</div>" for key , value in post_responses .items ()])}
6167 </div>
6268 </div>
6369 </div>
@@ -81,22 +87,54 @@ def generate_html_page(self) -> str:
8187 <meta charset="UTF-8">
8288 <meta name="viewport" content="width=device-width, initial-scale=1.0">
8389 <title>API Documentation</title>
90+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css">
8491 <style>
92+
8593 body {
8694 font-family: Arial, sans-serif;
8795 margin: 0;
8896 padding: 0;
89- background-color: #f9f9f9 ;
97+ background-color: #f3f3f3 ;
9098 color: #333;
99+ display: block;
100+ overflow-x: auto;
101+ }
102+ .span-key {
103+ font-size: 15px;
104+ color: #007bff;
91105 }
92106 h1, h2, h3 {
93107 margin: 0;
94108 padding: 10px 0;
95109 }
110+ pre {
111+
112+ margin-bottom: 10px;
113+ padding: 5px;
114+ font-family: monospace;
115+ margin: 10px;
116+ padding: 10px;
117+ white-space: pre-wrap; /* Since CSS 2.1 */
118+ white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
119+ white-space: -pre-wrap; /* Opera 4-6 */
120+ white-space: -o-pre-wrap; /* Opera 7 */
121+ word-wrap: break-word; /* Internet Explorer 5.5+ */
122+ }
123+ code{
124+ border-radius: 5px;
125+ }
126+ .summary {
127+ border-radius: 4px;
128+ box-shadow: 0 2px 15px rgba(0, 0, 0, 0.1);
129+ color: #222222;
130+ padding: 10px;
131+ border-left: 2px solid #007bff;
132+ }
96133 .container {
97134 max-width: 800px;
98135 margin: 40px auto;
99136 padding: 20px;
137+ border: 1px solid #007bff3;
100138 background: #fff;
101139 border-radius: 8px;
102140 box-shadow: 0 2px 15px rgba(0, 0, 0, 0.1);
@@ -113,11 +151,10 @@ def generate_html_page(self) -> str:
113151 }
114152 .section {
115153 border-radius: 5px;
116- overflow: hidden;
117- margin-bottom: 20px;
118154 transition: box-shadow 0.3s ease;
119155 }
120156 .section-header {
157+ margin-bottom: 10px;
121158 padding: 15px;
122159 background: #007bff;
123160 color: white;
@@ -133,6 +170,7 @@ def generate_html_page(self) -> str:
133170 display: none;
134171 overflow: hidden;
135172 background-color: #f1f1f1;
173+ margin-bottom: 10px;
136174 }
137175 .method {
138176 border-bottom: 1px solid #ddd;
@@ -152,14 +190,103 @@ def generate_html_page(self) -> str:
152190 }
153191 .collapse-icon {
154192 transition: transform 0.3s;
155- }
156- .collapse-icon.collapsed {
157193 transform: rotate(90deg);
158194 }
159- .section:hover {
160- box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15 );
195+ .collapse-icon.collapsed {
196+ transform: rotate(0deg );
161197 }
198+ pre code.hljs {
199+ display: block;
200+ overflow-x: auto;
201+ padding: 1em
202+ }
203+ code.hljs {
204+ padding: 3px 5px
205+ }
206+ /*
207+
208+ Atom One Light by Daniel Gamage
209+ Original One Light Syntax theme from https://github.com/atom/one-light-syntax
210+
211+ base: #fafafa
212+ mono-1: #383a42
213+ mono-2: #686b77
214+ mono-3: #a0a1a7
215+ hue-1: #0184bb
216+ hue-2: #4078f2
217+ hue-3: #a626a4
218+ hue-4: #50a14f
219+ hue-5: #e45649
220+ hue-5-2: #c91243
221+ hue-6: #986801
222+ hue-6-2: #c18401
223+
224+ */
225+ .hljs {
226+ color: #383a42;
227+ background: #fafafa
228+ }
229+ .hljs-comment,
230+ .hljs-quote {
231+ color: #a0a1a7;
232+ font-style: italic
233+ }
234+ .hljs-doctag,
235+ .hljs-keyword,
236+ .hljs-formula {
237+ color: #a626a4
238+ }
239+ .hljs-section,
240+ .hljs-name,
241+ .hljs-selector-tag,
242+ .hljs-deletion,
243+ .hljs-subst {
244+ color: #e45649
245+ }
246+ .hljs-literal {
247+ color: #0184bb
248+ }
249+ .hljs-string,
250+ .hljs-regexp,
251+ .hljs-addition,
252+ .hljs-attribute,
253+ .hljs-meta .hljs-string {
254+ color: #50a14f
255+ }
256+ .hljs-attr,
257+ .hljs-variable,
258+ .hljs-template-variable,
259+ .hljs-type,
260+ .hljs-selector-class,
261+ .hljs-selector-attr,
262+ .hljs-selector-pseudo,
263+ .hljs-number {
264+ color: #986801
265+ }
266+ .hljs-symbol,
267+ .hljs-bullet,
268+ .hljs-link,
269+ .hljs-meta,
270+ .hljs-selector-id,
271+ .hljs-title {
272+ color: #4078f2
273+ }
274+ .hljs-built_in,
275+ .hljs-title.class_,
276+ .hljs-class .hljs-title {
277+ color: #c18401
278+ }
279+ .hljs-emphasis {
280+ font-style: italic
281+ }
282+ .hljs-strong {
283+ font-weight: bold
284+ }
285+ .hljs-link {
286+ text-decoration: underline
287+ }
162288 </style>
289+
163290</head>
164291<body>
165292
@@ -176,6 +303,19 @@ def generate_html_page(self) -> str:
176303
177304 {{sections}}
178305
306+ <br>
307+ <hr>
308+ <br>
309+
310+ <h2>Full specification</h2>
311+ <pre><code class="language-json">{{spec}}</code></pre>
312+
313+ <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
314+
315+ <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/json.min.js"></script>
316+
317+ <script>hljs.highlightAll();</script>
318+
179319<script>
180320 document.querySelectorAll('.section-header').forEach(header => {
181321 header.addEventListener('click', () => {
@@ -191,6 +331,12 @@ def generate_html_page(self) -> str:
191331 }
192332 });
193333 });
334+
335+ document.addEventListener('DOMContentLoaded', (event) => {
336+ document.querySelectorAll('pre code').forEach((el) => {
337+ hljs.highlightElement(el);
338+ });
339+ });
194340</script>
195341
196342</body>
@@ -199,6 +345,7 @@ def generate_html_page(self) -> str:
199345
200346 content = {
201347 "{{openapi-version}}" : self .specification ["openapi" ],
348+ "{{spec}}" : json .dumps (self .specification , indent = 2 ),
202349 "{{info_title}}" : self .specification ["info" ]["title" ],
203350 "{{info_version}}" : self .specification ["info" ]["version" ],
204351 "{{info_description}}" : self .specification ["info" ]["description" ],
@@ -210,6 +357,7 @@ def generate_html_page(self) -> str:
210357 value ["post" ]["summary" ],
211358 value ["get" ]["responses" ],
212359 value ["post" ]["responses" ],
360+ value ,
213361 )
214362 for path , value in self .specification ["paths" ].items ()
215363 ]
0 commit comments