1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2025-06-13 20:12:29 -04:00

Compare commits

...

4 Commits

Author SHA1 Message Date
Edouard Griffiths
f7b9727ef9
Merge pull request #2450 from f4exb/fix-swagger
Fix swagger
2025-05-29 18:50:53 +02:00
f4exb
76b4623375 Upgrade Swagger UI to 5.22.0 and added WDSPRx.yaml to resources 2025-05-29 15:10:16 +02:00
f4exb
28077752a9 Swagger schema fixes 2025-05-29 12:48:11 +02:00
f4exb
3d3195489a Added Swagger schema validation container in the compose stack 2025-05-29 12:47:57 +02:00
31 changed files with 130 additions and 88 deletions

View File

@ -135,10 +135,12 @@
<file>webapi/doc/swagger/include/VORLocalizer.yaml</file> <file>webapi/doc/swagger/include/VORLocalizer.yaml</file>
<file>webapi/doc/swagger/include/WFMDemod.yaml</file> <file>webapi/doc/swagger/include/WFMDemod.yaml</file>
<file>webapi/doc/swagger/include/WFMMod.yaml</file> <file>webapi/doc/swagger/include/WFMMod.yaml</file>
<file>webapi/doc/swagger/include/WDSPRx.yaml</file>
<file>webapi/doc/swagger/include/Xtrx.yaml</file> <file>webapi/doc/swagger/include/Xtrx.yaml</file>
<file>webapi/doc/swagger-ui/favicon-16x16.png</file> <file>webapi/doc/swagger-ui/favicon-16x16.png</file>
<file>webapi/doc/swagger-ui/favicon-32x32.png</file> <file>webapi/doc/swagger-ui/favicon-32x32.png</file>
<file>webapi/doc/swagger-ui/index.html</file> <file>webapi/doc/swagger-ui/index.html</file>
<file>webapi/doc/swagger-ui/index.css</file>
<file>webapi/doc/swagger-ui/oauth2-redirect.html</file> <file>webapi/doc/swagger-ui/oauth2-redirect.html</file>
<file>webapi/doc/swagger-ui/swagger-ui-bundle.js</file> <file>webapi/doc/swagger-ui/swagger-ui-bundle.js</file>
<file>webapi/doc/swagger-ui/swagger-ui-bundle.js.map</file> <file>webapi/doc/swagger-ui/swagger-ui-bundle.js.map</file>
@ -148,6 +150,7 @@
<file>webapi/doc/swagger-ui/swagger-ui-es-bundle.js.map</file> <file>webapi/doc/swagger-ui/swagger-ui-es-bundle.js.map</file>
<file>webapi/doc/swagger-ui/swagger-ui-standalone-preset.js.map</file> <file>webapi/doc/swagger-ui/swagger-ui-standalone-preset.js.map</file>
<file>webapi/doc/swagger-ui/swagger-ui-standalone-preset.js</file> <file>webapi/doc/swagger-ui/swagger-ui-standalone-preset.js</file>
<file>webapi/doc/swagger-ui/swagger-initializer.js</file>
<file>webapi/doc/swagger-ui/swagger-ui.css</file> <file>webapi/doc/swagger-ui/swagger-ui.css</file>
<file>webapi/doc/swagger-ui/swagger-ui.css.map</file> <file>webapi/doc/swagger-ui/swagger-ui.css.map</file>
<file>webapi/doc/swagger-ui/swagger-ui.js</file> <file>webapi/doc/swagger-ui/swagger-ui.js</file>

View File

