Skip to content

Commit 04d07f6

Browse files
Merge pull request QuantConnect#75 from QuantConnect/bug-agreement-acceptance
Agreement Adjustment
2 parents 421142c + 946d206 commit 04d07f6

File tree

1 file changed

+34
-23
lines changed

1 file changed

+34
-23
lines changed

lean/commands/data/download.py

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@
1111
# See the License for the specific language governing permissions and
1212
# limitations under the License.
1313

14+
from datetime import datetime
1415
import itertools
1516
import re
17+
from time import sleep
1618
import webbrowser
1719
from collections import OrderedDict
1820
from typing import Iterable, List, Optional
@@ -28,7 +30,17 @@
2830
from lean.models.logger import Option
2931

3032
_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+
"""
3244

3345
def _get_data_information(organization: QCFullOrganization) -> QCDataInformation:
3446
"""Retrieves the datasources and prices information.
@@ -235,8 +247,12 @@ def _confirm_organization_balance(organization: QCFullOrganization, products: Li
235247
]))
236248

237249

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
240256
241257
:param organization: the organization that the user selected
242258
: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
246262

247263
info = api_client.data.get_info(organization.id)
248264

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)
251272

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...")
255276

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+
)
260281

261282

262283
def _confirm_payment(organization: QCFullOrganization, products: List[Product]) -> None:
@@ -393,14 +414,6 @@ def _get_available_datasets(organization: QCFullOrganization) -> List[Dataset]:
393414

394415
return available_datasets
395416

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-
404417
@click.command(cls=LeanCommand, requires_lean_config=True, allow_unknown_options=True)
405418
@click.option("--dataset", type=str, help="The name of the dataset to download non-interactively")
406419
@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,
438451
products = _select_products_interactive(selected_organization, datasets)
439452

440453
_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)
444455

445456
if is_interactive:
446457
_confirm_payment(selected_organization, products)

0 commit comments

Comments
 (0)