Skip to content

Commit b463230

Browse files
Fix #39 (#65)
* Fix MARKDOWN style table separators to use minimum 3 hyphens (issue #39) - Fix write_table_lines in md.py to use max(3, column_len) for separator width - Fix hardcoded '| -- | -- |' in type.html template to '| --- | --- |' - Update example1-output-plain.md snapshot to reflect corrected separators Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Update version, changelog * Fix test server startup race condition by polling port readiness Replace fixed sleep with a socket poll loop that waits until the Flask server is actually accepting connections before running tests. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Update serverfixtures.py --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 02864e4 commit b463230

6 files changed

Lines changed: 52 additions & 41 deletions

File tree

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,13 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [1.3.1] - 2026-03-??
9+
10+
- Add OAS 3.1 support, cross-version warnings, and fix nullable spacing, by @dcode.
11+
- Fix MARKDOWN style table separators to use minimum 3 hyphens (issue #39), reported by @michael-nok.
12+
813
## [1.3.0] - 2025-11-19
14+
915
- Add support for passing custom Jinja2 templates as an argument, by @sindrehan.
1016

1117
## [1.2.1] - 2025-07-30

openapidocs/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
__version__ = "1.3.0"
1+
__version__ = "1.3.1"
22
VERSION = __version__

openapidocs/mk/md.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ def write_table_lines(
4949
if write_headers:
5050
# add separator line after headers
5151
yield write_row(
52-
["-" * column_len for column_len in columns_widths.values()],
52+
["-" * max(3, column_len) for column_len in columns_widths.values()],
5353
columns_widths,
5454
padding,
5555
indent,

openapidocs/mk/v3/views_markdown/partial/type.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
{%- with props = handler.get_properties(definition) -%}
33
{% if props %}
44
| {{texts.name}} | {{texts.type}} |
5-
| -- | -- |
5+
| --- | --- |
66
{%- for name, schema in props %}
77
| {{name}} | {% include "partial/schema-repr.html" %} |
88
{%- endfor -%}

tests/res/example1-output-plain.md

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2954,7 +2954,7 @@ _Other possible types: text/json, text/plain_
29542954
### Category
29552955

29562956
| Name | Type |
2957-
| -- | -- |
2957+
| --- | --- |
29582958
| creationTime | string(date-time) |
29592959
| description | string &#124; null |
29602960
| eTag | string |
@@ -2968,7 +2968,7 @@ _Other possible types: text/json, text/plain_
29682968
### Country
29692969

29702970
| Name | Type |
2971-
| -- | -- |
2971+
| --- | --- |
29722972
| countryCode | string &#124; null |
29732973
| id | string &#124; null |
29742974
| name | string |
@@ -2978,15 +2978,15 @@ _Other possible types: text/json, text/plain_
29782978
### CreateOrganizationsBoundInput
29792979

29802980
| Name | Type |
2981-
| -- | -- |
2981+
| --- | --- |
29822982
| items | Array&lt;[OrganizationBoundInput](#organizationboundinput)&gt; |
29832983

29842984

29852985

29862986
### CreateReleaseInput
29872987

29882988
| Name | Type |
2989-
| -- | -- |
2989+
| --- | --- |
29902990
| categoryId | string |
29912991
| countries | Array&lt;string&gt; |
29922992
| description | string &#124; null |
@@ -2997,7 +2997,7 @@ _Other possible types: text/json, text/plain_
29972997
### CreateReleaseNodeInput
29982998

29992999
| Name | Type |
3000-
| -- | -- |
3000+
| --- | --- |
30013001
| fileId | string(uuid) |
30023002
| fileName | string |
30033003
| fileSize | integer(int32) |
@@ -3008,15 +3008,15 @@ _Other possible types: text/json, text/plain_
30083008
### CreateReleaseOutput
30093009

30103010
| Name | Type |
3011-
| -- | -- |
3011+
| --- | --- |
30123012
| id | string(uuid) |
30133013

30143014

30153015

30163016
### CurrentRelease
30173017

30183018
| Name | Type |
3019-
| -- | -- |
3019+
| --- | --- |
30203020
| categoryId | string &#124; null |
30213021
| countryCode | string &#124; null |
30223022
| countryName | string &#124; null |
@@ -3029,31 +3029,31 @@ _Other possible types: text/json, text/plain_
30293029
### DeleteReleaseNodeInput
30303030

30313031
| Name | Type |
3032-
| -- | -- |
3032+
| --- | --- |
30333033
| id | string(uuid) |
30343034

30353035

30363036

30373037
### FileDownloadStats
30383038

30393039
| Name | Type |
3040-
| -- | -- |
3040+
| --- | --- |
30413041
| uniqueDownloads | integer(int32) |
30423042

30433043

30443044

30453045
### FileUrl
30463046

30473047
| Name | Type |
3048-
| -- | -- |
3048+
| --- | --- |
30493049
| url | string &#124; null |
30503050

30513051

30523052

30533053
### GenericError
30543054

30553055
| Name | Type |
3056-
| -- | -- |
3056+
| --- | --- |
30573057
| code | integer(int32) |
30583058
| message | string |
30593059

@@ -3062,7 +3062,7 @@ _Other possible types: text/json, text/plain_
30623062
### HealthCheck
30633063

30643064
| Name | Type |
3065-
| -- | -- |
3065+
| --- | --- |
30663066
| alive | boolean |
30673067
| regionName | string &#124; null |
30683068
| timestamp | string(date-time) |
@@ -3072,7 +3072,7 @@ _Other possible types: text/json, text/plain_
30723072
### InitializeUploadInput
30733073

30743074
| Name | Type |
3075-
| -- | -- |
3075+
| --- | --- |
30763076
| fileName | string &#124; null |
30773077
| fileSize | integer(int32) |
30783078
| fileType | string &#124; null |
@@ -3083,7 +3083,7 @@ _Other possible types: text/json, text/plain_
30833083
### InitializeUploadOutput
30843084

30853085
| Name | Type |
3086-
| -- | -- |
3086+
| --- | --- |
30873087
| baseURL | string &#124; null |
30883088
| fileId | string &#124; null |
30893089
| fileName | string &#124; null |
@@ -3094,7 +3094,7 @@ _Other possible types: text/json, text/plain_
30943094
### MetaData
30953095

30963096
| Name | Type |
3097-
| -- | -- |
3097+
| --- | --- |
30983098
| buildNumber | string &#124; null |
30993099
| contactEmail | string &#124; null |
31003100
| version | string &#124; null |
@@ -3104,7 +3104,7 @@ _Other possible types: text/json, text/plain_
31043104
### NodeInfo
31053105

31063106
| Name | Type |
3107-
| -- | -- |
3107+
| --- | --- |
31083108
| creationTime | string(date-time) |
31093109
| eTag | string |
31103110
| extension | string |
@@ -3120,7 +3120,7 @@ _Other possible types: text/json, text/plain_
31203120
### OrganizationBoundInput
31213121

31223122
| Name | Type |
3123-
| -- | -- |
3123+
| --- | --- |
31243124
| id | string(uuid) |
31253125
| name | string &#124; null |
31263126

@@ -3129,7 +3129,7 @@ _Other possible types: text/json, text/plain_
31293129
### ProfessionalContext
31303130

31313131
| Name | Type |
3132-
| -- | -- |
3132+
| --- | --- |
31333133
| membership | Array&lt;[ProfessionalMembership](#professionalmembership)&gt; |
31343134
| signature | string &#124; null |
31353135

@@ -3138,7 +3138,7 @@ _Other possible types: text/json, text/plain_
31383138
### ProfessionalMembership
31393139

31403140
| Name | Type |
3141-
| -- | -- |
3141+
| --- | --- |
31423142
| brandNames | Array&lt;string&gt; |
31433143
| categoryId | string &#124; null |
31443144
| id | string(uuid) |
@@ -3156,7 +3156,7 @@ _Other possible types: text/json, text/plain_
31563156
### PublishReleaseInput
31573157

31583158
| Name | Type |
3159-
| -- | -- |
3159+
| --- | --- |
31603160
| eTag | string &#124; null |
31613161
| sendEmailNotifications | boolean |
31623162

@@ -3165,7 +3165,7 @@ _Other possible types: text/json, text/plain_
31653165
### Release
31663166

31673167
| Name | Type |
3168-
| -- | -- |
3168+
| --- | --- |
31693169
| category | [Category](#category) |
31703170
| categoryId | string &#124; null |
31713171
| countries | Array&lt;[ReleaseCountry](#releasecountry)&gt; |
@@ -3186,7 +3186,7 @@ _Other possible types: text/json, text/plain_
31863186
### ReleaseCountry
31873187

31883188
| Name | Type |
3189-
| -- | -- |
3189+
| --- | --- |
31903190
| country | [Country](#country) |
31913191
| countryId | string &#124; null |
31923192
| release | [Release](#release) |
@@ -3197,7 +3197,7 @@ _Other possible types: text/json, text/plain_
31973197
### ReleaseHistory
31983198

31993199
| Name | Type |
3200-
| -- | -- |
3200+
| --- | --- |
32013201
| data | string &#124; null |
32023202
| description | string |
32033203
| id | string(uuid) |
@@ -3211,7 +3211,7 @@ _Other possible types: text/json, text/plain_
32113211
### ReleaseNode
32123212

32133213
| Name | Type |
3214-
| -- | -- |
3214+
| --- | --- |
32153215
| id | string(uuid) |
32163216
| node | [NodeInfo](#nodeinfo) |
32173217
| nodeId | string(uuid) |
@@ -3223,7 +3223,7 @@ _Other possible types: text/json, text/plain_
32233223
### ReleaseNodeDownload
32243224

32253225
| Name | Type |
3226-
| -- | -- |
3226+
| --- | --- |
32273227
| accessGrantedByOrganizationId | string(uuid) &#124; null |
32283228
| id | string(uuid) |
32293229
| node | [NodeInfo](#nodeinfo) |
@@ -3239,7 +3239,7 @@ _Other possible types: text/json, text/plain_
32393239
### ReleaseNodeDownloadPaginatedSet
32403240

32413241
| Name | Type |
3242-
| -- | -- |
3242+
| --- | --- |
32433243
| items | Array&lt;[ReleaseNodeDownload](#releasenodedownload)&gt; |
32443244
| total | integer(int64) |
32453245

@@ -3248,7 +3248,7 @@ _Other possible types: text/json, text/plain_
32483248
### ReleaseOrganization
32493249

32503250
| Name | Type |
3251-
| -- | -- |
3251+
| --- | --- |
32523252
| displayName | string &#124; null |
32533253
| organizationId | string(uuid) |
32543254
| release | [Release](#release) |
@@ -3259,7 +3259,7 @@ _Other possible types: text/json, text/plain_
32593259
### ReleasePaginatedSet
32603260

32613261
| Name | Type |
3262-
| -- | -- |
3262+
| --- | --- |
32633263
| items | Array&lt;[Release](#release)&gt; |
32643264
| total | integer(int64) |
32653265

@@ -3268,7 +3268,7 @@ _Other possible types: text/json, text/plain_
32683268
### UpdateReleaseInput
32693269

32703270
| Name | Type |
3271-
| -- | -- |
3271+
| --- | --- |
32723272
| categoryId | string |
32733273
| countries | Array&lt;string&gt; |
32743274
| description | string &#124; null |
@@ -3418,7 +3418,7 @@ This section describes common parameters that are reused across operations.
34183418
### PageNumber
34193419

34203420
| Name | In | Type | Default | Nullable | Description |
3421-
| ---- | -- | ---- | ------- | -------- | ----------- |
3421+
| ---- | --- | ---- | ------- | -------- | ----------- |
34223422

34233423

34243424
## Security schemes

tests/serverfixtures.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import os
1+
import socket
22
from multiprocessing import Process
33
from time import sleep
44

@@ -16,18 +16,23 @@ def start_server():
1616
app.run(host="127.0.0.1", port=44777)
1717

1818

19-
def get_sleep_time():
20-
# when starting a server process,
21-
# a longer sleep time is necessary on Windows
22-
if os.name == "nt":
23-
return 1.5
24-
return 0.5
19+
def _wait_for_server(host, port, timeout=10.0):
20+
import time
21+
22+
deadline = time.monotonic() + timeout
23+
while time.monotonic() < deadline:
24+
try:
25+
with socket.create_connection((host, port), timeout=0.1):
26+
return
27+
except OSError:
28+
time.sleep(0.05)
29+
raise RuntimeError(f"Server on {host}:{port} did not start within {timeout}s")
2530

2631

2732
def _start_server_process(target):
2833
server_process = Process(target=target)
2934
server_process.start()
30-
sleep(get_sleep_time())
35+
_wait_for_server("127.0.0.1", SERVER_PORT)
3136

3237
if not server_process.is_alive():
3338
raise TypeError("The server process did not start!")

0 commit comments

Comments
 (0)