Code Monkey home page Code Monkey logo

openapi-cli-generator's Introduction

OpenAPI CLI Generator

GoDoc Build Status Go Report Card Platforms

openapi-to-cli


Note: this project has been superceded by Restish, an advanced auto-configured OpenAPI CLI that just works:


This project can be used to generate CLIs from OpenAPI 3 specs. The generated CLIs have the following features:

  • Authentication support for API keys and Auth0.
  • Commands, subcommands, & flag parsing through Cobra
  • Configuration through Viper
    • JSON, YAML, or TOML config files in /etc/ and $HOME, e.g. {"verbose": true} in ~/.my-app/config.json
    • From environment: APP_NAME_VERBOSE=1
    • From flags: --verbose
  • HTTP middleware through Gentleman
  • Command middleware with custom parameters (see customization below)
  • Input through stdin or CLI shorthand
  • Built-in cache to save data between runs
  • Fast structured logging via zerolog
  • Pretty output colored by Chroma
  • Response filtering & projection by JMESPath plus enhancements

Getting Started

First, make sure you have Go installed. Then, you can grab this project:

$ go get -u github.com/danielgtaylor/openapi-cli-generator

Next, make your project directory and generate the commands file.

# Set up your new project
$ mkdir my-cli && cd my-cli

# Create the default main file. The app name is used for config and env settings.
$ openapi-cli-generator init <app-name>

# Generate the commands
$ openapi-cli-generator generate openapi.yaml

Last, add a line like the following to your main.go file:

openapiRegister(false)

If you would like to generate a client for many APIs and have each available under their own namespace, pass true instead. Next, build your client:

# Build & install the generated client.
$ go install

# Test it out!
$ my-cli --help

OpenAPI Extensions

Several extensions properties may be used to change the behavior of the CLI.

Name Description
x-cli-aliases Sets up command aliases for operations.
x-cli-description Provide an alternate description for the CLI.
x-cli-ignore Ignore this path, operation, or parameter.
x-cli-hidden Hide this path, or operation.
x-cli-name Provide an alternate name for the CLI.
x-cli-waiters Generate commands/params to wait until a certain state is reached.

Aliases

The following example shows how you would set up a command that can be invoked by either list-items or simply ls:

paths:
  /items:
    get:
      operationId: ListItems
      x-cli-aliases:
        - ls

Description

You can override the default description easily:

paths:
  /items:
    description: Some info talking about HTTP headers.
    x-cli-description: Some info talking about command line arguments.

Exclusion

It is possible to exclude paths, operations, and/or parameters from the generated CLI. No code will be generated as they will be completely skipped.

