I'm trying to execute this command in the command prompt, to generate code for python:
java -jar modules\swagger-codegen-cli\target\swagger-codegen-cli.jar \
generate \
-i http://localhost/test/swagger-docs/api-docs.json \
-l python -o c:\temp\python_testapi_client
And it shows me this error:
Exception in thread "main" java.lang.RuntimeException: missing swagger input or config!
at io.swagger.codegen.DefaultGenerator.generate(DefaultGenerator.java:89)
at io.swagger.codegen.cmd.Generate.run(Generate.java:223)
at io.swagger.codegen.SwaggerCodegen.main(SwaggerCodegen.java:36)
And when I open this file in my browser, it contains:
{
"swaggerVersion": "1.2",
"apis": [{
"path": "\/v1-machinetags",
"description": "Deletes machine tags by they titles."
}, {
"path": "\/v1-photos",
"description": "Uploads photo with tags."
}, {
"path": "\/v1-photos-bymachinetags",
"description": "List of photos with possibility filtering by Machine tags."
}, {
"path": "\/v1-photos-bytags",
"description": "List of photos with possibility filtering by tags."
}, {
"path": "\/v1-photos-user-bymachinetags",
"description": "List of photos of a specific user with possibility filtering by machine tags."
}, {
"path": "\/v1-photos-user-bytags",
"description": "List of photos of a specific user with possibility filtering by tags."
}, {
"path": "\/v1-photos",
"description": "Deletes photo."
}, {
"path": "\/v1-photos-machinetags",
"description": "Associate photo with machine tags."
}, {
"path": "\/v1-photos-tags",
"description": "Associate photo with tags."
}, {
"path": "\/v1-resources",
"description": "Add a new RDF resource ."
}, {
"path": "\/v1-tags",
"description": "Deletes tags by they titles."
}, {
"path": "\/v1-triplets",
"description": "Get All triplets."
}, {
"path": "\/v1-triplets-bylanguages",
"description": "Get Resources by a given language."
}, {
"path": "\/v1-triplets-bytypes",
"description": "Get Resources by a given type."
}],
"apiVersion": "0.1",
"info": {
"title": "Symfony2",
"description": "My awesome Symfony2 app!",
"TermsOfServiceUrl": null,
"contact": null,
"license": null,
"licenseUrl": null
},
"authorizations": []
}
Related
My goal is to display the 6 most recent items in the current users OneDrive.
Using https://graph.microsoft.com/v1.0/me/drive/recent?top=6 gives me the correct documents.
Some of these documents are OneNote Items.
At www.office.com the OneNote Items are displayed with the Notebook's displayname.
In the API response only the filename is contained.
Testing this is Microsoft's example data here:
https://developer.microsoft.com/en-us/graph/graph-explorer
Example response
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#Collection(driveItem)",
"#odata.nextLink": "https://graph.microsoft.com/v1.0/me/drive/recent?top=6&expand=section&$skiptoken=s!Njs3NGI0MzJjYS1mNmIzLTQ5YmQtOWIxMC02OTIyNjRlMTI3YTI",
"value": [
...
{
"#odata.type": "#microsoft.graph.driveItem",
"createdDateTime": "2017-08-07T16:08:45Z",
"id": "01BYE5RZ2IKLBQXYXELFD23BMJIB545TH6",
"lastModifiedDateTime": "2020-01-09T03:02:37Z",
"name": "Fabrikam.one",
"webUrl": "https://m365x214355-my.sharepoint.com/personal/meganb_m365x214355_onmicrosoft_com/_layouts/15/Doc.aspx?sourcedoc=%7B0BC35248-E4E2-4759-AD85-89407BCECCFE%7D&file=Fabrikam.one&action=edit&mobileredirect=true&wdorigin=Sharepoint&DefaultItemOpen=1",
"size": 55782,
"createdBy": {
"user": {
"email": "MeganB#M365x214355.onmicrosoft.com",
"displayName": "Megan Bowen"
}
},
"lastModifiedBy": {
"user": {
"email": "",
"displayName": "System Account"
}
},
"file": {
"mimeType": "application/msonenote"
},
"fileSystemInfo": {
"createdDateTime": "2017-08-07T16:08:45Z",
"lastModifiedDateTime": "2020-01-09T03:02:37Z"
},
"remoteItem": {
"createdDateTime": "2017-08-07T16:08:45Z",
"id": "01BYE5RZ2IKLBQXYXELFD23BMJIB545TH6",
"lastModifiedDateTime": "2020-01-09T03:02:37Z",
"name": "Fabrikam.one",
"size": 55782,
"webDavUrl": "https://m365x214355-my.sharepoint.com/personal/meganb_m365x214355_onmicrosoft_com/Documents/Fabrikam.one",
"webUrl": "https://m365x214355-my.sharepoint.com/personal/meganb_m365x214355_onmicrosoft_com/_layouts/15/Doc.aspx?sourcedoc=%7B0BC35248-E4E2-4759-AD85-89407BCECCFE%7D&file=Fabrikam.one&action=edit&mobileredirect=true&wdorigin=Sharepoint&DefaultItemOpen=1",
"createdBy": {
"user": {
"email": "MeganB#M365x214355.onmicrosoft.com",
"displayName": "Megan Bowen"
}
},
"file": {
"mimeType": "application/msonenote"
},
"fileSystemInfo": {
"createdDateTime": "2017-08-07T16:08:45Z",
"lastModifiedDateTime": "2020-01-09T03:02:37Z"
},
"lastModifiedBy": {
"user": {
"email": "",
"displayName": "System Account"
}
},
"parentReference": {
"driveType": "business",
"driveId": "b!-RIj2DuyvEyV1T4NlOaMHk8XkS_I8MdFlUCq1BlcjgmhRfAj3-Z8RY2VpuvV_tpd",
"id": "01BYE5RZ56Y2GOVW7725BZO354PWSELRRZ"
},
"shared": {
"scope": "users"
},
"sharepointIds": {
"listId": "23f045a1-e6df-457c-8d95-a6ebd5feda5d",
"listItemId": "36",
"listItemUniqueId": "0bc35248-e4e2-4759-ad85-89407bceccfe",
"siteId": "d82312f9-b23b-4cbc-95d5-3e0d94e68c1e",
"siteUrl": "https://m365x214355-my.sharepoint.com/personal/meganb_m365x214355_onmicrosoft_com",
"webId": "2f91174f-f0c8-45c7-9540-aad4195c8e09"
}
}
},
...
]
}
Is there a way to retrieve the OneNote notebook's name from here?
The API provides a way to retrieve all notebooks like so:
https://graph.microsoft.com/v1.0/me/onenote/notebooks
However I do not see a connection between these responses.
Maybe relevant how to find OneNote Notebook object from driveItem with MS Graph? - this shows a workaround. I am curious if there is a better solution.
I have a production keyvault that keeps a reference of secrets that projects can use, but only if deployed using ARM templates such secrets are not handled by people copy pasting them.
When a new project starts, as part of its deployment script, it will create its own keyvault.
I want to be able to run the templates/scripts as part of CI/CD. And this will today result in the same secret having a new version at each run, even though the value did not change.
How to make it only update the keyvault value when the master vault is updated.
In my deployment.sh script I use the following technique.
SendGridUriWithVersion=$((az group deployment create ... assume that the secret exists ... || az group deployment create ... assume that the secret exists ... ) | jq -r '.properties.outputs.secretUriWithVersion.value')
and it works because in the template there is a parameter, if set, that will retrieve the secret and compare it with the new value and only insert if difference. The original problem is that the deployment fails if the secret is not already set (this happens for the first deployment etc).
But then due to Unix ||, the same script is run again without the parameter set and it will use a condition to not try to get the old value and therefore run successful.
Here are the example in dept:
SecretName="Sendgrid"
SourceSecretName="Sendgrid"
SourceVaultName="io-board"
SourceResourceGroup="io-board"
SendGridUriWithVersion=$((az group deployment create -n ${SecretName}-secret -g $(prefix)-$(projectName)-$(projectEnv) --template-uri https://management.dotnetdevops.org/providers/DotNetDevOps.AzureTemplates/templates/KeyVaults/${keyVaultName}/secrets/${SecretName}?sourced=true --parameters sourceVault=${SourceVaultName} sourceResourceGroup=${SourceResourceGroup} sourceSecretName=${SourceSecretName} update=true || az group deployment create -n ${SecretName}-secret -g $(prefix)-$(projectName)-$(projectEnv) --template-uri https://management.dotnetdevops.org/providers/DotNetDevOps.AzureTemplates/templates/KeyVaults/${keyVaultName}/secrets/${SecretName}?sourced=true --parameters sourceVault=${SourceVaultName} sourceResourceGroup=${SourceResourceGroup} sourceSecretName=${SourceSecretName}) | jq -r '.properties.outputs.secretUriWithVersion.value')
The https://management.dotnetdevops.org/providers/DotNetDevOps.AzureTemplates/templates/KeyVaults/{keyvaultName}/secrets/{secretName}?sourced=true returns a template
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"keyVaultName": {
"type": "string",
"defaultValue": "io-board-data-ingest-dev"
},
"secretName": {
"type": "string",
"metadata": {
"description": "Name of the secret to store in the vault"
},
"defaultValue": "DataStorage"
},
"sourceVaultSubscription": {
"type": "string",
"defaultValue": "[subscription().subscriptionId]"
},
"sourceVault": {
"type": "string",
"defaultValue": "[subscription().subscriptionId]"
},
"sourceResourceGroup": {
"type": "string",
"defaultValue": "[resourceGroup().name]"
},
"sourceSecretName": {
"type": "string"
},
"update": {
"type": "bool",
"defaultValue": false
}
},
"variables": {
"empty": {
"value": ""
},
"test": {
"reference": {
"keyVault": {
"id": "[resourceId(subscription().subscriptionId, resourceGroup().name, 'Microsoft.KeyVault/vaults', parameters('keyVaultName'))]"
},
"secretName": "[parameters('secretName')]"
}
}
},
"resources": [
{
"apiVersion": "2018-05-01",
"name": "AddLinkedSecret",
"type": "Microsoft.Resources/deployments",
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[concat('https://management.dotnetdevops.org/providers/DotNetDevOps.AzureTemplates/templates/KeyVaults/',parameters('keyVaultName'),'/secrets/',parameters('secretName'))]",
"contentVersion": "1.0.0.0"
},
"parameters": {
"existingValue": "[if(parameters('update'),variables('test'),variables('empty'))]",
"secretValue": {
"reference": {
"keyVault": {
"id": "[resourceId(parameters('sourceVaultSubscription'), parameters('sourceResourceGroup'), 'Microsoft.KeyVault/vaults', parameters('sourceVault'))]"
},
"secretName": "[parameters('sourceSecretName')]"
}
}
}
}
}
],
"outputs": {
"secretUriWithVersion": {
"type": "string",
"value": "[reference('AddLinkedSecret').outputs.secretUriWithVersion.value]"
}
}
}
and that template has a nested call to https://management.dotnetdevops.org/providers/DotNetDevOps.AzureTemplates/templates/KeyVaults/{keyvaultName}/secrets/{secretName} which gives the one with the condition
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"keyVaultName": {
"type": "string",
"defaultValue": "io-board-data-ingest-dev",
"metadata": {
"description": "Name of the existing vault"
}
},
"secretName": {
"type": "string",
"metadata": {
"description": "Name of the secret to store in the vault"
},
"defaultValue": "DataStorage"
},
"secretValue": {
"type": "securestring",
"metadata": {
"description": "Value of the secret to store in the vault"
}
},
"existingValue": {
"type": "securestring",
"defaultValue": ""
}
},
"variables": {},
"resources": [
{
"type": "Microsoft.KeyVault/vaults/secrets",
"condition": "[not(equals(parameters('existingValue'),parameters('secretValue')))]",
"apiVersion": "2015-06-01",
"name": "[concat(parameters('keyVaultName'), '/', parameters('secretName'))]",
"properties": {
"value": "[parameters('secretValue')]"
}
}
],
"outputs": {
"secretUriWithVersion": {
"type": "string",
"value": "[reference(resourceId(resourceGroup().name, 'Microsoft.KeyVault/vaults/secrets', parameters('keyVaultName'), parameters('secretName')), '2015-06-01').secretUriWithVersion]"
}
}
}
Have an MS Flow trying to call the Graph API to update a user's profile photo. It takes a username and jpg photo file and then calls an HTTP connection secured using Azure AD (with https://graph.microsoft.com as the resource URI). Unfortunately, I get the error The file you chose isn't an image. Please choose a different file. which seems to indicate that I am not posting the file encoded in a way that MS Graph recognizes.
I've tried all variations I can think of with the body (using the #binary, #base64ToBinary, etc):
"body": "#{triggerBody()?['file']?['contentBytes']}"
to try to get it to treat "correctly", but with no luck.
This is the full flow definition:
{
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"$connections": {
"defaultValue": {},
"type": "Object"
},
"$authentication": {
"defaultValue": {},
"type": "SecureObject"
}
},
"triggers": {
"manual": {
"type": "Request",
"kind": "Button",
"inputs": {
"schema": {
"type": "object",
"properties": {
"file": {
"title": "Photo",
"type": "object",
"x-ms-dynamically-added": true,
"description": "Please select file or image",
"x-ms-content-hint": "FILE",
"properties": {
"name": {
"type": "string"
},
"contentBytes": {
"type": "string",
"format": "byte"
}
}
},
"text": {
"title": "Username",
"type": "string",
"x-ms-dynamically-added": true,
"description": "user#domain.com",
"x-ms-content-hint": "TEXT"
}
},
"required": [
"text"
]
}
}
}
},
"actions": {
"Invoke_an_HTTP_request": {
"runAfter": {},
"metadata": {
"flowSystemMetadata": {
"swaggerOperationId": "InvokeHttp"
}
},
"type": "ApiConnection",
"inputs": {
"host": {
"connection": {
"name": "#json(decodeBase64(triggerOutputs().headers['X-MS-APIM-Tokens']))['$connections']['webcontents_1']['connectionId']"
}
},
"method": "post",
"body": {
"method": "PUT",
"url": "https://graph.microsoft.com/v1.0/users/#{triggerBody()['text']}/photo/$value",
"headers": {
"Content-Type": "image/jpeg"
},
"body": "#{triggerBody()?['file']?['contentBytes']}"
},
"path": "/codeless/InvokeHttp",
"authentication": {
"type": "Raw",
"value": "#json(decodeBase64(triggerOutputs().headers['X-MS-APIM-Tokens']))['$ConnectionKey']"
}
}
}
}
}
and the full error:
{
"error": {
"code": 502,
"message": "{\r\n \"error\": {\r\n \"code\": 502,\r\n \"source\": \"unitedstates-002.azure-apim.net\",\r\n \"clientRequestId\": \"e105d9f2-af13-4a5b-8fbd-c84c49cadc8f\",\r\n \"message\": \"BadGateway\",\r\n \"innerError\": {\r\n \"error\": {\r\n \"code\": \"ErrorInternalServerError\",\r\n \"message\": \"An internal server error occurred. The operation failed., The file you chose isn't an image. Please choose a different file.\",\r\n \"innerError\": {\r\n \"request-id\": \"e3214f20-8592-4fb0-9d34-677322b231ae\",\r\n \"date\": \"2019-07-30T21:42:10\"\r\n }\r\n }\r\n }\r\n }\r\n}"
}
}
What is the best way to represent a generic response/payload object that has basic fields such as message, total elements, data, and status? Where the variability between each API is the data element. For instance, one API could be for permissions, so the data element would hold an array of permissions. But for another API, it would hold a different array of object types. My main goal is to have reuse with a payload object and to define the next "layer" of actual data.
I want to be able to define a data type that's generic - like a "response" that has basic fields but I want to be able to further define that content for each API (data containing permissions or roles or whatever).
Here are some JSON samples of what's been attempted but isn't rendering the way we would expect it to in Swagger UI (i.e. a flat structure of 4 elements with data defined per the API).
Example 1 - composition:
{
"swagger": "2.0",
"host": "localhost:8888",
"info": {
"version": "0.0.1",
"title": "API"
},
"paths": {
"/permissions": {
"get": {
"description": "Returns all permissions",
"operationId": "getPermissions",
"produces": [
"application/json"
],
"responses": {
"200": {
"description": "success",
"schema": {
"$ref": "#/definitions/permissionResponse"
}
}
}
}
}
},
"definitions": {
"response": {
"type": "object",
"properties": {
"message": {
"type": "string",
"description": "A string indicating the response from the server."
},
"totalElements": {
"type": "integer",
"format": "int64",
"description": "The number of items retrieved."
},
"status": {
"type": "string",
"description": "A string indicating the response from the server."
}
}
},
"permissionResponse": {
"allOf": [
{
"$ref": "#/definitions/response"
}, {
"type": "object",
"properties": {
"data": {
"type": "array",
"description": "The collection of items returned from the API request.",
"items": {
"$ref": "#/definitions/permission"
}
}
}
}
]
},
"permission": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int64",
"description": "Unique identifier representing a specific permission."
},
"label": {
"type": "string",
"description": "The label of a permission."
},
"description": {
"type": "string",
"description": "A description of the permission."
},
"active": {
"type": "boolean",
"description": "A flag indicating whether a permission is active."
}
},
"required": [
"id",
"label",
"description",
"active"
]
}
}
}
Example 2 - composition variation:
{
"swagger": "2.0",
"host": "localhost:8888",
"info": {
"version": "0.0.1",
"title": "API"
},
"paths": {
"/permissions": {
"get": {
"description": "Returns all permissions",
"operationId": "getPermissions",
"produces": [
"application/json"
],
"responses": {
"200": {
"description": "success",
"schema": {
"$ref": "#/definitions/permissionResponse"
}
}
}
}
}
},
"definitions": {
"response": {
"type": "object",
"properties": {
"message": {
"type": "string",
"description": "A string indicating the response from the server."
},
"totalElements": {
"type": "integer",
"format": "int64",
"description": "The number of items retrieved."
},
"status": {
"type": "string",
"description": "A string indicating the response from the server."
}
}
},
"permissionResponse": {
"allOf": [
{
"$ref": "#/definitions/response"
}],
"type": "object",
"properties": {
"data": {
"type": "array",
"description": "The collection of items returned from the API request.",
"items": {
"$ref": "#/definitions/permission"
}
}
}
},
"permission": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int64",
"description": "Unique identifier representing a specific permission."
},
"label": {
"type": "string",
"description": "The label of a permission."
},
"description": {
"type": "string",
"description": "A description of the permission."
},
"active": {
"type": "boolean",
"description": "A flag indicating whether a permission is active."
}
},
"required": [
"id",
"label",
"description",
"active"
]
}
}
Example 3 - additional properties:
{
"swagger": "2.0",
"host": "localhost:8888",
"info": {
"version": "0.0.1",
"title": "API"
},
"paths": {
"/permissions": {
"get": {
"description": "Returns all permissions",
"operationId": "getPermissions",
"produces": [
"application/json"
],
"responses": {
"200": {
"description": "success",
"schema": {
"$ref": "#/definitions/permissionResponse"
}
}
}
}
}
},
"definitions": {
"response": {
"type": "object",
"properties": {
"message": {
"type": "string",
"description": "A string indicating the response from the server."
},
"totalElements": {
"type": "integer",
"format": "int64",
"description": "The number of items retrieved."
},
"status": {
"type": "string",
"description": "A string indicating the response from the server."
}
}
},
"permissionResponse": {
"type": "object",
"properties": {
"data": {
"type": "array",
"description": "The collection of items returned from the API request.",
"items": {
"$ref": "#/definitions/permission"
}
}
},
"additionalProperties": {
"$ref": "#/definitions/response"
}
},
"permission": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int64",
"description": "Unique identifier representing a specific permission."
},
"label": {
"type": "string",
"description": "The label of a permission."
},
"description": {
"type": "string",
"description": "A description of the permission."
},
"active": {
"type": "boolean",
"description": "A flag indicating whether a permission is active."
}
},
"required": [
"id",
"label",
"description",
"active"
]
}
}
Example 1 renders well with swagger2markup showing the consolidated view of the data with the other 3 elements and having a permission array. However, with Swagger UI, it renders it differently, separating the objects out.
Markup rendered:
Swagger UI rendered
Swagger UI rendered - expanded
We are using swagger 2.0 to document our .Net Web API's which we are hosting in Azure behind Azure API Management. I am having troubles getting the documentation to detail the complex objects that are being posted as part of the body. Azure shows no details about the object at all leaving me to have to document them myself. Below is the json file that I imported into Azure API Management.
{
"swagger": "2.0",
"info": {
"version": "1.0.0",
"title": "Hotel Search",
"description": "The seodecnvewjkl"
},
"basePath": "/v1",
"consumes": [
"application/xml",
"application/json"
],
"produces": [
"application/xml",
"application/json"
],
"schemes": [
"http",
"https"
],
"paths": {
"/hotels/search": {
"post": {
"operationId": "searchCommand",
"description": "Searches for hotels",
"parameters": [
{
"name": "hotelSearchRq",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/HotelSearchRq"
}
}
],
"responses": {
"200": {
"description": "Successful response",
"schema": {
"title": "HotelSearchRs",
"$ref": "#/definitions/HotelSearchRs"
}
},
"400": {
"description": "Bad Request"
},
"404": {
"description": "Unauthorised"
}
}
},
"get": {
"operationId": "searchQuery",
"parameters": [
{
"name": "CorrelationId",
"in": "query",
"type": "string"
}
],
"responses": {
"200": {
"description": "Successful response"
}
}
}
}
},
"definitions": {
"StayDetail": {
"type": "object",
"properties": {
"NumberOfGuests": {
"type": "integer"
},
"CheckinDate": {
"type": "string",
"format": "date",
"description": "the date that the stay starts from"
}
}
},
"HotelSearchCriteria": {
"type": "object",
"properties": {
"MaximumResults": {
"type": "integer",
"format": "int64"
},
"StayDetails": {
"$ref": "#/definitions/StayDetail"
}
}
},
"HotelSearchRq": {
"type": "object",
"properties": {
"CustomerTransactionIdentifier": {
"type": "string",
"description": "The customers transaction identifier"
},
"search_criteria": {
"$ref": "#/definitions/HotelSearchCriteria"
}
}
},
"HotelSearchRs": {
"type": "object"
}
}
}
Azure Api Management operation screen
Can someone please help me with how I can get the body documented automatically from the swagger documentation?
Currently the request and response body information from a Swagger doc are not displayed in the developer portal documentation.
This is no longer the case. Samples and schema are displayed in the developer portal.