direct-cli 0.3.1__tar.gz → 0.3.3__tar.gz

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 (211) hide show
  1. direct_cli-0.3.3/CHANGELOG.md +11 -0
  2. {direct_cli-0.3.1 → direct_cli-0.3.3}/PKG-INFO +56 -11
  3. {direct_cli-0.3.1 → direct_cli-0.3.3}/README.md +55 -10
  4. direct_cli-0.3.3/direct_cli/_vendor/tapi_yandex_direct/endpoints.py +14 -0
  5. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/_vendor/tapi_yandex_direct/tapi_yandex_direct.py +8 -10
  6. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/_vendor/tapi_yandex_direct/v4/adapter.py +24 -11
  7. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/_vendor/tapi_yandex_direct/v4/adapter.pyi +2 -0
  8. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/api.py +6 -0
  9. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/auth.py +152 -16
  10. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/cli.py +3 -3
  11. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/commands/adextensions.py +27 -2
  12. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/commands/adgroups.py +36 -1
  13. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/commands/adimages.py +27 -6
  14. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/commands/ads.py +55 -4
  15. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/commands/advideos.py +11 -6
  16. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/commands/audiencetargets.py +18 -1
  17. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/commands/auth.py +75 -9
  18. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/commands/bidmodifiers.py +16 -0
  19. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/commands/bids.py +10 -1
  20. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/commands/businesses.py +9 -2
  21. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/commands/campaigns.py +40 -20
  22. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/commands/creatives.py +11 -1
  23. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/commands/dynamicads.py +26 -1
  24. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/commands/dynamicfeedadtargets.py +22 -2
  25. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/commands/feeds.py +9 -2
  26. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/commands/keywordbids.py +18 -2
  27. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/commands/keywords.py +50 -13
  28. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/commands/leads.py +23 -1
  29. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/commands/negativekeywordsharedsets.py +10 -5
  30. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/commands/reports.py +124 -22
  31. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/commands/sitelinks.py +9 -2
  32. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/commands/smartadtargets.py +26 -1
  33. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/commands/turbopages.py +16 -2
  34. direct_cli-0.3.3/direct_cli/commands/v4account.py +218 -0
  35. direct_cli-0.3.3/direct_cli/commands/v4events.py +118 -0
  36. direct_cli-0.3.3/direct_cli/commands/v4finance.py +448 -0
  37. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/commands/v4shells.py +0 -15
  38. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/commands/vcards.py +13 -3
  39. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/reports_coverage.py +113 -15
  40. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/smoke_matrix.py +7 -0
  41. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/utils.py +25 -0
  42. direct_cli-0.3.3/direct_cli/v4/money.py +78 -0
  43. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/v4_contracts.py +85 -22
  44. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli.egg-info/PKG-INFO +56 -11
  45. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli.egg-info/SOURCES.txt +13 -1
  46. {direct_cli-0.3.1 → direct_cli-0.3.3}/pyproject.toml +2 -2
  47. {direct_cli-0.3.1 → direct_cli-0.3.3}/scripts/build_api_coverage_report.py +1 -0
  48. {direct_cli-0.3.1 → direct_cli-0.3.3}/scripts/sandbox_write_live.py +1 -1
  49. {direct_cli-0.3.1 → direct_cli-0.3.3}/scripts/test_dangerous_commands.sh +4 -0
  50. {direct_cli-0.3.1 → direct_cli-0.3.3}/scripts/test_safe_commands.sh +30 -0
  51. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/API_COVERAGE.md +26 -2
  52. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/MANUAL_COVERAGE.md +13 -0
  53. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/api_coverage_payloads.py +28 -0
  54. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/cassettes/test_integration_live_write/test_live_draft_adgroups_add_update_delete.yaml +6 -6
  55. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/cassettes/test_integration_live_write/test_live_draft_adimages_add_get_delete.yaml +1 -1
  56. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/cassettes/test_integration_live_write/test_live_draft_ads_add_update_delete.yaml +8 -8
  57. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/cassettes/test_integration_live_write/test_live_draft_ads_suspend_resume_archive_unarchive.yaml +10 -10
  58. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/cassettes/test_integration_live_write/test_live_draft_advideos_add_get.yaml +2 -2
  59. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/cassettes/test_integration_live_write/test_live_draft_audiencetargets_add_delete.yaml +5 -5
  60. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/cassettes/test_integration_live_write/test_live_draft_audiencetargets_suspend_resume.yaml +5 -5
  61. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/cassettes/test_integration_live_write/test_live_draft_bids_set.yaml +7 -7
  62. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/cassettes/test_integration_live_write/test_live_draft_campaign_create_get_delete.yaml +4 -4
  63. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/cassettes/test_integration_live_write/test_live_draft_creatives_chain_advideo_to_creative.yaml +3 -3
  64. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/cassettes/test_integration_live_write/test_live_draft_dynamicads_add_delete.yaml +1 -1
  65. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/cassettes/test_integration_live_write/test_live_draft_dynamicads_suspend_resume.yaml +1 -1
  66. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/cassettes/test_integration_live_write/test_live_draft_keywordbids_set.yaml +7 -7
  67. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/cassettes/test_integration_live_write/test_live_draft_keywords_add_update_delete.yaml +7 -7
  68. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/cassettes/test_integration_live_write/test_live_draft_keywords_suspend_resume.yaml +8 -8
  69. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/cassettes/test_integration_live_write/test_live_draft_sitelinks_add_get_delete.yaml +3 -3
  70. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/cassettes/test_integration_live_write/test_live_draft_smartadtargets_add_update_delete.yaml +3 -3
  71. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/cassettes/test_integration_live_write/test_live_draft_smartadtargets_suspend_resume.yaml +3 -3
  72. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/cassettes/test_integration_write/TestWriteAdExtensions.test_add_delete.yaml +2 -2
  73. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/cassettes/test_integration_write/TestWriteAdGroups.test_add_update_delete.yaml +5 -5
  74. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/cassettes/test_integration_write/TestWriteAdImages.test_add_delete.yaml +1 -1
  75. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/cassettes/test_integration_write/TestWriteAds.test_add_text_ad_update_delete.yaml +5 -5
  76. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/cassettes/test_integration_write/TestWriteAudienceTargets.test_add_delete.yaml +7 -7
  77. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/cassettes/test_integration_write/TestWriteBidModifiersAdd.test_add_delete_mobile.yaml +4 -4
  78. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/cassettes/test_integration_write/TestWriteBidModifiersSet.test_set_without_id_is_rejected.yaml +3 -3
  79. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/cassettes/test_integration_write/TestWriteBids.test_set_bid.yaml +5 -5
  80. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/cassettes/test_integration_write/TestWriteCampaignDraftLifecycle.test_draft_create_get_delete.yaml +4 -4
  81. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/cassettes/test_integration_write/TestWriteCampaigns.test_campaign_lifecycle.yaml +6 -6
  82. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/cassettes/test_integration_write/TestWriteDynamicAds.test_add_update_delete.yaml +1 -1
  83. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/cassettes/test_integration_write/TestWriteFeeds.test_add_update_delete.yaml +3 -3
  84. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/cassettes/test_integration_write/TestWriteKeywordBids.test_set_keyword_bid.yaml +5 -5
  85. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/cassettes/test_integration_write/TestWriteKeywords.test_add_update_delete.yaml +5 -5
  86. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/cassettes/test_integration_write/TestWriteNegativeKeywordSharedSets.test_add_update_delete.yaml +3 -3
  87. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/cassettes/test_integration_write/TestWriteRetargeting.test_add_delete.yaml +2 -2
  88. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/cassettes/test_integration_write/TestWriteSitelinks.test_add_delete.yaml +1 -1
  89. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/cassettes/test_integration_write/TestWriteSmartAdTargets.test_add_update_delete.yaml +3 -3
  90. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/cassettes/test_integration_write/TestWriteVCards.test_add_delete.yaml +4 -4
  91. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/conftest.py +1 -1
  92. direct_cli-0.3.1/tests/reports_cache/raw/spec.html → direct_cli-0.3.3/tests/reports_cache/raw/period.html +9 -9
  93. direct_cli-0.3.3/tests/reports_cache/raw/spec.html +660 -0
  94. direct_cli-0.3.3/tests/reports_cache/spec.json +1645 -0
  95. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/test_api_coverage.py +210 -19
  96. direct_cli-0.3.3/tests/test_auth_oauth.py +657 -0
  97. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/test_dry_run.py +316 -0
  98. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/test_smoke_matrix.py +6 -2
  99. direct_cli-0.3.3/tests/test_transport_contract.py +66 -0
  100. direct_cli-0.3.3/tests/test_v4_contracts.py +292 -0
  101. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/test_v4_foundation.py +4 -0
  102. direct_cli-0.3.3/tests/test_v4_live_contracts.py +154 -0
  103. direct_cli-0.3.3/tests/test_v4_safety.py +15 -0
  104. direct_cli-0.3.3/tests/test_v4account.py +304 -0
  105. direct_cli-0.3.3/tests/test_v4events.py +162 -0
  106. direct_cli-0.3.3/tests/test_v4finance_money.py +489 -0
  107. direct_cli-0.3.3/tests/test_v4finance_read.py +229 -0
  108. direct_cli-0.3.1/tests/reports_cache/spec.json +0 -583
  109. direct_cli-0.3.1/tests/test_auth_oauth.py +0 -206
  110. direct_cli-0.3.1/tests/test_transport_contract.py +0 -23
  111. direct_cli-0.3.1/tests/test_v4_contracts.py +0 -141
  112. direct_cli-0.3.1/tests/test_v4_live_contracts.py +0 -79
  113. {direct_cli-0.3.1 → direct_cli-0.3.3}/.env.example +0 -0
  114. {direct_cli-0.3.1 → direct_cli-0.3.3}/.github/copilot-instructions.md +0 -0
  115. {direct_cli-0.3.1 → direct_cli-0.3.3}/.github/workflows/api-coverage.yml +0 -0
  116. {direct_cli-0.3.1 → direct_cli-0.3.3}/.github/workflows/claude-code-review.yml +0 -0
  117. {direct_cli-0.3.1 → direct_cli-0.3.3}/.github/workflows/claude.yml +0 -0
  118. {direct_cli-0.3.1 → direct_cli-0.3.3}/.gitignore +0 -0
  119. {direct_cli-0.3.1 → direct_cli-0.3.3}/AGENTS.md +0 -0
  120. {direct_cli-0.3.1 → direct_cli-0.3.3}/CLAUDE.md +0 -0
  121. {direct_cli-0.3.1 → direct_cli-0.3.3}/MANIFEST.in +0 -0
  122. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/__init__.py +0 -0
  123. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/_deprecated.py +0 -0
  124. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/_smoke_probes.py +0 -0
  125. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/_vendor/__init__.py +0 -0
  126. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/_vendor/tapi_yandex_direct/__init__.py +0 -0
  127. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/_vendor/tapi_yandex_direct/exceptions.py +0 -0
  128. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/_vendor/tapi_yandex_direct/resource_mapping.py +0 -0
  129. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/_vendor/tapi_yandex_direct/tapi_yandex_direct.pyi +0 -0
  130. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/_vendor/tapi_yandex_direct/v4/__init__.py +0 -0
  131. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/_vendor/tapi_yandex_direct/v4/resource_mapping.py +0 -0
  132. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/commands/__init__.py +0 -0
  133. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/commands/agencyclients.py +0 -0
  134. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/commands/balance.py +0 -0
  135. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/commands/changes.py +0 -0
  136. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/commands/clients.py +0 -0
  137. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/commands/dictionaries.py +0 -0
  138. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/commands/keywordsresearch.py +0 -0
  139. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/commands/retargeting.py +0 -0
  140. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/commands/strategies.py +0 -0
  141. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/commands/v4goals.py +0 -0
  142. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/output.py +0 -0
  143. /direct_cli-0.3.1/direct_cli/v4.py → /direct_cli-0.3.3/direct_cli/v4/__init__.py +0 -0
  144. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli/wsdl_coverage.py +0 -0
  145. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli.egg-info/dependency_links.txt +0 -0
  146. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli.egg-info/entry_points.txt +0 -0
  147. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli.egg-info/requires.txt +0 -0
  148. {direct_cli-0.3.1 → direct_cli-0.3.3}/direct_cli.egg-info/top_level.txt +0 -0
  149. {direct_cli-0.3.1 → direct_cli-0.3.3}/docs/superpowers/plans/2026-04-12-issue-32-completion.md +0 -0
  150. {direct_cli-0.3.1 → direct_cli-0.3.3}/docs/superpowers/specs/2026-04-23-vendor-tapi-yandex-direct-design.md +0 -0
  151. {direct_cli-0.3.1 → direct_cli-0.3.3}/scripts/anonymize_cassettes.py +0 -0
  152. {direct_cli-0.3.1 → direct_cli-0.3.3}/scripts/build_api_coverage_checklist.py +0 -0
  153. {direct_cli-0.3.1 → direct_cli-0.3.3}/scripts/check_reports_drift.py +0 -0
  154. {direct_cli-0.3.1 → direct_cli-0.3.3}/scripts/check_wsdl_drift.py +0 -0
  155. {direct_cli-0.3.1 → direct_cli-0.3.3}/scripts/patch_vendor_imports.py +0 -0
  156. {direct_cli-0.3.1 → direct_cli-0.3.3}/scripts/refresh_reports_cache.py +0 -0
  157. {direct_cli-0.3.1 → direct_cli-0.3.3}/scripts/refresh_wsdl_cache.py +0 -0
  158. {direct_cli-0.3.1 → direct_cli-0.3.3}/scripts/release_pypi.sh +0 -0
  159. {direct_cli-0.3.1 → direct_cli-0.3.3}/scripts/test_sandbox_write.sh +0 -0
  160. {direct_cli-0.3.1 → direct_cli-0.3.3}/scripts/update_vendor.sh +0 -0
  161. {direct_cli-0.3.1 → direct_cli-0.3.3}/setup.cfg +0 -0
  162. {direct_cli-0.3.1 → direct_cli-0.3.3}/setup.py +0 -0
  163. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/API_ISSUE_AUDIT.md +0 -0
  164. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/__init__.py +0 -0
  165. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/fixtures/test-video.mp4 +0 -0
  166. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/reports_cache/raw/fields-list.html +0 -0
  167. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/reports_cache/raw/headers.html +0 -0
  168. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/reports_cache/raw/type.html +0 -0
  169. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/test_auth_bw.py +0 -0
  170. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/test_auth_op.py +0 -0
  171. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/test_balance.py +0 -0
  172. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/test_cli.py +0 -0
  173. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/test_comprehensive.py +0 -0
  174. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/test_integration.py +0 -0
  175. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/test_integration_live_write.py +0 -0
  176. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/test_integration_write.py +0 -0
  177. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/test_reports_drift.py +0 -0
  178. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/test_v4goals.py +0 -0
  179. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/test_vendor_imports.py +0 -0
  180. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/wsdl_cache/adextensions.xml +0 -0
  181. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/wsdl_cache/adgroups.xml +0 -0
  182. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/wsdl_cache/adimages.xml +0 -0
  183. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/wsdl_cache/ads.xml +0 -0
  184. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/wsdl_cache/advideos.xml +0 -0
  185. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/wsdl_cache/agencyclients.xml +0 -0
  186. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/wsdl_cache/audiencetargets.xml +0 -0
  187. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/wsdl_cache/bidmodifiers.xml +0 -0
  188. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/wsdl_cache/bids.xml +0 -0
  189. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/wsdl_cache/businesses.xml +0 -0
  190. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/wsdl_cache/campaigns.xml +0 -0
  191. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/wsdl_cache/changes.xml +0 -0
  192. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/wsdl_cache/clients.xml +0 -0
  193. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/wsdl_cache/creatives.xml +0 -0
  194. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/wsdl_cache/dictionaries.xml +0 -0
  195. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/wsdl_cache/dynamicfeedadtargets.xml +0 -0
  196. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/wsdl_cache/dynamictextadtargets.xml +0 -0
  197. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/wsdl_cache/feeds.xml +0 -0
  198. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/wsdl_cache/imports/adextensiontypes.xsd +0 -0
  199. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/wsdl_cache/imports/general.xsd +0 -0
  200. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/wsdl_cache/imports/generalclients.xsd +0 -0
  201. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/wsdl_cache/keywordbids.xml +0 -0
  202. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/wsdl_cache/keywords.xml +0 -0
  203. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/wsdl_cache/keywordsresearch.xml +0 -0
  204. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/wsdl_cache/leads.xml +0 -0
  205. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/wsdl_cache/negativekeywordsharedsets.xml +0 -0
  206. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/wsdl_cache/retargetinglists.xml +0 -0
  207. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/wsdl_cache/sitelinks.xml +0 -0
  208. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/wsdl_cache/smartadtargets.xml +0 -0
  209. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/wsdl_cache/strategies.xml +0 -0
  210. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/wsdl_cache/turbopages.xml +0 -0
  211. {direct_cli-0.3.1 → direct_cli-0.3.3}/tests/wsdl_cache/vcards.xml +0 -0