paths:
  /included:
    description: I will get included in the CLI.
  /excluded:
    x-cli-ignore: true
    description: I will not be in the CLI :-(

Alternatively, you can have the path or operation exist in the UI but be hidden from the standard help list. Specific help is still available via my-cli my-hidden-operation --help:

paths:
  /hidden:
    x-cli-hidden: true

Name

You can override the default name for the API, operations, and params:

info:
  x-cli-name: foo
paths:
  /items:
    operationId: myOperation
    x-cli-name: my-op
    parameters:
      - name: id
        x-cli-name: item-id
        in: query

With the above, you would be able to call my-cli my-op --item-id=12.

Waiters

Waiters allow you to declaratively define special commands and parameters that will cause a command to block and wait until a particular condition has been met. This is particularly useful for asyncronous operations. For example, you might submit an order and then wait for that order to have been charged successfully before continuing on.

At a high level, waiters consist of an operation and a set of matchers that select a value and compare it to an expectation. For the example above, you might call the GetOrder operation every 30 seconds until the response's JSON status field is equal to charged. Here is what that would look like in your OpenAPI YAML file:

info:
  title: Orders API
paths:
  /order/{id}:
    get:
      operationId: GetOrder
      description: Get an order's details.
      parameters:
        - name: id
          in: path
      responses:
        200:
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    enum: ['placed', 'charged', 'shipped', 'returned']
x-cli-waiters:
  order-charged:
    delay: 30
    attempts: 10
    operationId: GetOrder
    matchers:
      - select: response.body#status
        expected: charged

The generated CLI will work like this: my-cli wait order-charged $ID where $ID corresponds to the GetOrder operation's id parameter. It will try to get and match the status 10 times, with a pause of 30 seconds between tries. If it matches, it will exit with a zero status code. If it fails, it will exit with a non-zero exit code and log a message.

This is a great start, but we can make this a little bit friendlier to use. Take a look at this modified waiter configuration:

x-cli-waiters:
  order-charged:
    short: Short description for CLI `--help`
    long: Long description for CLI `--help`
    delay: 30
    attempts: 10
    operationId: GetOrder
    matchers:
      - select: response.body#status
        expected: charged
      - select: response.status
        expected: 404
        state: failure
    after:
      CreateOrder:
        id: response.body#order_id

Here we added two new features:

  1. A short-circuit to fail fast. If we type an invalid order ID then we want the command to exit immediately with a non-zero exit code.

  2. The after block allows us to add a parameter to an existing operation to invoke the waiter. This block says that after a call to CreateOrder with a --wait-order-charged param, it should call the waiter's GetOrder operation with the id param set to the result of the response.body#order_id selector.

You can now create and wait on an order via my-cli create-order <order.json --wait-order-charged.

Matchers

The following matcher fields are available:

Field Description Example
select The value selection criteria. See the selector table below. response.status
test The test to perform. Defaults to equal but can be set to any and all to match list items. equal
expected The expected value charged
state The state to set. Defaults to success but can be set to failure. success

The following selectors are available:

Selector Description Argument Example
request.param Request parameter Parameter name request.param#id
request.body Request body query JMESPath query request.body#order.id
response.status Response HTTP status code - response.status
response.header Response HTTP header Header name response.header#content-type
response.body Response body query JMESPath query response.body#orders[].status

Customization

Your main.go is the entrypoint to your generated CLI, and may be customized to add additional logic and features. For example, you might set custom headers or handle auth before a request goes out on the wire. The apikey module provides a sample implementation.

Configuration Description

TODO: Show table describing all well-known configuration keys.

Custom Global Flags

It's possible to supply custom flags and a pre-run function. For example, say your OpenAPI spec has two servers: production and testing. You could add a --test flag to select the second server.

func main() {
	// ... init code ...

	// Add a `--test` flag to enable hitting testing.
	cli.AddGlobalFlag("test", "", "Use test endpoint", false)

	cli.PreRun = func(cmd *cobra.Command, args []string) error {
		if viper.GetBool("test") {
			// Use the test server
			viper.Set("server-index", 1)
		}
}

HTTP Middleware

Gentleman provides support for HTTP request and response middleware. Don't forget to call h.Next(ctx) in your handler! For example:

// Register a request middleware handler to print the path.
cli.Client.UseRequest(func(ctx *context.Context, h context.Handler) {
	fmt.Printf("Request path: %s\n", ctx.Request.URL.Path)
	h.Next(ctx)
})

// Register a response middleware handler to print the status code.
cli.Client.UseResponse(func(ctx *context.Context, h context.Handler) {
	fmt.Printf("Response status: %d\n", ctx.Response.StatusCode)
	h.Next(ctx)
})

Custom Command Flags & Middleware

While the above HTTP middleware is great for adding headers or logging various things, there are times when you need to modify the behavior of a generated command. You can do so by registering custom command flags and using command middleware.

Flags and middleware are applied to a command path, which is a space-separated list of commands in a hierarchy. For example, if you have a command foo which has a subcommand bar, then the command path to reference bar for flags and middleware would be foo bar.

Note that any calls to cli.AddFlag must be made before calling the generated command registration function (e.g. openapiRegister(...)) or the flags will not get created properly.

Here's an example showing how a custom flag can change the command response:

// Register a new custom flag for the `foo` command.
cli.AddFlag("foo", "custom", "", "description", "")

cli.RegisterAfter("foo", func(cmd *cobra.Command, params *viper.Viper, resp *gentleman.Response, data interface{}) interface{} {
  m := data.(map[string]interface{})
  m["custom"] = params.GetString("custom")
  return m
})

// Register our generated commands with the CLI after the above.
openapiRegister(false)

If the foo command would normally return a JSON object like {"hello": "world"} it would now return the following if called with --custom=test:

{
  "custom": "test",
  "hello": "world"
}

Authentication & Authorization

See the apikey module for a simple example of a pre-shared key.

If instead you use a third party auth system that vends tokens and want your users to be able to log in and use the API, here's an example using Auth0:

func main() {
	cli.Init(&cli.Config{
		AppName:   "example",
		EnvPrefix: "EXAMPLE",
		Version:   "1.0.0",
	})

  // Auth0 requires a client ID, issuer base URL, and audience fields when
  // requesting a token. We set these up here and use the Authorization Code
  // with PKCE flow to log in, which opens a browser for the user to log into.
  clientID := "abc123"
  issuer := "https://mycompany.auth0.com/"

  cli.UseAuth("user", &oauth.AuthCodeHandler{
    ClientID: "clientID",
    AuthorizeURL: issuer+"authorize",
    TokenURL: issuer+"oauth/token",
    Keys: []string{"audience"},
    Params: []string{"audience"},
    Scopes: []string{"offline_access"},
  })

  // TODO: Register API commands here
  // ...

	cli.Root.Execute()
}

Note that there is a convenience module when using Auth0 specifically, allowing you to do this:

auth0.InitAuthCode(clientID, issuer,
  auth0.Type("user"),
  auth0.Scopes("offline_access"))

The expanded example above is more useful when integrating with other services since it uses basic OAuth 2 primitives.

Development

Working with Templates

The code generator is configured to bundle all necessary assets into the final executable by default. If you wish to modify the templates, you can use the go-bindata tool to help:

# One-time setup of the go-bindata tool:
$ go get -u github.com/shuLhan/go-bindata/...

# Set up development mode (load data from actual files in ./templates/)
$ go-bindata -debug ./templates/...

# Now, do all your edits to the templates. You can test with:
$ go run *.go generate my-api.yaml

# Build the final static embedded files and code generator executable.
$ go generate
$ go install

License

https://dgt.mit-license.org/

openapi-cli-generator's People

Contributors

danielgtaylor avatar danielklim avatar xlab avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

openapi-cli-generator's Issues

openapi-cli-generator init <app-name> not working MacOS

I successfully installed go and then used the "go get -u github.com/danielgtaylor/openapi-cli-generator" you gave.
But the init command doesn't work.
Gives me the following error on MacOS Terminal:
-bash: openapi-cli-generator: command not found

Possibility to pass location of the config and credentials file

Currently the location of the config and credentials file is hard-coded to certain locations - see:

Creds.AddConfigPath("$HOME/." + viper.GetString("app-name") + "/")

viper.AddConfigPath("/etc/" + appName + "/")

This would allow to use dynamically created config and credentials files to prevent race conditions, if the CLI is used in parallel for different situations.

Is it possible to pass the body params as flags too?

Thanks for this great tool!
For the use case I'm trying, It seems non-intuitive to know all body params for a POST/PUT/PATCH.
It might be better to pass the body json params as CLI arguments or flags. Is this supported via some x-cli extensions?

Also, any support for JWT token auth?

Server Variables

Currently, OpenAPI 3 server variables are not handled at all. They are required to have defaults, so at the very least we should string replace the template values with the defaults.

A better implementation would also expose these as optional parameters for the generated CLI. One complication is that different servers might have different variables, so the ones that get exposed might depend on the current server index.

Call openapiYmlRegister() instead of openapiRegister()

Hi,
(Really great tool you've written, thanks)

The readme.md says to call openapiRegister() from main.go, but I have to call openapiYmlRegister() instead.

I don't know if this is a bug or what, but since I'm not fluent in go, it took me some time to track down the issue.

I was getting the following error message:

# command-line-arguments
./main.go:16:9: undefined: openapiRegister

Crash with empty list + `--raw`

When getting an empty list of data either as the response or queried via --query it will cause a crash when paired with --raw:

panic: runtime error: index out of range

goroutine 1 [running]:
github.com/danielgtaylor/openapi-cli-generator/cli.(*DefaultFormatter).Format(0xc0004b55ff, 0x1680080, 0xc000424440, 0x16b1060, 0xc0002e18f0)
	/Users/dan/Projects/pkg/mod/github.com/danielgtaylor/[email protected]/cli/formatter.go:142 +0xa7f

Support Array Parameters

Currently anything that isn't a basic type is just treated as a string. It would be good to support arrays via StringSlice(...) parameters and then have them encoded correctly via #5.

Alternatively, the shorthand could be updated to support top level arrays and scalars and then be used for any complex parameter type.

How to setup the credentials file?

Hello,
I can't figure out how to setup a credentials file. I'm a complete go newbie. This is my main.go:

package main

import (
    "github.com/danielgtaylor/openapi-cli-generator/cli"
    "github.com/danielgtaylor/openapi-cli-generator/apikey"
)

func main() {
	cli.Init(&cli.Config{
		AppName:   "example",
		EnvPrefix: "EXAMPLE",
		Version:   "1.0.0",
	})

  exampleRegister(false)
  apikey.Init("Authorization", apikey.LocationHeader)

   cli.Creds.Set("profiles.default.api_key", "mykey")
   
   cli.Root.Execute()
}

This works, but the api key is hardcorded. Where and how should I define the key in the credentials file? I've tried:

./.example/config.json:

{ "example":
    { "profiles":
        { "default":
            { "api_key": "mykey"
            }
        }
    }
}

Any help is appreciated!

loader.LoadSwaggerFromYAMLData undefined

Go get fails with:
/main.go:479:24: loader.LoadSwaggerFromYAMLData undefined (type *openapi3.SwaggerLoade r has no field or method LoadSwaggerFromYAMLData)

In getkin/kin-openapi@82a13f9, getkin library changed the LoadSwaggerFromYAMLData to a generic LoadSwaggerFromData so theoretically, just changing the function call in line 479 should fix this error.

Creating subcommands

Hi,
Thanks for a very useful tool!

I can't seem to figure out how to create subcommands like $ docker container rm <containerName>.

If i try adding the path: /container/rm/{containerName}, the command will be created as $ docker container-rm <containerName>

This is the first time that I am using both OpenAPI and this tool, so I am in no way an expert.

Thanks!

Panic when attempting to generate CLI for YNAB's API

I am attempting to generate a CLI for YNAB's API (spec) via Docker (because I really do not want to setup then tear down a go env for this single use-case).

This isn't straightforward as the YNAB API spec is OpenAPI v2 so I converted it to v3 with this tool (then validated the generated spec with this tool).

I uploaded the resulting v3 YAML as a gist.

I then wrote this, potentially bogus, Dockerfile:

FROM golang

WORKDIR /go/ynab-cli

RUN go get -u github.com/danielgtaylor/openapi-cli-generator && \
    curl --silent -o ynab.openapi.yaml https://gist.githubusercontent.com/Phrohdoh/d1ecea1fbe1c8566fad5fd97aa99b346/raw/962661a47d8248aa2edd3618ad6c74d000219fe4/ynab_v1.openapi_v3.yaml && \
    openapi-cli-generator init ynab && \
    cat main.go | sed 's|// TODO: Add register commands here\.|openapiRegister(false)|g' > main.go

RUN openapi-cli-generator generate ynab.openapi.yaml
RUN go install

CMD ynab-cli

When I run the following from the directory containing my Dockerfile:

$ docker build -t gen-ynab-cli .

I get the following output:

Sending build context to Docker daemon   2.56kB
Step 1/6 : FROM golang
 ---> b860ab44e93e
Step 2/6 : WORKDIR /go/ynab-cli
 ---> Using cache
 ---> dfba7020dd36
Step 3/6 : RUN go get -u github.com/danielgtaylor/openapi-cli-generator &&     curl --silent -o ynab.openapi.yaml https://gist.githubusercontent.com/Phrohdoh/d1ecea1fbe1c8566fad5fd97aa99b346/raw/962661a47d8248aa2edd3618ad6c74d000219fe4/ynab_v1.openapi_v3.yaml &&     openapi-cli-generator init ynab &&     cat main.go | sed 's|// TODO: Add register commands here\.|openapiRegister(false)|g' > main.go &&     cat main.go
 ---> Using cache
 ---> e7a8c5ae42a6
Step 4/6 : RUN openapi-cli-generator generate ynab.openapi.yaml
 ---> Running in 4250354ef5c6
panic: 25:9: expected ';', found '.' (and 10 more errors)

goroutine 1 [running]:
main.writeFormattedFile(0xc000160c00, 0xf, 0xc0002ae000, 0x10af6, 0x12000)
        /go/src/github.com/danielgtaylor/openapi-cli-generator/main.go:586 +0x112
main.generate(0xc0000b7b80, 0xc0000530a0, 0x1, 0x1)
        /go/src/github.com/danielgtaylor/openapi-cli-generator/main.go:654 +0x5b0
github.com/spf13/cobra.(*Command).execute(0xc0000b7b80, 0xc000053080, 0x1, 0x1, 0xc0000b7b80, 0xc000053080)
        /go/src/github.com/spf13/cobra/command.go:766 +0x2ae
github.com/spf13/cobra.(*Command).ExecuteC(0xc0000b7680, 0xc00008df78, 0x1, 0x1)
        /go/src/github.com/spf13/cobra/command.go:850 +0x2fc
github.com/spf13/cobra.(*Command).Execute(...)
        /go/src/github.com/spf13/cobra/command.go:800
main.main()
        /go/src/github.com/danielgtaylor/openapi-cli-generator/main.go:674 +0x1c0
The command '/bin/sh -c openapi-cli-generator generate ynab.openapi.yaml' returned a non-zero code: 2

With the relevant portion being:

panic: 25:9: expected ';', found '.' (and 10 more errors)

goroutine 1 [running]:
main.writeFormattedFile(0xc000160c00, 0xf, 0xc0002ae000, 0x10af6, 0x12000)
        /go/src/github.com/danielgtaylor/openapi-cli-generator/main.go:586 +0x112
main.generate(0xc0000b7b80, 0xc0000530a0, 0x1, 0x1)
        /go/src/github.com/danielgtaylor/openapi-cli-generator/main.go:654 +0x5b0
github.com/spf13/cobra.(*Command).execute(0xc0000b7b80, 0xc000053080, 0x1, 0x1, 0xc0000b7b80, 0xc000053080)
        /go/src/github.com/spf13/cobra/command.go:766 +0x2ae
github.com/spf13/cobra.(*Command).ExecuteC(0xc0000b7680, 0xc00008df78, 0x1, 0x1)
        /go/src/github.com/spf13/cobra/command.go:850 +0x2fc
github.com/spf13/cobra.(*Command).Execute(...)
        /go/src/github.com/spf13/cobra/command.go:800
main.main()
        /go/src/github.com/danielgtaylor/openapi-cli-generator/main.go:674 +0x1c0

Am I attempting to use this project incorrectly or is the generated v3 YAML doc invalid?

Any help/input would be greatly appreciated!

Error main.go:132:40: undefined: openapi3.Swagger

While running command - "go get -u github.com/danielgtaylor/openapi-cli-generator" I am getting the following errors "main.go:132:40: undefined: openapi3.Swagger" "main.go:625:12: undefined: openapi3.NewSwaggerLoader" "main.go:626:15: undefined: openapi3.Swagger". No sure what is missing, but based on the openapi3 some fields were renamed i.e openapi3.Swagger to openapi3.T.

I am new with go and openapi-cli-generator

Installing forked package

Any idea why installing from danielgtaylor repo causes installing of the kalzoo fork?

go get github.com/danielgtaylor/openapi-cli-generator
# github.com/danielgtaylor/openapi-cli-generator
../../../../../go/pkg/mod/github.com/kalzoo/[email protected]/main.go:433:14: undefined: uppercaseAcronym

IP addresses not handled well by shorthand

Example that fails:

$ j 1.1.1.1

Causes:

panic: stdin:1:10 (9): no match found, expected: ",", [ \t\r\n], [0-9] or EOF

goroutine 1 [running]:
main.main.func1(0xc420013180, 0xc42000c440, 0x2, 0x2)
	/Users/dan/Projects/src/github.com/danielgtaylor/openapi-cli-generator/j/main.go:26 +0x2f4
github.com/danielgtaylor/openapi-cli-generator/vendor/github.com/spf13/cobra.(*Command).execute(0xc420013180, 0xc4200101c0, 0x2, 0x2, 0xc420013180, 0xc4200101c0)
	/Users/dan/Projects/src/github.com/danielgtaylor/openapi-cli-generator/vendor/github.com/spf13/cobra/command.go:766 +0x2c1
github.com/danielgtaylor/openapi-cli-generator/vendor/github.com/spf13/cobra.(*Command).ExecuteC(0xc420013180, 0x1218e9a, 0x20, 0xc42005a8f0)
	/Users/dan/Projects/src/github.com/danielgtaylor/openapi-cli-generator/vendor/github.com/spf13/cobra/command.go:852 +0x30a
github.com/danielgtaylor/openapi-cli-generator/vendor/github.com/spf13/cobra.(*Command).Execute(0xc420013180, 0x1212666, 0x6)
	/Users/dan/Projects/src/github.com/danielgtaylor/openapi-cli-generator/vendor/github.com/spf13/cobra/command.go:800 +0x2b
main.main()
	/Users/dan/Projects/src/github.com/danielgtaylor/openapi-cli-generator/j/main.go:53 +0x315

Links Support

Add the ability to follow OpenAPI 3 links to fetch additional data and add it to the response for a given operation. For example, you might get an item overview with a link to get item details. A new CLI option like --link=details could then be used to trigger the additional request and put a details field into the response with the response data from the details call. All of this would happen before response filtering/projection so you can select just the fields you care about.

Bonus: support an extension like x-collection so this works for calls that return a list of items, so that you can get the link for each item in the list by treating index 0 as a wildcard in the body pointer.

CLI-specific examples

Provide a way to give CLI-specific examples to an operation. Should use some extension like x-cli-examples and you should be able to give a list where the items have both a description and the example itself. These would show up in the help for the command.

Support OAuth Flows

Add an auth module with support for the OAuth flows described in the OpenAPI spec with as much automation as possible. Should support profiles and if possible, be usable with a flag to the openapi-cli-generator init command or be automatically detected from the OpenAPI document.

  • Client credentials flow
  • Authorization code flow
  • Multi-auth (more than one way supported in one CLI)

"undefined: openapiRegister" error

Hi,

I've tried to follow the instructions in the README of this project, however when reaching the go install step I get the following error:

$ go install
# github.com/exoscale/cli
./main.go:14:2: undefined: openapiRegister

Where is the openapiRegister() function supposed to come from? There's not such function definition in the files generated, did I miss something?

Handle Pagination

For APIs with paginated responses, the cli package should include utilities for handling the response and fetching subsequent pages automatically up to some limit.

For example, the GitHub API v3 uses Link headers with hypermedia relations to provide pagination.

In general there seem to be three models in use:

  1. Passing a page size and page number to get items. Maybe also some way to get a total page count.
  2. Passing an iterator value to get the next set of items. When no iterator is (or no items are) returned you are done.
  3. Using link relations to provide full URLs to fetch more items.

There should be a new OpenAPI extension to hint to the CLI which of these cases it is, how to handle it (e.g. parameter names), and whether to fetch all or expose limits via parameters in the CLI.

Waiter Support

Add an OpenAPI extension to provide waiter support that blocks until a specific state has been met. Typically you would do a request on a cadence to return some state information and use a query to match a state in the response to exit the loop.

For example, the configuration for such a feature might look something like:

x-cli-waiters:
  order-ready:
    delay: 10
    attempts: 30
    operation: GetOrder
    matchers:
      - select: response.body#order.status
        expected: Ready

Assuming the GetOrder operation has a required order-id parameter, this results in a command something like:

$ my-cli wait order-ready $ORDER_ID

This could also be automatically combined with creation or update operations by mapping response information to parameters on the waiter operation:

x-cli-waiters:
  order-ready:
    # ...
    operation: GetOrder
    after:
      PostOrder:
        order-id: response.body#order.id

Then you could do something like:

# With automatic waiter:
$ my-cli post-order <details.json --wait-order-ready

# Without:
$ ID=my-cli post-order <details.json -q order.id
$ my-cli wait order-ready $ID

This gets even more difficult with multiple params where you have to save the response and somehow get each param to pass into the wait command.

Add Simple API Key Auth

It would cover a lot of use-cases to have a basic API key or API key+secret style auth module with support for profiles. This could even be added as an option to the openapi-cli-generator init command so you don't need to write any Go.

Nested objects in args

Thanks so much for this awesome project! I have been able to use it to quickly create a CLI for my web API.

However, my more complex search queries require nested objects and lists.

For example, my POST body would look like this-
'{"queries":[{"type":"queryText","value":"climate"}],"filters":[{"type":"geometry","geometry":{"type":"Polygon","coordinates":[[[-176.64917,0.197754],[-124.790955,0.197754],[-124.790955,34.85889],[-176.64917,34.85889],[-176.64917,0.197754]]]}}],"facets":true,"page":{"max":20,"offset":0}}'

How would I write this on the command line? No matter what I try, I get an error like this-

FATAL openapi.go:1101 Unable to get body
stdin:1:73 (72): no match found, expected: [^,:}], [^:] or EOF

Am I doing it wrong or is this a limitation of the json parsing?

Make binary self-contained

Instead of generating openapi-spec.go, make it possible for users to download a single binary and not need a Go build environment.

So instead of using code generation, build in the cli dependencies and abstract the openapi spec environment.

Build broken with undefined zerolog.LevelWidth

With more recent versions of the zerolog package, LevelWidth has been removed, and so this no longer builds:

$ go build
# github.com/danielgtaylor/openapi-cli-generator/cli
../../../go/src/github.com/danielgtaylor/openapi-cli-generator/cli/log.go:60:6: undefined: zerolog.LevelWidth
../../../go/src/github.com/danielgtaylor/openapi-cli-generator/cli/log.go:61:18: undefined: zerolog.LevelWidth
../../../go/src/github.com/danielgtaylor/openapi-cli-generator/cli/log.go:64:21: undefined: zerolog.LevelWidth

More specifically, this was broken by the recent rewriting of the zerolog.ConsoleWriter interface.

J how to escape "," symbols?

Hey, I am trying to pass a string with , symbols in it, tried several ways, but didn't succeded to escape it..

โฏ j foo :~ "http://example.com/a,b,c,d", bar: baz 
{
  "bar": "baz",
  "foo": [
    "http://example.com/a",
    "b",
    "c",
    "d"
  ]
}

foo should be a string in my case, not an array...

How to set default value to custom header

Hi ,
I am trying to have a custom header in my spec like below :

-  name: 'Client-Type'
    in: header
    schema:
        type: string

./cli --Client-Type

I don't want to force user to pass the header like above example command, it should take from spec instead.

So I modified it like below :

 -  name: 'Client-Type'
    in: header
    schema:
        type: string
        default: "my-header"
        nullable: true

Still, I don't see this header in my request. And it expects me to pass the same from CLI.

Can you please suggest on this ?

Thanks in advance ;)

Add Help to Describe CLI Config

It's not obvious how to set configuration values. Describe locations of config files, how to set values, how to use environment variables, and how to pass config (not request input) to the generated CLI.

Is this project still maintained?

Hi,

We're interested in using your software as a foundation to build our CLIs with, although it's currently missing some features we need: we'd gladly contribute those to your codebase, however it looks like this project has been inactive for a while now, so we're wondering if you're still maintaining it and so if it's still worth capitalizing on it rather than fork it and implement the changes we need on our end?

Thank you for your work! ๐Ÿ‘

Getting Started Issues

I want to build a cli from my company's api and I'm trying to get started with the openapi-cli-generator https://github.com/danielgtaylor/openapi-cli-generator but I'm running into some different errors.

I took the petstore demo api https://petstore.swagger.io/v2/swagger.json removed the top of the file comments and converted it to yaml using https://www.json2yaml.com/ then following the steps on the openapi-cli-generator github page, I run openapi-cli-generator generate petstore.yaml

and I get this type of error: Failed to resolve '#/definitions/Pet' in fragment in URI: 'definitions': Struct field not found: definitions which is complaining about lines like schema: "$ref": "#/definitions/Pet" in the yaml file. I tried replacing the $ref values with '' ex "$ref":"" and now I can run openapi-cli-generator generate petstore.yaml Was relacing the ref values with empty string the right thing to do? What is the nature of the problem.

Next, the git hub instructions say to add a line like openapiRegister(false) what is this supposed to do exactly? What does it mean to register a command? Are these the commands that will be part of the cli? What does the syntax look like? The github page doesn't give any examples

Is there supposed to be a one cli command per api call in the generated cli?
petstore-cli PetstoreFindPetsByStatus --help - unknown command "PetstoreFindPetsByStatus" for "petstore-cli.exe" (I need to register the command that I want?)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.