Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CTOOLS-348: allow timeout and rate limit retry configuration #37

Merged
merged 1 commit into from
Sep 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions generate/config-template.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@
},
"extensions/file_access_token.mustache": {
"destinationFilename": "${PACKAGE_NAME}/extensions/file_access_token.py"
},
"extensions/configuration_options.mustache": {
"destinationFilename": "${PACKAGE_NAME}/extensions/configuration_options.py"
}
}
}
33 changes: 32 additions & 1 deletion generate/templates/README.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,9 @@ import {{{packageName}}}

## Getting Started

You'll need to provide some configuration to connect to the {{appName}} - see the articles about [short-lived access tokens](https://support.lusid.com/knowledgebase/article/KA-01654) and a [long-lived Personal Access Token](https://support.lusid.com/knowledgebase/article/KA-01774). This configuration can be provided using a secrets file or environment variables.
You'll need to provide some configuration to connect to the {{appName}} - see the articles about [short-lived access tokens](https://support.lusid.com/knowledgebase/article/KA-01654) and a [long-lived Personal Access Token](https://support.lusid.com/knowledgebase/article/KA-01774). This configuration can be provided using a secrets file or environment variables.

For some configuration it is also possible to override the global configuration at the ApiClientFactory level, or at the request level. For the set of configuration which can be overridden, please see [ConfigurationOptions](sdk/{{packageName}}/extensions/configuration_options.py). For a code illustration of this configuration being overridden, please see the [example](#example).

### Environment variables

Expand All @@ -78,6 +80,18 @@ FBN_ACCESS_TOKEN

You can send your requests to the {{appName}} via a proxy, by setting `FBN_PROXY_ADDRESS`. If your proxy has basic auth enabled, you must also set `FBN_PROXY_USERNAME` and `FBN_PROXY_PASSWORD`.

Other optional configuration

```bash
# sdk client timeouts in milliseconds - a value of 0 means no timeout, otherwise timeout values must be a positive integer
# please note - the chances of seeing a network issue increase with the duration of the request
# for this reason, rather than increasing the timeout, it will be more reliable to use an alternate polling style endpoint where these exist
FBN_TOTAL_TIMEOUT_MS # the default is 1800000 (30 minutes)
FBN_CONNECT_TIMEOUT_MS # the default is 0 (no timeout)
FBN_READ_TIMEOUT_MS # the default is 0 (no timeout)
FBN_RATE_LIMIT_RETRIES # the default is 2
```

### Secrets file

The secrets file must be in the current working directory.
Expand Down Expand Up @@ -126,6 +140,23 @@ You can send your requests to the {{appName}} via a proxy, by adding a proxy sec
}
```

Other optional configuration

```javascript
{
"api":
{
// sdk client timeouts in milliseconds - a value of 0 means no timeout, otherwise timeout values must be a positive integer
// please note - the chances of seeing a network issue increase with the duration of the request
// for this reason, rather than increasing the timeout, it will be more reliable to use an alternate polling style endpoint where these exist
"totalTimeoutMs":<timeout-in-ms>, // the default is 1800000 (30 minutes)
"connectTimeoutMs":<timeout-in-ms>, // the default is 0 (no timeout)
"readTimeoutMs":<timeout-in-ms>, // the default is 0 (no timeout)
"rateLimitRetries":<retries-when-being-rate-limited> // the default is 2
}
}
```

{{#apiInfo}}{{#apis}}{{#-first}}{{#operations}}{{#operation}}{{#-first}}### Example
{{> example}}
{{/-first}}{{/operation}}{{/operations}}{{/-first}}{{/apis}}{{/apiInfo}}
Expand Down
19 changes: 10 additions & 9 deletions generate/templates/api.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ from {{packageName}}.exceptions import ( # noqa: F401
ApiTypeError,
ApiValueError
)
from {{packageName}}.extensions.configuration_options import ConfigurationOptions


{{#operations}}
Expand Down Expand Up @@ -66,10 +67,9 @@ class {{classname}}:
{{/allParams}}
:param async_req: Whether to execute the request asynchronously.
:type async_req: bool, optional
:param _request_timeout: timeout setting for this request.
If one number provided, it will be total request
timeout. It can also be a pair (tuple) of
(connection, read) timeouts.
:param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
:param opts: Configuration options for this request
:type opts: ConfigurationOptions, optional
:return: Returns the result object.
If the method is called asynchronously,
returns the request thread.
Expand Down Expand Up @@ -112,10 +112,9 @@ class {{classname}}:
:param _return_http_data_only: response data instead of ApiResponse
object with status code, headers, etc
:type _return_http_data_only: bool, optional
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
(connection, read) timeouts.
:param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
:param opts: Configuration options for this request
:type opts: ConfigurationOptions, optional
:param _request_auth: set to override the auth_settings for an a single
request; this effectively ignores the authentication
in the spec for a single request.
Expand Down Expand Up @@ -162,7 +161,8 @@ class {{classname}}:
'_request_timeout',
'_request_auth',
'_content_type',
'_headers'
'_headers',
'opts'
]
)

Expand Down Expand Up @@ -304,6 +304,7 @@ class {{classname}}:
_return_http_data_only=_params.get('_return_http_data_only'), # noqa: E501
_preload_content=_params.get('_preload_content', True),
_request_timeout=_params.get('_request_timeout'),
opts=_params.get('opts'),
{{#servers.0}}
_host=_host,
{{/servers.0}}
Expand Down
43 changes: 26 additions & 17 deletions generate/templates/api_client.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ class ApiClient:
files=None, response_types_map=None, auth_settings=None,
_return_http_data_only=None, collection_formats=None,
_preload_content=True, _request_timeout=None, _host=None,
_request_auth=None):
_request_auth=None, opts=None):

config = self.configuration

Expand Down Expand Up @@ -230,7 +230,8 @@ class ApiClient:
headers=header_params,
post_params=post_params, body=body,
_preload_content=_preload_content,
_request_timeout=_request_timeout)
_request_timeout=_request_timeout,
opts=opts)
except ApiException as e:
if e.body:
e.body = e.body.decode('utf-8')
Expand Down Expand Up @@ -390,7 +391,8 @@ class ApiClient:
response_types_map=None, auth_settings=None,
async_req=None, _return_http_data_only=None,
collection_formats=None, _preload_content=True,
_request_timeout=None, _host=None, _request_auth=None):
_request_timeout=None, _host=None, _request_auth=None,
opts=None):
"""Makes the HTTP request (synchronous) and returns deserialized data.

To make an async_req request, set the async_req parameter.
Expand All @@ -417,10 +419,9 @@ class ApiClient:
Default is True.
:param collection_formats: dict of collection formats for path, query,
header, and post parameters.
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
(connection, read) timeouts.
:param _request_timeout: Timeout setting. Do not use - use the opts parameter instead
:param opts: Configuration options for this request
:type opts: ConfigurationOptions, optional
:param _request_auth: set to override the auth_settings for an a single
request; this effectively ignores the authentication
in the spec for a single request.
Expand All @@ -439,7 +440,7 @@ class ApiClient:
response_types_map, auth_settings,
_return_http_data_only, collection_formats,
_preload_content, _request_timeout, _host,
_request_auth)
_request_auth, opts)

return self.pool.apply_async(self.__call_api, (resource_path,
method, path_params,
Expand All @@ -452,61 +453,69 @@ class ApiClient:
collection_formats,
_preload_content,
_request_timeout,
_host, _request_auth))
_host, _request_auth,
opts))

def request(self, method, url, query_params=None, headers=None,
post_params=None, body=None, _preload_content=True,
_request_timeout=None):
_request_timeout=None, opts=None):
"""Makes the HTTP request using RESTClient."""
if method == "GET":
return self.rest_client.get_request(url,
query_params=query_params,
_preload_content=_preload_content,
_request_timeout=_request_timeout,
headers=headers)
headers=headers,
opts=opts)
elif method == "HEAD":
return self.rest_client.head_request(url,
query_params=query_params,
_preload_content=_preload_content,
_request_timeout=_request_timeout,
headers=headers)
headers=headers,
opts=opts)
elif method == "OPTIONS":
return self.rest_client.options_request(url,
query_params=query_params,
headers=headers,
_preload_content=_preload_content,
_request_timeout=_request_timeout)
_request_timeout=_request_timeout,
opts=opts)
elif method == "POST":
return self.rest_client.post_request(url,
query_params=query_params,
headers=headers,
post_params=post_params,
_preload_content=_preload_content,
_request_timeout=_request_timeout,
body=body)
body=body,
opts=opts)
elif method == "PUT":
return self.rest_client.put_request(url,
query_params=query_params,
headers=headers,
post_params=post_params,
_preload_content=_preload_content,
_request_timeout=_request_timeout,
body=body)
body=body,
opts=opts)
elif method == "PATCH":
return self.rest_client.patch_request(url,
query_params=query_params,
headers=headers,
post_params=post_params,
_preload_content=_preload_content,
_request_timeout=_request_timeout,
body=body)
body=body,
opts=opts)
elif method == "DELETE":
return self.rest_client.delete_request(url,
query_params=query_params,
headers=headers,
_preload_content=_preload_content,
_request_timeout=_request_timeout,
body=body)
body=body,
opts=opts)
else:
raise ApiValueError(
"http method must be `GET`, `HEAD`, `OPTIONS`,"
Expand Down
Loading