@@ -0,0 +1,11 @@
1
+ # Changelog
2
+
3
+ ## 0.3.3
4
+
5
+ **BREAKING CHANGE:** OAuth profiles created before 0.3.3 (without `refresh_token` and `expires_at`) are no longer accepted. Any such profile will fail immediately with an "incomplete profile" error. Run `direct auth login --profile <name>` to re-authenticate and create a valid 0.3.3 profile.
6
+
7
+ - Added refresh token persistence for OAuth profiles.
8
+ - Added automatic OAuth access token refresh before expiry.
9
+ - Added `expires_in` details to `direct auth status`.
10
+ - Added JSON output for `direct auth status`.
11
+ - Kept `direct auth login --oauth-token` as a manual access-token import without auto-refresh.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: direct-cli
3
- Version: 0.3.1
3
+ Version: 0.3.3
4
4
  Summary: Command-line interface for Yandex Direct API
5
5
  Author: axisrow
6
6
  License: MIT
@@ -83,7 +83,6 @@ OAuth and profile commands:
83
83
  direct auth login
84
84
  direct auth login --profile agency1
85
85
  direct auth login --code abc123 --profile agency1
86
- direct auth login --oauth-token y0_example --profile agency1
87
86
  direct auth list
88
87
  direct auth use --profile agency1
