11
11
# See the License for the specific language governing permissions and
12
12
# limitations under the License.
13
13
14
+ from datetime import datetime
14
15
import itertools
15
16
import re
17
+ from time import sleep
16
18
import webbrowser
17
19
from collections import OrderedDict
18
20
from typing import Iterable , List , Optional
28
30
from lean .models .logger import Option
29
31
30
32
_data_information : Optional [QCDataInformation ] = None
31
-
33
+ _presigned_terms = """
34
+ Data Terms of Use has been signed previously.
35
+ Find full agreement at: {link}
36
+ ==========================================================================
37
+ CLI API Access Agreement: On {signed_time} You Agreed:
38
+ - Display or distribution of data obtained through CLI API Access is not permitted.
39
+ - Data and Third Party Data obtained via CLI API Access can only be used for individual or internal employee's use.
40
+ - Data is provided in LEAN format can not be manipulated for transmission or use in other applications.
41
+ - QuantConnect is not liable for the quality of data received and is not responsible for trading losses.
42
+ ==========================================================================
43
+ """
32
44
33
45
def _get_data_information (organization : QCFullOrganization ) -> QCDataInformation :
34
46
"""Retrieves the datasources and prices information.
@@ -235,8 +247,12 @@ def _confirm_organization_balance(organization: QCFullOrganization, products: Li
235
247
]))
236
248
237
249
238
- def _accept_agreement (organization : QCFullOrganization , open_browser : bool ) -> None :
239
- """Asks the user to accept the CLI API Access and Data Agreement.
250
+ def _verify_accept_agreement (organization : QCFullOrganization , open_browser : bool ) -> None :
251
+ """ Verifies that the user has accepted the agreement.
252
+ If they haven't, asks the user to accept the CLI API Access and Data Agreement.
253
+ If they have, reminds them of the agreement and moves on.
254
+
255
+ The API will enforce signing the agreement at the end of the day but this is how we keep it in the process of the CLI
240
256
241
257
:param organization: the organization that the user selected
242
258
:param open_browser: whether the CLI should automatically open the agreement in the browser
@@ -246,17 +262,22 @@ def _accept_agreement(organization: QCFullOrganization, open_browser: bool) -> N
246
262
247
263
info = api_client .data .get_info (organization .id )
248
264
249
- if open_browser :
250
- webbrowser .open (info .agreement )
265
+ # Is signed
266
+ if organization .data .current :
267
+ logger .info (_presigned_terms .format (link = info .agreement , signed_time = datetime .fromtimestamp (organization .data .signedTime )))
268
+ sleep (1 )
269
+ else :
270
+ if open_browser :
271
+ webbrowser .open (info .agreement )
251
272
252
- logger .info (f"Go to the following url to accept the CLI API Access and Data Agreement:" )
253
- logger .info (info .agreement )
254
- logger .info ("Waiting until the CLI API Access and Data Agreement has been accepted..." )
273
+ logger .info (f"Go to the following url to accept the CLI API Access and Data Agreement:" )
274
+ logger .info (info .agreement )
275
+ logger .info ("Waiting until the CLI API Access and Data Agreement has been accepted..." )
255
276
256
- container .task_manager ().poll (
257
- make_request = lambda : api_client .organizations .get (organization .id ),
258
- is_done = lambda data : data .data .signedTime != organization . data . signedTime
259
- )
277
+ container .task_manager ().poll (
278
+ make_request = lambda : api_client .organizations .get (organization .id ),
279
+ is_done = lambda data : data .data .current != False
280
+ )
260
281
261
282
262
283
def _confirm_payment (organization : QCFullOrganization , products : List [Product ]) -> None :
@@ -393,14 +414,6 @@ def _get_available_datasets(organization: QCFullOrganization) -> List[Dataset]:
393
414
394
415
return available_datasets
395
416
396
-
397
- def _is_bulk_download (products : List [Product ]) -> bool :
398
- for product in products :
399
- if "data-type" in product .option_results and product .option_results ["data-type" ].value == "bulk" :
400
- return True
401
- return False
402
-
403
-
404
417
@click .command (cls = LeanCommand , requires_lean_config = True , allow_unknown_options = True )
405
418
@click .option ("--dataset" , type = str , help = "The name of the dataset to download non-interactively" )
406
419
@click .option ("--organization" , type = str , help = "The name or id of the organization to purchase and download data with" )
@@ -438,9 +451,7 @@ def download(ctx: click.Context,
438
451
products = _select_products_interactive (selected_organization , datasets )
439
452
440
453
_confirm_organization_balance (selected_organization , products )
441
-
442
- if not _is_bulk_download (products ):
443
- _accept_agreement (selected_organization , is_interactive )
454
+ _verify_accept_agreement (selected_organization , is_interactive )
444
455
445
456
if is_interactive :
446
457
_confirm_payment (selected_organization , products )
0 commit comments