1657249268
Automatically generate OpenApi, Swagger, and Redoc documentation from your existing CakePHP code
Check out the demo applications for examples.
This is built for CakePHP 4.x only. Supported versions:
Version | Branch | Cake Version | PHP Version |
---|---|---|---|
2.* | master | ^4.2 | 8.0+ |
1.* | 1.next | ^4.0 | 7.2+ |
SwaggerBake requires CakePHP4 and a few dependencies that will be automatically installed via composer.
composer require cnizzardini/cakephp-swagger-bake
Run bin/cake plugin load SwaggerBake
or manually load the plugin:
# src/Application.php
public function bootstrap(): void
{
// other logic...
$this->addPlugin('SwaggerBake');
}
For standard applications that have not split their API into plugins, the automated setup should work. Otherwise use the manual setup.
Run the installer:
bin/cake swagger install
Then load the config and add a route.
Create a base swagger.yml file at config\swagger.yml
. An example file is provided here.
Create a swagger_bake.php config file at config/swagger_bake.php
file. See the example file here for further explanation. Then just add a route.
For more read sections on Multiple Instances of SwaggerBake and Extending Views and Controllers
In your config/bootstrap.php
file:
Configure::load('swagger_bake', 'default', false);
Create a route for the SwaggerUI page in config/routes.php
, example:
$builder->connect(
'/api',
['plugin' => 'SwaggerBake', 'controller' => 'Swagger', 'action' => 'index']
);
You can now browse to either /api
for swagger or /api?doctype=redoc
for redoc. Your OpenAPI JSON will exist at /api/swagger.json
.
bin/cake swagger bake
If Hot Reload is enabled (see config) OpenAPI will be generated each time you browse to SwaggerUI (or Redoc) in your web browser.
You can also generate OpenAPI programmatically:
$swagger = (new \SwaggerBake\Lib\SwaggerFactory())->create();
$swagger->getArray(); # returns swagger array
$swagger->toString(); # returns swagger json
$swagger->writeFile('/full/path/to/your/swagger.json'); # writes swagger.json
Your RESTful routes are used to build OpenAPI paths and operations.
SwaggerBake will parse the DocBlocks on your controller actions for additional OpenAPI data.
/**
* OpenAPI Operation Summary
*
* This displays as the operations long description
*
* @link https://book.cakephp.org/4/en/index.html External documentation
* @deprecated Indicates the operation is deprecated
* @throws \Cake\Http\Exception\BadRequestException Appears as 400 response with this description
* @throws \Exception Appears as 500 response with this description
*/
public function index() {}
If you prefer, you may use the OpenApiOperation, OpenApiResponse attributes instead. These attributes take precedence over doc block parsing. Read below for a full list of attributes.
OpenAPI schema is built from your Table and Entity classes and any validators you've defined in them. You may adjust the default schema using the OpenApiSchema and OpenApiSchemaProperty attributes.
For additional functionality the following PHP8 Attributes may be used. These can be imported individually from the SwaggerBake\Lib\Attribute
namespace. Read the Attributes docs for detailed examples. If you are using version 1 you will need to use annotations.
Attribute | Usage | Description |
---|---|---|
OpenApiDto | Controller Action | Builds OpenAPI query params and request bodies from Data Transfer Objects |
OpenApiForm | Controller Action | Builds OpenAPI for application/x-www-form-urlencoded request bodies |
OpenApiHeader | Controller Action | Create OpenAPI header parameters |
OpenApiOperation | Controller Action | Modifies OpenAPI operation |
OpenApiPaginator | Controller Action | Create OpenAPI query params from CakePHP Paginator Component |
OpenApiPath | Controller | Modifies OpenAPI paths |
OpenApiPathParam | Controller Action | Modify an existing OpenAPI path parameter |
OpenApiQueryParam | Controller Action | Builds OpenAPI query param |
OpenApiRequestBody | Controller Action | Modify OpenAPI request body |
OpenApiResponse | Controller Action | Modify OpenAPI response |
OpenApiSchema | Entity | Modifies OpenAPI schema |
OpenApiSchemaProperty | Entity or Class | Modifies an OpenAPI schema property or defines OpenApiResponse schema |
OpenApiSearch | Controller Action | Create OpenAPI query params from CakePHP Search plugin |
OpenApiSecurity | Controller Action | Create/modify OpenAPI security |
DTO class property | Builds OpenAPI query param from Data Transfer Objects (deprecated, use OpenApiQueryParam in v2.2.5+) | |
DTO class property | Builds OpenAPI request body property from Data Transfer Objects (deprecated, use OpenApiSchemaProperty in v2.2.5+) |
SwaggerBake comes with an event system to allow for further control over your OpenAPI schema.
Event | Description |
---|---|
SwaggerBake.Operation.created | Dispatched each time an OpenAPI Path > Operation is created |
SwaggerBake.Path.created | Dispatched each time an OpenAPI Path is created |
SwaggerBake.Schema.created | Dispatched each time an OpenAPI Schema is created |
SwaggerBake.initialize | Dispatched during initialization phase on SwaggerBake |
SwaggerBake.beforeRender | Dispatched before SwaggerBake outputs OpenAPI JSON |
By default, SwaggerBake uses '#/components/schemas/Exception'
as your OpenAPI documentations Exception schema. See the default swagger.yml and exceptionSchema
in swagger_bake.php for more info. You can further customize with attributes and @throws
.
Using the ref
or schema
properties of OpenApiResponse.
@throws
tag and OpenApiExceptionSchemaInterfaceImplement SwaggerBake\Lib\OpenApiExceptionSchemaInterface
on your exception class, then document the exception with a @throws
tag in your controller action's doc block.
/**
* @throws \App\Exception\MyException
*/
public function add(){}
Example exception class:
class MyException implements OpenApiExceptionSchemaInterface
{
public static function getExceptionCode(): string
{
return '400';
}
public static function getExceptionDescription(): ?string
{
return 'An optional description'; // returning null omits the response description
}
public static function getExceptionSchema(): Schema|string
{
return (new \SwaggerBake\Lib\OpenApi\Schema())
->setTitle('MyException')
->setProperties([
(new SchemaProperty())->setType('string')->setName('code')->setExample('400'),
(new SchemaProperty())->setType('string')->setName('message')->setExample('error'),
(new SchemaProperty())->setType('string')->setName('wherever')->setExample('whatever you want')
]);
}
}
It's possible to write extensions for SwaggerBake. Read the extensions documentation. There are several other options to extend functionality documented below:
You may use your own swagger or redoc install in lieu of the version that comes with SwaggerBake. Simply don't add a custom route as indicated in the installation steps. In this case just reference the generated swagger.json within your userland Swagger UI install.
You might want to perform some additional logic (checking for authentication) before rendering the built-in Swagger UI. This is easy to do. Just create your own route and controller, then reference the built-in layout and template:
// config/routes.php
$builder->connect('/my-swagger-docs', ['controller' => 'MySwagger', 'action' => 'index']);
To get started, copy SwaggerController into your project.
Note: SwaggerUiComponent has been deprecated in version 2.3.0 and will be removed in version 3.
You will need to use your own controller (see above). From there you can copy the layouts and templates into your project and inform your controller action to use them instead. Checkout out the CakePHP documentation on Views for specifics. This can be useful if you'd like to add additional functionality to SwaggerUI (or Redoc) using their APIs or if your project is not installed in your web servers document root (i.e. a sub-folder).
If your application has multiple APIs that are split into plugins you can generate unique OpenAPI schema, Swagger UI, and Redoc for each plugin. Setup a new swagger_bake.php
and swagger.yaml
in plugins/OtherApi/config
. These configurations should point to your plugins paths and namespaces. Next, create a custom SwaggerController and load the configuration within initialize()
:
public function initialize(): void
{
parent::initialize();
Configure::load('OtherApi.swagger_bake', 'default', false); // note: `false` for the third argument is important
/*
* Only load the component if you are using a version older than v2.3.0. This component will be deprecated
* in v3.0.0
*/
$this->loadComponent('SwaggerBake.SwaggerUi');
}
When running bin/cake swagger bake
you will need to specify your plugins swagger_bake config:
bin/cake swagger bake --config OtherApi.swagger_bake
In addition to swagger bake
these console helpers provide insight into how your Swagger documentation is generated.
swagger routes
Displays a list of routes that can be viewed in Swagger.
bin/cake swagger routes
swagger models
Displays a list of models that can be viewed in Swagger.
bin/cake swagger models
SwaggerBake comes with Bake templates for scaffolding RESTful controllers compatible with SwaggerBake and OpenAPI 3.0 schema. Using the bake theme is completely optional, but will save you some time since the default bake theme is not specifically designed for RESTful APIs.
bin/cake bake controller {Name} --theme SwaggerBake
No API definition provided.
Verify that swagger.json exists.
Unable to create swagger file. Try creating an empty file first or checking permissions
Create the swagger.json manually matching the path in your config/swagger_bake.php
file.
Output file is not writable
Change permissions on your swagger.json file
, 764
should do.
Controller not found
Make sure a controller actually exists for the route resource.
Make sure yours route are properly defined in config/routes.php
per the CakePHP RESTful routing documentation.
Sample schema is determined using CakePHP naming conventions. Does your controller name match your model names? For customizing response schema see OpenApiResponse.
Sample schema is determined using CakePHP naming conventions. Does your controller name match your model names? For customizing request schema see OpenApiRequestBody.
Either disable CSRF protection on your main route in config/routes.php
or enable CSRF protection in Swagger UI. The library does not currently support adding this in for you.
Swagger UI sends HTTP DELETE without an accept
header. If the record does not exist, an exception is generated. This results in an HTML response being generated which can be quite large and cause the UI to be slow to render. To get around this you can force an accept
value on the header using the CakePHP middleware:
# src/Application.php
public function middleware(MiddlewareQueue $middlewareQueue): MiddlewareQueue
{
$middlewareQueue
->add(function(ServerRequestInterface $request, RequestHandlerInterface $handler){
$accept = $request->getHeader('accept');
if ($request->getMethod() === 'DELETE' && reset($accept) === '*/*') {
$request = $request->withHeader('accept', 'application/json');
}
return $handler->handle($request);
});
// other middleware...
return $middlewareQueue;
}
Read more about CakePHP middleware in the official documentation.
Send pull requests to help improve this library. You can include SwaggerBake in your primary Cake project as a local source to make developing easier:
Make a fork of this repository and clone it to your localhost
Remove cnizzardini\cakephp-swagger-bake
from your composer.json
Add a paths repository to your composer.json
"minimum-stability": "dev",
"repositories": [
{
"type": "path",
"url": "/absolute/local-path-to/cakephp-swagger-bake",
"options": {
"symlink": true
}
}
]
composer require cnizzardini/cakephp-swagger-bake @dev
Undo these steps when you're done. Read the full composer documentation on loading from path here: https://getcomposer.org/doc/05-repositories.md#path
Check out the extensions documentation to add functionality to this project.
PHPUnit Test Suite:
composer test
PHPUnit, PHPCS, PHPSTAN, and PHPMD:
composer analyze
GrumPHP can be used to run tests and static analyzers in a pre-commit hook.
composer grumphp-init
I've set grumphp to be installed globally: https://github.com/phpro/grumphp/blob/master/doc/installation/global.md
Author: cnizzardini
Source Code: https://github.com/cnizzardini/cakephp-swagger-bake
License: MIT license
1656088140
serverless-openapi-plugin
Serverless plugin to generate AWS serverless architecture from openApi definition.
It also generate validation (using Joi) for headers/query/params and body.
On your serverless.yml
add:
plugins:
-serverless-openapi-plugin
By default the plugin is looking for a definition.yml
, but you can override this setting using:
customs:
definition: mydefinition.yml
In order to generate handlers, you need to specify the handler name at root or operation level with x-serverless-handler
key.
Simple as:
serverless openapi
Author: jaumard
Source Code: https://github.com/jaumard/serverless-openapi-plugin
License:
1656080760
The plugin provides the functionality to merge OpenApiSpecification files (formerly known as swagger) with one or multiple YML files containing the the x-amazon-apigateway extensions. There are several use-cases to keep both information separated, e.g. it is needed to deploy different api gateway integrations depending on a stage environment.
When dealing with functional tests you do not want to test the production environment, but only a mocking response.
The plugin supports YML based OpenApi3 specification files only
See the examples folder for a full working example
Installation & Setup
Run npm install
in your Serverless project.
$ npm install --save-dev serverless-openapi-integration-helper
Add the plugin to your serverless.yml file
plugins:
- serverless-openapi-integration-helper
Plugin configuration
You can configure the plugin under the key openApiIntegration. See See Configuration Reference for a list of available options
The mapping array must be used to configure where the files containing the x-amazon-apigateway-integration blocks are located.
openApiIntegration:
package: true #New feature! Hook into the package & deploy process
inputFile: schema.yml
mapping:
- stage: [dev, prod] #multiple stages
path: integrations
- stage: test #single stage
path: mocks
In the above example all YML files inside the integrations directory will be processed and merged with the schema.yml file when deploying the dev stage
serverless deploy --stage=dev
To use a different x-amazon-apigateway to perform functional tests (with mocking responses e.g) the directory mock is processed and merged with the schema.yml file when deploying the test stage
serverless deploy --stage=test
Usage
You can setup a fully working API GATEWAY with any openApi 3.0 specification file First create the input file containing the OpenApiSpecification
# ./schema.yml
openapi: 3.0.0
info:
description: User Registration
version: 1.0.0
title: UserRegistration
paths:
/api/v1/user:
post:
summary: adds a user
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Customer'
responses:
'201':
description: user created
components:
schemas:
Customer:
type: object
required:
- email_address
- password
properties:
email_address:
type: string
example: test@example.com
password:
type: string
format: password
example: someStrongPassword#
The plugin will generate the x-amazon-apigateway integrations objects for all methods that do not have an integration.
#generate a file containing a gateway mock integration in the directory /mocks
serverless integration create --output mocks --type mock --stage=test
#generate a file containing the production integration in the directory integrations/
serverless integration create --output integrations --type http --stage=prod
Supported types are
The plugin now generates a merged file during deployment that is automatically injected in your serverless resources
#Create OpenApi File containing mocking responses (usable in functional tests) and deploy to ApiGateway
serverless deploy --stage==test
#Create OpenApi File containing the production integration and deploy to ApiGateway
serverless deploy --stage=prod
The generated output is automatically injected in the resources.Resources.YOUR_API_GATEWAY.Properties.Body property
resources:
Resources:
ApiGatewayRestApi:
Type: AWS::ApiGateway::RestApi
Properties:
ApiKeySourceType: HEADER
Body: ~ #autogenerated by plugin
Description: "Some Description"
FailOnWarnings: false
Name: ${opt:stage, self:provider.stage}-some-name
EndpointConfiguration:
Types:
- REGIONAL
ApiGatewayDeployment:
Type: AWS::ApiGateway::Deployment
Properties:
RestApiId:
Ref: ApiGatewayRestApi
StageName: ${opt:stage, self:provider.stage}
Commands
The generate command can be used independently with
serverless integration merge --stage=dev
Of course then the API Gateway Body property has to be specified manually
resources:
Resources:
ApiGatewayRestApi:
Type: AWS::ApiGateway::RestApi
Properties:
ApiKeySourceType: HEADER
Body: ${file(openapi-integration/api.yml)}
CORS generator
The plugin can generate full CORS support out of the box.
openApiIntegration:
cors: true
...
If enabled, the plugin generates all required OPTIONS methods as well as the required header informations and adds a mocking response to API Gateway. You can customize the CORS templates by placing your own files inside a directory openapi-integration (in your project root). The following files can be overwritten:
Filename | Description |
---|---|
headers.yml | All headers required for CORS support |
integration.yml | Contains the x-amazon-apigateway-integration block |
path.yml | OpenApi specification for the OPTIONS method |
response-parameters.yml | The response Parameters of the x-amazon-apigateway-integration responses |
See the EXAMPLES directory for detailed instructions.
Auto Mock Generator
If enabled, the plugin generates mocking responses for all methods that do not have an x-amazon-apigateway-integration block defined. It takes the first 2xx response defined in the openApi specification and generates a simple mocking response on the fly
openApiIntegration:
autoMock: true
...
When using the autoMock feature, you do not need to specify inputPath mappings, since all endpoints are mocked automatically
openApiIntegration:
package: true
inputFile: schema.yml
mapping: ~
VALIDATION generator
The plugin supports full request validation out of the box
openApiIntegration:
validation: true
...
If enabled, the plugin generates the x-amazon-apigateway-request-validators blocks and adds a basic request validation to all methods. You can customize the VALIDATION template by placing your own files inside a directory openapi-integration (in your project root). The following files can be overwritten:
Filename | Description |
---|---|
request-validator.yml | The x-amazon-apigateway-request-validators block |
See the EXAMPLES directory for detailed instructions.
Proxy Manager
The proxymanager feature automates the complete generation of an HTTP proxy integration. You only have to define the target URL and all necessary AWS integration blocks are generated on-the-fly during deployment.
openApiIntegration:
cors: true
validation: true
mapping:
- stage: [dev, prod]
proxyManager:
type: http_proxy
baseUrl: https://www.example.com
pattern: "(?<=api\/v1)\/.+"
...
With this setting, no separate integration files need to be created
A combination of your own and auto-generated files is still possible without any problems
at the moment only http_proxy supported
The base url is required to map the path variable from the openapi specification to the URI from the aws integration.
Example:
#original openapi specification
paths:
/api/v1/user:
post:
...
will be translated to
#generated openapi specification output
paths:
/api/v1/user:
post:
...
x-amazon-apigateway-integration:
type: http_proxy
passthroughBehavior: when_no_match
httpMethod: POST
uri: https://www.example.com/api/v1/user
The pattern can be used to adapt the mapping of the base url using regexp, to remove a prefix, or a version string
Example:
baseUrl: https://www.example.com
pattern: "(?<=api\/v1)\/.+"
will translate the route /api/v1/user to https://www.example.com/user
Configuration Reference
configure the plugin under the key openApiIntegration
openApiIntegration:
inputFile: schema.yml #required
package: true #optional, defaults to false
inputDirectory: ./ #optional, defaults to ./
cors: true #optional, defaults to false
autoMock: true #optional, defaults to false
validation: true #optional, defaults to false
mapping: #optional, can be completely blank if autoMock option is enabled
- stage: [dev, prod] #multiple stages
path: integrations
proxyManager: #optional
type: http_proxy
baseUrl: https://example.com
pattern: "(?<=v1)\/.+"
- stage: test #single stage
path: mocks/customer.yml
outputFile: api.yml #optional, defaults to api.yml
outputDirectory: openapi-integration #optional, defaults to ./openapi-integration
Known Issues
When using serverless framework only to deploy your aws resources without having any lambda functions or triggers, the AWS Gateway deploymemt does not behave as expected. Any deployment to an existing stage will be ignored, since CloudFormation does not redeploy a stage if the DeploymentIdentifier has not changed.
The plugin serverless-random-gateway-deployment-id solves this problem by adding a random id to the deployment-name and all references to it on every deploy
See the examples folder for a full working example
Serverless variables inside the openapi integration files are not resolved correctly when using the package & deploy hooks. This problem can be solved by using the api gateway STAGE VARIABLES.
See the examples folder for a full working example
Example
service:
name: user-registration
provider:
name: aws
stage: dev
region: eu-central-1
plugins:
- serverless-openapi-integration-helper
openApiIntegration:
inputFile: schema.yml
package: true
mapping:
- path: integrations
stage: [dev, prod]
- path: mocks/customer.yml
stage: test
functions:
resources:
Resources:
ApiGatewayRestApi:
Type: AWS::ApiGateway::RestApi
Properties:
ApiKeySourceType: HEADER
Body: ~
Description: "Some Description"
FailOnWarnings: false
Name: ${opt:stage, self:provider.stage}-some-name
EndpointConfiguration:
Types:
- REGIONAL
ApiGatewayDeployment:
Type: AWS::ApiGateway::Deployment
Properties:
RestApiId:
Ref: ApiGatewayRestApi
StageName: ${opt:stage, self:provider.stage}
serverless deploy --stage=test
serverless deploy --stage=prod
Approach to a functional test of schema validation
The plugin works well in combination with the serverless-plugin-test-helper to automate tests against the deployed api gateway
npm install --save-dev serverless-plugin-test-helper
add the plugin as a plugin dependency in your serverless configuration file and configure the plugin according to the Readme
#./serveless.yml
plugins:
- serverless-plugin-test-helper
- serverless-openapi-integration-helper
[...]
resources:
Outputs:
GatewayUrl: # This is the key that will be used in the generated outputs file
Description: This is a helper for functional tests
Value: !Join
- ''
- - 'https://'
- !Ref ApiGatewayRestApi
- '.execute-api.'
- ${opt:region, self:provider.region}
- '.amazonaws.com/'
- ${opt:stage, self:provider.stage}
Resources:
ApiGatewayRestApi:
Type: AWS::ApiGateway::RestApi
Properties:
ApiKeySourceType: HEADER
Body: ~
Description: User Registration (${opt:stage, self:provider.stage})
FailOnWarnings: false
Name: ${opt:stage, self:provider.stage}-gateway
EndpointConfiguration:
Types:
- REGIONAL
ApiGatewayDeployment:
Type: AWS::ApiGateway::Deployment
Properties:
RestApiId:
Ref: ApiGatewayRestApi
StageName: ${opt:stage, self:provider.stage}
Add a functional test (e.g. with jest)
//tests/registration.js
import {getOutput} from 'serverless-plugin-test-helper';
import axios from 'axios';
axios.defaults.adapter = require('axios/lib/adapters/http'); //Todo
const URL = getOutput('GatewayUrl');
test('request validation on registration', async () => {
expect.assertions(1);
const {status} = await axios.post(URL + '/api/v1/user',
{
"email_address": "test@example.com",
"password": "someStrongPassword#"
},
{
headers: {
'Content-Type': 'application/json',
}
});
expect(status).toEqual(201);
});
test('request validation on registration (invalid request)', async () => {
expect.assertions(1);
try {
await axios.post(URL + '/api/v1/user',
{
"email": "test@example.com"
},
{
headers: {
'Content-Type': 'application/json',
}
});
} catch (e) {
expect(e.response).toMatchObject({
statusText: 'Bad Request',
status: 400
});
}
});
Then perform the functional test
serverless deploy --stage=test
npm test
serverless remove --stage=test
The command will
See the examples folder for a full working example
Feedback is appreciated! If you have an idea for how this plugin/library can be improved (or even just a complaint/criticism) then please open an issue.
Author: yndlingsfar
Source Code: https://github.com/yndlingsfar/serverless-openapi-integration-helper
License: MIT license
1656073080
Serverless OpenAPI Documentation Plugin
Generates OpenAPI 3.0.0 documentation from serverless configuration files. OpenAPI is formerly known as Swagger.
This plugin requires additional configuration to use, see the "Configuration" section for how to configure the plugin to generate documentation.
Below are the commandline options to run the generator:
serverless openapi generate [options]
Plugin: ServerlessOpenAPIDocumentation
openapi generate ...................... Generate OpenAPI v3 Documentation
--output / -o ...................... Output file location [default: openapi.yml|json]
--format / -f ...................... OpenAPI file format (yml|json) [default: yml]
--indent / -i ...................... File indentation in spaces [default: 2]
--help / -h ...................... Help
To configure this plugin to generate valid OpenAPI documentation there are two places you'll need to modify in your serverless.yml
file, the custom
variables section and the http
event section for each given function in your service.
This plugin is compatible with the same documentation configuration structure in serverless-aws-documentation and can run beside it.
The custom
section of your serverless.yml
can be configured as below:
custom:
documentation:
version: '1'
title: 'My API'
description: 'This is my API'
models: {}
These configurations can be quite verbose; you can separate it out into it's own file, such as serverless.doc.yml
as below:
custom:
documentation: ${file(serverless.doc.yml):documentation}
functions:
myFunc:
events:
- http:
path: getStuff
method: get
documentation: ${file(serverless.doc.yml):endpoints.myFunc}
For more info on serverless.yml
syntax, see their docs.
Models contain additional information that you can use to define schemas for endpoints. You must define the content type for each schema that you provide in the models.
The required directives for the models section are as follow:
name
: the name of the schemadescription
: a description of the schemacontentType
: the content type of the described request/response (ie. application/json
or application/xml
).schema
: The JSON Schema (website) that describes the model. You can either use inline YAML
to define these, or refer to an external schema file as belowcustom:
documentation:
models:
- name: "ErrorResponse"
description: "This is an error"
contentType: "application/json"
schema: ${file(models/ErrorResponse.json)}
- name: "PutDocumentResponse"
description: "PUT Document response model (external reference example)"
contentType: "application/json"
schema: ${file(models/PutDocumentResponse.json)}
- name: "PutDocumentRequest"
description: "PUT Document request model (inline example)"
contentType: "application/json"
schema:
$schema: "http://json-schema.org/draft-04/schema#"
properties:
SomeObject:
type: "object"
properties:
SomeAttribute:
type: "string"
To define the documentation for a given function event, you need to create a documentation
attribute for your http event in your serverless.yml
file.
The documentation
section of the event configuration can contain the following attributes:
summary
: a short description of the methoddescription
: a detailed description of the methodtags
: an array of tags for this eventdeprecated
: boolean indicator that indicates clients should migrate away from this functionrequestBody
: contains description of the requestdescription
: a description of the request bodyrequestModels
: a list of models to describe the request bodies (see requestModels below)queryParams
: a list of query parameters (see queryParams below)pathParams
: a list of path parameters (see pathParams below)cookieParams
: a list of cookie parameters (see cookieParams below)methodResponses
: an array of response models and applicable status codesstatusCode
: applicable http status code (ie. 200/404/500 etc.)responseBody
: contains description of the responsedescription
: a description of the body responseresponseHeaders
: a list of response headers (see responseHeaders below)responseModels
: a list of models to describe the request bodies (see responseModels below) for each Content-Type
functions:
createUser:
handler: "handler.create"
events:
- http:
path: "create"
method: "post"
documentation:
summary: "Create User"
description: "Creates a user and then sends a generated password email"
requestBody:
description: "A user information object"
requestModels:
application/json: "PutDocumentRequest"
pathParams:
- name: "username"
description: "The username for a user to create"
schema:
type: "string"
pattern: "^[-a-z0-9_]+$"
queryParams:
- name: "membershipType"
description: "The user's Membership Type"
schema:
type: "string"
enum:
- "premium"
- "standard"
cookieParams:
- name: "SessionId"
description: "A Session ID variable"
schema:
type: "string"
methodResponses:
- statusCode: 201
responseBody:
description: "A user object along with generated API Keys"
responseModels:
application/json: "PutDocumentResponse"
- statusCode: 500
responseBody:
description: "An error message when creating a new user"
responseModels:
application/json: "ErrorResponse"
queryParams
Query parameters can be described as follow:
name
: the name of the query variabledescription
: a description of the query variablerequired
: whether the query parameter is mandatory (boolean)schema
: JSON schema (inline or file)queryParams:
- name: "filter"
description: "The filter parameter"
required: true
schema:
type: "string"
pathParams
Path parameters can be described as follow:
name
: the name of the query variabledescription
: a description of the query variableschema
: JSON schema (inline or file)pathParams:
- name: "usernameId"
description: "The usernameId parameter"
schema:
type: "string"
cookieParams
Cookie parameters can be described as follow:
name
: the name of the query variabledescription
: a description of the query variablerequired
: whether the query parameter is mandatory (boolean)schema
: JSON schema (inline or file)cookieParams:
- name: "sessionId"
description: "The sessionId parameter"
required: true
schema:
type: "string"
requestModels
The requestModels
property allows you to define models for the HTTP Request of the function event. You can define a different model for each different Content-Type
. You can define a reference to the relevant request model named in the models
section of your configuration (see Defining Models section).
requestModels:
application/json: "CreateRequest"
application/xml: "CreateRequestXML"
methodResponses
You can define the response schemas by defining properties for your function event.
For an example of a methodResponses
configuration for an event see below:
methodResponse:
- statusCode: 200
responseHeaders:
- name: "Content-Type"
description: "Content Type header"
schema:
type: "string"
responseModels:
application/json: "CreateResponse"
application/xml: "CreateResponseXML"
responseModels
The responseModels
property allows you to define models for the HTTP Response of the function event. You can define a different model for each different Content-Type
. You can define a reference to the relevant response model named in the models
section of your configuration (see Defining Models section).
responseModels:
application/json: "CreateResponse"
application/xml: "CreateResponseXML"
responseHeaders
and requestHeaders
The responseHeaders/requestHeaders
section of the configuration allows you to define the HTTP headers for the function event.
The attributes for a header are as follow:
name
: the name of the HTTP Headerdescription
: a description of the HTTP Headerschema
: JSON schema (inline or file)responseHeaders:
- name: "Content-Type"
description: "Content Type header"
schema:
type: "string"
requestHeaders:
- name: "Content-Type"
description: "Content Type header"
schema:
type: "string"
Please view the example serverless.yml.
This plugin works for Serverless 1.x and up. Serverless 0.5 is not supported.
To add this plugin to your package.json:
Using npm:
npm install serverless-openapi-documentation --save-dev
Using Yarn:
yarn add serverless-openapi-documentation --dev
Next you need to add the plugin to the plugins
section of your serverless.yml
file.
plugins:
- serverless-openapi-documentation
You can confirm the plugin is correctly installed by running:
serverless | grep -i "ServerlessOpenAPIDocumentation"
It should return ServerlessOpenAPIDocumentation
as one of the plugins on the list.
Note: Add this plugin after
serverless-offline
to prevent issues withString.replaceAll
being overridden incorrectly.
The configuration is inspired by the format used in serverless-aws-documentation.
Works well with Lincoln OpenAPI Renderer.
Author: Temando
Source Code: https://github.com/temando/serverless-openapi-documentation
License: MIT license
1655837220
Dart OpenAPI Code Generator
openapi_freezed_dio_builder
generates client libraries for open api schema yaml files using Freezed and Dio.
This is a build_runner
library meant to be included in the dev_dependencies
of your project to allow generating of dart source files for client and server stubs for OpenAPI 3.0 schema files (Only yaml is supported right now).
Usage
pubspec.yaml
: dependencies:
freezed: any
json_annotation: ^3.0.1
openapi_base: any
dev_dependencies:
openapi_freezed_dio_builder: any
json_serializable: ^3.3.0
build_runner: ^1.10.0
lib
folder with the extension .openapi.yaml
. You can also use a symbolic link.openapi: 3.0.0
info:
x-dart-name: MyApiName
(flutter) pub run build_runner build --delete-conflicting-outputs
Example schema
openapi: 3.0.0
info:
version: 0.1.0
title: Example API
x-dart-name: TestApi
paths:
/hello/{name}:
parameters:
- name: name
in: path
required: true
schema:
type: string
get:
summary: Say Hello World to {name}
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/HelloResponse'
components:
schemas:
HelloResponse:
properties:
message:
type: string
description: 'The Hello World greeting ;-)'
Future<void> main() async {
final client = Api(
Dio(),
Uri.parse('https://virtserver.swaggerhub.com/hpoul/Testapi/1.0.0'),
);
final blubb = await client.helloNameGet(name: 'Blubb');
_logger.info('Response: ${blubb.data}');
}
dart run bin/example_client.dart
Try it out
Run in openapi_dart/packages/openapi_freezed_dio_builder/example
This is a fork of openapi_dart - thank you @hpoul for the great work!
Check out my other packages
Run this command:
With Dart:
$ dart pub add openapi_freezed_dio_builder
With Flutter:
$ flutter pub add openapi_freezed_dio_builder
This will add a line like this to your package's pubspec.yaml (and run an implicit dart pub get
):
dependencies:
openapi_freezed_dio_builder: ^0.9.3
Alternatively, your editor might support dart pub get
or flutter pub get
. Check the docs for your editor to learn more.
Now in your Dart code, you can use:
import 'package:openapi_freezed_dio_builder/openapi_freezed_dio_builder.dart';
example/README.md
This example contains example open api specs and their respective generated code.
They can be found at https://github.com/jonasbark/openapi_freezed_dio_builder/tree/master/packages/openapi_freezed_dio_builder/example
testapi.openapi.yaml
: A very minimal Hello World examplepetstore.openapi.yaml
: The pet store example provided by he open api spec.See directory for an example usage.
You can also try out: the code generator right inside your browser: https://jonasbark.github.io/openapi_freezed_dio_builder/
Author: jonasbark
Source Code: https://github.com/jonasbark/openapi_freezed_dio_builder
License: MIT
1654846620
Terraform Provider OpenAPI
This terraform provider aims to minimise as much as possible the efforts needed from service providers to create and maintain custom terraform providers. This provider uses terraform as the engine that will orchestrate and manage the cycle of the resources and depends on a swagger file (hosted on a remote endpoint) to successfully configure itself dynamically at runtime.
What are the main pain points that this terraform provider tries to tackle?
API terraform provider is a powerful full-fledged terraform provider that is able to configure itself at runtime based on a Swagger specification file containing the definitions of the APIs exposed. The dynamic nature of this provider is what makes it very flexible and convenient for service providers as subsequent upgrades to their APIs will not require new compilations of this provider. The service provider APIs are discovered on the fly and therefore the service providers can focus on their services rather than the tooling around it.
terraform-<type>-<name>_vX.Y.Z
, where <type>
is either provider or provisioner, <name>
is the provider's name and X.Y.Z
is the version of the plugin.More information about how terraform discovers third party terraform providers and naming conventions here.
There are multiple ways how the OpenAPI Terraform provider can be installed. Please refer to the OpenAPI Terraform provider installation document to learn more about it.
After having provisioned your environment with the OpenAPI Terraform provider you can now write Terraform configuration files using resources provided by the OpenAPI service. Refer to Using the OpenAPI Terraform Provider doc for more details.
You can generate the Terraform documentation automatically given an already Terraform compatible OpenAPI document using the The OpenAPI Terraform Documentation Renderer library. The OpenAPI document is the source of truth for both the OpenAPI Terraform provider as well as the user facing documentation.
The Publishing OpenAPI Terraform providers in the Terraform Registry document describes how service providers can make use of the OpenAPI Terraform provider library to create their own Terraform provider and register it in the Terraform Registry.
Additionally, the following documents provide deep insight regarding OpenAPI and Terraform as well as frequently asked questions:
Please follow the guidelines from:
![]() | |
---|---|
Powered by https://www.terraform.io | Following The OpenAPI Specification |
Author: dikhan
Source Code: https://github.com/dikhan/terraform-provider-openapi
License: Apache-2.0 license
1653595500
jest-openapi
Additional Jest matchers for asserting that HTTP responses satisfy an OpenAPI spec.
If your server's behaviour doesn't match your API documentation, then you need to correct your server, your documentation, or both. The sooner you know the better.
This plugin lets you automatically test whether your server's behaviour and documentation match. It adds Jest matchers that support the OpenAPI standard for documenting REST APIs. In your JavaScript tests, you can simply assert expect(responseObject).toSatisfyApiSpec()
Features:
$ref
in response definitions (i.e. $ref: '#/definitions/ComponentType/ComponentName'
)axios
, request-promise
, supertest
, superagent
, and chai-http
npm install --save-dev jest-openapi
yarn add --dev jest-openapi
ES6 / TypeScript
import jestOpenAPI from 'jest-openapi';
CommonJS / JavaScript
const jestOpenAPI = require('jest-openapi').default;
// Import this plugin
import jestOpenAPI from 'jest-openapi';
// Load an OpenAPI file (YAML or JSON) into this plugin
jestOpenAPI('path/to/openapi.yml');
// Write your test
describe('GET /example/endpoint', () => {
it('should satisfy OpenAPI spec', async () => {
// Get an HTTP response from your server (e.g. using axios)
const res = await axios.get('http://localhost:3000/example/endpoint');
expect(res.status).toEqual(200);
// Assert that the HTTP response satisfies the OpenAPI spec
expect(res).toSatisfyApiSpec();
});
});
path/to/openapi.yml
):openapi: 3.0.0
info:
title: Example API
version: 1.0.0
paths:
/example:
get:
responses:
200:
description: Response body should be an object with fields 'stringProperty' and 'integerProperty'
content:
application/json:
schema:
type: object
required:
- stringProperty
- integerProperty
properties:
stringProperty:
type: string
integerProperty:
type: integer
The assertion passes if the response status and body satisfy openapi.yml
:
// Response includes:
{
status: 200,
body: {
stringProperty: 'string',
integerProperty: 123,
},
};
The assertion fails if the response body is invalid:
// Response includes:
{
status: 200,
body: {
stringProperty: 'string',
integerProperty: 'invalid (should be an integer)',
},
};
Output from test failure:
expect(received).toSatisfyApiSpec() // Matches 'received' to a response defined in your API spec, then validates 'received' against it
expected received to satisfy the '200' response defined for endpoint 'GET /example/endpoint' in your API spec
received did not satisfy it because: integerProperty should be integer
received contained: {
body: {
stringProperty: 'string',
integerProperty: 'invalid (should be an integer)'
}
}
}
The '200' response defined for endpoint 'GET /example/endpoint' in API spec: {
'200': {
description: 'Response body should be a string',
content: {
'application/json': {
schema: {
type: 'string'
}
}
}
},
}
// Import this plugin and the function you want to test
import jestOpenAPI from 'jest-openapi';
import { functionToTest } from 'path/to/your/code';
// Load an OpenAPI file (YAML or JSON) into this plugin
jestOpenAPI('path/to/openapi.yml');
// Write your test
describe('functionToTest()', () => {
it('should satisfy OpenAPI spec', async () => {
// Assert that the function returns a value satisfying a schema defined in your OpenAPI spec
expect(functionToTest()).toSatisfySchemaInApiSpec('ExampleSchemaObject');
});
});
path/to/openapi.yml
):openapi: 3.0.0
info:
title: Example API
version: 1.0.0
paths:
/example:
get:
responses:
200:
description: Response body should be an ExampleSchemaObject
content:
application/json:
schema:
$ref: '#/components/schemas/ExampleSchemaObject'
components:
schemas:
ExampleSchemaObject:
type: object
required:
- stringProperty
- integerProperty
properties:
stringProperty:
type: string
integerProperty:
type: integer
The assertion passes if the object satisfies the schema ExampleSchemaObject
:
// object includes:
{
stringProperty: 'string',
integerProperty: 123,
};
The assertion fails if the object does not satisfy the schema ExampleSchemaObject
:
// object includes:
{
stringProperty: 123,
integerProperty: 123,
};
Output from test failure:
expect(received).not.toSatisfySchemaInApiSpec(schemaName) // Matches 'received' to a schema defined in your API spec, then validates 'received' against it
expected received to satisfy the 'StringSchema' schema defined in your API spec
object did not satisfy it because: stringProperty should be string
object was: {
{
stringProperty: 123,
integerProperty: 123
}
}
}
The 'ExampleSchemaObject' schema in API spec: {
type: 'object',
required: [
'stringProperty'
'integerProperty'
],
properties: {
stringProperty: {
type: 'string'
},
integerProperty: {
type: 'integer'
}
}
}
// Import this plugin
import jestOpenAPI from 'jest-openapi';
// Get an object representing your OpenAPI spec
const openApiSpec = {
openapi: '3.0.0',
info: {
title: 'Example API',
version: '0.1.0',
},
paths: {
'/example/endpoint': {
get: {
responses: {
200: {
description: 'Response body should be a string',
content: {
'application/json': {
schema: {
type: 'string',
},
},
},
},
},
},
},
},
};
// Load that OpenAPI object into this plugin
jestOpenAPI(openApiSpec);
// Write your test
describe('GET /example/endpoint', () => {
it('should satisfy OpenAPI spec', async () => {
// Get an HTTP response from your server (e.g. using axios)
const res = await axios.get('http://localhost:3000/example/endpoint');
expect(res.status).toEqual(200);
// Assert that the HTTP response satisfies the OpenAPI spec
expect(res).toSatisfyApiSpec();
});
});
// Import this plugin and an HTTP client (e.g. axios)
import jestOpenAPI from 'jest-openapi';
import axios from 'axios';
// Write your test
describe('GET /example/endpoint', () => {
// Load your OpenAPI spec from a web endpoint
beforeAll(async () => {
const response = await axios.get('url/to/openapi/spec');
const openApiSpec = response.data; // e.g. { openapi: '3.0.0', ... };
jestOpenAPI(openApiSpec);
});
it('should satisfy OpenAPI spec', async () => {
// Get an HTTP response from your server
const res = await axios.get('http://localhost:3000/example/endpoint');
expect(res.status).toEqual(200);
// Assert that the HTTP response satisfies the OpenAPI spec
expect(res).toSatisfyApiSpec();
});
});
If you've come here to help contribute - thanks! Take a look at the contributing docs to get started.
Author: Openapi-library
Source Code: https://github.com/openapi-library/OpenAPIValidators/tree/master/packages/jest-openapi
License: MIT license
1652863500
lark
Feishu/Lark Open API Go Sdk, Support ALL Open API and Event Callback.
Supported Features
go get github.com/chyroc/lark
API Count: 616, Event Count: 90
Click This to See ALL
cli := lark.New(lark.WithAppCredential("<APP_ID>", "<APP_SECRET>"))
cli := lark.New(
lark.WithAppCredential("<APP_ID>", "<APP_SECRET>"),
lark.WithOpenBaseURL("https://open.larksuite.com"),
lark.WithWWWBaseURL("https://www.larksuite.com"),
)
cli := lark.New(
lark.WithAppCredential("<APP_ID>", "<APP_SECRET>"),
lark.WithEventCallbackVerify("<ENCRYPT_KEY>", "<VERIFICATION_TOKEN>"),
)
cli := lark.New(
lark.WithAppCredential("<APP_ID>", "<APP_SECRET>"),
lark.WithHelpdeskCredential("<HELPDESK_ID>", "HELPDESK_TOKEN"),
)
for more about event callback example, see ./_examples/event_callback.go .
handle message callback example:
cli := lark.New(
lark.WithAppCredential("<APP_ID>", "<APP_SECRET>"),
lark.WithEventCallbackVerify("<ENCRYPT_KEY>", "<VERIFICATION_TOKEN>"),
)
// handle message callback
cli.EventCallback.HandlerEventIMMessageReceiveV1(func(ctx context.Context, cli *lark.Lark, schema string, header *lark.EventV2Header, event *lark.EventV2IMMessageReceiveV1) (string, error) {
_, _, err := cli.Message.Reply(event.Message.MessageID).SendText(ctx, "hi, "+event.Message.Content)
return "", err
})
http.HandleFunc("/api", func(w http.ResponseWriter, r *http.Request) {
cli.EventCallback.ListenCallback(r.Context(), r.Body, w)
})
fmt.Println("start server ...")
log.Fatal(http.ListenAndServe(":9726", nil))
for more about isv example, see ./_examples/isv.go .
create isv chat:
cli := lark.New(
lark.WithAppCredential("<APP_ID>", "<APP_SECRET>"),
lark.WithISV(true),
lark.WithStore("<NEW_STORE>"),
)
tenantKey1Cli := cli.WithTenant("<TENANT_KEY_1>")
resp, _, err := tenantKey1cli.Chat.CreateChat(ctx, &lark.CreateChatReq{
Name: ptr.String("<CHAT_NAME_1>"),
})
fmt.Println(resp, err)
for more about bot example, see ./_examples/bot.go .
get bot info example:
cli := lark.New(lark.WithAppCredential("<APP_ID>", "<APP_SECRET>"))
resp, _, err := cli.Bot.GetBotInfo(ctx, &lark.GetBotInfoReq{})
fmt.Println(resp, err)
for more about send message example, see ./_examples/send_message.go .
send text message example:
cli := lark.New(lark.WithAppCredential("<APP_ID>", "<APP_SECRET>"))
resp, _, err := cli.Message.Send().ToChatID("<CHAT_ID>").SendText(ctx, "<TEXT>")
fmt.Println(resp, err)
for more about other message example, see ./_examples/other_message.go .
send delete message example:
cli := lark.New(lark.WithAppCredential("<APP_ID>", "<APP_SECRET>"))
resp, _, err := cli.Message.DeleteMessage(ctx, &lark.DeleteMessageReq{
MessageID: "<MESSAGE_ID>",
})
fmt.Println(resp, err)
for more about chat example, see ./_examples/chat.go .
create chat example:
cli := lark.New(lark.WithAppCredential("<APP_ID>", "<APP_SECRET>"))
resp, _, err := cli.Chat.CreateChat(ctx, &lark.CreateChatReq{
Name: ptr.String("<CHAT_NAME>"),
})
fmt.Println(resp, err)
for more about file example, see ./_examples/file.go .
upload image example:
cli := lark.New(lark.WithAppCredential("<APP_ID>", "<APP_SECRET>"))
f, err := os.Open("<FILE_PATH>")
if err != nil {
panic(err)
}
resp, _, err := cli.File.UploadImage(ctx, &lark.UploadImageReq{
ImageType: lark.ImageTypeMessage,
Image: f,
})
fmt.Println(resp, err)
for more about calendar example, see ./_examples/calendar.go .
create calendar example:
cli := lark.New(lark.WithAppCredential("<APP_ID>", "<APP_SECRET>"))
resp, _, err := cli.Calendar.CreateCalendar(ctx, &lark.CreateCalendarReq{
Summary: ptr.String("<SUMMARY>"),
})
fmt.Println(resp, err)
Click Lark Chat Link to discuss.
https://godoc.org/github.com/chyroc/lark
Author: Chyroc
Source Code: https://github.com/chyroc/lark
License: Apache-2.0 license
1648079400
This is a general purpose OpenAPI code generator. It is currently used to completely generate the HTTP code in the Java SDK, and generate some of the HTTP code in our Golang SDK.
We currently have two HTTP endpoints. One for algod and one for indexer, so in most cases, this tool would be run once with each OpenAPI spec.
~$ mvn package -DskipTests
~$ java -jar target/generator-*-jar-with-dependencies.jar -h
You'll see that there are a number of subcommands:
The command line interface uses JCommander to define the command line interface. See Main.java.
The main code involves an OpenAPI parser / event generator and several listeners for the actual generation.
The template subcommand is using Apache Velocity as the underlying template engine. Things like variables, loops, and statements are all supported. So business logic can technically be implemented in the template if it's actually necessary.
There are three phases: client, query, and model. Each phase must provide two templates, one for the file generation and one to specify the filename to be used. If all results should go to the same file. For query and model generation the template will be executed once for each query / model. If you want to put everything in one file return the same filename twice in a row and the processing will exit early.
phase | filename | purpose |
---|---|---|
client | client.vm | Client class with functions to call each query. |
client | client_filename.vm | File to write to the client output directory. |
query | query.vm | Template to use for generating query files. |
query | query_filename.vm | File to write to the query output directory. |
model | model.vm | Template to use for generating model files. |
model | model_filename.vm | File to write to the model output directory. |
The template command will only run the templates which have an output directory is provided. So if you just want to regenerate models, only use the -m option.
-c, --clientOutputDir
Directory to write client file(s).
-m, --modelsOutputDir
Directory to write model file(s).
-q, --queryOutputDir
Directory to write query file(s).
The template subcommand accepts a --propertyFiles option. It can be provided multiple times, or as a comma separated list of files. Property files will be processed and bound to a velocity variable available to templates.
For details on a type you can put it directly into your template. It will be serialized along with its fields for your reference. Here is a high level description of what is available:
template | variable | type | purpose |
---|---|---|---|
all | str | StringHelpers.java | Some string utilities are available. See StringHelpers.java for details. There are simple things like $str.capitalize("someData") -> SomeData , and also some more complex helpers like $str.formatDoc($query.doc, "// ") which will split the document at the word boundary nearest to 80 characters without going over, and add a prefix to each new line. |
all | order | OrderHelpers.java | Some ordering utilities available. See OrderHelpers.java for details. An example utility function is $order.propertiesWithOrdering($props, $preferred_order) , where $props is a list of properties and $preferred_order is a string list to use when ordering the properties list. |
all | propFile | Properties | The contents of all property files are available with this variable. For example if package=com.algorand.v2.algod is in the property file, the template may use ${propFile.package} . |
all | models | HashMap<StructDef, List<TypeDef>> | A list of all models. |
all | queries | List<QueryDef> | A list of all queries. |
query | q | QueryDef | The current query definition. |
model | def | StructDef | The current model definition if multiple files are being generated. |
model | props | List<TypeDef> | A list of properties for the current model. |
In the following example, we are careful to generate the algod code first because the algod models are a strict subset of the indexer models. For that reason, we are able to reuse some overlapping models from indexer in algod.
~$ java -jar generator*jar template
-s algod.oas2.json
-t go_templates
-c algodClient
-m allModels
-q algodQueries
-p common_config.properties,algod_config.properties
~$ java -jar generator*jar template
-s indexer.oas2.json
-t go_templates
-c indexerClient
-m allModels
-q indexerQueries
-p common_config.properties,indexer_config.properties
There is a test template that gives you some basic usage in the test_templates directory.
You can generate the test code in the output directory with the following commands:
~$ mkdir output
~$ java -jar target/generator-*-jar-with-dependencies.jar \
template \
-s /path/to/a/spec/file/indexer.oas2.json \
-t test_templates/ \
-m output \
-q output \
-c output \
-p test_templates/my.properties
The Golang templates are in the go_templates directory.
The Golang HTTP API is only partially generated. The hand written parts were not totally consistent with the spec and that makes it difficult to regenerate them. Regardless, an attempt has been made. In the templates there are some macros which map "generated" values to the hand written ones. For example the query types have this mapping:
#macro ( queryType )
#if ( ${str.capitalize($q.name)} == "SearchForAccounts" )
SearchAccounts## The hand written client doesn't quite match the spec...
#elseif ( ${str.capitalize($q.name)} == "GetStatus" )
Status##
#elseif ( ${str.capitalize($q.name)} == "GetPendingTransactionsByAddress" )
PendingTransactionInformationByAddress##
#elseif ( ${str.capitalize($q.name)} == "GetPendingTransactions" )
PendingTransactions##
#else
${str.capitalize($q.name)}##
#end
#end
Other mappings are more specific to the language, such as the OpenAPI type to SDK type:
#macro ( toQueryType $param )##
#if ( $param.algorandFormat == "RFC3339 String" )
string##
#elseif ( $param.type == "integer" )
uint64##
#elseif ( $param.type == "string" )
string##
#elseif ( $param.type == "boolean" )
bool##
#elseif( $param.type == "binary" )
string##
#else
UNHANDLED TYPE
- ref: $!param.refType
- type: $!param.type
- array type: $!param.arrayType
- algorand format: $!param.algorandFormat
- format: $!param.format
##$unknown.type ## force a template failure because $unknown.type does not exist.
#end
#end
Because of this, we are phasing in code generation gradually by skipping some types. The skipped types are specified in the property files:
common_config.properties
model_skip=AccountParticipation,AssetParams,RawBlockJson,etc,...
algod_config.properties
query_skip=Block,BlockRaw,SendRawTransaction,SuggestedParams,etc,...
indexer_config.properties
query_skip=LookupAssetByID,LookupAccountTransactions,SearchForAssets,LookupAssetBalances,LookupAssetTransactions,LookupBlock,LookupTransactions,SearchForTransactions
The Java templates are in the java_templates directory.
These are not used yet, they are the initial experiments for the template engine. Since the Java SDK has used code generation from the beginning, we should be able to fully migrate to the template engine eventually.
In general, the automation pipeline will build and run whatever Dockerfile
is found in a repository's templates
directory. For instructions on how to configure the templates
directory, look at the repository template directory example.
If you are trying to verify that automatic code generation works as intended, we recommend creating a testing branch from that repository and using the SKIP_PR=true
environment variable to avoid creating pull requests. If all goes according to plan, generated files should be available in the container's /repo
directory.
The automatic generator scripts depend on certain prerequisites that are listed in automation/REQUIREMENTS.md. Once those conditions have been satisfied, automatically generating code for external repositories should be as easy as building and running a particular SDK's templates/Dockerfile
file.
Download Details:
Author: algorand
Source Code: https://github.com/algorand/generator
License:
#algorand #blockchain #cryptocurrency #java #golang #openapi
1646809200
Schemathesis
Schemathesis is a modern API testing tool for web applications built with Open API and GraphQL specifications.
It reads the application schema and generates test cases, which will ensure that your application is compliant with its schema (read more about how it works in our research paper).
The application under test could be written in any language; the only thing you need is a valid API schema in a supported format.
Simple to use and yet powerful to uncover hard-to-find errors thanks to the property-based testing approach backed by state-of-the-art Hypothesis library.
Schemathesis will be available as SaaS soon!
It is freemium with much better visuals for debugging, more checks, and static analysis :)
Signup to get notified when it is ready!
To install Schemathesis via pip
run the following command:
pip install schemathesis
You can also use our Docker image without installing Schemathesis as a Python package.
📣 Please fill out our quick survey so that we can learn how satisfied you are with Schemathesis, and what improvements we should make. Thank you!
You can use Schemathesis in the command line directly:
schemathesis run --stateful=links --checks all http://0.0.0.0:8081/schema.yaml
Or via Docker:
docker run schemathesis/schemathesis:stable run \
--stateful=links --checks all http://0.0.0.0:8081/schema.yaml
Or in your Python tests:
import schemathesis
schema = schemathesis.from_uri("http://0.0.0.0:8081/schema.yaml")
@schema.parametrize()
def test_api(case):
case.call_and_validate()
CLI is simple to use and requires no coding; the in-code approach gives more flexibility.
Both examples above will run hundreds of requests against the API under test and report all found failures and inconsistencies along with instructions to reproduce them.
💡 See a complete working example project in the /example
directory. 💡
Any contribution to development, testing, or any other area is highly appreciated and useful to the project. For guidance on how to contribute to Schemathesis, see the contributing guidelines.
Hi, my name is Dmitry! I started this project during my work at Kiwi.com. I am grateful to them for all the support they provided to this project during its early days and for the opportunity to evolve Schemathesis independently.
In order to grow the community of contributors and users, and allow me to devote more time to this project, please donate today.
Also, I occasionally write posts about Schemathesis in my blog.
Additional content:
Non-English content:
The code in this project is licensed under MIT license. By contributing to Schemathesis, you agree that your contributions will be licensed under its MIT license.
Author: schemathesis
Source Code: https://github.com/schemathesis/schemathesis
License: MIT License
1646802000
Prism is a set of packages for API mocking and contract testing with OpenAPI v2 (formerly known as Swagger) and OpenAPI v3.x.
Note: This branch refers to Prism 3.x, which is the current version most likely you will use. If you're looking for the 2.x version, look at the
2.x
branch
Overview
Prism requires NodeJS >= 12 to properly work.
npm install -g @stoplight/prism-cli
# OR
yarn global add @stoplight/prism-cli
For more installation options, see our installation documentation.
Prism can help you create a fake "mock" based off an OpenAPI document, which helps people see how your API will work before you even have it built. Run it locally with the prism mock
command to run your API on a HTTP server you can interact with.
prism mock https://raw.githack.com/OAI/OpenAPI-Specification/master/examples/v3.0/petstore-expanded.yaml
Learn more about how the mock server works.
Prism can help you check for discrepencies between your API implementation and the OpenAPI document that describes, letting you funnel HTTP traffic through it with the prism proxy
command.
prism proxy examples/petstore.oas2.yaml https://petstore.swagger.io/v2
Learn more about how the validation proxy works.
Submit your ideas for new functionality on the Stoplight Roadmap.
Cannot access mock server when using Docker?
Prism uses localhost by default, which usually means 127.0.0.1. When using docker the mock server will be unreachable outside of the container unless you run the mock command with -h 0.0.0.0
.
Why am I getting 404 errors when I include my basePath?
OpenAPI v2.0 had a concept called "basePath", which was essentially part of the HTTP path the stuff after host name and protocol, and before query string. Unlike the paths in your paths
object, this basePath was applied to every single URL, so Prism v2.x used to do the same. In OpenAPI v3.0 they merged the basePath concept in with the server.url, and Prism v3 has done the same.
We treat OAS2 host + basePath
the same as OAS3 server.url
, so we do not require them to go in the URL. If you have a base path of api/v1
and your path is defined as hello
, then a request to http://localhost:4010/hello
would work, but http://localhost:4010/api/v1/hello
will fail. This confuses some, but the other way was confusing to others. Check the default output of Prism CLI to see what URLs you have available.
Is there a hosted version of Prism?
Yes, hosted mocking is available as part of Stoplight Platform. Learn More
If you're using Prism for an interesting use case, contact us for a case study. We'll add it to a list here. Spread the goodness 🎉
If you are interested in contributing to Prism itself, check out our contributing docs ⇗ and code of conduct ⇗ to get started.
Prism is built on top of lots of excellent packages, and here are a few we'd like to say a special thanks to.
Check these projects out!
If you would like to thank us for creating Prism, we ask that you buy the world a tree.
Author: stoplightio
Source Code: https://github.com/stoplightio/prism
License: Apache-2.0 License
1646665200
The reason this package exists is to give you peace of mind when providing a RESTful API. Instead of chasing down preventable bugs and saying sorry to consumers, you can focus on more important things in life.
curl
commands to showcase how your API works. Users can try it themselves, right in their browsers.500 Internal Server Error
is returned if the response does not exactly match what your document says the output of a certain API endpoint should be. This decreases the effects of Hyrum's Law./user/info
?".openapi.yaml
or openapi.json
) against the OpenAPI 3.0 specification using the openapi-spec-validator.Declare pyramid_openapi3
as a dependency in your Pyramid project.
Include the following lines:
config.include("pyramid_openapi3")
config.pyramid_openapi3_spec('openapi.yaml', route='/api/v1/openapi.yaml')
config.pyramid_openapi3_add_explorer(route='/api/v1/')
openapi
view predicate to enable request/response validation:@view_config(route_name="foobar", openapi=True, renderer='json')
def myview(request):
return request.openapi_validated.parameters
For requests, request.openapi_validated
is available with two fields: parameters
and body
. For responses, if the payload does not match the API document, an exception is raised.
A feature introduced in OpenAPI3 is the ability to use $ref
links to external files (https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#referenceObject).
To use this, you must ensure that you have all of your spec files in a given directory (ensure that you do not have any code in this directory as all the files in it are exposed as static files), then replace the pyramid_openapi3_spec
call that you did in Getting Started with the following:
config.pyramid_openapi3_spec_directory('path/to/openapi.yaml', route='/api/v1/spec')
Some notes:
route
of your pyramid_openapi3_spec_directory
to the same value as the route
of pyramid_openapi3_add_explorer
.route
that you set for pyramid_openapi3_spec_directory
should not contain any file extensions, as this becomes the root for all of the files in your specified filepath
.pyramid_openapi3_spec_directory
and pyramid_openapi3_spec
in the same app.Provided with pyramid_openapi3
are a few validation features:
These features are enabled as a default, but you can disable them if you need to:
config.registry.settings["pyramid_openapi3.enable_endpoint_validation"] = False
config.registry.settings["pyramid_openapi3.enable_request_validation"] = False
config.registry.settings["pyramid_openapi3.enable_response_validation"] = False
Warning: Disabling request validation will result in
request.openapi_validated
no longer being available to use.
You can register routes in your pyramid application. First, write the x-pyramid-route-name
extension in the PathItem of the OpenAPI schema.
paths:
/foo:
x-pyramid-route-name: foo_route
get:
responses:
200:
description: GET foo
Then put the config directive pyramid_openapi3_register_routes
in the app_factory of your application.
config.pyramid_openapi3_register_routes()
This means is equals to
config.add_route("foo_route", pattern="/foo")
There are three examples provided with this package:
Both examples come with tests that exhibit pyramid_openapi's error handling and validation capabilities.
A fully built-out app, with 100% test coverage, providing a RealWorld.io API is available at niteoweb/pyramid-realworld-example-app. It is a Heroku-deployable Pyramid app that provides an API for a Medium.com-like social app. You are encouraged to use it as a scaffold for your next project.
The authors of pyramid_openapi3 believe that the approach of validating a manually-written API document is superior to the approach of generating the API document from Python code. Here are the reasons:
Both generation and validation against a document are lossy processes. The underlying libraries running the generation/validation will always have something missing. Either a feature from the latest OpenAPI specification, or an implementation bug. Having to fork the underlying library in order to generate the part of your API document that might only be needed for the frontend is unfortunate.
Validation on the other hand allows one to skip parts of validation that are not supported yet, and not block a team from shipping the document.
The validation approach does sacrifice DRY-ness, and one has to write the API document and then the (view) code in Pyramid. It feels a bit redundant at first. However, this provides a clear separation between the intent and the implementation.
The generation approach has the drawback of having to write Python code even for parts of the API document that the Pyramid backend does not handle, as it might be handled by a different system, or be specific only to documentation or only to the client side of the API. This bloats your Pyramid codebase with code that does not belong there.
You need to have pipenv and Python 3.7, 3.8, or 3.9 installed on your machine. Then you can run:
$ make tests
These packages tackle the same problem-space:
We do our best to follow the rules below.
openapi-core
, currently 0.13.4 through 0.13.8.Pipfile.lock
for a frozen-in-time known-good-set of all dependencies.A couple of projects that use pyramid_openapi3 in production:
Author: Pylons
Source Code: https://github.com/Pylons/pyramid_openapi3
License: MIT License
1646658000
Yet another library to generate OpenAPI documents and validate requests & responses with Python annotations.
install with pip: pip install spectree
Check the examples folder.
pydantic.BaseModel
spectree.SpecTree
instance with the web framework name you are using, like api = SpecTree('flask')
api.validate
decorate the route withquery
json
headers
cookies
resp
tags
security
context(query, json, headers, cookies)
(of course, you can access these from the original place where the framework offered)request.context
req.context
request.context
api.register(app)
/apidoc/redoc
or /apidoc/swagger
If the request doesn't pass the validation, it will return a 422 with a JSON error message(ctx, loc, msg, type).
For falcon response, this library only validates against media as it is the serializable object. Response.body(deprecated in falcon 3.0 and replaced by text) is a string representing response content and will not be validated. For no assigned media situation, resp
parameter in api.validate
should be like Response(HTTP_200=None)
This library also supports the injection of validated fields into view function arguments along with parameter annotation-based type declaration. This works well with linters that can take advantage of typing features like mypy. See the examples section below.
How to add summary and description to endpoints?
Just add docs to the endpoint function. The 1st line is the summary, and the rest is the description for this endpoint.
How to add a description to parameters?
Check the pydantic document about description in Field
.
Any config I can change?
Of course. Check the config document.
You can update the config when init the spectree like:
SpecTree('flask', title='Demo API', version='v1.0', path='doc')
What is
Response
and how to use it?
To build a response for the endpoint, you need to declare the status code with format HTTP_{code}
and corresponding data (optional).
Response(HTTP_200=None, HTTP_403=ForbidModel)
Response('HTTP_200') # equals to Response(HTTP_200=None)
# with custom code description
Response(HTTP_403=(ForbidModel, "custom code description"))
How to secure API endpoints?
For secure API endpoints, it is needed to define the security_schemes
argument in the SpecTree
constructor. security_schemes
argument needs to contain an array of SecurityScheme
objects. Then there are two ways to enforce security:
security
argument in the api.validate
decorator of relevant function/method (this corresponds to define security section on operation level, under paths
, in OpenAPI
). security
argument is defined as a dictionary, where each key is the name of security used in security_schemes
argument of SpecTree
constructor and its value is required security scope, as is showed in the following example:Click to expand the code example:
api = SpecTree(security_schemes=[
SecurityScheme(
name="auth_apiKey",
data={"type": "apiKey", "name": "Authorization", "in": "header"},
),
SecurityScheme(
name="auth_oauth2",
data={
"type": "oauth2",
"flows": {
"authorizationCode": {
"authorizationUrl": "https://example.com/oauth/authorize",
"tokenUrl": "https://example.com/oauth/token",
"scopes": {
"read": "Grants read access",
"write": "Grants write access",
"admin": "Grants access to admin operations",
},
},
},
},
),
# ...
],
# ...
)
# Not secured API endpoint
@api.validate(
resp=Response(HTTP_200=None),
)
def foo():
...
# API endpoint secured by API key type or OAuth2 type
@api.validate(
resp=Response(HTTP_200=None),
security={"auth_apiKey": [], "auth_oauth2": ["read", "write"]}, # Local security type
)
def bar():
...
security
argument in the SpecTree
constructor (this corresponds to the define security section on the root level in OpenAPI
). It is possible to override global security by defining local security, as well as override to no security on some API endpoint, in the security
argument of api.validate
decorator of relevant function/method as was described in the previous point. It is also shown in the following small example:Click to expand the code example:
api = SpecTree(security_schemes=[
SecurityScheme(
name="auth_apiKey",
data={"type": "apiKey", "name": "Authorization", "in": "header"},
),
SecurityScheme(
name="auth_oauth2",
data={
"type": "oauth2",
"flows": {
"authorizationCode": {
"authorizationUrl": "https://example.com/oauth/authorize",
"tokenUrl": "https://example.com/oauth/token",
"scopes": {
"read": "Grants read access",
"write": "Grants write access",
"admin": "Grants access to admin operations",
},
},
},
},
),
# ...
],
security={"auth_apiKey": []}, # Global security type
# ...
)
# Force no security
@api.validate(
resp=Response(HTTP_200=None),
security={}, # Locally overridden security type
)
def foo():
...
# Force another type of security than global one
@api.validate(
resp=Response(HTTP_200=None),
security={"auth_oauth2": ["read"]}, # Locally overridden security type
)
def bar():
...
# Use the global security
@api.validate(
resp=Response(HTTP_200=None),
)
def foobar():
...
What should I return when I'm using the library?
No need to change anything. Just return what the framework required.
How to log when the validation failed?
Validation errors are logged with the INFO level. Details are passed into extra
. Check the falcon example for details.
How can I write a customized plugin for another backend framework?
Inherit spectree.plugins.base.BasePlugin
and implement the functions you need. After that, init like api = SpecTree(backend=MyCustomizedPlugin)
.
How to use a customized template page?
SpecTree(page_templates={"page_name": "customized page contains {spec_url} for rendering"})
In the above example, the key "page_name" will be used in the URL to access this page "/apidoc/page_name". The value should be a string that contains {spec_url}
which will be used to access the OpenAPI JSON file.
How can I change the response when there is a validation error? Can I record some metrics?
This library provides before
and after
hooks to do these. Check the doc or the test case. You can change the handlers for SpecTree or a specific endpoint validation.
How to change the default
ValidationError
status code?
You can change the validation_error_status
in SpecTree (global) or a specific endpoint (local). This also takes effect in the OpenAPI documentation.
Try it with http post :8000/api/user name=alice age=18
. (if you are using httpie
)
from flask import Flask, request, jsonify
from pydantic import BaseModel, Field, constr
from spectree import SpecTree, Response
class Profile(BaseModel):
name: constr(min_length=2, max_length=40) # Constrained Str
age: int = Field(
...,
gt=0,
lt=150,
description='user age(Human)'
)
class Config:
schema_extra = {
# provide an example
'example': {
'name': 'very_important_user',
'age': 42,
}
}
class Message(BaseModel):
text: str
app = Flask(__name__)
api = SpecTree('flask')
@app.route('/api/user', methods=['POST'])
@api.validate(json=Profile, resp=Response(HTTP_200=Message, HTTP_403=None), tags=['api'])
def user_profile():
"""
verify user profile (summary of this endpoint)
user's name, user's age, ... (long description)
"""
print(request.context.json) # or `request.json`
return jsonify(text='it works')
if __name__ == "__main__":
api.register(app) # if you don't register in api init step
app.run(port=8000)
# opt in into annotations feature
api = SpecTree("flask", annotations=True)
@app.route('/api/user', methods=['POST'])
@api.validate(resp=Response(HTTP_200=Message, HTTP_403=None), tags=['api'])
def user_profile(json: Profile):
"""
verify user profile (summary of this endpoint)
user's name, user's age, ... (long description)
"""
print(json) # or `request.json`
return jsonify(text='it works')
import falcon
from wsgiref import simple_server
from pydantic import BaseModel, Field, constr
from spectree import SpecTree, Response
class Profile(BaseModel):
name: constr(min_length=2, max_length=40) # Constrained Str
age: int = Field(
...,
gt=0,
lt=150,
description='user age(Human)'
)
class Message(BaseModel):
text: str
api = SpecTree('falcon')
class UserProfile:
@api.validate(json=Profile, resp=Response(HTTP_200=Message, HTTP_403=None), tags=['api'])
def on_post(self, req, resp):
"""
verify user profile (summary of this endpoint)
user's name, user's age, ... (long description)
"""
print(req.context.json) # or `req.media`
resp.media = {'text': 'it works'}
if __name__ == "__main__":
app = falcon.API()
app.add_route('/api/user', UserProfile())
api.register(app)
httpd = simple_server.make_server('localhost', 8000, app)
httpd.serve_forever()
# opt in into annotations feature
api = SpecTree("falcon", annotations=True)
class UserProfile:
@api.validate(resp=Response(HTTP_200=Message, HTTP_403=None), tags=['api'])
def on_post(self, req, resp, json: Profile):
"""
verify user profile (summary of this endpoint)
user's name, user's age, ... (long description)
"""
print(req.context.json) # or `req.media`
resp.media = {'text': 'it works'}
import uvicorn
from starlette.applications import Starlette
from starlette.routing import Route, Mount
from starlette.responses import JSONResponse
from pydantic import BaseModel, Field, constr
from spectree import SpecTree, Response
class Profile(BaseModel):
name: constr(min_length=2, max_length=40) # Constrained Str
age: int = Field(
...,
gt=0,
lt=150,
description='user age(Human)'
)
class Message(BaseModel):
text: str
api = SpecTree('starlette')
@api.validate(json=Profile, resp=Response(HTTP_200=Message, HTTP_403=None), tags=['api'])
async def user_profile(request):
"""
verify user profile (summary of this endpoint)
user's name, user's age, ... (long description)
"""
print(request.context.json) # or await request.json()
return JSONResponse({'text': 'it works'})
if __name__ == "__main__":
app = Starlette(routes=[
Mount('api', routes=[
Route('/user', user_profile, methods=['POST']),
])
])
api.register(app)
uvicorn.run(app)
# opt in into annotations feature
api = SpecTree("flask", annotations=True)
@api.validate(resp=Response(HTTP_200=Message, HTTP_403=None), tags=['api'])
async def user_profile(request, json=Profile):
"""
verify user profile (summary of this endpoint)
user's name, user's age, ... (long description)
"""
print(request.context.json) # or await request.json()
return JSONResponse({'text': 'it works'})
ValidationError: missing field for headers
The HTTP headers' keys in Flask are capitalized, in Falcon are upper cases, in Starlette are lower cases. You can use pydantic.root_validators(pre=True)
to change all the keys into lower cases or upper cases.
ValidationError: value is not a valid list for the query
Since there is no standard for HTTP queries with multiple values, it's hard to find a way to handle this for different web frameworks. So I suggest not to use list type in query until I find a suitable way to fix it.
Author: 0b01001001
Source Code: https://github.com/0b01001001/spectree
License: Apache-2.0 License
1646650800
Generate modern Python clients from OpenAPI 3.x documents.
This generator does not support OpenAPI 2.x FKA Swagger. If you need to use an older document, try upgrading it to version 3 first with one of many available converters.
This project is still in development and does not support all OpenAPI features
This tool focuses on creating the best developer experience for Python developers by:
I recommend you install with pipx so you don't conflict with any other packages you might have: pipx install openapi-python-client --include-deps
.
Note the
--include-deps
option which will also makeblack
,isort
, andautoflake
available in your path so thatopenapi-python-client
can use them to clean up the generated code.
If you use pipx run
then the post-generation hooks will not be available unless you install them manually.
You can also install with normal pip: pip install openapi-python-client
Then, if you want tab completion: openapi-python-client --install-completion
openapi-python-client generate --url https://my.api.com/openapi.json
This will generate a new client library named based on the title in your OpenAPI spec. For example, if the title of your API is "My API", the expected output will be "my-api-client". If a folder already exists by that name, you'll get an error.
If you have an openapi.json
file available on disk, in any CLI invocation you can build off that instead by replacing --url
with a --path
:
openapi-python-client generate --path location/on/disk/openapi.json
openapi-python-client update --url https://my.api.com/openapi.json
For more usage details run
openapi-python-client --help
or read usage
This feature leverages Jinja2's ChoiceLoader and FileSystemLoader. This means you do not need to customize every template. Simply copy the template(s) you want to customize from the default template directory to your own custom template directory (file names must match exactly) and pass the template directory through the custom-template-path
flag to the generate
and update
commands. For instance,
openapi-python-client update \
--url https://my.api.com/openapi.json \
--custom-template-path=relative/path/to/mytemplates
Be forewarned, this is a beta-level feature in the sense that the API exposed in the templates is undocumented and unstable.
pyproject.toml
file with some basic metadata intended to be used with Poetry.README.md
you'll most definitely need to update with your project's detailsclient
module which will have both a Client
class and an AuthenticatedClient
class. You'll need these for calling the functions in the api
module.api
module which will contain one module for each tag in your OpenAPI spec, as well as a default
module for endpoints without a tag. Each of these modules in turn contains one function for calling each endpoint.models
module which has all the classes defined by the various schemas in your OpenAPI specFor a full example you can look at the end_to_end_tests
directory which has an openapi.json
file. "golden-record" in that same directory is the generated client from that OpenAPI document.
You can pass a YAML (or JSON) file to openapi-python-client with the --config
option in order to change some behavior. The following parameters are supported:
Used to change the name of generated model classes. This param should be a mapping of existing class name (usually a key in the "schemas" section of your OpenAPI document) to class_name and module_name. As an example, if the name of the a model in OpenAPI (and therefore the generated class name) was something like "_PrivateInternalLongName" and you want the generated client's model to be called "ShortName" in a module called "short_name" you could do this:
Example:
class_overrides:
_PrivateInternalLongName:
class_name: ShortName
module_name: short_name
The easiest way to find what needs to be overridden is probably to generate your client and go look at everything in the models folder.
Used to change the name of generated client library project/package. If the project name is changed but an override for the package name isn't provided, the package name will be converted from the project name using the standard convention (replacing -
's with _
's).
Example:
project_name_override: my-special-project-name
package_name_override: my_extra_special_package_name
When generating properties, the name
attribute of the OpenAPI schema will be used. When the name
is not a valid Python identifier (e.g. begins with a number) this string will be prepended. Defaults to "field_".
Example:
field_prefix: attr_
Specify the package version of the generated client. If unset, the client will use the version of the OpenAPI spec.
Example:
package_version_override: 1.2.3
In the config file, there's an easy way to tell openapi-python-client
to run additional commands after generation. Here's an example showing the default commands that will run if you don't override them in config:
post_hooks:
- "autoflake -i -r --remove-all-unused-imports --remove-unused-variables --ignore-init-module-imports ."
- "isort ."
- "black ."
Author: openapi-generators
Source Code: https://github.com/openapi-generators/openapi-python-client
License: MIT License
1646643600
Openapi-core is a Python library that adds client-side and server-side support for the OpenAPI Specification v3.
Check documentation to see more details about the features. All documentation is in the "docs" directory and online at openapi-core.readthedocs.io
Recommended way (via pip):
$ pip install openapi-core
Alternatively you can download the code and install from the repository:
$ pip install -e git+https://github.com/p1c2u/openapi-core.git#egg=openapi_core
Firstly create your specification object:
from json import load
from openapi_core import OpenAPISpec as Spec
with open('openapi.json', 'r') as spec_file:
spec_dict = load(spec_file)
spec = Spec.create(spec_dict)
Now you can use it to validate against requests
from openapi_core.validation.request.validators import RequestValidator
validator = RequestValidator(spec)
result = validator.validate(request)
# raise errors if request invalid
result.raise_for_errors()
# get list of errors
errors = result.errors
and unmarshal request data from validation result
# get parameters object with path, query, cookies and headers parameters
validated_params = result.parameters
# or specific parameters
validated_path_params = result.parameters.path
# get body
validated_body = result.body
# get security data
validated_security = result.security
Request object should be instance of OpenAPIRequest class (See Integrations).
You can also validate against responses
from openapi_core.validation.response.validators import ResponseValidator
validator = ResponseValidator(spec)
result = validator.validate(request, response)
# raise errors if response invalid
result.raise_for_errors()
# get list of errors
errors = result.errors
and unmarshal response data from validation result
# get headers
validated_headers = result.headers
# get data
validated_data = result.data
Response object should be instance of OpenAPIResponse class (See Integrations).
Tornado OpenAPI 3 request and response validation library.
Pyramid addon for OpenAPI3 validation of requests and responses.
Python library that validates schema against the OpenAPI Schema Specification v3.0.
Python library that validates OpenAPI Specs against the OpenAPI 2.0 (aka Swagger) and OpenAPI 3.0 specification
OpenAPI 3.0 Support for the Bottle Web Framework
Author: p1c2u
Source Code: https://github.com/p1c2u/openapi-core
License: BSD-3-Clause License