89
88
  direct auth status --profile agency1
@@ -95,6 +94,8 @@ Notes:
95
94
  - Select credentials with `--profile`.
96
95
  - `--login` remains Direct client login.
97
96
  - Authorization is performed via `direct auth login`.
97
+ - OAuth profiles store refresh tokens and refresh access tokens automatically.
98
+ - `direct auth login --oauth-token TOKEN` is a manual access-token import and does not auto-refresh.
98
99
  - Alias `auth_login` is not supported.
99
100
 
100
101
  Credential resolution priority:
@@ -147,6 +148,45 @@ direct v4goals get-retargeting-goals --campaign-ids 123,456 --format table
147
148
  direct v4goals get-stat-goals --campaign-ids 123 --dry-run
148
149
  ```
149
150
 
151
+ ### V4 Live Events
152
+
153
+ ```bash
154
+ direct v4events get-events-log --from 2026-04-14T00:00:00 --to 2026-04-15T00:00:00
155
+ direct v4events get-events-log --from 2026-04-14T00:00:00 --to 2026-04-15T00:00:00 --currency RUB --limit 100 --offset 0 --format table
156
+ ```
157
+
158
+ ### V4 Live Finance
159
+
160
+ Finance methods require an extra financial token for money operations. In the
161
+ Yandex Direct web UI, open Tools -> API -> Financial operations, enable the
162
+ financial operations checkbox, click Save, then issue the master token on the
163
+ same Financial operations page and confirm by SMS. Direct CLI can compute the
164
+ per-request token from `--master-token`, `--operation-num`, and
165
+ `--finance-login`; alternatively pass a precomputed token with `--finance-token`.
166
+ Environment variables are
167
+ `YANDEX_DIRECT_MASTER_TOKEN`, `YANDEX_DIRECT_FINANCE_LOGIN`,
168
+ `YANDEX_DIRECT_FINANCE_TOKEN`, and `YANDEX_DIRECT_OPERATION_NUM`. Money mutation
169
+ commands are dry-run-only in this release and always require `--dry-run`; dry-run
170
+ output masks the financial token.
171
+
172
+ ```bash
173
+ direct v4finance get-credit-limits --logins client-login --master-token MASTER_TOKEN --operation-num 123 --finance-login agency-login
174
+ direct v4finance get-credit-limits --logins client-login,other-client --format table
175
+ direct v4finance check-payment --custom-transaction-id A123456789012345678901234567890B
176
+ direct v4finance transfer-money --from-campaign-id 123 --to-campaign-id 456 --amount 100.50 --currency RUB --master-token MASTER_TOKEN --operation-num 123 --finance-login agency-login --dry-run
177
+ direct v4finance pay-campaigns --campaign-ids 123,456 --amount 100.50 --currency RUB --contract-id CONTRACT_ID --pay-method Bank --master-token MASTER_TOKEN --operation-num 123 --finance-login agency-login --dry-run
178
+ ```
179
+
180
+ ### V4 Live Shared Account
181
+
182
+ Shared-account mutations are dry-run-only in this release and always require
183
+ `--dry-run`.
184
+
185
+ ```bash
186
+ direct v4account enable-shared-account --client-login client-login --dry-run
187
+ direct v4account account-management --action Update --account-id 1327944 --day-budget 100.50 --spend-mode Default --money-in-sms Yes --money-out-sms No --email ops@example.com --money-warning-value 25 --dry-run
188
+ ```
189
+
150
190
  ### CLI Convention
151
191
 
152
192
  The current CLI convention is defined as follows.
@@ -344,6 +384,7 @@ direct keywords delete --id 88888
344
384
  ```bash
