aiverify-moonshot 0.4.2__py3-none-any.whl → 0.4.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. {aiverify_moonshot-0.4.2.dist-info → aiverify_moonshot-0.4.4.dist-info}/METADATA +12 -10
  2. {aiverify_moonshot-0.4.2.dist-info → aiverify_moonshot-0.4.4.dist-info}/RECORD +35 -31
  3. moonshot/api.py +2 -0
  4. moonshot/integrations/cli/benchmark/cookbook.py +36 -28
  5. moonshot/integrations/cli/benchmark/datasets.py +56 -47
  6. moonshot/integrations/cli/benchmark/metrics.py +39 -30
  7. moonshot/integrations/cli/benchmark/recipe.py +63 -73
  8. moonshot/integrations/cli/benchmark/result.py +62 -54
  9. moonshot/integrations/cli/benchmark/run.py +75 -66
  10. moonshot/integrations/cli/common/common.py +8 -0
  11. moonshot/integrations/cli/common/connectors.py +101 -85
  12. moonshot/integrations/cli/common/dataset.py +66 -0
  13. moonshot/integrations/cli/common/prompt_template.py +30 -27
  14. moonshot/integrations/cli/redteam/attack_module.py +45 -30
  15. moonshot/integrations/cli/redteam/context_strategy.py +36 -30
  16. moonshot/integrations/cli/redteam/session.py +101 -76
  17. moonshot/integrations/cli/utils/process_data.py +52 -0
  18. moonshot/integrations/web_api/app.py +1 -1
  19. moonshot/integrations/web_api/routes/dataset.py +46 -1
  20. moonshot/integrations/web_api/schemas/dataset_create_dto.py +18 -0
  21. moonshot/integrations/web_api/schemas/recipe_create_dto.py +0 -2
  22. moonshot/integrations/web_api/services/bookmark_service.py +6 -2
  23. moonshot/integrations/web_api/services/dataset_service.py +25 -0
  24. moonshot/integrations/web_api/services/recipe_service.py +0 -1
  25. moonshot/src/api/api_dataset.py +35 -0
  26. moonshot/src/api/api_recipe.py +0 -3
  27. moonshot/src/datasets/dataset.py +116 -0
  28. moonshot/src/recipes/recipe.py +0 -15
  29. moonshot/src/recipes/recipe_arguments.py +0 -4
  30. moonshot/src/utils/log.py +12 -6
  31. moonshot/src/utils/pagination.py +25 -0
  32. {aiverify_moonshot-0.4.2.dist-info → aiverify_moonshot-0.4.4.dist-info}/WHEEL +0 -0
  33. {aiverify_moonshot-0.4.2.dist-info → aiverify_moonshot-0.4.4.dist-info}/licenses/AUTHORS.md +0 -0
  34. {aiverify_moonshot-0.4.2.dist-info → aiverify_moonshot-0.4.4.dist-info}/licenses/LICENSE.md +0 -0
  35. {aiverify_moonshot-0.4.2.dist-info → aiverify_moonshot-0.4.4.dist-info}/licenses/NOTICES.md +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: aiverify-moonshot
3
- Version: 0.4.2
3
+ Version: 0.4.4
4
4
  Summary: AI Verify advances Gen AI testing with Project Moonshot.
5
5
  Project-URL: Repository, https://github.com/aiverify-foundation/moonshot
6
6
  Project-URL: Documentation, https://aiverify-foundation.github.io/moonshot/
@@ -15,9 +15,11 @@ Classifier: License :: OSI Approved :: Apache Software License
15
15
  Classifier: Programming Language :: Python :: 3
16
16
  Classifier: Programming Language :: Python :: 3.11
17
17
  Requires-Python: >=3.11
18
- Requires-Dist: ijson==3.2.3
18
+ Requires-Dist: datasets==2.20.0
19
+ Requires-Dist: ijson==3.3.0
19
20
  Requires-Dist: jinja2==3.1.4
20
- Requires-Dist: pydantic==2.7.1
21
+ Requires-Dist: pandas==2.2.2
22
+ Requires-Dist: pydantic==2.8.2
21
23
  Requires-Dist: pyparsing==3.1.2
22
24
  Requires-Dist: python-dotenv==1.0.1
23
25
  Requires-Dist: python-slugify==8.0.4
@@ -25,25 +27,25 @@ Requires-Dist: xxhash==3.4.1
25
27
  Provides-Extra: all
26
28
  Requires-Dist: cmd2==2.4.3; extra == 'all'
27
29
  Requires-Dist: dependency-injector==4.41.0; extra == 'all'
28
- Requires-Dist: fastapi==0.110.3; extra == 'all'
30
+ Requires-Dist: fastapi==0.112.0; extra == 'all'
29
31
  Requires-Dist: rich==13.7.1; extra == 'all'
30
- Requires-Dist: typing-extensions==4.12.0; extra == 'all'
31
- Requires-Dist: uvicorn==0.29.0; extra == 'all'
32
+ Requires-Dist: typing-extensions==4.12.2; extra == 'all'
33
+ Requires-Dist: uvicorn==0.30.5; extra == 'all'
32
34
  Provides-Extra: cli
33
35
  Requires-Dist: cmd2==2.4.3; extra == 'cli'
34
36
  Requires-Dist: rich==13.7.1; extra == 'cli'
35
37
  Provides-Extra: web-api
36
38
  Requires-Dist: dependency-injector==4.41.0; extra == 'web-api'
37
- Requires-Dist: fastapi==0.110.3; extra == 'web-api'
38
- Requires-Dist: typing-extensions==4.12.0; extra == 'web-api'
39
- Requires-Dist: uvicorn==0.29.0; extra == 'web-api'
39
+ Requires-Dist: fastapi==0.112.0; extra == 'web-api'
40
+ Requires-Dist: typing-extensions==4.12.2; extra == 'web-api'
41
+ Requires-Dist: uvicorn==0.30.5; extra == 'web-api'
40
42
  Description-Content-Type: text/markdown
41
43
 
42
44
  <div align="center">
43
45
 
