├── .gitignore ├── README.md ├── build.sbt ├── src └── main │ └── scala │ └── com │ └── josephpconley │ └── swagger2postman │ ├── CollectionArgs.scala │ ├── app │ ├── v12 │ │ └── Swagger2PostmanApp.scala │ └── v2 │ │ └── Swagger2PostmanApp.scala │ ├── models │ ├── postman │ │ └── PostmanCollection.scala │ └── swagger │ │ ├── v12 │ │ ├── Swagger2Postman.scala │ │ └── SwaggerDoc.scala │ │ └── v2 │ │ ├── Swagger2Postman.scala │ │ └── SwaggerDoc.scala │ └── utils │ ├── ConversionUtils.scala │ └── HttpEnabled.scala └── v2petstore-swagger.json /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | target 3 | postman.json -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # swagger2postman 2 | 3 | [![Join the chat at https://gitter.im/josephpconley/swagger2postman](https://badges.gitter.im/josephpconley/swagger2postman.svg)](https://gitter.im/josephpconley/swagger2postman?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 4 | Create a Postman collection from Swagger documentation 5 | 6 | ##Motivation 7 | 8 | [Swagger UI](https://github.com/swagger-api/swagger-ui) provides a nice way to interact with an API documented by the [Swagger specification](https://github.com/swagger-api/swagger-spec). 9 | But if you're working with an identical API across multiple environments, or you want to test edge cases that Swagger UI doesn't support 10 | (like omitting a required query parameter), Swagger UI comes up a bit short. 11 | 12 | [Postman](https://www.getpostman.com/) to the rescue! Using Postman you can define variables for multiple environments and have more control over request generation. 13 | 14 | ##Purpose 15 | This library takes Swagger documentation served in JSON and converts it into a JSON collection which can be imported directly into Postman. 16 | You can see a full description of the Swagger JSON spec at [http://swagger.io/specification/](http://swagger.io/specification/) 17 | 18 | ##Command line 19 | 20 | To convert a Swagger 2.0 JSON file to a valid Postman collection: 21 | 22 | sbt "runMain com.josephpconley.swagger2postman.app.v2.Swagger2PostmanApp [ ... ]" 23 | 24 | To convert a Swagger 1.2 hosted endpoint to a valid Postman collection: 25 | 26 | sbt "runMain com.josephpconley.swagger2postman.app.v12.Swagger2PostmanApp [ ... ]" 27 | 28 | 29 | ##Demo 30 | 31 | Try out an online version at [http://app.josephpconley.com/swagger2postman](http://app.josephpconley.com/swagger2postman) 32 | 33 | Or using `curl` to convert a Swagger 2.0 document into a Postman JSON import file: 34 | 35 | curl -X POST --data "@v2petstore-swagger.json" "http://app.josephpconley.com/swagger20?name=my_collection&header_key=header_value" --header "Content-Type:application/json" > my_collection.json 36 | 37 | 38 | ##Multiple environments 39 | 40 | To take advantage of multi-environment testing, I would first run swagger2postman against a hosted Swagger doc. 41 | Then I do a simple Find/Replace, replacing the target host with a handlebars variable like `{{host}}`. 42 | Then I create environments in Postman that define a value for the config key `host`. 43 | Toggling these environments with your imported collection will let you seamlessly test your API in different environments. 44 | 45 | You can also use environment variables for authentication. If your API uses a header for authentication, then pass a `headerKey`=`{{headerValue}}` 46 | so that all endpoints get a global authentication header with an environment-dependent value. 47 | 48 | ##Release Notes 49 | ### 1.1 50 | - Initial support for Swagger 2.0 51 | 52 | ### 1.0 53 | - Initial support for Swagger 1.2 -------------------------------------------------------------------------------- /build.sbt: -------------------------------------------------------------------------------- 1 | name := "swagger2postman" 2 | 3 | organization := "com.josephpconley" 4 | 5 | version := "1.1" 6 | 7 | resolvers += "Typesafe Repo" at "http://repo.typesafe.com/typesafe/releases/" 8 | 9 | libraryDependencies ++= Seq( 10 | "com.typesafe.play" %% "play-json" % "2.3.4", 11 | "org.rogach" %% "scallop" % "0.9.5", 12 | "com.stackmob" %% "newman" % "1.3.5" 13 | ) -------------------------------------------------------------------------------- /src/main/scala/com/josephpconley/swagger2postman/CollectionArgs.scala: -------------------------------------------------------------------------------- 1 | package com.josephpconley.swagger2postman 2 | 3 | import com.josephpconley.swagger2postman.utils.ConversionUtils 4 | import play.api.libs.json.Json 5 | 6 | import ConversionUtils._ 7 | 8 | case class CollectionArgs(host: String, name: String, headers: Map[String, String] = Map.empty){ 9 | val docUrl = host + "/api-docs" 10 | val owner = "12345" 11 | val collectionId = genUUID 12 | } 13 | 14 | trait CollectionFormats { 15 | implicit val collectionFmt = Json.format[CollectionArgs] 16 | } 17 | -------------------------------------------------------------------------------- /src/main/scala/com/josephpconley/swagger2postman/app/v12/Swagger2PostmanApp.scala: -------------------------------------------------------------------------------- 1 | package com.josephpconley.swagger2postman.app.v12 2 | 3 | import java.io.PrintWriter 4 | import java.net.URL 5 | 6 | import com.josephpconley.swagger2postman.CollectionArgs 7 | import com.josephpconley.swagger2postman.models.swagger._ 8 | import com.stackmob.newman._ 9 | import com.stackmob.newman.dsl._ 10 | import play.api.libs.json._ 11 | 12 | import scala.concurrent._ 13 | import scala.concurrent.duration._ 14 | import scala.language.postfixOps 15 | import scala.util.Try 16 | 17 | object Swagger2PostmanApp 18 | extends v12.Swagger2Postman 19 | with v2.Swagger2Postman 20 | with App { 21 | implicit val httpClient = new ApacheHttpClient 22 | 23 | if(args.length < 2){ 24 | throw new IllegalArgumentException("Invalid number of arguments, must be [ ... ]") 25 | } 26 | 27 | val headerMap = args.drop(2) map { kv => 28 | val h = kv.split("=") 29 | h.head -> h.last 30 | } toMap 31 | 32 | val cArgs = CollectionArgs(host = args(0), name = args(1), headers = headerMap) 33 | 34 | val postmanJson = Try(execute(cArgs.docUrl)) map { res => 35 | val swaggerDoc = Json.fromJson[v12.SwaggerDoc](Json.parse(res)).get 36 | toPostman(swaggerDoc, cArgs) 37 | } getOrElse { 38 | Try(execute(cArgs.host)) map { res => 39 | val swaggerDoc = Json.fromJson[v2.SwaggerDoc](Json.parse(res)).get 40 | toPostman(swaggerDoc, cArgs) 41 | } getOrElse { 42 | throw new RuntimeException("Unable to reach Swagger 1.2 and 2.0 endpoints.") 43 | } 44 | } 45 | 46 | println(postmanJson) 47 | val writer = new PrintWriter("postman.json", "UTF-8") 48 | writer.append(Json.prettyPrint(postmanJson)) 49 | writer.close() 50 | 51 | def execute(url: String) = Await.result(GET(new URL(url)).apply, Duration.Inf).bodyString 52 | } -------------------------------------------------------------------------------- /src/main/scala/com/josephpconley/swagger2postman/app/v2/Swagger2PostmanApp.scala: -------------------------------------------------------------------------------- 1 | package com.josephpconley.swagger2postman.app.v2 2 | 3 | import java.io.PrintWriter 4 | import java.net.URL 5 | 6 | import com.josephpconley.swagger2postman.CollectionArgs 7 | import com.josephpconley.swagger2postman.models.swagger._ 8 | import com.stackmob.newman._ 9 | import com.stackmob.newman.dsl._ 10 | import play.api.libs.json._ 11 | 12 | import scala.concurrent._ 13 | import scala.concurrent.duration._ 14 | import scala.io.Source 15 | import scala.language.postfixOps 16 | import scala.util.Try 17 | 18 | object Swagger2PostmanApp 19 | extends v2.Swagger2Postman 20 | with App { 21 | implicit val httpClient = new ApacheHttpClient 22 | 23 | if(args.length < 2){ 24 | throw new IllegalArgumentException("Invalid number of arguments, must be [ ... ]") 25 | } 26 | 27 | val headerMap = args.drop(2) map { kv => 28 | val h = kv.split("=") 29 | h.head -> h.last 30 | } toMap 31 | 32 | val cArgs = CollectionArgs(host = "host", name = args(1), headers = headerMap) 33 | 34 | val fileJson = Source.fromFile(args(0)).getLines.mkString 35 | Json.fromJson[v2.SwaggerDoc](Json.parse(fileJson)).fold( 36 | invalid => { 37 | println("Error converting Swagger v2 doc to Postman json") 38 | println(Json.prettyPrint(JsError.toFlatJson(invalid))) 39 | }, 40 | swaggerDoc => { 41 | val postmanJson = toPostman(swaggerDoc, cArgs) 42 | println(postmanJson) 43 | 44 | val writer = new PrintWriter("postman.json", "UTF-8") 45 | writer.append(Json.prettyPrint(postmanJson)) 46 | writer.close() 47 | } 48 | ) 49 | } 50 | -------------------------------------------------------------------------------- /src/main/scala/com/josephpconley/swagger2postman/models/postman/PostmanCollection.scala: -------------------------------------------------------------------------------- 1 | package com.josephpconley.swagger2postman.models.postman 2 | 3 | import org.joda.time.DateTime 4 | import play.api.libs.json._ 5 | 6 | case class PostmanCollection( 7 | id: String, 8 | name: String, 9 | description: String = "", 10 | order: Seq[String] = Seq.empty[String], 11 | folders: Seq[PostmanFolder], 12 | timestamp: Long = DateTime.now().getMillis, 13 | synced: Boolean = false, 14 | owner: String, 15 | sharedWithTeam: Boolean = false, 16 | subscribed: Boolean = false, 17 | remoteLink: String = "", 18 | public: Boolean = false, 19 | write: Boolean = true, 20 | requests: Seq[PostmanRequest]) 21 | 22 | case class PostmanFolder( 23 | id: String, 24 | name: String, 25 | description: String, 26 | write: Boolean = true, 27 | order: Seq[String], 28 | collection_name: String, 29 | collection_owner: String, 30 | collection_id: String, 31 | collection: String, 32 | owner: String) 33 | 34 | case class PostmanRequest( 35 | id: String, 36 | headers: String = "", 37 | url: String, 38 | preRequestScript: String = "", 39 | pathVariables: JsObject = Json.obj(), 40 | method: String, 41 | data: JsArray = Json.arr(), 42 | dataMode: String = "params", 43 | rawModeData: Option[String] = None, 44 | version: Int = 2, 45 | tests: String = "", 46 | currentHelper: String = "normal", 47 | helperAttributes: JsObject = Json.obj(), 48 | time: Long = DateTime.now().getMillis, 49 | name: String, 50 | description: String, 51 | collectionId: String, 52 | responses: JsArray = Json.arr(), 53 | synced: Boolean = false) 54 | 55 | trait PostmanFormats { 56 | implicit val reqFmt = Json.format[PostmanRequest] 57 | implicit val folderFmt = Json.format[PostmanFolder] 58 | implicit val collFmt = Json.format[PostmanCollection] 59 | } -------------------------------------------------------------------------------- /src/main/scala/com/josephpconley/swagger2postman/models/swagger/v12/Swagger2Postman.scala: -------------------------------------------------------------------------------- 1 | package com.josephpconley.swagger2postman.models.swagger.v12 2 | 3 | import com.josephpconley.swagger2postman.CollectionArgs 4 | import com.josephpconley.swagger2postman.models.postman._ 5 | import com.josephpconley.swagger2postman.utils.{HttpEnabled, ConversionUtils} 6 | import play.api.libs.json.{Json, JsValue} 7 | 8 | import scala.util.Try 9 | 10 | import ConversionUtils._ 11 | 12 | trait Swagger2Postman 13 | extends PostmanFormats 14 | with HttpEnabled { 15 | 16 | def toPostman(swaggerDoc: SwaggerDoc, cArgs: CollectionArgs): JsValue = { 17 | 18 | val requests = swaggerDoc.apis map { api => 19 | val apiRes = execute(cArgs.docUrl + api.path) 20 | val swaggerApi = Json.fromJson[SwaggerApi](Json.parse(apiRes)).get 21 | 22 | val requests = 23 | for { 24 | endpoint <- swaggerApi.apis 25 | operation <- endpoint.operations 26 | } yield { 27 | 28 | val queryParams = operation.parameters filter (_.paramType == "query") match { 29 | case Nil => "" 30 | case list => "?" + list.map(_.name + "=").mkString("&") 31 | } 32 | 33 | val bodyOpt = operation.parameters find (_.paramType == "body") flatMap (_.defaultValue) 34 | val headers: Map[String, String] = 35 | if(bodyOpt.isDefined && Try(Json.parse(bodyOpt.get)).isSuccess){ 36 | Map("Content-Type" -> "application/json") ++ cArgs.headers 37 | } else { 38 | cArgs.headers 39 | } 40 | 41 | PostmanRequest( 42 | id = genUUID, 43 | url = cArgs.host + endpoint.path + queryParams, 44 | headers = headers map (h => s"${h._1}: ${h._2}") mkString "\n", 45 | method = operation.method, 46 | rawModeData = bodyOpt, 47 | dataMode = bodyOpt map (_ => "raw") getOrElse "params", 48 | name = operation.nickname, 49 | description = operation.notes, 50 | collectionId = cArgs.collectionId 51 | ) 52 | } 53 | 54 | val folder = 55 | PostmanFolder( 56 | id = genUUID, 57 | name = api.path, 58 | description = api.description, 59 | order = requests map (_.id), 60 | collection_name = cArgs.name, 61 | collection_owner = cArgs.owner, 62 | collection_id = cArgs.collectionId, 63 | collection = cArgs.collectionId, 64 | owner = cArgs.owner 65 | ) 66 | 67 | folder -> requests 68 | } 69 | 70 | val postmanCollection = PostmanCollection( 71 | id = cArgs.collectionId, 72 | name = cArgs.name, 73 | folders = requests.map(_._1), 74 | owner = cArgs.owner, 75 | requests = requests.map(_._2).flatten 76 | ) 77 | 78 | Json.toJson(postmanCollection) 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/main/scala/com/josephpconley/swagger2postman/models/swagger/v12/SwaggerDoc.scala: -------------------------------------------------------------------------------- 1 | package com.josephpconley.swagger2postman.models.swagger.v12 2 | 3 | import play.api.libs.json.Json 4 | 5 | case class SwaggerDoc( 6 | apiVersion: String, 7 | swaggerVersion: String, 8 | apis: Seq[SwaggerApiPath]) 9 | 10 | object SwaggerDoc extends SwaggerFormats 11 | 12 | case class SwaggerApiPath( 13 | path: String, 14 | description: String) 15 | 16 | case class SwaggerApi( 17 | apiVersion: String, 18 | swaggerVersion: String, 19 | basePath: String, 20 | resourcePath: String, 21 | apis: Seq[SwaggerEndpoint]) 22 | 23 | object SwaggerApi extends SwaggerFormats 24 | 25 | case class SwaggerEndpoint( 26 | path: String, 27 | operations: Seq[SwaggerOperation]) 28 | 29 | case class SwaggerOperation( 30 | method: String, 31 | summary: String, 32 | notes: String, 33 | nickname: String, 34 | parameters: Seq[SwaggerParam]) 35 | 36 | case class SwaggerParam( 37 | name: String, 38 | defaultValue: Option[String], 39 | required: Boolean, 40 | paramType: String) 41 | 42 | trait SwaggerFormats { 43 | implicit val paramFmt = Json.format[SwaggerParam] 44 | implicit val opFmt = Json.format[SwaggerOperation] 45 | implicit val endpointFmt = Json.format[SwaggerEndpoint] 46 | implicit val apiFmt = Json.format[SwaggerApi] 47 | implicit val apiPathFmt = Json.format[SwaggerApiPath] 48 | implicit val docFmt = Json.format[SwaggerDoc] 49 | } -------------------------------------------------------------------------------- /src/main/scala/com/josephpconley/swagger2postman/models/swagger/v2/Swagger2Postman.scala: -------------------------------------------------------------------------------- 1 | package com.josephpconley.swagger2postman.models.swagger.v2 2 | 3 | import com.josephpconley.swagger2postman.CollectionArgs 4 | import com.josephpconley.swagger2postman.models.postman._ 5 | import com.josephpconley.swagger2postman.utils.ConversionUtils 6 | 7 | import play.api.libs.json.{JsValue, Json} 8 | 9 | import ConversionUtils._ 10 | 11 | trait Swagger2Postman extends PostmanFormats { 12 | 13 | def toPostman(swaggerDoc: SwaggerDoc, cArgs: CollectionArgs): JsValue = { 14 | 15 | val requests: Seq[(String, PostmanRequest)] = 16 | for { 17 | (path, operations) <- swaggerDoc.paths.toSeq 18 | (method, operation) <- operations.toSeq 19 | } yield { 20 | 21 | val queryParams = operation.parameters.map { params => 22 | params.filter(_.in == "query") match { 23 | case Nil => "" 24 | case list => "?" + list.map(_.name + "=").mkString("&") 25 | } 26 | }.getOrElse("") 27 | 28 | //TODO remove double slash 29 | operation.tags.head -> PostmanRequest( 30 | id = genUUID, 31 | url = s"http://${swaggerDoc.host}${swaggerDoc.basePath}$path$queryParams", 32 | headers = cArgs.headers map (h => s"${h._1}: ${h._2}") mkString "\n", 33 | method = method, 34 | rawModeData = None, 35 | //dataMode = bodyOpt map (_ => "raw") getOrElse "params", 36 | name = operation.operationId, 37 | description = operation.summary + "\r\n" + operation.description.getOrElse(""), 38 | collectionId = cArgs.collectionId 39 | ) 40 | } 41 | 42 | val folders = swaggerDoc.tags map { tag => 43 | PostmanFolder( 44 | id = genUUID, 45 | name = tag.name, 46 | description = tag.description.getOrElse(""), 47 | order = requests filter (_._1 == tag.name) map (_._2.id), 48 | collection_name = cArgs.name, 49 | collection_owner = cArgs.owner, 50 | collection_id = cArgs.collectionId, 51 | collection = cArgs.collectionId, 52 | owner = cArgs.owner 53 | ) 54 | } 55 | 56 | val postmanCollection = PostmanCollection( 57 | id = cArgs.collectionId, 58 | name = cArgs.name, 59 | folders = folders, 60 | owner = cArgs.owner, 61 | requests = requests.map(_._2) 62 | ) 63 | 64 | Json.toJson(postmanCollection) 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/scala/com/josephpconley/swagger2postman/models/swagger/v2/SwaggerDoc.scala: -------------------------------------------------------------------------------- 1 | package com.josephpconley.swagger2postman.models.swagger.v2 2 | 3 | import play.api.libs.json.Json 4 | 5 | case class SwaggerDoc( 6 | swagger: String, 7 | info: SwaggerInfo, 8 | host: String, 9 | basePath: String, 10 | tags: Seq[SwaggerTag], 11 | paths: Map[String, Map[String, SwaggerPath]]) 12 | 13 | object SwaggerDoc { 14 | implicit val paramFmt = Json.format[SwaggerParam] 15 | implicit val pathFmt = Json.format[SwaggerPath] 16 | implicit val tagFmt = Json.format[SwaggerTag] 17 | implicit val infoFmt = Json.format[SwaggerInfo] 18 | implicit val docFmt = Json.format[SwaggerDoc] 19 | } 20 | 21 | case class SwaggerInfo(description: Option[String], version: String, title: String) 22 | 23 | case class SwaggerTag(name: String, description: Option[String]) 24 | 25 | case class SwaggerPath(tags: Seq[String], summary: String, description: Option[String] = None, operationId: String, parameters: Option[Seq[SwaggerParam]] = None) 26 | 27 | case class SwaggerParam(in: String, name: String, description: Option[String], required: Boolean) 28 | -------------------------------------------------------------------------------- /src/main/scala/com/josephpconley/swagger2postman/utils/ConversionUtils.scala: -------------------------------------------------------------------------------- 1 | package com.josephpconley.swagger2postman.utils 2 | 3 | object ConversionUtils { 4 | 5 | def genUUID = java.util.UUID.randomUUID.toString 6 | } 7 | -------------------------------------------------------------------------------- /src/main/scala/com/josephpconley/swagger2postman/utils/HttpEnabled.scala: -------------------------------------------------------------------------------- 1 | package com.josephpconley.swagger2postman.utils 2 | 3 | trait HttpEnabled { 4 | 5 | def execute(url: String): String 6 | } 7 | -------------------------------------------------------------------------------- /v2petstore-swagger.json: -------------------------------------------------------------------------------- 1 | {"swagger":"2.0","info":{"description":"This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.","version":"1.0.0","title":"Swagger Petstore","termsOfService":"http://swagger.io/terms/","contact":{"email":"apiteam@swagger.io"},"license":{"name":"Apache 2.0","url":"http://www.apache.org/licenses/LICENSE-2.0.html"}},"host":"petstore.swagger.io","basePath":"/v2","tags":[{"name":"pet","description":"Everything about your Pets","externalDocs":{"description":"Find out more","url":"http://swagger.io"}},{"name":"store","description":"Access to Petstore orders"},{"name":"user","description":"Operations about user","externalDocs":{"description":"Find out more about our store","url":"http://swagger.io"}}],"schemes":["http"],"paths":{"/pet":{"post":{"tags":["pet"],"summary":"Add a new pet to the store","description":"","operationId":"addPet","consumes":["application/json","application/xml"],"produces":["application/xml","application/json"],"parameters":[{"in":"body","name":"body","description":"Pet object that needs to be added to the store","required":true,"schema":{"$ref":"#/definitions/Pet"}}],"responses":{"405":{"description":"Invalid input"}},"security":[{"petstore_auth":["write:pets","read:pets"]}]},"put":{"tags":["pet"],"summary":"Update an existing pet","description":"","operationId":"updatePet","consumes":["application/json","application/xml"],"produces":["application/xml","application/json"],"parameters":[{"in":"body","name":"body","description":"Pet object that needs to be added to the store","required":true,"schema":{"$ref":"#/definitions/Pet"}}],"responses":{"400":{"description":"Invalid ID supplied"},"404":{"description":"Pet not found"},"405":{"description":"Validation exception"}},"security":[{"petstore_auth":["write:pets","read:pets"]}]}},"/pet/findByStatus":{"get":{"tags":["pet"],"summary":"Finds Pets by status","description":"Multiple status values can be provided with comma separated strings","operationId":"findPetsByStatus","produces":["application/xml","application/json"],"parameters":[{"name":"status","in":"query","description":"Status values that need to be considered for filter","required":true,"type":"array","items":{"type":"string","enum":["available","pending","sold"],"default":"available"},"collectionFormat":"multi"}],"responses":{"200":{"description":"successful operation","schema":{"type":"array","items":{"$ref":"#/definitions/Pet"}}},"400":{"description":"Invalid status value"}},"security":[{"petstore_auth":["write:pets","read:pets"]}]}},"/pet/findByTags":{"get":{"tags":["pet"],"summary":"Finds Pets by tags","description":"Muliple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.","operationId":"findPetsByTags","produces":["application/xml","application/json"],"parameters":[{"name":"tags","in":"query","description":"Tags to filter by","required":true,"type":"array","items":{"type":"string"},"collectionFormat":"multi"}],"responses":{"200":{"description":"successful operation","schema":{"type":"array","items":{"$ref":"#/definitions/Pet"}}},"400":{"description":"Invalid tag value"}},"security":[{"petstore_auth":["write:pets","read:pets"]}],"deprecated":true}},"/pet/{petId}":{"get":{"tags":["pet"],"summary":"Find pet by ID","description":"Returns a single pet","operationId":"getPetById","produces":["application/xml","application/json"],"parameters":[{"name":"petId","in":"path","description":"ID of pet to return","required":true,"type":"integer","format":"int64"}],"responses":{"200":{"description":"successful operation","schema":{"$ref":"#/definitions/Pet"}},"400":{"description":"Invalid ID supplied"},"404":{"description":"Pet not found"}},"security":[{"api_key":[]}]},"post":{"tags":["pet"],"summary":"Updates a pet in the store with form data","description":"","operationId":"updatePetWithForm","consumes":["application/x-www-form-urlencoded"],"produces":["application/xml","application/json"],"parameters":[{"name":"petId","in":"path","description":"ID of pet that needs to be updated","required":true,"type":"integer","format":"int64"},{"name":"name","in":"formData","description":"Updated name of the pet","required":false,"type":"string"},{"name":"status","in":"formData","description":"Updated status of the pet","required":false,"type":"string"}],"responses":{"405":{"description":"Invalid input"}},"security":[{"petstore_auth":["write:pets","read:pets"]}]},"delete":{"tags":["pet"],"summary":"Deletes a pet","description":"","operationId":"deletePet","produces":["application/xml","application/json"],"parameters":[{"name":"api_key","in":"header","required":false,"type":"string"},{"name":"petId","in":"path","description":"Pet id to delete","required":true,"type":"integer","format":"int64"}],"responses":{"400":{"description":"Invalid ID supplied"},"404":{"description":"Pet not found"}},"security":[{"petstore_auth":["write:pets","read:pets"]}]}},"/pet/{petId}/uploadImage":{"post":{"tags":["pet"],"summary":"uploads an image","description":"","operationId":"uploadFile","consumes":["multipart/form-data"],"produces":["application/json"],"parameters":[{"name":"petId","in":"path","description":"ID of pet to update","required":true,"type":"integer","format":"int64"},{"name":"additionalMetadata","in":"formData","description":"Additional data to pass to server","required":false,"type":"string"},{"name":"file","in":"formData","description":"file to upload","required":false,"type":"file"}],"responses":{"200":{"description":"successful operation","schema":{"$ref":"#/definitions/ApiResponse"}}},"security":[{"petstore_auth":["write:pets","read:pets"]}]}},"/store/inventory":{"get":{"tags":["store"],"summary":"Returns pet inventories by status","description":"Returns a map of status codes to quantities","operationId":"getInventory","produces":["application/json"],"parameters":[],"responses":{"200":{"description":"successful operation","schema":{"type":"object","additionalProperties":{"type":"integer","format":"int32"}}}},"security":[{"api_key":[]}]}},"/store/order":{"post":{"tags":["store"],"summary":"Place an order for a pet","description":"","operationId":"placeOrder","produces":["application/xml","application/json"],"parameters":[{"in":"body","name":"body","description":"order placed for purchasing the pet","required":true,"schema":{"$ref":"#/definitions/Order"}}],"responses":{"200":{"description":"successful operation","schema":{"$ref":"#/definitions/Order"}},"400":{"description":"Invalid Order"}}}},"/store/order/{orderId}":{"get":{"tags":["store"],"summary":"Find purchase order by ID","description":"For valid response try integer IDs with value >= 1 and <= 10. Other values will generated exceptions","operationId":"getOrderById","produces":["application/xml","application/json"],"parameters":[{"name":"orderId","in":"path","description":"ID of pet that needs to be fetched","required":true,"type":"integer","maximum":10.0,"minimum":1.0,"format":"int64"}],"responses":{"200":{"description":"successful operation","schema":{"$ref":"#/definitions/Order"}},"400":{"description":"Invalid ID supplied"},"404":{"description":"Order not found"}}},"delete":{"tags":["store"],"summary":"Delete purchase order by ID","description":"For valid response try integer IDs with positive integer value. Negative or non-integer values will generate API errors","operationId":"deleteOrder","produces":["application/xml","application/json"],"parameters":[{"name":"orderId","in":"path","description":"ID of the order that needs to be deleted","required":true,"type":"integer","minimum":1.0,"format":"int64"}],"responses":{"400":{"description":"Invalid ID supplied"},"404":{"description":"Order not found"}}}},"/user":{"post":{"tags":["user"],"summary":"Create user","description":"This can only be done by the logged in user.","operationId":"createUser","produces":["application/xml","application/json"],"parameters":[{"in":"body","name":"body","description":"Created user object","required":true,"schema":{"$ref":"#/definitions/User"}}],"responses":{"default":{"description":"successful operation"}}}},"/user/createWithArray":{"post":{"tags":["user"],"summary":"Creates list of users with given input array","description":"","operationId":"createUsersWithArrayInput","produces":["application/xml","application/json"],"parameters":[{"in":"body","name":"body","description":"List of user object","required":true,"schema":{"type":"array","items":{"$ref":"#/definitions/User"}}}],"responses":{"default":{"description":"successful operation"}}}},"/user/createWithList":{"post":{"tags":["user"],"summary":"Creates list of users with given input array","description":"","operationId":"createUsersWithListInput","produces":["application/xml","application/json"],"parameters":[{"in":"body","name":"body","description":"List of user object","required":true,"schema":{"type":"array","items":{"$ref":"#/definitions/User"}}}],"responses":{"default":{"description":"successful operation"}}}},"/user/login":{"get":{"tags":["user"],"summary":"Logs user into the system","description":"","operationId":"loginUser","produces":["application/xml","application/json"],"parameters":[{"name":"username","in":"query","description":"The user name for login","required":true,"type":"string"},{"name":"password","in":"query","description":"The password for login in clear text","required":true,"type":"string"}],"responses":{"200":{"description":"successful operation","schema":{"type":"string"},"headers":{"X-Rate-Limit":{"type":"integer","format":"int32","description":"calls per hour allowed by the user"},"X-Expires-After":{"type":"string","format":"date-time","description":"date in UTC when token expires"}}},"400":{"description":"Invalid username/password supplied"}}}},"/user/logout":{"get":{"tags":["user"],"summary":"Logs out current logged in user session","description":"","operationId":"logoutUser","produces":["application/xml","application/json"],"parameters":[],"responses":{"default":{"description":"successful operation"}}}},"/user/{username}":{"get":{"tags":["user"],"summary":"Get user by user name","description":"","operationId":"getUserByName","produces":["application/xml","application/json"],"parameters":[{"name":"username","in":"path","description":"The name that needs to be fetched. Use user1 for testing. ","required":true,"type":"string"}],"responses":{"200":{"description":"successful operation","schema":{"$ref":"#/definitions/User"}},"400":{"description":"Invalid username supplied"},"404":{"description":"User not found"}}},"put":{"tags":["user"],"summary":"Updated user","description":"This can only be done by the logged in user.","operationId":"updateUser","produces":["application/xml","application/json"],"parameters":[{"name":"username","in":"path","description":"name that need to be updated","required":true,"type":"string"},{"in":"body","name":"body","description":"Updated user object","required":true,"schema":{"$ref":"#/definitions/User"}}],"responses":{"400":{"description":"Invalid user supplied"},"404":{"description":"User not found"}}},"delete":{"tags":["user"],"summary":"Delete user","description":"This can only be done by the logged in user.","operationId":"deleteUser","produces":["application/xml","application/json"],"parameters":[{"name":"username","in":"path","description":"The name that needs to be deleted","required":true,"type":"string"}],"responses":{"400":{"description":"Invalid username supplied"},"404":{"description":"User not found"}}}}},"securityDefinitions":{"petstore_auth":{"type":"oauth2","authorizationUrl":"http://petstore.swagger.io/oauth/dialog","flow":"implicit","scopes":{"write:pets":"modify pets in your account","read:pets":"read your pets"}},"api_key":{"type":"apiKey","name":"api_key","in":"header"}},"definitions":{"Order":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"petId":{"type":"integer","format":"int64"},"quantity":{"type":"integer","format":"int32"},"shipDate":{"type":"string","format":"date-time"},"status":{"type":"string","description":"Order Status","enum":["placed","approved","delivered"]},"complete":{"type":"boolean","default":false}},"xml":{"name":"Order"}},"Category":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"}},"xml":{"name":"Category"}},"User":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"username":{"type":"string"},"firstName":{"type":"string"},"lastName":{"type":"string"},"email":{"type":"string"},"password":{"type":"string"},"phone":{"type":"string"},"userStatus":{"type":"integer","format":"int32","description":"User Status"}},"xml":{"name":"User"}},"Tag":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"}},"xml":{"name":"Tag"}},"Pet":{"type":"object","required":["name","photoUrls"],"properties":{"id":{"type":"integer","format":"int64"},"category":{"$ref":"#/definitions/Category"},"name":{"type":"string","example":"doggie"},"photoUrls":{"type":"array","xml":{"name":"photoUrl","wrapped":true},"items":{"type":"string"}},"tags":{"type":"array","xml":{"name":"tag","wrapped":true},"items":{"$ref":"#/definitions/Tag"}},"status":{"type":"string","description":"pet status in the store","enum":["available","pending","sold"]}},"xml":{"name":"Pet"}},"ApiResponse":{"type":"object","properties":{"code":{"type":"integer","format":"int32"},"type":{"type":"string"},"message":{"type":"string"}}}},"externalDocs":{"description":"Find out more about Swagger","url":"http://swagger.io"}} 2 | --------------------------------------------------------------------------------