345
385
  # Get a report (saved to file)
346
386
  direct reports get --type CAMPAIGN_PERFORMANCE_REPORT --from 2024-01-01 --to 2024-01-31 --name "January Report" --fields "Date,CampaignId,Clicks,Cost" --format csv --output report.csv
387
+ direct reports get --type CUSTOM_REPORT --from 2024-01-01 --to 2024-01-31 --name "Goals Report" --fields "Date,CampaignId,GoalsRoi" --goals 12345,67890 --attribution-models AUTO --format csv --output goals-report.csv
347
388
 
348
389
  # List available report types
349
390
  direct reports list-types
@@ -509,9 +550,9 @@ Current command surface:
509
550
  | WSDL-backed API services | 29 |
510
551
  | Supported API services including Reports | 30 |
511
552
  | WSDL operations | 112 |
512
- | CLI groups including `auth` | 31 |
513
- | CLI subcommands including `auth` | 122 |
514
- | API CLI subcommands excluding `auth` | 118 |
553
+ | CLI groups including `auth` | 39 |
554
+ | CLI subcommands including `auth` | 130 |
555
+ | API CLI subcommands excluding `auth` | 126 |
515
556
 
516
557
  ### API Coverage And Drift Monitoring
517
558
 
@@ -549,7 +590,7 @@ CI runs a scheduled API coverage workflow that:
549
590
 
