Skip to content

mom1/apiclient-pydantic-generator

Repository files navigation

GitHub issues GitHub stars GitHub Release Date GitHub commits since latest release GitHub last commit GitHub license

PyPI PyPI PyPI - Downloads

apiclient-pydantic-generator

This code generator creates a ApiClient app from an openapi file.

This project uses:

This project highly inspired fastapi-code-generator

Installation

To install apiclient-pydantic-generator:

$ pip install apiclient-pydantic-generator

Usage

The apiclient-pydantic-generator command:

Usage: apiclient-codegen [OPTIONS]

Options:
  -i, --input FILENAME     [required]
  -o, --output PATH        [required]
  -t, --template-dir PATH
  -b, --base_url TEXT
  -p, --prefix TEXT        If "My" then will be MyApiClient  [default: My]
  -a, --base_api_cls TEXT  Base class for client class  [default: apiclient.APIClient]
  --formater [yapf|black]  [default: yapf]
  --skip-deprecated        Don't generate code for deprecated operations
                           [default: True]
  --install-completion     Install completion for the current shell.
  --show-completion        Show completion for the current shell, to copy it
                           or customize the installation.
  --help                   Show this message and exit.

Example

OpenAPI

petstore.yaml
    
      openapi: '3.0.0'
      info:
        version: 1.0.0
        title: Swagger Petstore
        license:
          name: MIT
      servers:
        - url: http://petstore.swagger.io/v1
      paths:
        /pets:
          get:
            summary: List all pets
            operationId: listPets
            tags:
              - pets
            parameters:
              - name: limit
                in: query
                description: How many items to return at one time (max 100)
                required: false
                schema:
                  type: integer
                  format: int32
            responses:
              '200':
                description: A paged array of pets
                headers:
                  x-next:
                    description: A link to the next page of responses
                    schema:
                      type: string
                content:
                  application/json:
                    schema:
                      $ref: '#/components/schemas/Pets'
              default:
                description: unexpected error
                content:
                  application/json:
                    schema:
                      $ref: '#/components/schemas/Error'
                      x-amazon-apigateway-integration:
                        uri:
                          Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                        passthroughBehavior: when_no_templates
                        httpMethod: POST
                        type: aws_proxy
          post:
            summary: Create a pet
            operationId: createPets
            tags:
              - pets
            responses:
              '201':
                description: Null response
              default:
                description: unexpected error
                content:
                  application/json:
                    schema:
                      $ref: '#/components/schemas/Error'
                      x-amazon-apigateway-integration:
                        uri:
                          Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
                        passthroughBehavior: when_no_templates
                        httpMethod: POST
                        type: aws_proxy
        /pets/{petId}:
          get:
            summary: Info for a specific pet
            operationId: showPetById
            tags:
              - pets
            parameters:
              - name: petId
                in: path
                required: true
                description: The id of the pet to retrieve
                schema:
                  type: string
            responses:
              '200':
                description: Expected response to a valid request
                content:
                  application/json:
                    schema:
                      $ref: '#/components/schemas/Pets'
              default:
                description: unexpected error
                content:
                  application/json:
                    schema:
                      $ref: '#/components/schemas/Error'
          x-amazon-apigateway-integration:
            uri:
              Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${PythonVersionFunction.Arn}/invocations
            passthroughBehavior: when_no_templates
            httpMethod: POST
            type: aws_proxy
      components:
        schemas:
          Pet:
            required:
              - id
              - name
            properties:
              id:
                type: integer
                format: int64
              name:
                type: string
              tag:
                type: string
          Pets:
            type: array
            description: list of pet
            items:
              $ref: '#/components/schemas/Pet'
          Error:
            required:
              - code
              - message
            properties:
              code:
                type: integer
                format: int32
              message:
                type: string
    
  
$ apiclient-codegen --input petstore.yaml --output app_petstore --prefix PetStore

app_petstore/__init__.py:

from .client import PetStoreAPIClient


__all__ = ('PetStoreAPIClient', )

app_petstore/client.py:

from __future__ import annotations

from apiclient import APIClient
from apiclient_pydantic import serialize_all_methods

from .endpoints import Endpoints
from .models import LimitQueryParams, PetIdPathParams, Pets


@serialize_all_methods()
class PetStoreAPIClient(APIClient):
    def list_pets(self, query_params: LimitQueryParams) -> Pets:
        """List all pets"""
        return self.get(Endpoints.list_pets, query_params)

    def create_pets(self) -> None:
        """Create a pet"""
        self.post(Endpoints.create_pets)

    def show_pet_by_id(self, path_params: PetIdPathParams) -> Pets:
        """Info for a specific pet"""
        return self.get(Endpoints.show_pet_by_id.format(**path_params))

app_petstore/endpoints.py:

from apiclient import endpoint


@endpoint(base_url='http://petstore.swagger.io/v1')
class Endpoints:
    list_pets: str = '/pets'
    create_pets: str = '/pets'
    show_pet_by_id: str = '/pets/{pet_id}'

app_petstore/models.py:

from __future__ import annotations

from typing import List, Optional

from pydantic import BaseModel, Field


class Pet(BaseModel):
    id: int
    name: str
    tag: Optional[str] = None


class Pets(BaseModel):
    __root__: List[Pet] = Field(..., description='list of pet')


class Error(BaseModel):
    code: int
    message: str


class LimitQueryParams(BaseModel):
    limit: Optional[int] = None


class PetIdPathParams(BaseModel):
    petId: str

Using a class:

from apiclient.request_formatters import JsonRequestFormatter
from apiclient.response_handlers import JsonResponseHandler

from app_petstore import PetStoreAPIClient


pet_client = PetStoreAPIClient(response_handler=JsonResponseHandler, request_formatter=JsonRequestFormatter)
pets = pet_client.list_pets()
for pet in pets:
    print(pet.name)

Generate stub files pyi

You can use stubmaker

> stubmaker --module-root app_petstore.client --src-root app_petstore/client.py --output-dir app_petstore/client.py

app_petstore/client.pyi:

import apiclient.client


class PetStoreAPIClient(apiclient.client.APIClient):
    def create_pets(self) -> 'None':
        """Create a pet
        """
        ...

    def show_pet_by_id(self, *, petId: str) -> 'Pets':
        """Info for a specific pet
        """
        ...

License

apiclient-pydantic-generator is released under the MIT License. http://www.opensource.org/licenses/mit-license