首页 文章

在python中使用swagger codegen客户端向api调用添加标头的细节尚不清楚

提问于
浏览
5

指出正确的文档,教程,示例或提供一个,显示如何将特定的身份验证令牌添加到Python中Swagger生成的API客户端中的特定标头?

在这里's what I'尝试过:
使用正确的curl命令,我的API调用可以正常工作:

curl -v -H 'X-CAG-Authorization: AG_CONSUMER_TOKEN access-key=31337-70k3n' \
     'https://api.company.net/api/v1/user/detail?user=1'

*   Trying 10.10.1.10...
* Connected to api.company.net (10.10.1.10) port 443 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
* Server certificate: *.company.net
* Server certificate: COMODO RSA Organization Validation Secure Server CA
* Server certificate: COMODO RSA Certification Authority
> GET /api/v1/user/detail?user=1 HTTP/1.1
> Host: api.company.net
> User-Agent: curl/7.49.1
> Accept: */*
> X-CAG-Authorization: AG_CONSUMER_TOKEN access-key=31337-70k3n
> 
< HTTP/1.1 200 OK
< Server: openresty
< Date: Thu, 22 Dec 2016 19:46:05 GMT
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
< Connection: close
< Vary: Accept-Encoding
< Vary: Accept-Encoding
< X-UA-Compatible: IE=edge
< 
{"successful":true,"message":"SUCCESS","body":{"…

但是,当我在我的Python(2.7.12)客户端中尝试相同的基本请求时,我获得了授权失败,尽管确认该令牌使其成为即将使用的标头 . 有关正确使用客户端的方法或如何获取确切请求和响应的更多详细信息的更多详细信息将不胜感激 .

/Users/me/VEnvs/sku-grade/bin/python /Users/me/prj/code/python_client/api_example.py
HEADERS:
{'X-CAG-Authorization': 'AG_CONSUMER_TOKEN access-key=31337-70k3n', 'User-Agent': 'Swagger-Codegen/1.0.0/python'}
Exception when calling SupplierApi->get_api_v1_user_details: (401)
Reason: Unauthorized
HTTP response headers: HTTPHeaderDict({'Date': 'Thu, 22 Dec 2016 21:09:30 GMT', 'Content-Length': '636', 'Content-Type': 'application/json; charset=UTF-8', 'Connection': 'keep-alive', 'Server': 'nginx'})
HTTP response body: {
  "code" : "PRECONDITION_FAILED",
  "type" : "UnauthorizedApiDeniedException",
  "message" : "Target API(/api/v1/user/details) is not available, you have to get a grant in advance.",
  "messages" : {…

这是一个招摇的api规范: swagger.yaml

---
swagger: "2.0"
info:
  description: "API"
  version: "TEMPORARY"
  title: "User Details"
  termsOfService: "http://wiki.company.net/tos"
  contact:
    name: "…"
  license:
    name: "…"
host: "api.company.net"
basePath: "/api/v1"
tags:
- name: "supplier"
  description: "Supplier"
schemes:
- "https"
produces:
- "application/json"
paths:
  /user/details:
    get:
      tags:
      - "supplier"
      summary: "userDetails"
      operationId: "getApiV1UserDetails"
      consumes:
      - "application/json"
      produces:
      - "application/json;charset=utf-8"
      parameters:
      - name: "user"
        in: "query"
        description: "user id"
        required: true
        type: "integer"
        format: "Long"
      responses:
        200:
          description: "OK"
          schema:
            $ref: "#/definitions/SupplierResponseOfUserDetailsDto"
        401:
          description: "Unauthorized"
        403:
          description: "Forbidden"
        404:
          description: "Not Found"
definitions:
  SupplierResponseOfUserDetailsDto:
    type: "object"
    properties:
      body:
        $ref: "#/definitions/UserDetailsDto"
      message:
        type: "string"
      successful:
        type: "boolean"
  UserDetailsDto:
    type: "object"
    properties:
      name:
        type: "string"

swagger-codegen是从http://editor.swagger.io/运行的,我按照api示例尝试添加额外的 Headers : api_example.py

from __future__ import print_function
import time
import swagger_client
from swagger_client import ApiClient
from swagger_client import Configuration
from swagger_client.rest import ApiException
from pprint import pprint

# Setup the authentication token header
conf = Configuration()
conf.api_key_prefix = {"teamname": "AG_CONSUMER_TOKEN"}
conf.api_key = {
    "teamname": "access-key=31337-70k3n"
}
conf.api_client = ApiClient(None, "X-CAG-Authorization",
                            conf.get_api_key_with_prefix("teamname"))

# create an instance of the API class
api_instance = swagger_client.SupplierApi()
user = 1
try:
    api_response = api_instance.get_api_v1_user_details(user)
    pprint(api_response)
except ApiException as e:
    print("Exception when calling "
          "SupplierApi->get_api_v1_user_details: %s\n" % e)

通过将 print(self.api_client.default_headers) 放入 supplier_api.py ,我可以看到 Headers 似乎已设置 .

{'X-CAG-Authorization': 'AG_CONSUMER_TOKEN access-key=31337-70k3n', 'User-Agent': 'Swagger-Codegen/1.0.0/python'}

那么我的例子又应该改变一下,让它传递 Headers 并获得完全符合简单卷曲调用的方式?

更新我也试过定义它:

security:
      - api_key: []
securityDefinitions:
  api_key:
    type: "apiKey"
    name: "X-CAG-Authorization"
    in: "header"

然后只设置密钥:

swagger_client.configuration.api_key['X-CAG-Authorization'] = \
    'access-key=31337-70k3n'
swagger_client.configuration.api_key_prefix['X-CAG-Authorization'] = \
    'AG_CONSUMER_TOKEN'

但是除了 Headers 从我正在打印的默认 Headers 中消失之外,这并没有太大变化 .

2 回答

  • 2

    我已经尝试过您的代码示例,看起来您的 Headers 实际上已传递给服务器 .

    您可以通过将 print headers 添加到 swagger_client/rest.py 文件来确认这一点,就在此之前:

    r = self.pool_manager.request(method, url,
                                  fields=query_params,
                                  preload_content=_preload_content,
                                  timeout=timeout,
                                  headers=headers)
    

    你确定服务器端没有问题吗?也许有些 Headers 打破了身份验证?

    以下curl命令是否也有效?

    curl -v \
     -H 'X-CAG-Authorization: AG_CONSUMER_TOKEN access-key=31337-70k3n' \
     -H 'Content-Type: application/json' \
     -H 'Accept: application/json;charset=utf-8' \
     -H 'User-Agent: Swagger-Codegen/1.0.0/python' \
     'https://api.company.net/api/v1/user/detail?user=1'
    

    因为这应该给你完全相同的答案,返回到swagger,这是401错误 . 如果是,您可以从服务器端进行调试 . 如果没有,我不知道 .

  • 2

    在您的规范中,您需要描述安全设置(在您的情况下为API密钥),类似于OpenAPI / Swagger规范的 securityDefinitions 部分中定义的example .

    然后在 endpoints 中,您将需要"apply"类似于此example的安全定义

    之后,您可以在自动生成的Python API客户端的configuration.py中设置API密钥,HTTP请求将相应地包含API密钥(在规范的安全设置中定义的标头或URL查询字符串中)

    自Swagger Codegen最后一次稳定发布以来,对自动生成的Python API客户端进行了大量增强,因此我建议您拉出最新的master并在本地构建JAR以生成API客户端 .

相关问题