550
591
  `WRITE_SANDBOX` smoke is a live check against the Yandex Direct **sandbox**.
551
592
  It does not replay stored HTTP traffic and it does not create new recordings.
552
- Run it only when you intentionally want to call `api-sandbox.direct.yandex.com`:
593
+ Run it only when you intentionally want to call `api-sandbox.direct.yandex.ru`:
553
594
 
554
595
  ```bash
555
596
  set -a && source .env && set +a
@@ -691,13 +732,16 @@ OAuth и profile-команды:
691
732
  direct auth login
692
733
  direct auth login --profile agency1
693
734
  direct auth login --code abc123 --profile agency1
694
- direct auth login --oauth-token y0_example --profile agency1
695
735
  direct auth list
696
736
  direct auth use --profile agency1
697
737
  direct auth status --profile agency1
698
738
  direct --profile agency1 campaigns get
699
739
  ```
700
740
 
741
+ Примечания:
742
+ - OAuth profiles сохраняют refresh token и автоматически обновляют access token.
743
+ - `direct auth login --oauth-token TOKEN` импортирует access token вручную и не включает auto-refresh.
744
+
701
745
  Порядок выбора credentials:
702
746
 
703
747
  | Приоритет | Источник | Пример |
@@ -966,6 +1010,7 @@ direct keywords delete --id 88888
966
1010
  ```bash
967
1011
  # Сформировать отчёт (сохраняется в файл)
968
1012
  direct reports get --type CAMPAIGN_PERFORMANCE_REPORT --from 2024-01-01 --to 2024-01-31 --name "Отчёт за январь" --fields "Date,CampaignId,Clicks,Cost" --format csv --output report.csv
1013
+ direct reports get --type CUSTOM_REPORT --from 2024-01-01 --to 2024-01-31 --name "Отчёт по целям" --fields "Date,CampaignId,GoalsRoi" --goals 12345,67890 --attribution-models AUTO --format csv --output goals-report.csv
969
1014
 
970
1015
  # Список доступных типов отчётов
971
1016
  direct reports list-types
@@ -1132,16 +1177,16 @@ YANDEX_DIRECT_LIVE_WRITE=1 pytest -m integration_live_write -v --record-mode=rew
1132
1177
  | WSDL-backed API services | 29 |
1133
1178
  | API services с учётом Reports | 30 |
1134
1179
  | WSDL operations | 112 |
1135
- | CLI groups с `auth` | 31 |
1136
- | CLI subcommands с `auth` | 122 |
1137
- | API CLI subcommands без `auth` | 118 |
1180
+ | CLI groups с `auth` | 39 |
1181
+ | CLI subcommands с `auth` | 130 |
1182
+ | API CLI subcommands без `auth` | 126 |
1138
1183
 
1139
1184
  #### Live sandbox write smoke
1140
1185
 
1141
1186
  `WRITE_SANDBOX` smoke — это live-проверка против **sandbox-окружения**
1142
1187
  Яндекс Директа. Она не воспроизводит сохранённый HTTP-трафик и не создаёт
1143
1188
  новые записи. Запускайте её только когда намеренно хотите обратиться к
1144
- `api-sandbox.direct.yandex.com`:
1189
+ `api-sandbox.direct.yandex.ru`:
1145
1190
 
1146
1191
  ```bash
1147
1192
  set -a && source .env && set +a
@@ -44,7 +44,6 @@ OAuth and profile commands:
44
44
  direct auth login
45
45
  direct auth login --profile agency1
46
46
  direct auth login --code abc123 --profile agency1
47
- direct auth login --oauth-token y0_example --profile agency1
48
47
  direct auth list
49
48
  direct auth use --profile agency1
50
49
  direct auth status --profile agency1
@@ -56,6 +55,8 @@ Notes:
56
55
  - Select credentials with `--profile`.
57
56
  - `--login` remains Direct client login.
58
57
  - Authorization is performed via `direct auth login`.
58
+ - OAuth profiles store refresh tokens and refresh access tokens automatically.
59
+ - `direct auth login --oauth-token TOKEN` is a manual access-token import and does not auto-refresh.
59
60
  - Alias `auth_login` is not supported.
60
61
 
61
62
  Credential resolution priority:
@@ -108,6 +109,45 @@ direct v4goals get-retargeting-goals --campaign-ids 123,456 --format table
108
109
  direct v4goals get-stat-goals --campaign-ids 123 --dry-run
