BlueJeans ApiException:415 "Unsupported Media Type"
BlueJeans ApiException: 415 "Unsupported Media Type"
我正在尝试使用 BlueJeans API 按照 https://github.com/bluejeans/api-rest-meetings/blob/master/libs/python/docs/ApplicationApi.md#create_client_application 中的示例创建客户端应用程序。我已经获得了客户端 ID 和密码以及用户 ID,并将它们保存在我的 Django 设置中。我还编写了一个函数来获取访问令牌:
import json
from urllib.parse import urljoin
import requests
import logging
import BlueJeansMeetingsRestApi
from django.conf import settings
from rest_framework import status
logger = logging.getLogger(__name__)
class ConferenceScheduler(object):
BASE_URL = 'https://api.bluejeans.com'
@staticmethod
def get_token():
# Obtain an access token to initiate a session with BlueJeans
# (We use the Client Grant Type which grants us enterprise-level access)
response = requests.post(
url=urljoin(base=ConferenceScheduler.BASE_URL, url='/oauth2/token'),
json={
'grant_type': 'client_credentials',
'client_id': settings.BLUEJEANS_KEY,
'client_secret': settings.BLUEJEANS_SECRET})
if response.status_code == status.HTTP_200_OK:
return json.loads(response.content).get('access_token')
else:
logger.error(f"A request for a BlueJeans access token returned a non-200 response.\n"
f"Status code: {response.status_code}\n"
f"Reason: {response.reason}")
在 Django shell 中继续,我尝试按照示例中的步骤操作,但我得到了 ApiException
:
In [1]: from lucy_web.lib.conferencing import *
In [2]: BlueJeansMeetingsRestApi.configuration.api_key['access_token'] = ConferenceSch
...: eduler.get_token()
In [3]: api_instance = BlueJeansMeetingsRestApi.ApplicationApi()
In [4]: user_id = settings.BLUEJEANS_USER_ID
In [6]: application = BlueJeansMeetingsRestApi.Application()
In [7]: api_response = api_instance.create_client_application(user_id, application)
---------------------------------------------------------------------------
ApiException Traceback (most recent call last)
<ipython-input-7-1bf90ba9e2a8> in <module>()
----> 1 api_response = api_instance.create_client_application(user_id, application)
~/.local/share/virtualenvs/lucy-web-CVxkrCFK/lib/python3.6/site-packages/BlueJeansMeetingsRestApi/apis/application_api.py in create_client_application(self, user_id, application, **kwargs)
65 return self.create_client_application_with_http_info(user_id, application, **kwargs)
66 else:
---> 67 (data) = self.create_client_application_with_http_info(user_id, application, **kwargs)
68 return data
69
~/.local/share/virtualenvs/lucy-web-CVxkrCFK/lib/python3.6/site-packages/BlueJeansMeetingsRestApi/apis/application_api.py in create_client_application_with_http_info(self, user_id, application, **kwargs)
148 _preload_content=params.get('_preload_content', True),
149 _request_timeout=params.get('_request_timeout'),
--> 150 collection_formats=collection_formats)
151
152 def regenerate_client_application_secret(self, user_id, client_id, **kwargs):
~/.local/share/virtualenvs/lucy-web-CVxkrCFK/lib/python3.6/site-packages/BlueJeansMeetingsRestApi/api_client.py in call_api(self, resource_path, method, path_params, query_params, header_params, body, post_params, files, response_type, auth_settings, callback, _return_http_data_only, collection_formats, _preload_content, _request_timeout)
324 body, post_params, files,
325 response_type, auth_settings, callback,
--> 326 _return_http_data_only, collection_formats, _preload_content, _request_timeout)
327 else:
328 thread = threading.Thread(target=self.__call_api,
~/.local/share/virtualenvs/lucy-web-CVxkrCFK/lib/python3.6/site-packages/BlueJeansMeetingsRestApi/api_client.py in __call_api(self, resource_path, method, path_params, query_params, header_params, body, post_params, files, response_type, auth_settings, callback, _return_http_data_only, collection_formats, _preload_content, _request_timeout)
151 post_params=post_params, body=body,
152 _preload_content=_preload_content,
--> 153 _request_timeout=_request_timeout)
154
155 self.last_response = response_data
~/.local/share/virtualenvs/lucy-web-CVxkrCFK/lib/python3.6/site-packages/BlueJeansMeetingsRestApi/api_client.py in request(self, method, url, query_params, headers, post_params, body, _preload_content, _request_timeout)
369 _preload_content=_preload_content,
370 _request_timeout=_request_timeout,
--> 371 body=body)
372 elif method == "PUT":
373 return self.rest_client.PUT(url,
~/.local/share/virtualenvs/lucy-web-CVxkrCFK/lib/python3.6/site-packages/BlueJeansMeetingsRestApi/rest.py in POST(self, url, headers, query_params, post_params, body, _preload_content, _request_timeout)
261 _preload_content=_preload_content,
262 _request_timeout=_request_timeout,
--> 263 body=body)
264
265 def PUT(self, url, headers=None, query_params=None, post_params=None, body=None, _preload_content=True,
~/.local/share/virtualenvs/lucy-web-CVxkrCFK/lib/python3.6/site-packages/BlueJeansMeetingsRestApi/rest.py in request(self, method, url, query_params, headers, body, post_params, _preload_content, _request_timeout)
217
218 if not 200 <= r.status <= 299:
--> 219 raise ApiException(http_resp=r)
220
221 return r
ApiException: (415)
Reason: Unsupported Media Type
HTTP response headers: HTTPHeaderDict({'Server': 'BlueJeans Proxy', 'Date': 'Fri, 06 Jul 2018 22:17:24 GMT', 'X-NewRelic-App-Data': 'PxQAV1ZaABADUVZbBAACU0YdFGQHBDcQUQxLA1tMXV1dORYyVBNFDgFCa04tBkFoRB0RBwpSWAtKU1pGBwwGA14RFhFdSkJbUABKT10IVQcHT1QNA010WlYBAhtUXVIlC19CUgsIBhAcQlkMVldAU0cMVg8MOl0NClNqPERPCB0ASFFMBwMBU1UCAAZRSlNOEgYLWgAAVwMEXQoAUlUCAVAUag==', 'X-Trace-Token': 'sj1-prod-cobalt-03-158215204', 'Content-Type': 'application/json; charset=UTF-8', 'Content-Length': '47'})
HTTP response body: {"code":415,"message":"Unsupported Media Type"}
我对这里可能出现的问题感到困惑,因为 user_id
在文档中被指定为整数。如何从该端点获得有效响应?
更新
我还尝试使用 header 发出 'ordinary' 请求,其中包含 python request with authentication (access_token) 中所述的访问令牌。但是,在这种情况下,我得到了 401
(Unauthorized) 响应:
In [9]: BASE_URL = ConferenceScheduler.BASE_URL
In [10]: BASE_URL
Out[10]: 'https://api.bluejeans.com'
In [11]: url = urljoin(BASE_URL, f'/v1/user/{settings.BLUEJEANS_USER_ID}')
In [13]: session = requests.Session()
In [14]: token = ConferenceScheduler.get_token()
In [15]: session.headers.update({'Authorization': f'access_token {token}'})
In [16]: response = session.get(url)
In [17]: response.status_code
Out[17]: 401
In [19]: response.reason
Out[19]: 'Unauthorized'
我的令牌仍然有效,正如此 API 调用所检查的那样:
In [22]: response = requests.get(urljoin(BASE_URL, '/oauth2/tokenInfo'), params={'access_token': token}
...: )
In [23]: response.status_code
Out[23]: 200
所以另一个问题是:我如何使用 requests
而不是 BlueJeansMeetingsRestApi
来发出请求?
BlueJeans API 是使用 Swagger 代码生成项目构建的,我通过填写有效负载中的字段(描述、名称、应用徽标 URL 和重定向 URL).
通常,当您省略 http header: Content-Type: application/json[=10= 时,您会收到 415 Unsupported Media Type 错误]
添加这个,那个错误就会消失
我正在尝试使用 BlueJeans API 按照 https://github.com/bluejeans/api-rest-meetings/blob/master/libs/python/docs/ApplicationApi.md#create_client_application 中的示例创建客户端应用程序。我已经获得了客户端 ID 和密码以及用户 ID,并将它们保存在我的 Django 设置中。我还编写了一个函数来获取访问令牌:
import json
from urllib.parse import urljoin
import requests
import logging
import BlueJeansMeetingsRestApi
from django.conf import settings
from rest_framework import status
logger = logging.getLogger(__name__)
class ConferenceScheduler(object):
BASE_URL = 'https://api.bluejeans.com'
@staticmethod
def get_token():
# Obtain an access token to initiate a session with BlueJeans
# (We use the Client Grant Type which grants us enterprise-level access)
response = requests.post(
url=urljoin(base=ConferenceScheduler.BASE_URL, url='/oauth2/token'),
json={
'grant_type': 'client_credentials',
'client_id': settings.BLUEJEANS_KEY,
'client_secret': settings.BLUEJEANS_SECRET})
if response.status_code == status.HTTP_200_OK:
return json.loads(response.content).get('access_token')
else:
logger.error(f"A request for a BlueJeans access token returned a non-200 response.\n"
f"Status code: {response.status_code}\n"
f"Reason: {response.reason}")
在 Django shell 中继续,我尝试按照示例中的步骤操作,但我得到了 ApiException
:
In [1]: from lucy_web.lib.conferencing import *
In [2]: BlueJeansMeetingsRestApi.configuration.api_key['access_token'] = ConferenceSch
...: eduler.get_token()
In [3]: api_instance = BlueJeansMeetingsRestApi.ApplicationApi()
In [4]: user_id = settings.BLUEJEANS_USER_ID
In [6]: application = BlueJeansMeetingsRestApi.Application()
In [7]: api_response = api_instance.create_client_application(user_id, application)
---------------------------------------------------------------------------
ApiException Traceback (most recent call last)
<ipython-input-7-1bf90ba9e2a8> in <module>()
----> 1 api_response = api_instance.create_client_application(user_id, application)
~/.local/share/virtualenvs/lucy-web-CVxkrCFK/lib/python3.6/site-packages/BlueJeansMeetingsRestApi/apis/application_api.py in create_client_application(self, user_id, application, **kwargs)
65 return self.create_client_application_with_http_info(user_id, application, **kwargs)
66 else:
---> 67 (data) = self.create_client_application_with_http_info(user_id, application, **kwargs)
68 return data
69
~/.local/share/virtualenvs/lucy-web-CVxkrCFK/lib/python3.6/site-packages/BlueJeansMeetingsRestApi/apis/application_api.py in create_client_application_with_http_info(self, user_id, application, **kwargs)
148 _preload_content=params.get('_preload_content', True),
149 _request_timeout=params.get('_request_timeout'),
--> 150 collection_formats=collection_formats)
151
152 def regenerate_client_application_secret(self, user_id, client_id, **kwargs):
~/.local/share/virtualenvs/lucy-web-CVxkrCFK/lib/python3.6/site-packages/BlueJeansMeetingsRestApi/api_client.py in call_api(self, resource_path, method, path_params, query_params, header_params, body, post_params, files, response_type, auth_settings, callback, _return_http_data_only, collection_formats, _preload_content, _request_timeout)
324 body, post_params, files,
325 response_type, auth_settings, callback,
--> 326 _return_http_data_only, collection_formats, _preload_content, _request_timeout)
327 else:
328 thread = threading.Thread(target=self.__call_api,
~/.local/share/virtualenvs/lucy-web-CVxkrCFK/lib/python3.6/site-packages/BlueJeansMeetingsRestApi/api_client.py in __call_api(self, resource_path, method, path_params, query_params, header_params, body, post_params, files, response_type, auth_settings, callback, _return_http_data_only, collection_formats, _preload_content, _request_timeout)
151 post_params=post_params, body=body,
152 _preload_content=_preload_content,
--> 153 _request_timeout=_request_timeout)
154
155 self.last_response = response_data
~/.local/share/virtualenvs/lucy-web-CVxkrCFK/lib/python3.6/site-packages/BlueJeansMeetingsRestApi/api_client.py in request(self, method, url, query_params, headers, post_params, body, _preload_content, _request_timeout)
369 _preload_content=_preload_content,
370 _request_timeout=_request_timeout,
--> 371 body=body)
372 elif method == "PUT":
373 return self.rest_client.PUT(url,
~/.local/share/virtualenvs/lucy-web-CVxkrCFK/lib/python3.6/site-packages/BlueJeansMeetingsRestApi/rest.py in POST(self, url, headers, query_params, post_params, body, _preload_content, _request_timeout)
261 _preload_content=_preload_content,
262 _request_timeout=_request_timeout,
--> 263 body=body)
264
265 def PUT(self, url, headers=None, query_params=None, post_params=None, body=None, _preload_content=True,
~/.local/share/virtualenvs/lucy-web-CVxkrCFK/lib/python3.6/site-packages/BlueJeansMeetingsRestApi/rest.py in request(self, method, url, query_params, headers, body, post_params, _preload_content, _request_timeout)
217
218 if not 200 <= r.status <= 299:
--> 219 raise ApiException(http_resp=r)
220
221 return r
ApiException: (415)
Reason: Unsupported Media Type
HTTP response headers: HTTPHeaderDict({'Server': 'BlueJeans Proxy', 'Date': 'Fri, 06 Jul 2018 22:17:24 GMT', 'X-NewRelic-App-Data': 'PxQAV1ZaABADUVZbBAACU0YdFGQHBDcQUQxLA1tMXV1dORYyVBNFDgFCa04tBkFoRB0RBwpSWAtKU1pGBwwGA14RFhFdSkJbUABKT10IVQcHT1QNA010WlYBAhtUXVIlC19CUgsIBhAcQlkMVldAU0cMVg8MOl0NClNqPERPCB0ASFFMBwMBU1UCAAZRSlNOEgYLWgAAVwMEXQoAUlUCAVAUag==', 'X-Trace-Token': 'sj1-prod-cobalt-03-158215204', 'Content-Type': 'application/json; charset=UTF-8', 'Content-Length': '47'})
HTTP response body: {"code":415,"message":"Unsupported Media Type"}
我对这里可能出现的问题感到困惑,因为 user_id
在文档中被指定为整数。如何从该端点获得有效响应?
更新
我还尝试使用 header 发出 'ordinary' 请求,其中包含 python request with authentication (access_token) 中所述的访问令牌。但是,在这种情况下,我得到了 401
(Unauthorized) 响应:
In [9]: BASE_URL = ConferenceScheduler.BASE_URL
In [10]: BASE_URL
Out[10]: 'https://api.bluejeans.com'
In [11]: url = urljoin(BASE_URL, f'/v1/user/{settings.BLUEJEANS_USER_ID}')
In [13]: session = requests.Session()
In [14]: token = ConferenceScheduler.get_token()
In [15]: session.headers.update({'Authorization': f'access_token {token}'})
In [16]: response = session.get(url)
In [17]: response.status_code
Out[17]: 401
In [19]: response.reason
Out[19]: 'Unauthorized'
我的令牌仍然有效,正如此 API 调用所检查的那样:
In [22]: response = requests.get(urljoin(BASE_URL, '/oauth2/tokenInfo'), params={'access_token': token}
...: )
In [23]: response.status_code
Out[23]: 200
所以另一个问题是:我如何使用 requests
而不是 BlueJeansMeetingsRestApi
来发出请求?
BlueJeans API 是使用 Swagger 代码生成项目构建的,我通过填写有效负载中的字段(描述、名称、应用徽标 URL 和重定向 URL).
通常,当您省略 http header: Content-Type: application/json[=10= 时,您会收到 415 Unsupported Media Type 错误]
添加这个,那个错误就会消失