44
46
  ![Moonshot Logo](https://github.com/aiverify-foundation/moonshot/raw/main/misc/aiverify-moonshot-logo.png)
45
47
 
46
- **Version 0.4.2**
48
+ **Version 0.4.4**
47
49
 
48
50
  A simple and modular tool to evaluate any LLM application.
49
51
 
@@ -1,6 +1,6 @@
1
1
  moonshot/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  moonshot/__main__.py,sha256=NB_sWjPRcwr8BbFXtih2y3fbVYPZ1YS5dI_bNNaTD3U,7551
3
- moonshot/api.py,sha256=elAkJoQE6BuKTJ-E-7x1FLyMeb5I_B8G3ieIs--pS7A,4771
3
+ moonshot/api.py,sha256=f7vIMlpC-1ZQsbqipe2cTlP5dwgoVujQKYNxzEKcWlg,4822
4
4
  moonshot/integrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
5
  moonshot/integrations/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
6
  moonshot/integrations/cli/__main__.py,sha256=0VnYSj2AayvDCZ3uXpldPcjMHt2Yd7BWojWzFOGSSl4,679
@@ -8,30 +8,32 @@ moonshot/integrations/cli/active_session_cfg.py,sha256=n8hOFxFjvz26qbEFY4q7iPUZY
8
8
  moonshot/integrations/cli/cli.py,sha256=9tnzcxcSOjblxCUpyh3pK0ke0bLs3s-63OxXtYoZI2g,2769
9
9
  moonshot/integrations/cli/benchmark/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
10
  moonshot/integrations/cli/benchmark/benchmark.py,sha256=QUxr6DU11-XeH6Y3j1uPsZsotshgy64G_cWNf0Rn2_U,6303
11
- moonshot/integrations/cli/benchmark/cookbook.py,sha256=KPmLMYdbJDWhejHaU8WRilrQhSyEPOXHpdUGcV_bhhE,22032
12
- moonshot/integrations/cli/benchmark/datasets.py,sha256=VE1-7w64Afp0VePTgRJFruMJJUE-Q4Rit9WnoGRdGDA,7053
13
- moonshot/integrations/cli/benchmark/metrics.py,sha256=bkEedpPJLM3X-R5DyVR-g6RYKZXIImvuhtw6kLwJ9Ik,6156
14
- moonshot/integrations/cli/benchmark/recipe.py,sha256=n2mw_uKdNK_0rArriUSy1VWDjaK6rm1iaw-yF5J6D4k,23260
15
- moonshot/integrations/cli/benchmark/result.py,sha256=11KgObrq4QvpAfbaj_HTafqsQwT45bpGMQ8nKuxF_1A,9422
16
- moonshot/integrations/cli/benchmark/run.py,sha256=IHZjDumaWr0blK4ol_lOqWA2Q_lq5fWB-gqw9shV5Kc,6127
11
+ moonshot/integrations/cli/benchmark/cookbook.py,sha256=9mNuqsaVFCfXnLgVxJQ-fzwSgH8j082NR2gE-GPQbG8,22183
12
+ moonshot/integrations/cli/benchmark/datasets.py,sha256=E-kreuXkrNU39sFuVWGhutFHfoEhsVjFK4tmq7YQwxs,7193
13
+ moonshot/integrations/cli/benchmark/metrics.py,sha256=6wLn3WyqgUJKCRvblxiyx8X4nQ7gA1sKGcC_DNBIWBo,6351
14
+ moonshot/integrations/cli/benchmark/recipe.py,sha256=EYv94Qjq2hqn1zz9NzWaINEY9DNdY7TkSS57xHv6ymQ,22698
15
+ moonshot/integrations/cli/benchmark/result.py,sha256=U0SsjJYNQJYP_EZ3pAil4VaOQLMZHchfzq982nXU-jE,9486
16
+ moonshot/integrations/cli/benchmark/run.py,sha256=Rqdb_FspgQQhkLORjgdiyaijk7HTxM39giOzXpBXA1k,6161
17
17
  moonshot/integrations/cli/benchmark/runner.py,sha256=nAnNKihQD0AScl6vPFiFH_9MZU4ppeMG34QaLRidqvU,6602
18
18
  moonshot/integrations/cli/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
- moonshot/integrations/cli/common/common.py,sha256=kXqzOmtwU2LrFeosAr9h0Edond9kk3sWlH-jNb54i8M,2854
20
- moonshot/integrations/cli/common/connectors.py,sha256=kHm1ldo1LEYyrsw5hQMjwxIRk20WQZmsHug_0wCaRo0,13738
19
+ moonshot/integrations/cli/common/common.py,sha256=hSvxj-T91nhKfJtQqxrIPgYdS8P_g7wbOwpFpqBg90I,3090
20
+ moonshot/integrations/cli/common/connectors.py,sha256=8_U7KJzfsS9L13dMbouk5JKOy_ow4UhrILICCw27Q5c,13909
21
+ moonshot/integrations/cli/common/dataset.py,sha256=KZuwSV4Di7C378Aa2bRxIKCd03oo6HdMTEZpBZSQb5w,3113
21
22
  moonshot/integrations/cli/common/display_helper.py,sha256=8rVowW33XK0j0C_X_H1jUbFlFk1Y2WpzxmIUE3Ca5Co,1459
22
- moonshot/integrations/cli/common/prompt_template.py,sha256=CiR7b8dMaxf6nReLmlpRJynhCRiyvfydmYyp8AWjdyI,4682
23
+ moonshot/integrations/cli/common/prompt_template.py,sha256=KzawF2VaiWUKzRIrXX_TaHboiPVllSiqz5I_o2TqGiA,4812
23
24
  moonshot/integrations/cli/initialisation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
25
  moonshot/integrations/cli/initialisation/initialisation.py,sha256=zMjklhoBlYLPshe7Q16vBBbOfhbPjZc4_ooywAFp2XY,387
25
26
  moonshot/integrations/cli/redteam/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
26
- moonshot/integrations/cli/redteam/attack_module.py,sha256=kO_eXHMUM6ErBXFAAy1caM6W7EC9U_b8-Hdj1oBMipA,4060
27
- moonshot/integrations/cli/redteam/context_strategy.py,sha256=MikcpolrnZf80G2U6LO7oDhb5mYuQRVTJ76e90Cwbnw,6980
27
+ moonshot/integrations/cli/redteam/attack_module.py,sha256=sjjQdBno7rXNfrXqns55ERSfD0ZFE0CQoWOk-sTJcqo,4599
28
+ moonshot/integrations/cli/redteam/context_strategy.py,sha256=gLNgnd1oHWD1X93BQoKlR7G8b5g9P6AcKFLlE3WvETk,7065
28
29
  moonshot/integrations/cli/redteam/prompt_template.py,sha256=rWINvMFLax8ynIFJoX93xsB1cWJ8-dQ1nRyqgdri2yQ,2079
29
30
  moonshot/integrations/cli/redteam/redteam.py,sha256=144tVuiSWBLseC0EvvIuevHYJhqn39xvg36-1cLgGWQ,4257
30
- moonshot/integrations/cli/redteam/session.py,sha256=V-K-eFdgathpEM1WvpXoJElfBPT15buB7ckUGst-vLo,33266
31
+ moonshot/integrations/cli/redteam/session.py,sha256=auZ73LfMAGmT1jLJUjqY6oAsMWoSzHstiRGA8DKF6A4,33652
32
+ moonshot/integrations/cli/utils/process_data.py,sha256=QVL5vp2_8ZgGicmCAdeYEHkeb6f-NC775-JCzWziNiU,1901
31
33
  moonshot/integrations/web_api/.env.dev,sha256=0z5_Ut8rF-UqFZtgjkH2qoqORhD5_nSs2w_OeX2SteI,182
32
34
  moonshot/integrations/web_api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
35
  moonshot/integrations/web_api/__main__.py,sha256=MdnLi_ZF-olAAEJwTPU1iGYFYwo-fNWNT2qfchkH3y4,2050
34
- moonshot/integrations/web_api/app.py,sha256=7BL8w9ch52pLFlpSQqFxQZOxjDAs0cPV2TYx8WH90MU,3651
36
+ moonshot/integrations/web_api/app.py,sha256=rrL-N4cVO1qBQ5v6y039jfMqUdSC9jyqsgCudmyfZx0,3651
35
37
  moonshot/integrations/web_api/container.py,sha256=DVkJG_qm7ItcG6tgMYOqIj07wpKhPWOOfy6-bEv72y4,5915
36
38
  moonshot/integrations/web_api/logging_conf.py,sha256=t3EGRV6tZhV732KXe8_Tiy0fiwVAWxZX5Tt8VTgrrfg,3388
37
39
  moonshot/integrations/web_api/log/.gitkeep,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -42,7 +44,7 @@ moonshot/integrations/web_api/routes/benchmark_result.py,sha256=WZ_dI8qT4dli9hKP
42
44
  moonshot/integrations/web_api/routes/bookmark.py,sha256=K-1jL0IwOYvmYpgJvU65-lRfQlQhMzJk_n-Zf92IeR0,6135
43
45
  moonshot/integrations/web_api/routes/context_strategy.py,sha256=kJTpjrwxfYGyBLY_hAgpHOMZMtjV5Z6vpu7RIdHDylg,4828
44
46
  moonshot/integrations/web_api/routes/cookbook.py,sha256=oddmcdfhgH3qZb4_ThfUk8SBKmHOt51dFlAHubQh2fQ,8648
45
- moonshot/integrations/web_api/routes/dataset.py,sha256=Pvr1WRKom9UrLzfrHozSKXKxOz9BJfbxUZ6EB-M3g10,4319
47
+ moonshot/integrations/web_api/routes/dataset.py,sha256=qtxflHRDr31W3u6voOFE5iRHsCVr0MQ35H94Pw5M1YU,6114
46
48
  moonshot/integrations/web_api/routes/endpoint.py,sha256=ZFx0WUe3-GGdmBz_hzYiOmjvJHN4PQy_8lCKJMBjxcE,10715
47
49
  moonshot/integrations/web_api/routes/metric.py,sha256=f_HHexxKUfqFE5FkeCwRh8n36H2mREtLnK2pDrw3A-w,2856
48
50
  moonshot/integrations/web_api/routes/prompt_template.py,sha256=M3adeNeWvLQJJlFQ0uZqSXEuNpTcagApnuqWvLiL1mg,4890
@@ -54,12 +56,13 @@ moonshot/integrations/web_api/schemas/benchmark_runner_dto.py,sha256=nfNMt_9Xg0Y
54
56
  moonshot/integrations/web_api/schemas/bookmark_create_dto.py,sha256=C78vG8UG02N7Cmt6RSuS8e4sX_G-MLCiAWT-cF5BE8s,374
55
57
  moonshot/integrations/web_api/schemas/cookbook_create_dto.py,sha256=00SPVw7lEpfY9yOFdt1XkvvNAzfFRd7d7CA90qguhuQ,670
56
58
  moonshot/integrations/web_api/schemas/cookbook_response_model.py,sha256=eJtAi5cbGfSqP57qyzyeLqffPIrpM5lutqpW7_H0xLY,240
59
+ moonshot/integrations/web_api/schemas/dataset_create_dto.py,sha256=U4D_pmybKNVfdlFuOPC-tew8qs0FEz6z3dDlwY4NJW0,482
57
60
  moonshot/integrations/web_api/schemas/dataset_response_dto.py,sha256=s5x4-UXEWccWhK42E0FPXiHG6VqjuFuph-2t5atEkg4,171
58
61
  moonshot/integrations/web_api/schemas/endpoint_create_dto.py,sha256=oyw5xNsWg4GxQ5VNbSe_YqvWxE7OI3egPZINqIi3glw,646
59
62
  moonshot/integrations/web_api/schemas/endpoint_response_model.py,sha256=OmmM2uaPSgB2aqPFfkhseKkI5OKCKilXR19gDmwFlLc,321
60
63
  moonshot/integrations/web_api/schemas/prompt_response_model.py,sha256=S9PwxJERY1ppDaUKLlL9_skHcYcURIIvFnRZj24hLnE,303
61
64
  moonshot/integrations/web_api/schemas/prompt_template_response_model.py,sha256=V7znK-QjQVUXUbsmEy5hZHzjnHYCN1kDtvOxgyxF83k,195
62
- moonshot/integrations/web_api/schemas/recipe_create_dto.py,sha256=LrOzMZjBkpexcwU0nk1JPOLZHo9UP4_d_NS5cWBWkTI,1211
65
+ moonshot/integrations/web_api/schemas/recipe_create_dto.py,sha256=xXT1TlVM3jVGUH4FPrd64vRctoCV8ybnXga4Nb1VzEU,1117
63
66
  moonshot/integrations/web_api/schemas/recipe_response_model.py,sha256=qhjiMyr5fc6R3vOZlsellnX2NF5esaBeQAGQ8160mFo,217
64
67
  moonshot/integrations/web_api/schemas/session_create_dto.py,sha256=3Xhj5JOEEWwaoq1q4FZLBVUdpo59C6X6m4y_qLurEhg,493
65
68
  moonshot/integrations/web_api/schemas/session_prompt_dto.py,sha256=AcMq3UhKrZJIEYDrEfK8xPHeTNk2Ex4IDXrDWZwn6Fo,218
@@ -73,14 +76,14 @@ moonshot/integrations/web_api/services/benchmark_result_service.py,sha256=-oPvLL
73
76
  moonshot/integrations/web_api/services/benchmark_test_manager.py,sha256=zsB8zTDUvH-hT1c-rmyh71uO9ZuIxYbUP3msh8Hdkm4,4024
74
77
  moonshot/integrations/web_api/services/benchmark_test_state.py,sha256=MyhTxpAhhP66JF0ua1SMc_IIeIjDxQY5swOXv9cmYaY,1887
75
78
  moonshot/integrations/web_api/services/benchmarking_service.py,sha256=lJZeNTqxEPBLrZNX3Z9JIilgwetywSkv0deQkcb8mQs,1257
76
- moonshot/integrations/web_api/services/bookmark_service.py,sha256=l8CVC24JB2qmRDOHZh-F0S_KBa2pnZ_AhLxVAAimrmM,3384
79
+ moonshot/integrations/web_api/services/bookmark_service.py,sha256=jI9nXs1hjzO0CLG2LKaXSzDApLThkfCvPUkaNNV9A5A,3546
77
80
  moonshot/integrations/web_api/services/context_strategy_service.py,sha256=6YKnnG8JlE_1nlnr4Hq7rgz-sxI6oQglK0STaWPFQxQ,710
78
81
  moonshot/integrations/web_api/services/cookbook_service.py,sha256=avAFiX_ZrBvCZcGFuZlp1Zw9AQVSdZ5ysKIS5JfIeh8,6760
79
- moonshot/integrations/web_api/services/dataset_service.py,sha256=KAyfewnP2V-6vekktVll4uM_2-tVEzLXFddBVaseB88,768
82
+ moonshot/integrations/web_api/services/dataset_service.py,sha256=WmLyREkb8N44o8gKYtryanqefNjaGMuhzp0OK-wRq04,1710
80
83
  moonshot/integrations/web_api/services/endpoint_service.py,sha256=YhcVYMOCVq7BBWPqf0Doji6YdrtnT6ykJkCjZWj-9xs,2356
81
84
  moonshot/integrations/web_api/services/metric_service.py,sha256=xWC5Dk8aiU7tuHsxYedTTrEkbA3Ug1pV2nbaBas6cAg,456
82
85
  moonshot/integrations/web_api/services/prompt_template_service.py,sha256=5ds7pKDB2R0_0slVDwsCRIpIVdsgpqhI-3wQqSYcpuE,1226
83
- moonshot/integrations/web_api/services/recipe_service.py,sha256=rOCke7_NKNKrimg-ALl3DfYFZkMGmdDt2p81y68oMbU,5520
86
+ moonshot/integrations/web_api/services/recipe_service.py,sha256=q7hN3yskWnrhR4jUxlv9vHdZLTfXzAZ44vy3HYa7P-c,5465
84
87
  moonshot/integrations/web_api/services/runner_service.py,sha256=_ljFTVtMzt3fxlY0l2252KTxgVsqoQB6vsOXBIY0PIU,4584
85
88
  moonshot/integrations/web_api/services/session_service.py,sha256=g0iMGkSAbc2Vx3c9m4aqe15LknsiHgzs7ErV1hHq5nA,13821
86
89
  moonshot/integrations/web_api/services/utils/exceptions_handler.py,sha256=anaQQYLAXzbt-cL4nAZGm1TIlP9fKt7qYE7lrNtW_04,2070
@@ -98,11 +101,11 @@ moonshot/src/api/api_connector.py,sha256=JpwLFd7Vh1LRz6oB8fhO2iufMbSTt5RmrMe7nt5
98
101
  moonshot/src/api/api_connector_endpoint.py,sha256=UUuHzrgoj0bWcbOXPUJh7FEg-pzBOSo6DLgwqCZnLmw,5503
99
102
  moonshot/src/api/api_context_strategy.py,sha256=WqzUEw3f7gROJlc_G7bsGkuP3nO1HycFzn3dfcxzaoc,2153
100
103
  moonshot/src/api/api_cookbook.py,sha256=qFItf8KLaDgbDIrv8usbbzSFnoXOYLORQ7IaDvQ5haw,5744
101
- moonshot/src/api/api_dataset.py,sha256=ryBzXYe5yxGgG5Nhl6ri4GO3Mcv7rN4gEMWMQnPl6mA,1369
104
+ moonshot/src/api/api_dataset.py,sha256=3K6qoLWk6929OBv4W0Qx_Zqx-XgNUm5K16q-RjZBoXY,2670
102
105
  moonshot/src/api/api_environment_variables.py,sha256=ubUHvK7LyN1HhAE40ZTls6fDrbl6IYbxoPob68i4c_k,551
103
106
  moonshot/src/api/api_metrics.py,sha256=W32Jobh5wUYTsN8Jus0xGvEY1NVkvJrxZ8_a8tVuouI,1586
104
107
  moonshot/src/api/api_prompt_template.py,sha256=NsgEz9sOLLlb93CBDBPektfCDB8kviEGaG21m2onVjo,1332
105
- moonshot/src/api/api_recipe.py,sha256=kvtTlq-i5cZlr5h_CtFtTG2nf8tfcifCP3YScWeqgwY,6273
108
+ moonshot/src/api/api_recipe.py,sha256=1mU6c7OpyCUzCVqrmGoB1J2M-GhgIvvlKrjptplp5Z0,6122
106
109
  moonshot/src/api/api_red_teaming.py,sha256=Ar2KeGXOTkeVNvDpegGfIPpIvdEijZBcqb-4dDwOIRc,2019
107
110
  moonshot/src/api/api_result.py,sha256=M5zKF7ytKp237UZusLSYJ7QVfui85Ys0WEaYySGcAKw,2532
108
111
  moonshot/src/api/api_run.py,sha256=3PrETAVcFnJ09R0-xhWiFkEfqL6eYj4B2voEGJDPznU,2936
@@ -122,7 +125,7 @@ moonshot/src/cookbooks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3
122
125
  moonshot/src/cookbooks/cookbook.py,sha256=LjmbJtFwIPhupQlx6LjjIQLMfpwcWZKurduS8MBgqHI,9661
123
126
  moonshot/src/cookbooks/cookbook_arguments.py,sha256=iVp3x1-wi_RL7peTSr5TWbXnjuB_w7Uj29kJrQg48Y0,1210
124
127
  moonshot/src/datasets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
125
- moonshot/src/datasets/dataset.py,sha256=g8A_bP5BiXuV1gGh3Kn2mQRA2zuKlChmenjkoPQ48fA,10209
128
+ moonshot/src/datasets/dataset.py,sha256=xiq2hYDkhCalddsxjt4i4ur3GlDLHL8kQtonKrpEbb8,14939
126
129
  moonshot/src/datasets/dataset_arguments.py,sha256=b4FyLA-xBt9e6Itpx6FnTMbyHzvDVMzx4R5SNLqYoXA,1753
127
130
  moonshot/src/metrics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
128
131
  moonshot/src/metrics/metric.py,sha256=llqJYnwtllJRMfNhRRbKWjhzKymY961yR3Jw24COR-Y,7512
@@ -130,8 +133,8 @@ moonshot/src/metrics/metric_interface.py,sha256=RSCV8Um39Ns-SD8Os4TM1bwQl3pjaazk
130
133
  moonshot/src/prompt_templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
131
134
  moonshot/src/prompt_templates/prompt_template.py,sha256=IT4ufLFDX43rD_Ewa1lJbYIBW4fHaTu_YyzOvvUU3Ts,3500
132
135
  moonshot/src/recipes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
133
- moonshot/src/recipes/recipe.py,sha256=cAPNAZZAqn3NYu23oV6xrf2innWTAcCSn-EB2Z-_UY8,13808
134
- moonshot/src/recipes/recipe_arguments.py,sha256=7s0MnyIluBxZqaHY-sJdz5MC1c8iR35Tas4pwKpY7u8,4067
136
+ moonshot/src/recipes/recipe.py,sha256=PE4mimP7Y7lDanXib2uMrd9KpLWOxRdg0Cps5rLRQxU,13226
137
+ moonshot/src/recipes/recipe_arguments.py,sha256=9LdVJidB6Sci941QvnudBznvx9_NVCl8r-HvzSZInlY,3914
135
138
  moonshot/src/redteaming/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
136
139
  moonshot/src/redteaming/attack/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
137
140
  moonshot/src/redteaming/attack/attack_module.py,sha256=HrL7YdsW-wcFB5Dv8t3wkPvg2pf-c9Ep994qdbk1D3s,25061
@@ -163,11 +166,12 @@ moonshot/src/storage/storage.py,sha256=qQrGFPVzsDwYFrBWa3XLajSjhUtQBwGg4pAr54DFC
163
166
  moonshot/src/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
164
167
  moonshot/src/utils/find_feature.py,sha256=a5CZMcDJ-Hp2OlV1fRug8Yu32_31KxlMie9lf4_ij9U,1296
165
168
  moonshot/src/utils/import_modules.py,sha256=T9zTN59PFnvY2rjyWhSV9KSIAHxWV1pyBemF0y-hwtw,2844
166
- moonshot/src/utils/log.py,sha256=JtnsCk3RodBo-BmrOfKzyILYg6jiDlrByGfbvXFoAjk,2229
169
+ moonshot/src/utils/log.py,sha256=YNgD7Eh2OT36XlmVBKCGUTAh9TRp4Akfe4kDdvHASgs,2502
170
+ moonshot/src/utils/pagination.py,sha256=5seymyRoqyENIhKllAatr1T91kMCGFslcvRnJHyMSvc,814
167
171
  moonshot/src/utils/timeit.py,sha256=TvuF0w8KWhp0oZFY0cUU3UY0xlGKjchb0OkfYfgVTlc,866
168
- aiverify_moonshot-0.4.2.dist-info/METADATA,sha256=wCZOuFZXEuOH6psgKCe-ZQtj8dbsXPwPTnxsowc6wB0,12307
169
- aiverify_moonshot-0.4.2.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
170
- aiverify_moonshot-0.4.2.dist-info/licenses/AUTHORS.md,sha256=mmAbe3i3sT8JZHJMBhxp3i1xRehV0g7WB4T_eyIBuBs,59
171
- aiverify_moonshot-0.4.2.dist-info/licenses/LICENSE.md,sha256=mDOKOkWFbJmUORaAchXByEVGC1jw37QRn-zS14wY_wM,11347
172
- aiverify_moonshot-0.4.2.dist-info/licenses/NOTICES.md,sha256=0Ikx6IBGGQEOJeNb2MkRoXxTXwrtlMz6EDgLBFIz6v0,179593
173
- aiverify_moonshot-0.4.2.dist-info/RECORD,,
172
+ aiverify_moonshot-0.4.4.dist-info/METADATA,sha256=zQ4rKRFVE_p6uB6dgGBcKhIB4KXRn8ZzdBymh3d2y6g,12368
173
+ aiverify_moonshot-0.4.4.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
174
+ aiverify_moonshot-0.4.4.dist-info/licenses/AUTHORS.md,sha256=mmAbe3i3sT8JZHJMBhxp3i1xRehV0g7WB4T_eyIBuBs,59
175
+ aiverify_moonshot-0.4.4.dist-info/licenses/LICENSE.md,sha256=mDOKOkWFbJmUORaAchXByEVGC1jw37QRn-zS14wY_wM,11347
176
+ aiverify_moonshot-0.4.4.dist-info/licenses/NOTICES.md,sha256=0Ikx6IBGGQEOJeNb2MkRoXxTXwrtlMz6EDgLBFIz6v0,179593
177
+ aiverify_moonshot-0.4.4.dist-info/RECORD,,
moonshot/api.py CHANGED
@@ -29,6 +29,7 @@ from moonshot.src.api.api_dataset import (
29
29
  api_delete_dataset,
30
30
  api_get_all_datasets,
31
31
  api_get_all_datasets_name,
32
+ api_create_datasets
32
33
  )
33
34
  from moonshot.src.api.api_environment_variables import api_set_environment_variables
34
35
  from moonshot.src.api.api_metrics import (
@@ -115,6 +116,7 @@ __all__ = [
115
116
  "api_read_cookbook",
116
117
  "api_read_cookbooks",
117
118
  "api_update_cookbook",
119
+ "api_create_datasets",
118
120
  "api_delete_dataset",
119
121
  "api_get_all_datasets",
120
122
  "api_get_all_datasets_name",
@@ -23,7 +23,7 @@ from moonshot.integrations.cli.benchmark.recipe import (
23
23
  display_view_statistics_format,
24
24
  )
25
25
  from moonshot.integrations.cli.common.display_helper import display_view_list_format
26
- from moonshot.src.utils.find_feature import find_keyword
26
+ from moonshot.integrations.cli.utils.process_data import filter_data
27
27
 
28
28
  console = Console()
29
29
 
@@ -62,29 +62,31 @@ def list_cookbooks(args) -> list | None:
62
62
 
63
63
  This function retrieves all available cookbooks by calling the api_get_all_cookbook function from the
64
64
  moonshot.api module.
65
- It then displays the retrieved cookbooks using the display_cookbooks function.
65
+ It then displays the retrieved cookbooks using the _display_cookbooks function.
66
66
 
67
67
  Args:
68
68
  args: A namespace object from argparse. It should have an optional attribute:
69
69
  find (str): Optional field to find cookbook(s) with a keyword.
70
+ pagination (str): Optional field to paginate cookbooks.
70
71
 
71
72
  Returns:
72
73
  list | None: A list of Cookbook or None if there is no result.
73
74
  """
75
+
74
76
  try:
75
77
  cookbooks_list = api_get_all_cookbook()
76
78
  keyword = args.find.lower() if args.find else ""
77
- if keyword:
78
- filtered_cookbooks_list = find_keyword(keyword, cookbooks_list)
79
+ pagination = literal_eval(args.pagination) if args.pagination else ()
80
+
81
+ if cookbooks_list:
82
+ filtered_cookbooks_list = filter_data(cookbooks_list, keyword, pagination)
79
83
  if filtered_cookbooks_list:
80
- display_cookbooks(filtered_cookbooks_list)
84
+ _display_cookbooks(filtered_cookbooks_list)
81
85
  return filtered_cookbooks_list
82
- else:
83
- print("No cookbooks containing keyword found.")
84
- return None
85
- else:
86
- display_cookbooks(cookbooks_list)
87
- return cookbooks_list
86
+
87
+ console.print("[red]There are no cookbooks found.[/red]")
88
+ return None
89
+
88
90
  except Exception as e:
89
91
  print(f"[list_cookbooks]: {str(e)}")
90
92
 
@@ -236,7 +238,7 @@ def delete_cookbook(args) -> None:
236
238
  # ------------------------------------------------------------------------------
237
239
  # Helper functions: Display on cli
238
240
  # ------------------------------------------------------------------------------
239
- def display_cookbooks(cookbooks_list):
241
+ def _display_cookbooks(cookbooks_list):
240
242
  """
241
243
  Display the list of cookbooks in a tabular format.
242
244
 
@@ -247,22 +249,20 @@ def display_cookbooks(cookbooks_list):
247
249
  Args:
248
250
  cookbooks_list (list): A list of dictionaries, where each dictionary contains the details of a cookbook.
249
251
  """
250
- if cookbooks_list:
251
- table = Table(
252
- title="List of Cookbooks", show_lines=True, expand=True, header_style="bold"
253
- )
254
- table.add_column("No.", width=2)
255
- table.add_column("Cookbook", justify="left", width=78)
256
- table.add_column("Contains", justify="left", width=20, overflow="fold")
257
- for cookbook_id, cookbook in enumerate(cookbooks_list, 1):
258
- id, name, description, recipes = cookbook.values()
259
- cookbook_info = f"[red]ID: {id}[/red]\n\n[blue]{name}[/blue]\n{description}"
260
- recipes_info = display_view_list_format("Recipes", recipes)
261
- table.add_section()
262
- table.add_row(str(cookbook_id), cookbook_info, recipes_info)
263
- console.print(table)
264
- else:
265
- console.print("[red]There are no cookbooks found.[/red]")
252
+ table = Table(
253
+ title="List of Cookbooks", show_lines=True, expand=True, header_style="bold"
254
+ )
255
+ table.add_column("No.", width=2)
256
+ table.add_column("Cookbook", justify="left", width=78)
257
+ table.add_column("Contains", justify="left", width=20, overflow="fold")
258
+ for idx, cookbook in enumerate(cookbooks_list, 1):
259
+ id, name, description, recipes, *other_args = cookbook.values()
260
+ idx = cookbook.get("idx", idx)
261
+ cookbook_info = f"[red]ID: {id}[/red]\n\n[blue]{name}[/blue]\n{description}"
262
+ recipes_info = display_view_list_format("Recipes", recipes)
263
+ table.add_section()
264
+ table.add_row(str(idx), cookbook_info, recipes_info)
265
+ console.print(table)
266
266
 
267
267
 
268
268
  def display_view_cookbook(cookbook_info):
@@ -573,3 +573,11 @@ list_cookbooks_args.add_argument(
573
573
  help="Optional field to find cookbook(s) with keyword",
574
574
  nargs="?",
575
575
  )
576
+
577
+ list_cookbooks_args.add_argument(
578
+ "-p",
579
+ "--pagination",
580
+ type=str,
581
+ help="Optional tuple to paginate cookbook(s). E.g. (2,10) returns 2nd page with 10 items in each page.",
582
+ nargs="?",
583
+ )
@@ -1,3 +1,5 @@
1
+ from ast import literal_eval
2
+
1
3
  import cmd2
2
4
  from rich.console import Console
3
5
  from rich.table import Table
@@ -8,7 +10,7 @@ from moonshot.api import (
8
10
  api_get_all_datasets_name,
9
11
  )
10
12
  from moonshot.integrations.cli.common.display_helper import display_view_str_format
11
- from moonshot.src.utils.find_feature import find_keyword
13
+ from moonshot.integrations.cli.utils.process_data import filter_data
12
14
 
13
15
  console = Console()
14
16
 
@@ -21,12 +23,13 @@ def list_datasets(args) -> list | None:
21
23
  List all available datasets.
22
24
 
23
25
  This function retrieves all available datasets by calling the api_get_all_datasets function from the
24
- moonshot.api module. It then displays the datasets using the display_datasets function. If an exception occurs,
26
+ moonshot.api module. It then displays the datasets using the _display_datasets function. If an exception occurs,
25
27
  it prints an error message.
26
28
 
27
29
  Args:
28
30
  args: A namespace object from argparse. It should have an optional attribute:
29
31
  find (str): Optional field to find dataset(s) with a keyword.
32
+ pagination (str): Optional field to paginate datasets.
30
33
 
31
34
  Returns:
32
35
  list | None: A list of Dataset or None if there is no result.
@@ -35,17 +38,16 @@ def list_datasets(args) -> list | None:
35
38
  print("Listing datasets may take a while...")
36
39
  datasets_list = api_get_all_datasets()
37
40
  keyword = args.find.lower() if args.find else ""
38
- if keyword:
39
- filtered_datasets_list = find_keyword(keyword, datasets_list)
41
+ pagination = literal_eval(args.pagination) if args.pagination else ()
42
+
43
+ if datasets_list:
44
+ filtered_datasets_list = filter_data(datasets_list, keyword, pagination)
40
45
  if filtered_datasets_list:
41
- display_datasets(filtered_datasets_list)
46
+ _display_datasets(filtered_datasets_list)
42
47
  return filtered_datasets_list
43
- else:
44
- print("No datasets containing keyword found.")
45
- return None
46
- else:
47
- display_datasets(datasets_list)
48
- return datasets_list
48
+
49
+ console.print("[red]There are no datasets found.[/red]")
50
+ return None
49
51
  except Exception as e:
50
52
  print(f"[list_datasets]: {str(e)}")
51
53
 
@@ -56,7 +58,7 @@ def view_dataset(args) -> None:
56
58
 
57
59
  This function retrieves all available datasets and their names by calling the api_get_all_datasets and
58
60
  api_get_all_datasets_name functions. It then finds the dataset with the name specified in args.dataset_filename
59
- and displays it using the display_datasets function. If an exception occurs, it prints an error message.
61
+ and displays it using the _display_datasets function. If an exception occurs, it prints an error message.
60
62
 
61
63
  Args:
62
64
  args: A namespace object from argparse. It should have the following attribute:
@@ -72,8 +74,8 @@ def view_dataset(args) -> None:
72
74
 
73
75
  # Find the index of the dataset with the name args.dataset_filename
74
76
  dataset_index = datasets_name_list.index(args.dataset_filename)
75
- # Pass the corresponding dataset from datasets_list to display_datasets
76
- display_datasets([datasets_list[dataset_index]])
77
+ # Pass the corresponding dataset from datasets_list to _display_datasets
78
+ _display_datasets([datasets_list[dataset_index]])
77
79
 
78
80
  except Exception as e:
79
81
  print(f"[view_dataset]: {str(e)}")
@@ -112,7 +114,7 @@ def delete_dataset(args) -> None:
112
114
  # ------------------------------------------------------------------------------
113
115
  # Helper functions: Display on cli
114
116
  # ------------------------------------------------------------------------------
115
- def display_datasets(datasets_list: list):
117
+ def _display_datasets(datasets_list: list):
116
118
  """
117
119
  Displays a list of datasets in a table format.
118
120
 
@@ -125,39 +127,38 @@ def display_datasets(datasets_list: list):
125
127
  Returns:
126
128
  None
127
129
  """
128
- if datasets_list:
129
- table = Table(
130
- title="List of Datasets", show_lines=True, expand=True, header_style="bold"
130
+ table = Table(
131
+ title="List of Datasets", show_lines=True, expand=True, header_style="bold"
132
+ )
133
+ table.add_column("No.", width=2)
134
+ table.add_column("Dataset", justify="left", width=78)
135
+ for idx, dataset in enumerate(datasets_list, 1):
136
+ (
137
+ id,
138
+ name,
139
+ description,
140
+ _,
141
+ num_of_dataset_prompts,
142
+ created_date,
143
+ reference,
144
+ license,
145
+ *other_args,
146
+ ) = dataset.values()
147
+
148
+ idx = dataset.get("idx", idx)
149
+ prompt_info = display_view_str_format("Prompts", num_of_dataset_prompts)
150
+ created_date_info = display_view_str_format("Created Date", created_date)
151
+ license_info = display_view_str_format("License", license)
152
+ reference_info = display_view_str_format("Reference", reference)
153
+
154
+ dataset_info = (
155
+ f"[red]{id}[/red]\n\n[blue]{name}[/blue]\n{description}\n\n"
156
+ f"{prompt_info}\n\n{created_date_info}\n\n{license_info}\n\n{reference_info}"
131
157
  )
132
- table.add_column("No.", width=2)
133
- table.add_column("Dataset", justify="left", width=78)
134
- for dataset_no, dataset in enumerate(datasets_list, 1):
135
- (
136
- id,
137
- name,
138
- description,
139
- _,
140
- num_of_dataset_prompts,
141
- created_date,
142
- reference,
143
- license,
144
- ) = dataset.values()
145
-
146
- prompt_info = display_view_str_format("Prompts", num_of_dataset_prompts)
147
- created_date_info = display_view_str_format("Created Date", created_date)
148
- license_info = display_view_str_format("License", license)
149
- reference_info = display_view_str_format("Reference", reference)
150
-
151
- dataset_info = (
152
- f"[red]{id}[/red]\n\n[blue]{name}[/blue]\n{description}\n\n"
153
- f"{prompt_info}\n\n{created_date_info}\n\n{license_info}\n\n{reference_info}"
154
- )
155
-
156
- table.add_section()
157
- table.add_row(str(dataset_no), dataset_info)
158
- console.print(table)
159
- else:
160
- console.print("[red]There are no datasets found.[/red]")
158
+
159
+ table.add_section()
160
+ table.add_row(str(idx), dataset_info)
161
+ console.print(table)
161
162
 
162
163
 
163
164
  # ------------------------------------------------------------------------------
@@ -192,3 +193,11 @@ list_datasets_args.add_argument(
192
193
  help="Optional field to find dataset(s) with keyword",
193
194
  nargs="?",
194
195
  )
196
+
197
+ list_datasets_args.add_argument(
198
+ "-p",
199
+ "--pagination",
200
+ type=str,
201
+ help="Optional tuple to paginate dataset(s). E.g. (2,10) returns 2nd page with 10 items in each page.",
202
+ nargs="?",
203
+ )
@@ -1,9 +1,11 @@
1
+ from ast import literal_eval
2
+
1
3
  import cmd2
2
4
  from rich.console import Console
3
5
  from rich.table import Table
4
6
 
5
7
  from moonshot.api import api_delete_metric, api_get_all_metric, api_get_all_metric_name
6
- from moonshot.src.utils.find_feature import find_keyword
8
+ from moonshot.integrations.cli.utils.process_data import filter_data
7
9
 
8
10
  console = Console()
9
11
 
@@ -16,31 +18,32 @@ def list_metrics(args) -> list | None:
16
18
  List all available metrics.
17
19
 
18
20
  This function retrieves all available metrics by calling the api_get_all_metric function from the
19
- moonshot.api module. It then displays the metrics using the display_metrics function. If an exception occurs,
21
+ moonshot.api module. It then displays the metrics using the _display_metrics function. If an exception occurs,
20
22
  it prints an error message.
21
23
 
22
24
  Args:
23
25
  args: A namespace object from argparse. It should have an optional attribute:
24
26
  find (str): Optional field to find metric(s) with a keyword.
27
+ pagination (str): Optional field to paginate metrics.
25
28
 
26
29
  Returns:
27
30
  list | None: A list of Metric or None if there is no result.
28
31
  """
32
+
29
33
  try:
30
34
  print("Listing metrics may take a while...")
31
35
  metrics_list = api_get_all_metric()
32
36
  keyword = args.find.lower() if args.find else ""
33
- if keyword:
34
- filtered_metrics_list = find_keyword(keyword, metrics_list)
37
+ pagination = literal_eval(args.pagination) if args.pagination else ()
38
+
39
+ if metrics_list:
40
+ filtered_metrics_list = filter_data(metrics_list, keyword, pagination)
35
41
  if filtered_metrics_list:
36
- display_metrics(filtered_metrics_list)
42
+ _display_metrics(filtered_metrics_list)
37
43
  return filtered_metrics_list
38
- else:
39
- print("No metrics containing keyword found.")
40
- return None
41
- else:
42
- display_metrics(metrics_list)
43
- return metrics_list
44
+
45
+ console.print("[red]There are no metrics found.[/red]")
46
+ return None
44
47
  except Exception as e:
45
48
  print(f"[list_metrics]: {str(e)}")
46
49
 
@@ -51,7 +54,7 @@ def view_metric(args) -> None:
51
54
 
52
55
  This function retrieves all available metrics and their names by calling the api_get_all_metric and
53
56
  api_get_all_metric_name functions. It then finds the metric with the name specified in args.metric_filename
54
- and displays it using the display_metrics function. If an exception occurs, it prints an error message.
57
+ and displays it using the _display_metrics function. If an exception occurs, it prints an error message.
55
58
 
56
59
  Args:
57
60
  args: A namespace object from argparse. It should have the following attribute:
@@ -67,8 +70,8 @@ def view_metric(args) -> None:
67
70
 
68
71
  # Find the index of the metric with the name args.metric_filename
69
72
  metric_index = metrics_name_list.index(args.metric_filename)
70
- # Pass the corresponding metric from metrics_list to display_metrics
71
- display_metrics([metrics_list[metric_index]])
73
+ # Pass the corresponding metric from metrics_list to _display_metrics
74
+ _display_metrics([metrics_list[metric_index]])
72
75
 
73
76
  except Exception as e:
74
77
  print(f"[view_metric]: {str(e)}")
@@ -107,7 +110,7 @@ def delete_metric(args) -> None:
107
110
  # ------------------------------------------------------------------------------
108
111
  # Helper functions: Display on cli
109
112
  # ------------------------------------------------------------------------------
110
- def display_metrics(metrics_list: list):
113
+ def _display_metrics(metrics_list: list):
111
114
  """
112
115
  Displays a list of metrics in a table format.
113
116
 
@@ -120,21 +123,19 @@ def display_metrics(metrics_list: list):
120
123
  Returns:
121
124
  None
122
125
  """
123
- if metrics_list:
124
- table = Table(
125
- title="List of Metrics", show_lines=True, expand=True, header_style="bold"
126
- )
127
- table.add_column("No.", width=2)
128
- table.add_column("Metric", justify="left", width=78)
129
- for metric_no, metric in enumerate(metrics_list, 1):
130
- id, name, description = metric.values()
131
- result_info = f"[red]id: {id}[/red]\n\n[blue]{name}[/blue]\n{description}"
132
-
133
- table.add_section()
134
- table.add_row(str(metric_no), result_info)
135
- console.print(table)
136
- else:
137
- console.print("[red]There are no metrics found.[/red]")
126
+ table = Table(
127
+ title="List of Metrics", show_lines=True, expand=True, header_style="bold"
128
+ )
129
+ table.add_column("No.", width=2)
130
+ table.add_column("Metric", justify="left", width=78)
131
+ for idx, metric in enumerate(metrics_list, 1):
132
+ id, name, description, *other_args = metric.values()
133
+ idx = metric.get("idx", idx)
134
+ result_info = f"[red]id: {id}[/red]\n\n[blue]{name}[/blue]\n{description}"
135
+
136
+ table.add_section()
137
+ table.add_row(str(idx), result_info)
138
+ console.print(table)
138
139
 
139
140
 
140
141
  # ------------------------------------------------------------------------------
@@ -169,3 +170,11 @@ list_metrics_args.add_argument(
169
170
  help="Optional field to find metric(s) with keyword",
170
171
  nargs="?",
171
172
  )
173
+
174
+ list_metrics_args.add_argument(
175
+ "-p",
176
+ "--pagination",
177
+ type=str,
178
+ help="Optional tuple to paginate metric(s). E.g. (2,10) returns 2nd page with 10 items in each page.",
179
+ nargs="?",
180
+ )