109
110
  ```
110
111
 
112
+ ### V4 Live Events
113
+
114
+ ```bash
115
+ direct v4events get-events-log --from 2026-04-14T00:00:00 --to 2026-04-15T00:00:00
116
+ direct v4events get-events-log --from 2026-04-14T00:00:00 --to 2026-04-15T00:00:00 --currency RUB --limit 100 --offset 0 --format table
117
+ ```
118
+
119
+ ### V4 Live Finance
120
+
121
+ Finance methods require an extra financial token for money operations. In the
122
+ Yandex Direct web UI, open Tools -> API -> Financial operations, enable the
123
+ financial operations checkbox, click Save, then issue the master token on the
124
+ same Financial operations page and confirm by SMS. Direct CLI can compute the
125
+ per-request token from `--master-token`, `--operation-num`, and
126
+ `--finance-login`; alternatively pass a precomputed token with `--finance-token`.
127
+ Environment variables are
128
+ `YANDEX_DIRECT_MASTER_TOKEN`, `YANDEX_DIRECT_FINANCE_LOGIN`,
129
+ `YANDEX_DIRECT_FINANCE_TOKEN`, and `YANDEX_DIRECT_OPERATION_NUM`. Money mutation
130
+ commands are dry-run-only in this release and always require `--dry-run`; dry-run
131
+ output masks the financial token.
132
+
133
+ ```bash
134
+ direct v4finance get-credit-limits --logins client-login --master-token MASTER_TOKEN --operation-num 123 --finance-login agency-login
135
+ direct v4finance get-credit-limits --logins client-login,other-client --format table
136
+ direct v4finance check-payment --custom-transaction-id A123456789012345678901234567890B
137
+ direct v4finance transfer-money --from-campaign-id 123 --to-campaign-id 456 --amount 100.50 --currency RUB --master-token MASTER_TOKEN --operation-num 123 --finance-login agency-login --dry-run
138
+ direct v4finance pay-campaigns --campaign-ids 123,456 --amount 100.50 --currency RUB --contract-id CONTRACT_ID --pay-method Bank --master-token MASTER_TOKEN --operation-num 123 --finance-login agency-login --dry-run
139
+ ```
140
+
141
+ ### V4 Live Shared Account
142
+
143
+ Shared-account mutations are dry-run-only in this release and always require
144
+ `--dry-run`.
145
+
146
+ ```bash
147
+ direct v4account enable-shared-account --client-login client-login --dry-run
148
+ direct v4account account-management --action Update --account-id 1327944 --day-budget 100.50 --spend-mode Default --money-in-sms Yes --money-out-sms No --email ops@example.com --money-warning-value 25 --dry-run
149
+ ```
150
+
111
151
  ### CLI Convention
112
152
 
113
153
  The current CLI convention is defined as follows.
@@ -305,6 +345,7 @@ direct keywords delete --id 88888
305
345
  ```bash
306
346
  # Get a report (saved to file)
307
347
  direct reports get --type CAMPAIGN_PERFORMANCE_REPORT --from 2024-01-01 --to 2024-01-31 --name "January Report" --fields "Date,CampaignId,Clicks,Cost" --format csv --output report.csv
348
+ direct reports get --type CUSTOM_REPORT --from 2024-01-01 --to 2024-01-31 --name "Goals Report" --fields "Date,CampaignId,GoalsRoi" --goals 12345,67890 --attribution-models AUTO --format csv --output goals-report.csv
308
349
 
309
350
  # List available report types
310
351
  direct reports list-types
@@ -470,9 +511,9 @@ Current command surface:
470
511
  | WSDL-backed API services | 29 |
471
512
  | Supported API services including Reports | 30 |
472
513
  | WSDL operations | 112 |
473
- | CLI groups including `auth` | 31 |
474
- | CLI subcommands including `auth` | 122 |
475
- | API CLI subcommands excluding `auth` | 118 |
514
+ | CLI groups including `auth` | 39 |
515
+ | CLI subcommands including `auth` | 130 |
516
+ | API CLI subcommands excluding `auth` | 126 |
476
517
 
477
518
  ### API Coverage And Drift Monitoring
478
519
 
@@ -510,7 +551,7 @@ CI runs a scheduled API coverage workflow that:
510
551
 
511
552
  `WRITE_SANDBOX` smoke is a live check against the Yandex Direct **sandbox**.
512
553
  It does not replay stored HTTP traffic and it does not create new recordings.
513
- Run it only when you intentionally want to call `api-sandbox.direct.yandex.com`:
554
+ Run it only when you intentionally want to call `api-sandbox.direct.yandex.ru`:
514
555
 
515
556
  ```bash
516
557
  set -a && source .env && set +a
@@ -652,13 +693,16 @@ OAuth и profile-команды:
652
693
  direct auth login
653
694
  direct auth login --profile agency1
654
695
  direct auth login --code abc123 --profile agency1
655
- direct auth login --oauth-token y0_example --profile agency1
656
696
  direct auth list
657
697
  direct auth use --profile agency1
658
698
  direct auth status --profile agency1
659
699
  direct --profile agency1 campaigns get
660
700
  ```
661
701
 
702
+ Примечания:
703
+ - OAuth profiles сохраняют refresh token и автоматически обновляют access token.
704
+ - `direct auth login --oauth-token TOKEN` импортирует access token вручную и не включает auto-refresh.
705
+
662
706
  Порядок выбора credentials:
663
707
 
664
708
  | Приоритет | Источник | Пример |