@ -5530,6 +5530,7 @@ margin-bottom: 20px;
"description" : "List of DV serial devices available in the system" "description" : "List of DV serial devices available in the system"
}; };
defs.DemodAnalyzerActions = { defs.DemodAnalyzerActions = {
"required" : [ "channelId", "deviceId" ],
"properties" : { "properties" : {
"deviceId" : { "deviceId" : {
"type" : "integer", "type" : "integer",
@ -10587,6 +10588,7 @@ margin-bottom: 20px;
"description" : "MetisMISOSettings" "description" : "MetisMISOSettings"
}; };
defs.MorseDecoderActions = { defs.MorseDecoderActions = {
"required" : [ "channelId", "deviceId" ],
"properties" : { "properties" : {
"deviceId" : { "deviceId" : {
"type" : "integer", "type" : "integer",
@ -13257,10 +13259,12 @@ margin-bottom: 20px;
"type" : "integer" "type" : "integer"
}, },
"deviceIndex" : { "deviceIndex" : {
"type" : "integer" "type" : "integer",
"description" : "remote SDRangel instance deviceset index"
}, },
"channelIndex" : { "channelIndex" : {
"type" : "integer" "type" : "integer",
"description" : "remote SDRangel instance channel index"
}, },
"useReverseAPI" : { "useReverseAPI" : {
"type" : "integer", "type" : "integer",
@ -17230,7 +17234,8 @@ margin-bottom: 20px;
}, },
"nbLeadTime" : { "nbLeadTime" : {
"type" : "number", "type" : "number",
"format" : "float" "format" : "float",
"description" : "Advance time (s)"
}, },
"nbLagTime" : { "nbLagTime" : {
"type" : "number", "type" : "number",
@ -59472,7 +59477,7 @@ except ApiException as e:
</div> </div>
<div id="generator"> <div id="generator">
<div class="content"> <div class="content">
Generated 2025-05-03T17:59:40.379+02:00 Generated 2025-05-29T12:27:25.321+02:00
</div> </div>
</div> </div>
</div> </div>

View File

@ -0,0 +1,16 @@
html {
box-sizing: border-box;
overflow: -moz-scrollbars-vertical;
overflow-y: scroll;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
body {
margin: 0;
background: #fafafa;
}

View File

@ -4,35 +4,14 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>Swagger UI</title> <title>Swagger UI</title>
<link rel="stylesheet" type="text/css" href="./swagger-ui.css" > <link rel="stylesheet" type="text/css" href="./swagger-ui.css" />
<link rel="stylesheet" type="text/css" href="index.css" />
<link rel="icon" type="image/png" href="./favicon-32x32.png" sizes="32x32" /> <link rel="icon" type="image/png" href="./favicon-32x32.png" sizes="32x32" />
<link rel="icon" type="image/png" href="./favicon-16x16.png" sizes="16x16" /> <link rel="icon" type="image/png" href="./favicon-16x16.png" sizes="16x16" />
<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> </head>
<body> <body>
<div id="swagger-ui"></div> <div id="swagger-ui"></div>
<script src="./swagger-ui-bundle.js" charset="UTF-8"> </script> <script src="./swagger-ui-bundle.js" charset="UTF-8"> </script>
<script src="./swagger-ui-standalone-preset.js" charset="UTF-8"> </script> <script src="./swagger-ui-standalone-preset.js" charset="UTF-8"> </script>
<script> <script>

View File

@ -4,8 +4,6 @@
<title>Swagger UI: OAuth2 Redirect</title> <title>Swagger UI: OAuth2 Redirect</title>
</head> </head>
<body> <body>
</body>
</html>
<script> <script>
'use strict'; 'use strict';
function run () { function run () {
@ -15,31 +13,32 @@
var isValid, qp, arr; var isValid, qp, arr;
if (/code|token|error/.test(window.location.hash)) { if (/code|token|error/.test(window.location.hash)) {
qp = window.location.hash.substring(1); qp = window.location.hash.substring(1).replace('?', '&');
} else { } else {
qp = location.search.substring(1); qp = location.search.substring(1);
} }
arr = qp.split("&") arr = qp.split("&");
arr.forEach(function (v,i,_arr) { _arr[i] = '"' + v.replace('=', '":"') + '"';}) arr.forEach(function (v,i,_arr) { _arr[i] = '"' + v.replace('=', '":"') + '"';});
qp = qp ? JSON.parse('{' + arr.join() + '}', qp = qp ? JSON.parse('{' + arr.join() + '}',
function (key, value) { function (key, value) {
return key === "" ? value : decodeURIComponent(value) return key === "" ? value : decodeURIComponent(value);
} }
) : {} ) : {};
isValid = qp.state === sentState isValid = qp.state === sentState;
if (( if ((
oauth2.auth.schema.get("flow") === "accessCode"|| oauth2.auth.schema.get("flow") === "accessCode" ||
oauth2.auth.schema.get("flow") === "authorizationCode" oauth2.auth.schema.get("flow") === "authorizationCode" ||
oauth2.auth.schema.get("flow") === "authorization_code"
) && !oauth2.auth.code) { ) && !oauth2.auth.code) {
if (!isValid) { if (!isValid) {
oauth2.errCb({ oauth2.errCb({
authId: oauth2.auth.name, authId: oauth2.auth.name,
source: "auth", source: "auth",
level: "warning", level: "warning",
message: "Authorization may be unsafe, passed state was changed in server Passed state wasn't returned from auth server" message: "Authorization may be unsafe, passed state was changed in server. The passed state wasn't returned from auth server."
}); });
} }
@ -48,7 +47,7 @@
oauth2.auth.code = qp.code; oauth2.auth.code = qp.code;
oauth2.callback({auth: oauth2.auth, redirectUrl: redirectUrl}); oauth2.callback({auth: oauth2.auth, redirectUrl: redirectUrl});
} else { } else {
let oauthErrorMsg let oauthErrorMsg;
if (qp.error) { if (qp.error) {
oauthErrorMsg = "["+qp.error+"]: " + oauthErrorMsg = "["+qp.error+"]: " +
(qp.error_description ? qp.error_description+ ". " : "no accessCode received from the server. ") + (qp.error_description ? qp.error_description+ ". " : "no accessCode received from the server. ") +
@ -59,7 +58,7 @@
authId: oauth2.auth.name, authId: oauth2.auth.name,
source: "auth", source: "auth",
level: "error", level: "error",
message: oauthErrorMsg || "[Authorization failed]: no accessCode received from the server" message: oauthErrorMsg || "[Authorization failed]: no accessCode received from the server."
}); });
} }
} else { } else {
@ -68,7 +67,13 @@
window.close(); window.close();
} }
window.addEventListener('DOMContentLoaded', function () { if (document.readyState !== 'loading') {
run(); run();
}); } else {
document.addEventListener('DOMContentLoaded', function () {
run();
});
}
</script> </script>
</body>
</html>

View File

@ -0,0 +1,20 @@
window.onload = function() {
//<editor-fold desc="Changeable Configuration Block">
// the following lines will be replaced by docker/configurator, when it runs in a docker-container
window.ui = SwaggerUIBundle({
url: "https://petstore.swagger.io/v2/swagger.json",
dom_id: '#swagger-ui',
deepLinking: true,
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIStandalonePreset
],
plugins: [
SwaggerUIBundle.plugins.DownloadUrl
],
layout: "StandaloneLayout"
});
//</editor-fold>
};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -42,12 +42,13 @@ DemodAnalyzerSettings:
DemodAnalyzerActions: DemodAnalyzerActions:
description: "Demod Analyzer actions" description: "Demod Analyzer actions"
required:
- deviceId
- channelId
properties: properties:
deviceId: deviceId:
type: integer type: integer
required: true
description: "Device Id/Number that channel belongs to" description: "Device Id/Number that channel belongs to"
channelId: channelId:
type: integer type: integer
required: true
description: "Channel Id/Number of the channel within the device" description: "Channel Id/Number of the channel within the device"

View File

@ -59,12 +59,13 @@ MorseDecoderSettings:
MorseDecoderActions: MorseDecoderActions:
description: "Morse Decoder actions" description: "Morse Decoder actions"
required:
- deviceId
- channelId
properties: properties:
deviceId: deviceId:
type: integer type: integer
required: true
description: "Device Id/Number that channel belongs to" description: "Device Id/Number that channel belongs to"
channelId: channelId:
type: integer type: integer
required: true
description: "Channel Id/Number of the channel within the device" description: "Channel Id/Number of the channel within the device"

View File

@ -19,10 +19,10 @@ RemoteOutputSettings:
dataPort: dataPort:
type: integer type: integer
deviceIndex: deviceIndex:
device: remote SDRangel instance deviceset index description: remote SDRangel instance deviceset index
type: integer type: integer
channelIndex: channelIndex:
device: remote SDRangel instance channel index description: remote SDRangel instance channel index
type: integer type: integer
useReverseAPI: useReverseAPI:
description: Synchronize with reverse API (1 for yes, 0 for no) description: Synchronize with reverse API (1 for yes, 0 for no)

View File

@ -76,7 +76,7 @@ WDSPRxSettings:
nbLeadTime: nbLeadTime:
type: number type: number
format: float format: float
descriuption: Advance time (s) description: Advance time (s)
nbLagTime: nbLagTime:
type: number type: number
format: float format: float

View File

@ -2973,7 +2973,6 @@ definitions:
FeatureSet: FeatureSet:
description: "Grouping of features" description: "Grouping of features"
required: required:
- index
- featurecount - featurecount
properties: properties:
featurecount: featurecount:
@ -3018,7 +3017,6 @@ definitions:
required: required:
- index - index
- hwType - hwType
- streamIndex
- sequence - sequence
- serial - serial
- centerFrequency - centerFrequency
@ -3422,7 +3420,6 @@ definitions:
description: "Group of configuration" description: "Group of configuration"
required: required:
- groupName - groupName
- nbPresets
properties: properties:
groupName: groupName:
description: "Name of the configuration group" description: "Name of the configuration group"
@ -3530,4 +3527,3 @@ responses:
description: Function not implemented description: Function not implemented
schema: schema:
$ref: "#/definitions/ErrorResponse" $ref: "#/definitions/ErrorResponse"

View File

@ -22,6 +22,18 @@ services:
networks: networks:
default: default:
ipv4_address: 172.20.0.3 ipv4_address: 172.20.0.3
swaggerclient:
image: "jeanberu/swagger-cli"
user: "1000:1000"
entrypoint: "/bin/sh"
container_name: "sdrangel_swaggerclient"
volumes:
- "${SDRANGEL_BASE}:/opt/build/sdrangel:rw"
stdin_open: true
tty: true
networks:
default:
ipv4_address: 172.20.0.4
networks: networks:
default: default:
driver: bridge driver: bridge

View File

@ -41,8 +41,14 @@ Use `run.sh` to create or delete the Docker compose stack. It takes the followin
- `-b`: SDRangel source code root path (default `/opt/build/sdrangel`) - `-b`: SDRangel source code root path (default `/opt/build/sdrangel`)
- `-c`: Compose stack name (default `sdrangelswg`) - `-c`: Compose stack name (default `sdrangelswg`)
The stack is composed of two containers sharing the `172.20.0.0/16` network internally. The stack is composed of three containers sharing the `172.20.0.0/16` network internally.
- `sdrangel_swgserver`: The http server that listens on port `8081` serving files in `/opt/build/sdrangel/swagger/sdrangel` - `sdrangel_swgserver`: The http server that listens on port `8081` serving files in `/opt/build/sdrangel/swagger/sdrangel`
- `sdrangel_swgcodegen`: The container with the Swagger code generator. The working directory is `/opt/build/sdrangel/swagger/sdrangel`. - `sdrangel_swgcodegen`: The container with the Swagger code generator. The working directory is `/opt/build/sdrangel/swagger/sdrangel`
- `sdrangel_swaggerclient`: based on the `jeanberu/swagger-cli` image it can be used to validate the swagger schema (see next).
Use `login.sh` to start a shell in the `sdrangel_swgcodegen` container. At the prompt run `generate.sh` to generate the code from the Swagger definition files. Use `login.sh` to start a shell in the `sdrangel_swgcodegen` container. At the prompt run `generate.sh` to generate the code from the Swagger definition files.
To validate the swagger schema:
- Enter the `sdrangel_swaggerclient` container with: `docker exec -it sdrangel_swaggerclient /bin/sh`
- Validate the schema with the command: `swagger-cli validate /opt/build/sdrangel/swagger/sdrangel/api/swagger/swagger.yaml`
- Correct errors from the most inner ones (maximum tabs). Top level errors usually result from low level errors and are therefore quite cryptic.

View File

@ -42,12 +42,13 @@ DemodAnalyzerSettings:
DemodAnalyzerActions: DemodAnalyzerActions:
description: "Demod Analyzer actions" description: "Demod Analyzer actions"
required:
- deviceId
- channelId
properties: properties:
deviceId: deviceId:
type: integer type: integer
required: true
description: "Device Id/Number that channel belongs to" description: "Device Id/Number that channel belongs to"
channelId: channelId:
type: integer type: integer
required: true
description: "Channel Id/Number of the channel within the device" description: "Channel Id/Number of the channel within the device"

View File

@ -59,12 +59,13 @@ MorseDecoderSettings:
MorseDecoderActions: MorseDecoderActions:
description: "Morse Decoder actions" description: "Morse Decoder actions"
required:
- deviceId
- channelId
properties: properties:
deviceId: deviceId:
type: integer type: integer
required: true
description: "Device Id/Number that channel belongs to" description: "Device Id/Number that channel belongs to"
channelId: channelId:
type: integer type: integer
required: true
description: "Channel Id/Number of the channel within the device" description: "Channel Id/Number of the channel within the device"

View File

@ -19,10 +19,10 @@ RemoteOutputSettings:
dataPort: dataPort:
type: integer type: integer
deviceIndex: deviceIndex:
device: remote SDRangel instance deviceset index description: remote SDRangel instance deviceset index
type: integer type: integer
channelIndex: channelIndex:
device: remote SDRangel instance channel index description: remote SDRangel instance channel index
type: integer type: integer
useReverseAPI: useReverseAPI:
description: Synchronize with reverse API (1 for yes, 0 for no) description: Synchronize with reverse API (1 for yes, 0 for no)

View File

@ -76,7 +76,7 @@ WDSPRxSettings:
nbLeadTime: nbLeadTime:
type: number type: number
format: float format: float
descriuption: Advance time (s) description: Advance time (s)
nbLagTime: nbLagTime:
type: number type: number
format: float format: float

View File

@ -2973,7 +2973,6 @@ definitions:
FeatureSet: FeatureSet:
description: "Grouping of features" description: "Grouping of features"
required: required:
- index
- featurecount - featurecount
properties: properties:
featurecount: featurecount:
@ -3018,7 +3017,6 @@ definitions:
required: required:
- index - index
- hwType - hwType
- streamIndex
- sequence - sequence
- serial - serial
- centerFrequency - centerFrequency
@ -3422,7 +3420,6 @@ definitions:
description: "Group of configuration" description: "Group of configuration"
required: required:
- groupName - groupName
- nbPresets
properties: properties:
groupName: groupName:
description: "Name of the configuration group" description: "Name of the configuration group"
@ -3530,4 +3527,3 @@ responses:
description: Function not implemented description: Function not implemented
schema: schema:
$ref: "#/definitions/ErrorResponse" $ref: "#/definitions/ErrorResponse"

View File

@ -5530,6 +5530,7 @@ margin-bottom: 20px;
"description" : "List of DV serial devices available in the system" "description" : "List of DV serial devices available in the system"
}; };
defs.DemodAnalyzerActions = { defs.DemodAnalyzerActions = {
"required" : [ "channelId", "deviceId" ],
"properties" : { "properties" : {
"deviceId" : { "deviceId" : {
"type" : "integer", "type" : "integer",
@ -10587,6 +10588,7 @@ margin-bottom: 20px;
"description" : "MetisMISOSettings" "description" : "MetisMISOSettings"
}; };
defs.MorseDecoderActions = { defs.MorseDecoderActions = {
"required" : [ "channelId", "deviceId" ],
"properties" : { "properties" : {
"deviceId" : { "deviceId" : {
"type" : "integer", "type" : "integer",
@ -13257,10 +13259,12 @@ margin-bottom: 20px;
"type" : "integer" "type" : "integer"
}, },
"deviceIndex" : { "deviceIndex" : {
"type" : "integer" "type" : "integer",
"description" : "remote SDRangel instance deviceset index"
}, },
"channelIndex" : { "channelIndex" : {
"type" : "integer" "type" : "integer",
"description" : "remote SDRangel instance channel index"
}, },
"useReverseAPI" : { "useReverseAPI" : {
"type" : "integer", "type" : "integer",
@ -17230,7 +17234,8 @@ margin-bottom: 20px;
}, },
"nbLeadTime" : { "nbLeadTime" : {
"type" : "number", "type" : "number",
"format" : "float" "format" : "float",
"description" : "Advance time (s)"
}, },
"nbLagTime" : { "nbLagTime" : {
"type" : "number", "type" : "number",
@ -59472,7 +59477,7 @@ except ApiException as e:
</div> </div>
<div id="generator"> <div id="generator">
<div class="content"> <div class="content">
Generated 2025-05-03T17:59:40.379+02:00 Generated 2025-05-29T12:27:25.321+02:00
</div> </div>
</div> </div>
</div> </div>