OLD | NEW |
(Empty) | |
| 1 # Copyright 2016 Google Inc. All Rights Reserved. |
| 2 # |
| 3 # Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 # you may not use this file except in compliance with the License. |
| 5 # You may obtain a copy of the License at |
| 6 # |
| 7 # http://www.apache.org/licenses/LICENSE-2.0 |
| 8 # |
| 9 # Unless required by applicable law or agreed to in writing, software |
| 10 # distributed under the License is distributed on an "AS IS" BASIS, |
| 11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 # See the License for the specific language governing permissions and |
| 13 # limitations under the License. |
| 14 |
| 15 """Proxy that dispatches Discovery requests to the Discovery service.""" |
| 16 |
| 17 # pylint: disable=g-bad-name |
| 18 import httplib |
| 19 import json |
| 20 import logging |
| 21 |
| 22 |
| 23 class DiscoveryApiProxy(object): |
| 24 """Proxies discovery service requests to a known cloud endpoint.""" |
| 25 |
| 26 # The endpoint host we're using to proxy discovery and static requests. |
| 27 # Using separate constants to make it easier to change the discovery service. |
| 28 _DISCOVERY_PROXY_HOST = 'webapis-discovery.appspot.com' |
| 29 _STATIC_PROXY_HOST = 'webapis-discovery.appspot.com' |
| 30 _DISCOVERY_API_PATH_PREFIX = '/_ah/api/discovery/v1/' |
| 31 |
| 32 def _dispatch_request(self, path, body): |
| 33 """Proxies GET request to discovery service API. |
| 34 |
| 35 Args: |
| 36 path: A string containing the URL path relative to discovery service. |
| 37 body: A string containing the HTTP POST request body. |
| 38 |
| 39 Returns: |
| 40 HTTP response body or None if it failed. |
| 41 """ |
| 42 full_path = self._DISCOVERY_API_PATH_PREFIX + path |
| 43 headers = {'Content-type': 'application/json'} |
| 44 connection = httplib.HTTPSConnection(self._DISCOVERY_PROXY_HOST) |
| 45 try: |
| 46 connection.request('POST', full_path, body, headers) |
| 47 response = connection.getresponse() |
| 48 response_body = response.read() |
| 49 if response.status != 200: |
| 50 logging.error('Discovery API proxy failed on %s with %d.\r\n' |
| 51 'Request: %s\r\nResponse: %s', |
| 52 full_path, response.status, body, response_body) |
| 53 return None |
| 54 return response_body |
| 55 finally: |
| 56 connection.close() |
| 57 |
| 58 def generate_discovery_doc(self, api_config, api_format): |
| 59 """Generates a discovery document from an API file. |
| 60 |
| 61 Args: |
| 62 api_config: A string containing the .api file contents. |
| 63 api_format: A string, either 'rest' or 'rpc' depending on the which kind |
| 64 of discvoery doc is requested. |
| 65 |
| 66 Returns: |
| 67 The discovery doc as JSON string. |
| 68 |
| 69 Raises: |
| 70 ValueError: When api_format is invalid. |
| 71 """ |
| 72 if api_format not in ['rest', 'rpc']: |
| 73 raise ValueError('Invalid API format') |
| 74 path = 'apis/generate/' + api_format |
| 75 request_dict = {'config': json.dumps(api_config)} |
| 76 request_body = json.dumps(request_dict) |
| 77 return self._dispatch_request(path, request_body) |
| 78 |
| 79 def generate_directory(self, api_configs): |
| 80 """Generates an API directory from a list of API files. |
| 81 |
| 82 Args: |
| 83 api_configs: A list of strings which are the .api file contents. |
| 84 |
| 85 Returns: |
| 86 The API directory as JSON string. |
| 87 """ |
| 88 request_dict = {'configs': api_configs} |
| 89 request_body = json.dumps(request_dict) |
| 90 return self._dispatch_request('apis/generate/directory', request_body) |
| 91 |
| 92 def get_static_file(self, path): |
| 93 """Returns static content via a GET request. |
| 94 |
| 95 Args: |
| 96 path: A string containing the URL path after the domain. |
| 97 |
| 98 Returns: |
| 99 A tuple of (response, response_body): |
| 100 response: A HTTPResponse object with the response from the static |
| 101 proxy host. |
| 102 response_body: A string containing the response body. |
| 103 """ |
| 104 connection = httplib.HTTPSConnection(self._STATIC_PROXY_HOST) |
| 105 try: |
| 106 connection.request('GET', path, None, {}) |
| 107 response = connection.getresponse() |
| 108 response_body = response.read() |
| 109 finally: |
| 110 connection.close() |
| 111 return response, response_body |
OLD | NEW |