@@ -927,6 +971,7 @@ direct keywords delete --id 88888
927
971
  ```bash
928
972
  # Сформировать отчёт (сохраняется в файл)
929
973
  direct reports get --type CAMPAIGN_PERFORMANCE_REPORT --from 2024-01-01 --to 2024-01-31 --name "Отчёт за январь" --fields "Date,CampaignId,Clicks,Cost" --format csv --output report.csv
974
+ direct reports get --type CUSTOM_REPORT --from 2024-01-01 --to 2024-01-31 --name "Отчёт по целям" --fields "Date,CampaignId,GoalsRoi" --goals 12345,67890 --attribution-models AUTO --format csv --output goals-report.csv
930
975
 
931
976
  # Список доступных типов отчётов
932
977
  direct reports list-types
@@ -1093,16 +1138,16 @@ YANDEX_DIRECT_LIVE_WRITE=1 pytest -m integration_live_write -v --record-mode=rew
1093
1138
  | WSDL-backed API services | 29 |
1094
1139
  | API services с учётом Reports | 30 |
1095
1140
  | WSDL operations | 112 |
1096
- | CLI groups с `auth` | 31 |
1097
- | CLI subcommands с `auth` | 122 |
1098
- | API CLI subcommands без `auth` | 118 |
1141
+ | CLI groups с `auth` | 39 |
1142
+ | CLI subcommands с `auth` | 130 |
1143
+ | API CLI subcommands без `auth` | 126 |
1099
1144
 
1100
1145
  #### Live sandbox write smoke
1101
1146
 
1102
1147
  `WRITE_SANDBOX` smoke — это live-проверка против **sandbox-окружения**
1103
1148
  Яндекс Директа. Она не воспроизводит сохранённый HTTP-трафик и не создаёт
1104
1149
  новые записи. Запускайте её только когда намеренно хотите обратиться к
1105
- `api-sandbox.direct.yandex.com`:
1150
+ `api-sandbox.direct.yandex.ru`:
1106
1151
 
1107
1152
  ```bash
1108
1153
  set -a && source .env && set +a
@@ -0,0 +1,14 @@
1
+ """Runtime endpoints for Yandex Direct API transports."""
2
+
3
+ from typing import Any, Dict
4
+
5
+ DIRECT_API_PRODUCTION_ROOT = "https://api.direct.yandex.ru/"
6
+ DIRECT_API_SANDBOX_ROOT = "https://api-sandbox.direct.yandex.ru/"
7
+ DIRECT_DEBUG_ROOT = "https://"
8
+
9
+
10
+ def get_direct_api_root(api_params: Dict[str, Any]) -> str:
11
+ """Return the Direct API root for production or sandbox requests."""
12
+ if api_params.get("is_sandbox"):
13
+ return DIRECT_API_SANDBOX_ROOT
14
+ return DIRECT_API_PRODUCTION_ROOT
@@ -9,6 +9,7 @@ from tapi2 import TapiAdapter, generate_wrapper_from_adapter, JSONAdapterMixin
9
9
  from tapi2.exceptions import ResponseProcessException, ClientError, TapiException
10
10
 
11
11
  from . import exceptions
12
+ from .endpoints import DIRECT_DEBUG_ROOT, get_direct_api_root
12
13
  from .resource_mapping import RESOURCE_MAPPING_V5
13
14
 
14
15
  logger = logging.getLogger(__name__)
@@ -72,11 +73,8 @@ class YandexDirectClientAdapter(JSONAdapterMixin, TapiAdapter):
72
73
 
73
74
  def get_api_root(self, api_params: dict, resource_name: str) -> str:
74
75
  if resource_name == "debugtoken":
75
- return "https://"
76
- elif api_params.get("is_sandbox"):
77
- return "https://api-sandbox.direct.yandex.com/"
78
- else:
79
- return "https://api.direct.yandex.com/"
76
+ return DIRECT_DEBUG_ROOT
77
+ return get_direct_api_root(api_params)
80
78
 
81
79
  def get_request_kwargs(self, api_params: dict, *args, **kwargs) -> dict:
82
80
  """Обогащение запроса, параметрами"""
@@ -154,7 +152,7 @@ class YandexDirectClientAdapter(JSONAdapterMixin, TapiAdapter):
154
152
  "The report generation time has exceeded the server limit. "
155
153
  "Please try to change the request parameters, "
156
154
  "reduce the period or the amount of requested data.",
157
- **kwargs
155
+ **kwargs,
158
156
  )
159
157
  elif response.status_code == 405:
160
158
  raise exceptions.YandexDirectApiError(
@@ -162,7 +160,7 @@ class YandexDirectClientAdapter(JSONAdapterMixin, TapiAdapter):
162
160
  "This resource does not support the HTTP method {}\n".format(
163
161
  response.request.method
164
162
  ),
165
- **kwargs
163
+ **kwargs,
166
164
  )
167
165
 
168
166
  data = self.response_to_native(response)
@@ -190,7 +188,7 @@ class YandexDirectClientAdapter(JSONAdapterMixin, TapiAdapter):
190
188
  response: Response,
191
189
  request_kwargs: dict,
192
190
  api_params: dict,
193
- **kwargs
191
+ **kwargs,
194
192
  ) -> None:
195
193
  if response.status_code in (201, 202):
196
194
  pass
@@ -230,7 +228,7 @@ class YandexDirectClientAdapter(JSONAdapterMixin, TapiAdapter):
230
228
  response: Response,
231
229
  request_kwargs: dict,
232
230
  api_params: dict,
233
- **kwargs
231
+ **kwargs,
234
232
  ) -> bool:
235
233
  status_code = response.status_code
236
234
  error_data = error_message.get("error", {})
@@ -283,7 +281,7 @@ class YandexDirectClientAdapter(JSONAdapterMixin, TapiAdapter):
283
281
  response: Response,
284
282
  request_kwargs: dict,
285
283
  api_params: dict,
286
- **kwargs
284
+ **kwargs,
287
285
  ) -> Optional[dict]:
288
286
  limit = response_data["result"].get("LimitedBy")
289
287
  if limit:
