Custom rule for application/problem+json using Stoplight Spectral CLI
I'm trying to make a custom rule based on the unkown-error-format that can be found here here. Using this Open API document as an example:
openapi-generated.yaml
openapi: 3.0.3
info:
title: API
version: 1.0.0
servers:
- url: https://api.com/
paths:
/:
get:
tags: []
summary: Your GET endpoint
description: Your GET endpoint
operationId: get-endpoint
responses:
"500":
description: Error
content:
application/json:
schema:
properties:
errorDescription:
type: string
and this rule set:
.spectral.yml
extends:
- https://raw.githubusercontent.com/openapi-contrib/style-guides/master/apisyouwonthate.yml
rules:
unknown-error-format: error
When running
spectral lint --ruleset .spectral.yml openapi-generated.yaml
I was expecting an error to be returned, because the 500 response content is application/json
and not one of the allowed values application/vnd.api+json
, application/problem+xml
, and application/problem+json
.
Instead no errors are found:
No results with a severity of 'error' or higher found!
I experimented with some other Spectral core functions that should make the linter return an error, but it does not. I suspect the expression in given is not returning the right result, internally.
Additionally, I tried using this JSON Path Demo to check if the output array with "application/json" is returned for the path in the rule's given. It does.
Is there a problem with this rule or am I doing something wrong?
I'm using Spectral version 6.1.0.
Thanks in advance.
do you know?
how many words do you know
See also questions close to this topic
-
Is an OpenAPI path with multiple variables in the same segment valid?
Is the following valid?
GET image/{id}/{palette}.{file_extension}
I want to be able to do something like this: example:
GET image/1/falsecolor.jpg GET image/4/alternative.png GET image/9/falsecolor.tiff
Basically, the palette defines how is the image is colored (color palette) and the extension is the file format better suited for your application (mobile deals best with one file format, web with another, etc), all OpenAPI linters I tried do validate it, there is nothing that I can find in the documentation for the OpenAPI that says that this is not a valid approach, but when I uploaded this to Postman, it borked beyond recognition, loading the palette and the file extension both as collection variables instead of API properties, and Postman is supposedly OpenAPI compliant/compatible, so I am wondering if this is actually a non-compliant path parameter.
-
nSwag Client: Is there a better/easier approach to affect PropertyNameCaseInsensitive?
We are attempting to integrate System.Text.Json into our REST API and rest clients, previously using Newtonsoft.
We are using nswag CSharpClientGenerator.GenerateFile to generate our REST API clients via code (not nSwag Studio).
Because of the casing differences between the property names and the json name, items are not correctly deserializing. We have been able to over come this by setting PropertyNameCaseInsensitive = true.
We were able to do this via a partial class as below:
partial class MakeClient { partial void UpdateJsonSerializerSettings(JsonSerializerOptions settings) { settings.PropertyNameCaseInsensitive = true; } }
I really don't want to create these partial classes for every client.
Is there an easier way to do this, such as injecting JsonSerializerOptions into the client, or some type of global setting?
-
AWS API Gateway: Why setting "application/json" mapping template for GET request is required for MOCK integration to work?
I'm setting up a mock integration for GET requests with AWS API Gateway, and wonder why it only works when the
application/json
request template is specified. To my understanding GET request does not have a body and hence does not have a Content-Type header. What is special about 'application/json'? Is this behavior documented somewhere or am I missing some defaults somewhere?Here is terraform code for my API Gateway:
resource "aws_api_gateway_rest_api" "test-api" { name = "test-api" endpoint_configuration { types = ["REGIONAL"] } body = jsonencode(yamldecode(file("openapi.yaml"))) }
openapi: "3.0.1" info: version: "1.0" title: example paths: /test: get: responses: "200": description: demo headers: Content-Type: { schema: { type: 'string' } } x-amazon-apigateway-integration: type: MOCK passthroughBehavior: when_no_templates # the next line is required. # API Gateway returns 500 error if I remove it. why? # API Gateway returns 415 error if I change application/json to text/plain. why? requestTemplates: { 'application/json': '{"statusCode": 200}' } responses: default: statusCode: 200 responseParameters: { 'method.response.header.Content-Type': "'text/plain'" } responseTemplates: {'text/plain': 'hello'}
Here is an example log output when requestTemplates is set to
{ 'text/plain': '{"statusCode": 200}' }
Execution log for request 09c6d06b-669c-4717-86a2-c8489136f760 Fri May 06 14:28:24 UTC 2022 : Starting execution for request: 09c6d06b-669c-4717-86a2-c8489136f760 Fri May 06 14:28:24 UTC 2022 : HTTP Method: GET, Resource Path: /test Fri May 06 14:28:24 UTC 2022 : Method request path: {} Fri May 06 14:28:24 UTC 2022 : Method request query string: {} Fri May 06 14:28:24 UTC 2022 : Method request headers: {} Fri May 06 14:28:24 UTC 2022 : Method request body before transformations: Fri May 06 14:28:24 UTC 2022 : Execution failed: null Fri May 06 14:28:24 UTC 2022 : Method completed with status: 415
-
Testing custom Lint rule with custom scopes
On the project I have a bunch of custom Lint rules. At some point of time I had a need to report single issue with different severity, depending on the
scope
. Since issue is tightly coupled with a scope I created two issues:val ISSUE_1 = Issue.create( ... severity = WARNING, implementation = Implementation(MyDetector::class.java, Scope.ALL_RESOURCES_SCOPE) ) val ISSUE_2 = Issue.create( ... severity = INFORMATIONAL, implementation = Implementation(MyDetector::class.java, Scope.RESOURCE_FILE_SCOPE), )
Then in some place within the detector I've implemented the following logic:
if (context.scope.contains(Scope.ALL_RESOURCE_FILES) { context.report(ISSUE_1, ...) } else { context.report(ISSUE_2, ...) }
Everything works like a charm in both Gradle and IDE. The issue occurs on attempt to unit test the logic.
I wrote the following two tests:
@Test fun test1() { val layout = xml(...) lint() .customScope(Scope.ALL_RESOURCES_SCOPE) .files(layout) .issues(ISSUE_2) .run() .expectClean() }
This one passes as
ISSUE_2
requires another scope - it is simply not run.@Test fun test2() { val layout = xml(...) lint() .customScope(Scope.ALL_RESOURCES_SCOPE) .files(layout) .issues(ISSUE_1) .run() .expect("some_output") }
And this one fails! But it fails not because of the wrong expectation. No, it fails, because the following assertion in the
LintDriver
class:fun analyze() { //noinspection ExpensiveAssertion assert(!scope.contains(Scope.ALL_RESOURCE_FILES) || scope.contains(Scope.RESOURCE_FILE)) ...
What is the correct way to verify issue/detector against the
Scope.ALL_RESOURCE_FILES
then? -
add custom lint error marker for codemirror
I receive the errors in my code from an external API. It gives me the
1)line number 2) error description
I could achieve the highlighting process but I need to add a lint error marker on the left side of the textarea.
The following code enable me to add lint marker when the page is load by definingoption called 'lintWith', However, I need to add these lint markers when I click on the button.
The is the code I'm using:
<html> <head> <link rel="stylesheet" href="codemirror/lib/codemirror.css"> <script src="codemirror/lib/codemirror.js"></script> <script src="codemirror/addon/edit/matchbrackets.js"></script> <script src="codemirror/mode/python/python.js"></script> <!-- <script src="codemirror/addon/selection/active-line.js"></script> --> <link rel="stylesheet" href="codemirror/addon/lint/lint.css"> <script src="codemirror/addon/lint/lint.js"></script> <script src="codemirror/addon/lint/javascript-lint.js"></script> <script src="cm-validator-remote.js"></script> <style type="text/css"> .CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;} .CodeMirror-empty { outline: 1px solid #c22; } </style> </head> <body> <div><textarea id="code" name="code" placeholder="Code goes here..."> mycode pass a__ = 5 Check Hello World 123456 </textarea></div> </body> <script type="text/javascript"> function check_syntax(code, result_cb) { var error_list = [{ line_no: 2, column_no_start: 14, column_no_stop: 17, fragment: "def doesNothing:\n", message: "invalid syntax.......", severity: "error" }, { line_no: 4, column_no_start: 1, column_no_stop: 3, fragment: "a__ = 5\n", message: "convention violation", severity: "error" }] result_cb(error_list); } var editor = CodeMirror.fromTextArea(document.getElementById("code"), { mode: { name: "python", version: 2, singleLineStringErrors: false }, lineNumbers: true, indentUnit: 4, tabMode: "shift", gutters: ["CodeMirror-lint-markers"], lintWith: { "getAnnotations": CodeMirror.remoteValidator, "async": true, "check_cb": check_syntax } }); function AddLintMarker(){ // I want to add the lintWith markers when click on this button // i've tried like this editor.setOption("lintWith.getAnnotations",CodeMirror.remoteValidator ) but it doesn't work } </script> <input type="button" value="add boxes" onclick="AddLintMarker()"> </html>
Here the code lint marker is added when the page is load because it is assigned to the editor but I want the lint maker to shows only when I click on the button and provide values to the check_syntx function,
and for the lintWith it is defined in the lint.js as the following :
CodeMirror.defineOption("lintWith", false, function(cm, val, old) { if (old && old != CodeMirror.Init) { clearMarks(cm); cm.off("change", onChange); CodeMirror.off(cm.getWrapperElement(), "mouseover", cm._lintState.onMouseOver); delete cm._lintState; } if (val) { var gutters = cm.getOption("gutters"), hasLintGutter = false; for (var i = 0; i < gutters.length; ++i) if (gutters[i] == GUTTER_ID) hasLintGutter = true; var state = cm._lintState = new LintState(cm, parseOptions(val), hasLintGutter); cm.on("change", onChange); CodeMirror.on(cm.getWrapperElement(), "mouseover", state.onMouseOver); startLinting(cm); } });
-
How to implement linting feature in code-mirror for a custom mode
I have used ngx-codemirror and set mode to rego. Highlighting is working correctly. How should i implement lint feature for this mode.
-
I am trying to pre-process data for MLP classifier . I am generating 40 MFCC's and 222 spectral centroids per .wav file
This is my model evaluation code
# Display model architecture summary model.summary() # Calculate pre-training accuracy score = model.evaluate(x_test, y_test, verbose=1) accuracy = 100*score[1] print("Pre-training accuracy: %.4f%%" % accuracy)
I have converted both of my features into a list('F[]') this way.
X = np.array(featuresdf.feature_mfcc.tolist() , dtype=object) # print(type(X)) X2 = np.array(featuresdf.sc.tolist() , dtype=object) # print(type(X2)) # print(X2) F = [] for i , val in enumerate(X): temp_x = val temp_x2 = X2[i] # concat = temp_x + temp_x2 concat = np.hstack((temp_x,temp_x2)) F.append(concat) # y dependant variable jo hum predict karenge. y = np.array(featuresdf.class_label.tolist())
-
Spectral signature of classified image in GEE using Random Forest
I am using this script to draw average spectral signature of all classes together and each class separately of a classified image by RF algorithm in GEE.
var bands = ['B1', 'B2', 'B3', 'B4','B5','B6','B7', 'B8', 'B8A', 'B9' ,'B11', 'B12','NDVI', 'EVI', 'GNDVI', 'NBR', 'NDII']; var Training_Points = Water.merge(Residential).merge(Agricultural).merge(Arbusti).merge(BoschiMisti).merge(Latifoglie).merge(Conifere).merge(BareSoil); var classes = ee.Image().byte().paint(Training_Points, "land_class").rename("land_class") var stratified_points = classes.stratifiedSample({ numPoints: 50, classBand: 'land_class', scale: 10, region: Training_Points, geometries: false, tileScale: 6 }) print(stratified_points, 'stratified_points') //Create training data var training_Stratified = RF_classified.select(bands).sampleRegions({ collection: stratified_points, properties: ['land_class'], scale:10, tileScale:2 }); var bands = RF_classified.bandNames() var numBands = bands.length() var bandsWithClass = bands.add('land_class') var classIndex = bandsWithClass.indexOf('land_class') // Use .combine() to get a reducer capable of computing multiple stats on the input var combinedReducer = ee.Reducer.mean().combine({ reducer2: ee.Reducer.stdDev(), sharedInputs: true}) // Use .repeat() to get a reducer for each band and then use .group() to get stats by class var repeatedReducer = combinedReducer.repeat(numBands).group(classIndex) var stratified_points_Stats = training_Stratified.reduceColumns({ selectors: bands.add('land_class'), reducer: repeatedReducer, }) // Result is a dictionary, we do some post-processing to extract the results var groups = ee.List(stratified_points_Stats.get('groups')) var classNames = ee.List(['Water','Residential', 'Agricultural', 'Arbusti', 'BoschiMisti', 'Latifoglie','Conifere', 'BareSoil']) var fc = ee.FeatureCollection(groups.map(function(item) { // Extract the means var values = ee.Dictionary(item).get('mean') var groupNumber = ee.Dictionary(item).get('group') var properties = ee.Dictionary.fromLists(bands, values) var withClass = properties.set('class', classNames.get(groupNumber)) return ee.Feature(null, withClass) })) // Chart spectral signatures of training data var options = { title: 'Average Spectral Signatures', hAxis: {title: 'Bands'}, vAxis: {title: 'Reflectance', viewWindowMode:'explicit', viewWindow: { max:6000, min:0 }}, lineWidth: 1, pointSize: 4, series: { 0: {color: '105af0'}, 1: {color: 'dc350a'}, 2: {color: 'caa712'}, 3: {color: 'b9ffa4'}, 4: {color: '369b47'}, 5: {color: '21ff2d'}, 6: {color: '275b25'}, 7: {color: 'f7e084'}, }}; // Default band names don't sort propertly Instead, we can give a dictionary with labels for each band in the X-Axis var bandDescriptions = { 'B2': 'B2/Blue', 'B3': 'B3/Green', 'B4': 'B4/Red', 'B5': 'B5/Red Edge 1', 'B6': 'B5/Red Edge 2', 'B7': 'B7/Red Edge 3', 'B8': 'B8/NIR', 'B8A': 'B8A/Red Edge 4', 'B11': 'B11/SWIR-1', 'B12': 'B12/SWIR-2' } // Create the chart and set options. var chart = ui.Chart.feature.byProperty({ features: fc, xProperties: bandDescriptions, seriesProperty: 'class' }) .setChartType('ScatterChart') .setOptions(options); print(chart) var classChart = function(land_class, label, color) { var options = { title: 'Spectral Signatures for ' + label + ' Class', hAxis: {title: 'Bands'}, vAxis: {title: 'Reflectance', viewWindowMode:'explicit', viewWindow: { max:6000, min:0 }}, lineWidth: 1, pointSize: 4, }; var fc = training_Stratified.filter(ee.Filter.eq('land_class', land_class)) var chart = ui.Chart.feature.byProperty({ features: fc, xProperties: bandDescriptions, }) .setChartType('ScatterChart') .setOptions(options); print(chart) } classChart(0, 'Water') classChart(1, 'Residential') classChart(2, 'Agricultural') classChart(3, 'Arbusti') classChart(4, 'BoschiMisti') classChart(5, 'Latifoglie') classChart(6, 'Conifere') classChart(7, 'BareSoil')
I receive the error:
Error generating chart: Image.select: Pattern 'B1' did not match any bands.
I do not understand where is the problem since I used the same script before to draw histogram of training data and it worked well.
-
OpenAPI Specification - Use of Discriminator and oneOf - Spectral listing
OpenAPI Discriminator using oneOf
A minimal example of using a discriminator with an openApi spec and linting with Spectral.
Error message:
~/git/openapi_discriminator/openapi/v1/api.yaml 22:23 error oas3-valid-media-example "example" property must match exactly one schema in oneOf paths./discriminatortest.get.responses[200].content.application/json.example
Background
OpenAPI schema with simple GET method which can return different types of
Animal
.A subclass of
Animal
is defined which can either be aChicken
or aDog
.The only property
Animals
have arelegs
. A discriminator is used to distinguish between aChicken
orDog
where aChicken
hastwo
legs
and aDog
hasfour
legs.Aim
I was to verify that the example in a request response matches only one schema.
Question
I thought using a discriminator might mean that anything with
two
legs
is aChicken
and anything withfour
legs
is aDog
.Am I mistaken and it is still legitimate for a
Dog
to havetwo
legs
, and this is why it's erroring?I could change it to
anyOf
but then the discriminator has no use?Code
Code repo - openapi_discriminator
openapi_discriminator/openapi/v1/api.yaml
:openapi: "3.0.3" info: title: Open API Discriminator Example version: "v1" tags: - name: discriminator paths: /discriminatortest: get: tags: - discriminator summary: Example using discriminator description: "Demonstrate a minimal example" responses: "200": description: Created content: application/json: schema: {$ref: "schemas.yaml#/components/schemas/Animal"} example: legs: "two"
openapi_discriminator/openapi/v1/schemas.yaml
:openapi: "3.0.3" components: schemas: Animal: type: object discriminator: propertyName: legs mapping: two: Chicken four: Dog oneOf: - $ref: '#/components/schemas/Dog' - $ref: '#/components/schemas/Chicken' Chicken: type: object required: - legs properties: legs: type: string Dog: type: object required: - legs properties: legs: type: string
openapi_discriminator/openapi/.spectral.yml
extends: spectral:oas rules: info-contact: false info-description: false oas3-api-servers: false openapi-tags: true operation-tags: true operation-operationId: false operation-description: true
Run linting command:
spectral lint "openapi/v1/api.yaml" --ruleset openapi/.spectral.yml
-
Postman Authorization with petstore swagger and Prism
I've been testing out stoplight prism https://stoplight.io/open-source/prism/ and using a https://petstore.swagger.io/ doc to run my mocks I'm able to use the GET method for /pet and get mocked results back using Prism. The swagger is requesting me to authenticate to use the PUT/UPDATE/DELETE methods.
After authenticating with the steps below. I'm still getting an error:
{ "type":"https://stoplight.io/prism/errors#NOT_ACCEPTABLE", "title":"The server cannot produce a representation for your accept header", "status":406, "detail":"Unable to find content for application/json" }
Steps:
- https://petstore.swagger.io/
- click authorize
- I add in a random client_id
- then add read and write scopes.
- I open my postman and select Authorization and add the following:
I click the Get New Access Token button and click the option to add token.
Then in my headers I add the following:
When I do my post I get the following error:
{ "type":"https://stoplight.io/prism/errors#NOT_ACCEPTABLE", "title":"The server cannot produce a representation for your accept header", "status":406, "detail":"Unable to find content for application/json" }
-
How to configure/define file upload in POST req in Stoplight Studio - for OpenAPI documentation
[Please bear with me, I'm completely new to APIs, OpenAPI and Stoplight Studio.]
BACKGROUND FOR THE QUESTION
I am using Stoplight Studio to implement OpenAPI documentation for a POST request, which involves a file upload.
This is what my FormData looks like:
body:{"displayName":"exampleFileCSV","fields":[/*<<content from my fileupload>>*/]} uploadFile: (binary)
This is what my Postman POST request looks like:
QUESTION:
I'm not able to figure out how to reproduce the same request in Stoplight Studio to document the API in OpenAPI. I need to configure the post request with the formData:{body, fileUpload}:
If that's not possible, I would like to know how it is implemented in swagger.json alone.