@@ -18,6 +18,7 @@ from tapi2 import JSONAdapterMixin, TapiAdapter, generate_wrapper_from_adapter
18
18
  from tapi2.exceptions import ClientError, ResponseProcessException, TapiException
19
19
 
20
20
  from .. import exceptions
21
+ from ..endpoints import get_direct_api_root
21
22
  from .resource_mapping import (
22
23
  RESOURCE_MAPPING_V4_LIVE,
23
24
  SUPPORTED_V4_METHODS,
@@ -33,9 +34,7 @@ class V4LiveClientAdapter(JSONAdapterMixin, TapiAdapter):
33
34
  super().__init__(*args, **kwargs)
34
35
 
35
36
  def get_api_root(self, api_params: dict, resource_name: str) -> str:
36
- if api_params.get("is_sandbox"):
37
- return "https://api-sandbox.direct.yandex.ru/"
38
- return "https://api.direct.yandex.ru/"
37
+ return get_direct_api_root(api_params)
39
38
 
40
39
  def get_request_kwargs(self, api_params: dict, *args, **kwargs) -> dict:
41
40
  params = super().get_request_kwargs(api_params, *args, **kwargs)
@@ -43,11 +42,14 @@ class V4LiveClientAdapter(JSONAdapterMixin, TapiAdapter):
43
42
  token = api_params.get("access_token")
44
43
  login = api_params.get("login")
45
44
  language = api_params.get("language", "en")
46
-
47
- # Enrich the JSON body with token / locale. format_data_to_request does
48
- # not see api_params, so we do this here, after super() has already
49
- # serialised the user data. Agency/client selection is transport-level
50
- # (Client-Login header); method params must stay schema-shaped.
45
+ finance_token = api_params.get("finance_token")
46
+ operation_num = api_params.get("operation_num")
47
+
48
+ # Enrich the JSON body with top-level v4 Live fields.
49
+ # format_data_to_request does not see api_params, so we do this here,
50
+ # after super() has already serialised the user data. Agency/client
51
+ # selection is transport-level (Client-Login header); method params
52
+ # must stay schema-shaped.
51
53
  raw = params.get("data")
52
54
  if raw:
53
55
  if isinstance(raw, (bytes, bytearray)):
@@ -67,6 +69,10 @@ class V4LiveClientAdapter(JSONAdapterMixin, TapiAdapter):
67
69
  body.setdefault("token", token)
68
70
  if language:
69
71
  body.setdefault("locale", language)
72
+ if finance_token:
73
+ body.setdefault("finance_token", finance_token)
74
+ if operation_num is not None:
75
+ body.setdefault("operation_num", operation_num)
70
76
 
71
77
  params["data"] = orjson.dumps(body)
72
78
 
@@ -100,7 +106,9 @@ class V4LiveClientAdapter(JSONAdapterMixin, TapiAdapter):
100
106
  data = None
101
107
  return data
102
108
 
103
- def process_response(self, response: Response, request_kwargs: dict, **kwargs) -> dict:
109
+ def process_response(
110
+ self, response: Response, request_kwargs: dict, **kwargs
111
+ ) -> dict:
104
112
  # Mirror the v5 behaviour: turn the serialised body back into a dict so
105
113
  # downstream hooks (extract, retry) can read it.
106
114
  if isinstance(request_kwargs.get("data"), (bytes, bytearray, str)):
@@ -180,8 +188,13 @@ class V4LiveClientAdapter(JSONAdapterMixin, TapiAdapter):
180
188
 
181
189
  return False
182
190
 
183
- def extract(self, data, response: Optional[Response] = None,
184
- request_kwargs: Optional[dict] = None, **kwargs):
191
+ def extract(
192
+ self,
193
+ data,
194
+ response: Optional[Response] = None,
195
+ request_kwargs: Optional[dict] = None,
196
+ **kwargs,
197
+ ):
185
198
  # v4 Live always nests payload under "data". For methods returning a
186
199
  # bare scalar (TransferMoney → 1), the scalar comes through unchanged.
187
200
  # response / request_kwargs are accepted but unused — they are kept
@@ -49,6 +49,8 @@ class YandexDirectV4Live:
49
49
  language: str = "en",
50
50
  retry_if_exceeded_limit: bool = True,
51
51
  retries_if_server_error: int = 5,
52
+ finance_token: Optional[str] = None,
53
+ operation_num: Optional[int] = None,
52
54
  ) -> None: ...
53
55
 
54
56
  def v4live(self) -> V4LiveExecutor: ...
@@ -80,6 +80,8 @@ def create_v4_client(
80
80
  language: Optional[str] = None,
81
81
  retry_if_exceeded_limit: bool = True,
82
82
  retries_if_server_error: int = 5,
83
+ finance_token: Optional[str] = None,
84
+ operation_num: Optional[int] = None,
83
85
  ) -> YandexDirectV4Live:
84
86
  """
85
87
  Create YandexDirect v4 Live client.
@@ -96,6 +98,8 @@ def create_v4_client(
96
98
  language: API locale
97
99
  retry_if_exceeded_limit: Retry when the API limit is exceeded
98
100
  retries_if_server_error: Number of retries for server errors
101
+ finance_token: Financial token for v4 Live finance methods
102
+ operation_num: Financial operation number for v4 Live finance methods
99
103
 
100
104
  Returns:
101
105
  YandexDirect v4 Live client instance
@@ -117,6 +121,8 @@ def create_v4_client(
117
121
  language=language or "en",
118
122
  retry_if_exceeded_limit=retry_if_exceeded_limit,
119
123
  retries_if_server_error=retries_if_server_error,
124
+ finance_token=finance_token,
125
+ operation_num=operation_num,
120
126
  )
121
127
 
122
128