direct-cli 0.4.0__tar.gz → 0.4.2__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.
- {direct_cli-0.4.0 → direct_cli-0.4.2}/CHANGELOG.md +197 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/CLAUDE.md +3 -3
- {direct_cli-0.4.0 → direct_cli-0.4.2}/PKG-INFO +79 -24
- {direct_cli-0.4.0 → direct_cli-0.4.2}/README.md +78 -23
- direct_cli-0.4.2/direct_cli/_autotargeting.py +206 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/direct_cli/_bidding_strategy.py +876 -882
- direct_cli-0.4.2/direct_cli/_flag_validation.py +53 -0
- direct_cli-0.4.2/direct_cli/_smoke_probes.py +173 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/direct_cli/_vendor/tapi_yandex_direct/__init__.py +1 -1
- direct_cli-0.4.2/direct_cli/_vendor/tapi_yandex_direct/endpoints.py +27 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/direct_cli/_vendor/tapi_yandex_direct/tapi_yandex_direct.py +37 -15
- {direct_cli-0.4.0 → direct_cli-0.4.2}/direct_cli/_vendor/tapi_yandex_direct/tapi_yandex_direct.pyi +9 -3
- {direct_cli-0.4.0 → direct_cli-0.4.2}/direct_cli/_vendor/tapi_yandex_direct/v4/adapter.py +10 -6
- {direct_cli-0.4.0 → direct_cli-0.4.2}/direct_cli/_vendor/tapi_yandex_direct/v4/adapter.pyi +1 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/direct_cli/api.py +23 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/direct_cli/auth.py +235 -33
- {direct_cli-0.4.0 → direct_cli-0.4.2}/direct_cli/cli.py +135 -24
- direct_cli-0.4.2/direct_cli/commands/_lifecycle.py +92 -0
- direct_cli-0.4.2/direct_cli/commands/adextensions.py +124 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/direct_cli/commands/adgroups.py +309 -446
- direct_cli-0.4.2/direct_cli/commands/adimages.py +122 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/direct_cli/commands/ads.py +574 -726
- direct_cli-0.4.2/direct_cli/commands/advideos.py +96 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/direct_cli/commands/agencyclients.py +149 -203
- direct_cli-0.4.2/direct_cli/commands/audiencetargets.py +198 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/direct_cli/commands/auth.py +153 -18
- {direct_cli-0.4.0 → direct_cli-0.4.2}/direct_cli/commands/balance.py +12 -14
- {direct_cli-0.4.0 → direct_cli-0.4.2}/direct_cli/commands/bidmodifiers.py +163 -234
- direct_cli-0.4.2/direct_cli/commands/bids.py +226 -0
- direct_cli-0.4.2/direct_cli/commands/businesses.py +57 -0
- direct_cli-0.4.2/direct_cli/commands/campaigns.py +7205 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/direct_cli/commands/changes.py +45 -58
- {direct_cli-0.4.0 → direct_cli-0.4.2}/direct_cli/commands/clients.py +94 -124
- direct_cli-0.4.2/direct_cli/commands/creatives.py +150 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/direct_cli/commands/dictionaries.py +26 -42
- direct_cli-0.4.2/direct_cli/commands/dynamicads.py +189 -0
- direct_cli-0.4.2/direct_cli/commands/dynamicfeedadtargets.py +190 -0
- direct_cli-0.4.2/direct_cli/commands/feeds.py +402 -0
- direct_cli-0.4.2/direct_cli/commands/keywordbids.py +299 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/direct_cli/commands/keywords.py +211 -407
- direct_cli-0.4.2/direct_cli/commands/keywordsresearch.py +68 -0
- direct_cli-0.4.2/direct_cli/commands/leads.py +80 -0
- direct_cli-0.4.2/direct_cli/commands/negativekeywordsharedsets.py +128 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/direct_cli/commands/reports.py +68 -67
- direct_cli-0.4.2/direct_cli/commands/retargeting.py +210 -0
- direct_cli-0.4.2/direct_cli/commands/sitelinks.py +289 -0
- direct_cli-0.4.2/direct_cli/commands/smartadtargets.py +281 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/direct_cli/commands/strategies.py +223 -294
- direct_cli-0.4.2/direct_cli/commands/turbopages.py +67 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/direct_cli/commands/v4account.py +54 -105
- direct_cli-0.4.2/direct_cli/commands/v4adimage.py +187 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/direct_cli/commands/v4events.py +18 -27
- {direct_cli-0.4.0 → direct_cli-0.4.2}/direct_cli/commands/v4finance.py +193 -134
- {direct_cli-0.4.0 → direct_cli-0.4.2}/direct_cli/commands/v4forecast.py +10 -49
- {direct_cli-0.4.0 → direct_cli-0.4.2}/direct_cli/commands/v4goals.py +7 -49
- direct_cli-0.4.2/direct_cli/commands/v4keywords.py +64 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/direct_cli/commands/v4tags.py +34 -59
- {direct_cli-0.4.0 → direct_cli-0.4.2}/direct_cli/commands/v4wordstat.py +12 -49
- direct_cli-0.4.2/direct_cli/commands/vcards.py +245 -0
- direct_cli-0.4.2/direct_cli/i18n.py +158 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/direct_cli/output.py +26 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/direct_cli/smoke_matrix.py +4 -0
- direct_cli-0.4.2/direct_cli/translations/adextensions.json +11 -0
- direct_cli-0.4.2/direct_cli/translations/adgroups.json +74 -0
- direct_cli-0.4.2/direct_cli/translations/adimages.json +13 -0
- direct_cli-0.4.2/direct_cli/translations/ads.json +134 -0
- direct_cli-0.4.2/direct_cli/translations/advideos.json +11 -0
- direct_cli-0.4.2/direct_cli/translations/agencyclients.json +32 -0
- direct_cli-0.4.2/direct_cli/translations/audiencetargets.json +17 -0
- direct_cli-0.4.2/direct_cli/translations/auth.json +25 -0
- direct_cli-0.4.2/direct_cli/translations/balance.json +4 -0
- direct_cli-0.4.2/direct_cli/translations/bidmodifiers.json +46 -0
- direct_cli-0.4.2/direct_cli/translations/bids.json +31 -0
- direct_cli-0.4.2/direct_cli/translations/businesses.json +5 -0
- direct_cli-0.4.2/direct_cli/translations/campaigns.json +313 -0
- direct_cli-0.4.2/direct_cli/translations/changes.json +18 -0
- direct_cli-0.4.2/direct_cli/translations/clients.json +41 -0
- direct_cli-0.4.2/direct_cli/translations/common.json +20 -0
- direct_cli-0.4.2/direct_cli/translations/creatives.json +12 -0
- direct_cli-0.4.2/direct_cli/translations/dictionaries.json +10 -0
- direct_cli-0.4.2/direct_cli/translations/dynamicads.json +10 -0
- direct_cli-0.4.2/direct_cli/translations/dynamicfeedadtargets.json +12 -0
- direct_cli-0.4.2/direct_cli/translations/feeds.json +37 -0
- direct_cli-0.4.2/direct_cli/translations/keywordbids.json +20 -0
- direct_cli-0.4.2/direct_cli/translations/keywords.json +62 -0
- direct_cli-0.4.2/direct_cli/translations/keywordsresearch.json +7 -0
- direct_cli-0.4.2/direct_cli/translations/leads.json +7 -0
- direct_cli-0.4.2/direct_cli/translations/negativekeywordsharedsets.json +11 -0
- direct_cli-0.4.2/direct_cli/translations/reports.json +23 -0
- direct_cli-0.4.2/direct_cli/translations/retargeting.json +16 -0
- direct_cli-0.4.2/direct_cli/translations/sitelinks.json +26 -0
- direct_cli-0.4.2/direct_cli/translations/smartadtargets.json +19 -0
- direct_cli-0.4.2/direct_cli/translations/strategies.json +60 -0
- direct_cli-0.4.2/direct_cli/translations/turbopages.json +6 -0
- direct_cli-0.4.2/direct_cli/translations/v4account.json +51 -0
- direct_cli-0.4.2/direct_cli/translations/v4adimage.json +15 -0
- direct_cli-0.4.2/direct_cli/translations/v4events.json +19 -0
- direct_cli-0.4.2/direct_cli/translations/v4finance.json +37 -0
- direct_cli-0.4.2/direct_cli/translations/v4forecast.json +14 -0
- direct_cli-0.4.2/direct_cli/translations/v4goals.json +5 -0
- direct_cli-0.4.2/direct_cli/translations/v4keywords.json +6 -0
- direct_cli-0.4.2/direct_cli/translations/v4shells.json +3 -0
- direct_cli-0.4.2/direct_cli/translations/v4tags.json +30 -0
- direct_cli-0.4.2/direct_cli/translations/v4wordstat.json +10 -0
- direct_cli-0.4.2/direct_cli/translations/vcards.json +34 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/direct_cli/utils.py +97 -7
- direct_cli-0.4.2/direct_cli/v4/emit.py +79 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/direct_cli/v4/money.py +8 -27
- {direct_cli-0.4.0 → direct_cli-0.4.2}/direct_cli/v4_contracts.py +1 -2
- {direct_cli-0.4.0 → direct_cli-0.4.2}/direct_cli.egg-info/PKG-INFO +79 -24
- {direct_cli-0.4.0 → direct_cli-0.4.2}/direct_cli.egg-info/SOURCES.txt +63 -1
- direct_cli-0.4.0/docs/audits/PROJECT_WIRE_SHAPE_AUDIT_2026-05-29.md → direct_cli-0.4.2/docs/audits/PROJECT_WIRE_SHAPE_AUDIT_2026-05-30.md +11 -64
- direct_cli-0.4.2/docs/audits/WIRE_SHAPE_TRIAGE_2026-05-30.md +85 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/docs/audits/wire_shape.json +17 -441
- {direct_cli-0.4.0 → direct_cli-0.4.2}/pyproject.toml +6 -1
- {direct_cli-0.4.0 → direct_cli-0.4.2}/scripts/audit_wire_shape.py +49 -10
- {direct_cli-0.4.0 → direct_cli-0.4.2}/scripts/build_api_coverage_report.py +16 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/scripts/check_all_docs_urls.py +15 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/scripts/patch_vendor_imports.py +109 -2
- direct_cli-0.4.2/scripts/probe_drift_urls.sh +59 -0
- direct_cli-0.4.2/tests/MANUAL_COVERAGE.md +147 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/api_coverage_payloads.py +5 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_read_cassettes/test_read_command[creatives_get].yaml +2 -2
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_read_cassettes/test_read_command[retargeting_get].yaml +2 -2
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_read_cassettes/test_read_command[strategies_get].yaml +2 -2
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_v5_live_write/test_v5_live_draft_ads_add_update_delete.yaml +64 -64
- direct_cli-0.4.2/tests/cassettes/test_v5_live_write/test_v5_live_draft_audiencetargets_add_delete.yaml +560 -0
- direct_cli-0.4.2/tests/cassettes/test_v5_live_write/test_v5_live_draft_audiencetargets_suspend_resume.yaml +622 -0
- direct_cli-0.4.2/tests/cassettes/test_v5_live_write/test_v5_live_draft_feeds_add_update_delete.yaml +250 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_v5_live_write/test_v5_live_draft_keywords_add_update_delete.yaml +122 -60
- direct_cli-0.4.0/tests/cassettes/test_v5_live_write/test_v5_live_draft_audiencetargets_suspend_resume.yaml → direct_cli-0.4.2/tests/cassettes/test_v5_live_write/test_v5_live_draft_retargeting_add_update_delete.yaml +40 -103
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_v5_live_write/test_v5_live_draft_smartadtargets_add_update_delete.yaml +24 -24
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_v5_live_write/test_v5_live_draft_smartadtargets_suspend_resume.yaml +24 -24
- direct_cli-0.4.0/tests/cassettes/test_v5_live_write/test_v5_live_draft_audiencetargets_add_delete.yaml → direct_cli-0.4.2/tests/cassettes/test_v5_live_write/test_v5_live_draft_strategies_add_update_archive_unarchive.yaml +49 -50
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/conftest.py +122 -8
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/test_api_coverage.py +13 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/test_audit_wire_shape.py +40 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/test_auth_bw.py +30 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/test_auth_oauth.py +425 -2
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/test_auth_op.py +30 -0
- direct_cli-0.4.2/tests/test_autotargeting.py +228 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/test_balance.py +20 -0
- direct_cli-0.4.2/tests/test_bidding_strategy_constants.py +197 -0
- direct_cli-0.4.2/tests/test_cassette_integrity.py +87 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/test_cli.py +94 -9
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/test_comprehensive.py +2 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/test_dry_run.py +216 -20
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/test_env_loading.py +54 -0
- direct_cli-0.4.2/tests/test_field_names_option.py +85 -0
- direct_cli-0.4.2/tests/test_flag_validation.py +130 -0
- direct_cli-0.4.2/tests/test_handle_api_errors.py +101 -0
- direct_cli-0.4.2/tests/test_i18n.py +388 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/test_integration.py +12 -14
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/test_low_coverage_payloads.py +71 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/test_read_cassettes.py +6 -2
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/test_reports_parsing.py +55 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/test_transport_contract.py +20 -10
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/test_v4_exit_codes.py +9 -9
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/test_v4account.py +26 -26
- direct_cli-0.4.2/tests/test_v4adimage.py +176 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/test_v4events.py +4 -4
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/test_v4finance_money.py +121 -16
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/test_v4finance_read.py +9 -9
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/test_v4forecast.py +6 -6
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/test_v4goals.py +6 -6
- direct_cli-0.4.2/tests/test_v4keywords.py +112 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/test_v4tags.py +4 -4
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/test_v4wordstat.py +7 -7
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/test_v5_live_write.py +218 -7
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/test_vendor_imports.py +119 -0
- direct_cli-0.4.0/direct_cli/_smoke_probes.py +0 -94
- direct_cli-0.4.0/direct_cli/_vendor/tapi_yandex_direct/endpoints.py +0 -14
- direct_cli-0.4.0/direct_cli/commands/adextensions.py +0 -163
- direct_cli-0.4.0/direct_cli/commands/adimages.py +0 -157
- direct_cli-0.4.0/direct_cli/commands/advideos.py +0 -116
- direct_cli-0.4.0/direct_cli/commands/audiencetargets.py +0 -305
- direct_cli-0.4.0/direct_cli/commands/bids.py +0 -247
- direct_cli-0.4.0/direct_cli/commands/businesses.py +0 -67
- direct_cli-0.4.0/direct_cli/commands/campaigns.py +0 -7547
- direct_cli-0.4.0/direct_cli/commands/creatives.py +0 -170
- direct_cli-0.4.0/direct_cli/commands/dynamicads.py +0 -292
- direct_cli-0.4.0/direct_cli/commands/dynamicfeedadtargets.py +0 -296
- direct_cli-0.4.0/direct_cli/commands/feeds.py +0 -445
- direct_cli-0.4.0/direct_cli/commands/keywordbids.py +0 -320
- direct_cli-0.4.0/direct_cli/commands/keywordsresearch.py +0 -88
- direct_cli-0.4.0/direct_cli/commands/leads.py +0 -84
- direct_cli-0.4.0/direct_cli/commands/negativekeywordsharedsets.py +0 -172
- direct_cli-0.4.0/direct_cli/commands/retargeting.py +0 -236
- direct_cli-0.4.0/direct_cli/commands/sitelinks.py +0 -302
- direct_cli-0.4.0/direct_cli/commands/smartadtargets.py +0 -394
- direct_cli-0.4.0/direct_cli/commands/turbopages.py +0 -79
- direct_cli-0.4.0/direct_cli/commands/vcards.py +0 -282
- direct_cli-0.4.0/direct_cli/i18n.py +0 -107
- direct_cli-0.4.0/tests/MANUAL_COVERAGE.md +0 -92
- direct_cli-0.4.0/tests/test_i18n.py +0 -118
- {direct_cli-0.4.0 → direct_cli-0.4.2}/.env.example +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/.github/copilot-instructions.md +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/.github/workflows/api-coverage.yml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/.github/workflows/claude.yml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/.github/workflows/quality.yml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/.gitignore +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/AGENTS.md +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/MANIFEST.in +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/direct_cli/__init__.py +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/direct_cli/_deprecated.py +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/direct_cli/_vendor/__init__.py +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/direct_cli/_vendor/tapi_yandex_direct/exceptions.py +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/direct_cli/_vendor/tapi_yandex_direct/resource_mapping.py +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/direct_cli/_vendor/tapi_yandex_direct/v4/__init__.py +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/direct_cli/_vendor/tapi_yandex_direct/v4/resource_mapping.py +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/direct_cli/commands/__init__.py +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/direct_cli/commands/v4shells.py +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/direct_cli/reports_coverage.py +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/direct_cli/v4/__init__.py +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/direct_cli/wsdl_coverage.py +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/direct_cli.egg-info/dependency_links.txt +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/direct_cli.egg-info/entry_points.txt +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/direct_cli.egg-info/requires.txt +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/direct_cli.egg-info/top_level.txt +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/docs/audits/API_COVERAGE.md +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/docs/audits/issue-198-mutating-wsdl-audit.md +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/docs/superpowers/plans/2026-04-12-issue-32-completion.md +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/docs/superpowers/specs/2026-04-23-vendor-tapi-yandex-direct-design.md +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/scripts/anonymize_cassettes.py +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/scripts/build_api_coverage_checklist.py +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/scripts/build_wsdl_optional_field_audit.py +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/scripts/check_reports_drift.py +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/scripts/check_wsdl_drift.py +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/scripts/preflight_check.sh +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/scripts/refresh_reports_cache.py +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/scripts/refresh_wsdl_cache.py +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/scripts/release_pypi.sh +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/scripts/sandbox_write_audit.py +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/scripts/sandbox_write_live.py +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/scripts/test_dangerous_commands.sh +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/scripts/test_safe_commands.sh +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/scripts/test_sandbox_write.sh +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/scripts/update_vendor.sh +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/setup.cfg +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/setup.py +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/API_COVERAGE.md +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/API_ISSUE_AUDIT.md +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/WSDL_OPTIONAL_FIELD_AUDIT.md +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/__init__.py +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/_orphan_store.py +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_integration_write/TestWriteAdExtensions.test_add_delete.yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_integration_write/TestWriteAdGroups.test_add_update_delete.yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_integration_write/TestWriteAdImages.test_add_delete.yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_integration_write/TestWriteAds.test_add_text_ad_update_delete.yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_integration_write/TestWriteAudienceTargets.test_add_delete.yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_integration_write/TestWriteBidModifiersAdd.test_add_delete_mobile.yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_integration_write/TestWriteBidModifiersSet.test_set_without_id_is_rejected.yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_integration_write/TestWriteBids.test_set_bid.yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_integration_write/TestWriteBidsRead.test_bids_get.yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_integration_write/TestWriteBidsRead.test_bids_set_auto.yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_integration_write/TestWriteCampaignDraftLifecycle.test_draft_create_get_delete.yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_integration_write/TestWriteCampaigns.test_campaign_lifecycle.yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_integration_write/TestWriteDynamicAds.test_add_update_delete.yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_integration_write/TestWriteFeeds.test_add_update_delete.yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_integration_write/TestWriteKeywordBids.test_set_keyword_bid.yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_integration_write/TestWriteKeywords.test_add_update_delete.yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_integration_write/TestWriteNegativeKeywordSharedSets.test_add_update_delete.yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_integration_write/TestWriteRetargeting.test_add_delete.yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_integration_write/TestWriteRetargetingUpdate.test_retargeting_update.yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_integration_write/TestWriteSitelinks.test_add_delete.yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_integration_write/TestWriteSmartAdTargets.test_add_update_delete.yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_integration_write/TestWriteStrategies.test_strategies_lifecycle.yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_integration_write/TestWriteVCards.test_add_delete.yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_read_cassettes/test_read_command[adextensions_get].yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_read_cassettes/test_read_command[adgroups_get].yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_read_cassettes/test_read_command[adimages_get].yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_read_cassettes/test_read_command[ads_get].yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_read_cassettes/test_read_command[advideos_get].yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_read_cassettes/test_read_command[audiencetargets_get].yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_read_cassettes/test_read_command[bidmodifiers_get].yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_read_cassettes/test_read_command[bids_get].yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_read_cassettes/test_read_command[businesses_get].yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_read_cassettes/test_read_command[campaigns_get].yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_read_cassettes/test_read_command[changes_check].yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_read_cassettes/test_read_command[changes_check_campaigns].yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_read_cassettes/test_read_command[changes_check_dictionaries].yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_read_cassettes/test_read_command[clients_get].yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_read_cassettes/test_read_command[dictionaries_get].yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_read_cassettes/test_read_command[dynamicads_get].yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_read_cassettes/test_read_command[dynamicfeedadtargets_get].yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_read_cassettes/test_read_command[feeds_get].yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_read_cassettes/test_read_command[keywordbids_get].yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_read_cassettes/test_read_command[keywords_get].yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_read_cassettes/test_read_command[keywordsresearch_deduplicate].yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_read_cassettes/test_read_command[keywordsresearch_has_search_volume].yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_read_cassettes/test_read_command[leads_get].yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_read_cassettes/test_read_command[negativekeywordsharedsets_get].yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_read_cassettes/test_read_command[reports_get].yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_read_cassettes/test_read_command[sitelinks_get].yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_read_cassettes/test_read_command[smartadtargets_get].yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_read_cassettes/test_read_command[turbopages_get].yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_read_cassettes/test_read_command[v4events_get_events_log].yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_read_cassettes/test_read_command[v4finance_get_clients_units].yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_read_cassettes/test_read_command[v4forecast_list].yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_read_cassettes/test_read_command[v4goals_get_stat_goals].yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_read_cassettes/test_read_command[v4tags_get_campaigns].yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_read_cassettes/test_read_command[v4wordstat_list_reports].yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_read_cassettes/test_read_command[vcards_get].yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_read_cassettes/test_v4finance_check_payment_unknown_transaction.yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_v5_live_write/test_v5_live_draft_adgroups_add_update_delete.yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_v5_live_write/test_v5_live_draft_adimages_add_get_delete.yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_v5_live_write/test_v5_live_draft_ads_suspend_resume_archive_unarchive.yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_v5_live_write/test_v5_live_draft_advideos_add_get.yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_v5_live_write/test_v5_live_draft_bids_set.yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_v5_live_write/test_v5_live_draft_campaign_create_get_delete.yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_v5_live_write/test_v5_live_draft_creatives_chain_advideo_to_creative.yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_v5_live_write/test_v5_live_draft_dynamicads_add_delete.yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_v5_live_write/test_v5_live_draft_dynamicads_suspend_resume.yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_v5_live_write/test_v5_live_draft_keywordbids_set.yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_v5_live_write/test_v5_live_draft_keywords_suspend_resume.yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/cassettes/test_v5_live_write/test_v5_live_draft_sitelinks_add_get_delete.yaml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/fixtures/test-video.mp4 +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/reports_cache/raw/fields-list.html +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/reports_cache/raw/headers.html +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/reports_cache/raw/period.html +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/reports_cache/raw/spec.html +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/reports_cache/raw/type.html +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/reports_cache/spec.json +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/test_auth_write_json.py +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/test_changes.py +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/test_cli_contract.py +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/test_integration_write.py +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/test_reports_drift.py +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/test_sandbox_write_audit.py +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/test_smoke_matrix.py +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/test_unknown_option_hints.py +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/test_v4_contracts.py +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/test_v4_foundation.py +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/test_v4_live_contracts.py +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/test_v4_runtime_shape.py +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/test_v4_safety.py +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/test_wsdl_parity_gate.py +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/wsdl_cache/adextensions.xml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/wsdl_cache/adgroups.xml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/wsdl_cache/adimages.xml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/wsdl_cache/ads.xml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/wsdl_cache/advideos.xml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/wsdl_cache/agencyclients.xml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/wsdl_cache/audiencetargets.xml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/wsdl_cache/bidmodifiers.xml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/wsdl_cache/bids.xml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/wsdl_cache/businesses.xml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/wsdl_cache/campaigns.xml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/wsdl_cache/changes.xml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/wsdl_cache/clients.xml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/wsdl_cache/creatives.xml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/wsdl_cache/dictionaries.xml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/wsdl_cache/dynamicfeedadtargets.xml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/wsdl_cache/dynamictextadtargets.xml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/wsdl_cache/feeds.xml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/wsdl_cache/imports/adextensiontypes.xsd +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/wsdl_cache/imports/general.xsd +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/wsdl_cache/imports/generalclients.xsd +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/wsdl_cache/keywordbids.xml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/wsdl_cache/keywords.xml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/wsdl_cache/keywordsresearch.xml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/wsdl_cache/leads.xml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/wsdl_cache/negativekeywordsharedsets.xml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/wsdl_cache/retargetinglists.xml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/wsdl_cache/sitelinks.xml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/wsdl_cache/smartadtargets.xml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/wsdl_cache/strategies.xml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/wsdl_cache/turbopages.xml +0 -0
- {direct_cli-0.4.0 → direct_cli-0.4.2}/tests/wsdl_cache/vcards.xml +0 -0
|
@@ -1,5 +1,202 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.4.2
|
|
4
|
+
|
|
5
|
+
**BREAKING CHANGES - get requires SelectionCriteria (#498):**
|
|
6
|
+
|
|
7
|
+
- `adgroups` / `ads` / `keywords` / `strategies` / `creatives` / `dynamicads` /
|
|
8
|
+
`smartadtargets` / `audiencetargets` `get` now refuse an empty
|
|
9
|
+
`SelectionCriteria` before the API call, raising a `UsageError` that asks for
|
|
10
|
+
at least one filter — instead of sending `{"SelectionCriteria": {}}` (which the
|
|
11
|
+
API rejects with the opaque error 4001 for ad-group/ad/keyword resources).
|
|
12
|
+
Extends the same guard already shipped for `bids` / `keywordbids` in 0.4.1
|
|
13
|
+
(#483). WSDL declares `GetRequest.SelectionCriteria` as `minOccurs=1` for all
|
|
14
|
+
eight resources.
|
|
15
|
+
- `retargeting get` gains `--dry-run` and the shared read/pagination option
|
|
16
|
+
stack; its `SelectionCriteria` stays optional (WSDL `minOccurs=0`), so a
|
|
17
|
+
no-filter call is still valid and now omits the empty criteria from the
|
|
18
|
+
payload.
|
|
19
|
+
- All eight commands and `retargeting get` build their request via the shared
|
|
20
|
+
`build_common_params` helper, completing the dedup epic #491 (B3c).
|
|
21
|
+
|
|
22
|
+
**BREAKING CHANGES - auth precedence (#489):**
|
|
23
|
+
|
|
24
|
+
- Base `YANDEX_DIRECT_TOKEN` / `YANDEX_DIRECT_LOGIN` credentials from the
|
|
25
|
+
environment or current-directory `.env` now win over the active OAuth profile
|
|
26
|
+
selected by `direct auth use` when `--profile` is not passed. Explicit
|
|
27
|
+
`--token`, `--login`, and `--profile` still take priority.
|
|
28
|
+
- `direct auth status` reports the selected effective credentials, including
|
|
29
|
+
base env/`.env` and secret-manager fallbacks, instead of reporting only the
|
|
30
|
+
active OAuth profile.
|
|
31
|
+
- `direct auth login` can now ask interactive users whether to save the OAuth
|
|
32
|
+
access token and resolved login into the current-directory `.env`; the default
|
|
33
|
+
answer is no.
|
|
34
|
+
|
|
35
|
+
**Docs — live-write coverage limitation (#538):**
|
|
36
|
+
|
|
37
|
+
- Documented why the SMART_CAMPAIGN / DYNAMIC_TEXT_CAMPAIGN / `adimages`
|
|
38
|
+
live-write lifecycle (`dynamicads`, `smartadtargets`, `adimages`) stays
|
|
39
|
+
recorded only as 3500/5004 error cassettes. Verified via direct API calls that
|
|
40
|
+
the available sandbox **agency** account has no client accounts under it
|
|
41
|
+
(`agencyclients.get` → empty), cannot create one (3001 "No rights to create
|
|
42
|
+
clients", access by request only), and that without a client login every
|
|
43
|
+
agency-scoped mutation returns 8000. Closed #538 as a documented account-tier
|
|
44
|
+
limitation; no CLI code change. See `tests/MANUAL_COVERAGE.md`.
|
|
45
|
+
|
|
46
|
+
## 0.4.1
|
|
47
|
+
|
|
48
|
+
Russian-default CLI localization across all command modules (epic #466).
|
|
49
|
+
|
|
50
|
+
**Fixed — bug hunt (#483):**
|
|
51
|
+
|
|
52
|
+
- `bids get` / `keywordbids get`: refuse an empty `SelectionCriteria` before the
|
|
53
|
+
API call, raising a `UsageError` that asks for at least one filter
|
|
54
|
+
(`--campaign-ids` / `--adgroup-ids` / `--keyword-ids` / `--serving-statuses`)
|
|
55
|
+
instead of letting the API reject it with the opaque error 4001.
|
|
56
|
+
- `bids set-auto`: require exactly one of `--campaign-id`, `--adgroup-id`, or
|
|
57
|
+
`--keyword-id` via the shared `add_single_id_selector` (the three are mutually
|
|
58
|
+
exclusive per the API docs), matching `bids set`.
|
|
59
|
+
- `reports get`: reject a `--fields` value that parses to an empty list (for
|
|
60
|
+
example `",,,"`) before building the request, instead of sending an invalid
|
|
61
|
+
`FieldNames: []` (API error 8000).
|
|
62
|
+
- Error-handling consistency: `get`/lifecycle handlers across `bids`,
|
|
63
|
+
`keywordbids`, `negativekeywordsharedsets`, `balance`, `strategies`,
|
|
64
|
+
`retargeting`, `ads` (all 8 commands), and `advideos` now re-raise
|
|
65
|
+
`click.UsageError` / `click.ClickException` before the generic
|
|
66
|
+
`except Exception`, so validation errors keep their Click formatting and
|
|
67
|
+
exit code 2 instead of being downgraded to an `Abort`.
|
|
68
|
+
- Vendor `tapi_yandex_direct`: `to_columns()` no longer raises `IndexError` on
|
|
69
|
+
report rows shorter than the header (pads with `""`); the error handler reads
|
|
70
|
+
`error_detail` with `.get()` so an unfamiliar error structure no longer masks
|
|
71
|
+
the original API error with a `KeyError`.
|
|
72
|
+
- `utils.parse_priority_goals_spec`: corrected the item type annotation to
|
|
73
|
+
`List[Dict[str, Any]]` (items hold `"YES"/"NO"` strings, not only ints).
|
|
74
|
+
|
|
75
|
+
**Fixed — `--help` hung on a client-login network call (#480 follow-up):**
|
|
76
|
+
|
|
77
|
+
- After #480, `get_credentials` resolved the bare Client-Login via a network
|
|
78
|
+
`clients.get` on every CLI invocation — including `<group> --help` — whenever
|
|
79
|
+
an OAuth profile with an email login had not yet been migrated. That call had
|
|
80
|
+
no timeout, so a slow link or a Yandex SmartCaptcha gateway could hang the
|
|
81
|
+
CLI. Help/version passes now skip the resolver, the resolver is capped with a
|
|
82
|
+
hard timeout, and the unit suite neutralizes it so tests never touch the
|
|
83
|
+
network.
|
|
84
|
+
|
|
85
|
+
**Fixed — auth login saved Passport email, breaking v4 (#480):**
|
|
86
|
+
|
|
87
|
+
- `direct auth login` (OAuth / PKCE) stored the Passport email
|
|
88
|
+
(`<login>@yandex.ru`) in `auth.json`, which Direct v4 AccountManagement
|
|
89
|
+
rejects with `FaultCode 259` ("This client does not exist") — breaking
|
|
90
|
+
`direct balance` and `direct v4account ...`. Login now resolves the bare
|
|
91
|
+
**Client-Login** via a one-shot v5 `clients.get` (`resolve_account_login`),
|
|
92
|
+
falling back to the Passport login only if that call fails.
|
|
93
|
+
- `get_credentials` migrates older profiles in place: when a stored OAuth login
|
|
94
|
+
is an email whose local part matches the token owner's resolved Client-Login,
|
|
95
|
+
it is rewritten to the bare login (one-time, persisted). Agency profiles whose
|
|
96
|
+
login differs from the token owner are never clobbered, and an explicit
|
|
97
|
+
`--login` is never overridden.
|
|
98
|
+
|
|
99
|
+
**Localized — interpolated error messages (#478), completing epic #466:**
|
|
100
|
+
|
|
101
|
+
- Rewrote all 121 interpolated `click.UsageError` / `click.BadParameter` /
|
|
102
|
+
`print_*` messages (114 f-strings + 7 string concatenations) across the
|
|
103
|
+
command modules into the stable `t("<template>").format(**kwargs)` pattern,
|
|
104
|
+
with 96 unique English templates translated to Russian (6 shared templates,
|
|
105
|
+
e.g. `Provide a non-empty comma-separated {wsdl_key} list.`, in
|
|
106
|
+
`common.json`). Placeholder names, conversions, and format specs are
|
|
107
|
+
preserved verbatim in both locales, so the rendered English text is
|
|
108
|
+
byte-identical to before and the Russian render fills the same fields.
|
|
109
|
+
- `t()` gained `@overload` signatures (`str -> str`, `None -> None`) so
|
|
110
|
+
`t(...).format(...)` type-checks without touching call sites.
|
|
111
|
+
- `tests/test_i18n.py` now (a) flags f-string / concat — not just static —
|
|
112
|
+
bare literals in `_RUNTIME_MESSAGE_FUNCS` calls (also covering
|
|
113
|
+
`print_success`), accepting only `t(...)` / `t(...).format(...)`; and
|
|
114
|
+
(b) asserts placeholder parity between every English template key and its
|
|
115
|
+
Russian translation. This completes the error-message localization checklist
|
|
116
|
+
of epic #466.
|
|
117
|
+
|
|
118
|
+
**Localized — static error messages (#477):**
|
|
119
|
+
|
|
120
|
+
- Wrapped all 179 static `click.UsageError` / `click.BadParameter` string
|
|
121
|
+
literals (and the `auth` OAuth-code `click.prompt`) across 33 command
|
|
122
|
+
modules in `t(...)`, with Russian translations added to the per-module
|
|
123
|
+
`translations/*.json` catalogs; seven messages shared across modules
|
|
124
|
+
(e.g. `Provide at least one field to update`,
|
|
125
|
+
`--status and --statuses are mutually exclusive`) live in `common.json`.
|
|
126
|
+
Validation errors now render in Russian by default and in English under
|
|
127
|
+
`--locale en`. Flag names, enum values, and WSDL field names are unchanged.
|
|
128
|
+
- Extended `tests/test_i18n.py::test_localized_groups_wrap_runtime_messages`
|
|
129
|
+
to also scan `UsageError` / `BadParameter` / `prompt` / `confirm` (bare or
|
|
130
|
+
`click.<Name>`); a bare string literal first argument is rejected. Only
|
|
131
|
+
static `ast.Constant` literals are enforced for now — interpolated
|
|
132
|
+
(f-string / concat) messages are stage B (#478).
|
|
133
|
+
- Test suite defaults the CLI locale to English (`tests/conftest.py` autouse
|
|
134
|
+
fixture) so the existing English error-contract assertions stay valid; the
|
|
135
|
+
Russian default remains covered by `tests/test_i18n.py`.
|
|
136
|
+
|
|
137
|
+
**Added — scalable i18n mechanism (#467):**
|
|
138
|
+
|
|
139
|
+
- Source-string-keyed translation catalog: the English `help=` / docstring /
|
|
140
|
+
epilog text is the catalog key, with Russian translations in external
|
|
141
|
+
`direct_cli/translations/*.json` files (one per module, plus shared
|
|
142
|
+
`common.json`). No `cls=`/`help_key` edits in command modules —
|
|
143
|
+
`cli._apply_directcli_classes` retypes every plain `click.Option` to
|
|
144
|
+
`LocalizedOption` and localizes command/group docstrings and epilogs at
|
|
145
|
+
render time.
|
|
146
|
+
- `t()` is now source-keyed and context-free safe (`set_active_locale`), so
|
|
147
|
+
`print_*` runtime messages localize too. `--locale` is eager so the root
|
|
148
|
+
`--help` epilog honors an inline `--locale`.
|
|
149
|
+
- `tests/test_i18n.py` gains a `LOCALIZED_GROUPS` registry with two enforced
|
|
150
|
+
invariants per localized module: translation completeness (no silent English
|
|
151
|
+
leak under the Russian default) and `print_*` runtime-message wrapping.
|
|
152
|
+
- `v4finance` migrated to the new mechanism and fully localized as the
|
|
153
|
+
reference module.
|
|
154
|
+
|
|
155
|
+
**Localized — Core search (#468):**
|
|
156
|
+
|
|
157
|
+
- Russian help/docstrings for `campaigns`, `ads`, `adgroups`, `keywords`,
|
|
158
|
+
`keywordbids`, and `bids` (510 unique strings across the six modules).
|
|
159
|
+
WSDL field paths, enum values, and flag names are kept verbatim; only
|
|
160
|
+
human-readable text is translated. These groups join `LOCALIZED_GROUPS`,
|
|
161
|
+
so their translation completeness is now enforced by `test_i18n.py`.
|
|
162
|
+
|
|
163
|
+
**Localized — Targeting & creatives (#469):**
|
|
164
|
+
|
|
165
|
+
- Russian help/docstrings for `strategies`, `bidmodifiers`, `smartadtargets`,
|
|
166
|
+
`vcards`, `feeds`, `dynamicads`, `audiencetargets`, `dynamicfeedadtargets`,
|
|
167
|
+
`retargeting`, `negativekeywordsharedsets`, `adextensions`, `adimages`,
|
|
168
|
+
`sitelinks`, `creatives`, `advideos`, and `turbopages` (247 unique strings
|
|
169
|
+
across the sixteen modules). WSDL field paths, enum values, and flag names
|
|
170
|
+
are kept verbatim; only human-readable text is translated. These groups
|
|
171
|
+
join `LOCALIZED_GROUPS`, so their translation completeness is now enforced
|
|
172
|
+
by `test_i18n.py`.
|
|
173
|
+
|
|
174
|
+
**Localized — Account, clients, reporting (#470):**
|
|
175
|
+
|
|
176
|
+
- Russian help/docstrings for `clients`, `agencyclients`, `reports`, `changes`,
|
|
177
|
+
`auth`, `leads`, `dictionaries`, `keywordsresearch`, `businesses`, and
|
|
178
|
+
`balance` (142 source strings across the ten modules). WSDL field paths,
|
|
179
|
+
enum values, and flag names are kept verbatim; only human-readable text is
|
|
180
|
+
translated.
|
|
181
|
+
- First modules with localized **runtime messages**: `print_*` calls carrying a
|
|
182
|
+
human-readable literal (`auth` interactive prompts, the `agencyclients delete`
|
|
183
|
+
not-supported notice) are now wrapped in `t()` so they follow the active
|
|
184
|
+
locale. `print_error(str(e))` API-error passthroughs are unchanged. These
|
|
185
|
+
groups join `LOCALIZED_GROUPS`, enforcing both translation completeness and
|
|
186
|
+
the runtime-message wrapping invariant.
|
|
187
|
+
|
|
188
|
+
**Localized — v4 Live services (#471), completing epic #466:**
|
|
189
|
+
|
|
190
|
+
- Russian help/docstrings for `v4account`, `v4tags`, `v4forecast`,
|
|
191
|
+
`v4wordstat`, `v4events`, `v4adimage`, `v4goals`, `v4keywords`, and `v4meta`
|
|
192
|
+
(87 source strings across the nine modules). `v4finance` was already
|
|
193
|
+
localized as the reference module in #467.
|
|
194
|
+
- With these groups, **all 42 CLI command groups are in `LOCALIZED_GROUPS`**:
|
|
195
|
+
the completeness invariant now covers the entire command tree, so every
|
|
196
|
+
English help/docstring string ships with a Russian translation under the
|
|
197
|
+
Russian default. The `v4 Live` epilog (single-sourced docs URL) stays
|
|
198
|
+
verbatim per the URL-registry rule. This closes the localization epic #466.
|
|
199
|
+
|
|
3
200
|
## 0.4.0
|
|
4
201
|
|
|
5
202
|
Milestone release closing the 0.4.0 roadmap (#123): typed Yandex Direct
|
|
@@ -24,9 +24,9 @@ Click group-of-groups. Each Yandex Direct API resource = one file in `direct_cli
|
|
|
24
24
|
|
|
25
25
|
**Request flow:** `cli.py` → `auth.py` (resolves token/login) → `api.py` (`create_client`) → `tapi_yandex_direct.YandexDirect` → Yandex API → `output.py` (format/print).
|
|
26
26
|
|
|
27
|
-
**Credentials priority (CLI):** CLI flags (`--token`, `--login`) >
|
|
27
|
+
**Credentials priority (CLI):** explicit CLI flags (`--token`, `--login`, `--profile`) > base env/current working directory `.env` (`YANDEX_DIRECT_TOKEN`, `YANDEX_DIRECT_LOGIN`) > active profile from `direct auth login` / `direct auth use` > 1Password/Bitwarden refs. Explicit `--profile` is isolated and does not fall back to base `.env` login. See `direct_cli/auth.py` (`get_credentials`) and README table for the full chain.
|
|
28
28
|
|
|
29
|
-
**Credentials priority (tests):**
|
|
29
|
+
**Credentials priority (tests):** env vars/current working directory `.env` > active profile > skip. Tests must not silently hit production when a developer has an active `direct auth` profile, so env vars take precedence over the profile (see `tests/test_v4_live_contracts.py::_credentials`).
|
|
30
30
|
|
|
31
31
|
**Shared utilities** (`utils.py`): `parse_ids`, `parse_json`, `build_selection_criteria`, `build_common_params`, `get_default_fields`, `COMMON_FIELDS` dict. All command modules import from here — don't duplicate.
|
|
32
32
|
|
|
@@ -106,7 +106,7 @@ Builds dist artifacts, runs twine checks, uploads to TestPyPI + PyPI. Does **not
|
|
|
106
106
|
|
|
107
107
|
- **Unit** (`test_cli.py`, `test_comprehensive.py`) — no API calls, no token needed.
|
|
108
108
|
- **Integration** (`test_integration.py`, `@pytest.mark.integration`) — require `.env` with `YANDEX_DIRECT_TOKEN` and `YANDEX_DIRECT_LOGIN`. Auto-skip if absent.
|
|
109
|
-
- **Credential resolution in tests:** env vars first, then active `direct auth` profile, then skip. This
|
|
109
|
+
- **Credential resolution in tests:** env vars/current working directory `.env` first, then active `direct auth` profile, then skip. This matches the safe CLI default for base env vs. active profile: a developer machine with an active profile must not silently hit production on a plain `pytest`.
|
|
110
110
|
|
|
111
111
|
## Dangerous Commands — Never Auto-Test
|
|
112
112
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: direct-cli
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.2
|
|
4
4
|
Summary: Command-line interface for Yandex Direct API
|
|
5
5
|
Author: axisrow
|
|
6
6
|
License: MIT
|
|
@@ -106,6 +106,9 @@ Notes:
|
|
|
106
106
|
- If the first non-interactive step includes `--client-secret`, the secret is remembered for the matching completion step.
|
|
107
107
|
- If a profile already stores a confidential OAuth client, `direct auth login --code CODE --profile NAME` reuses the saved `client_id` and `client_secret`.
|
|
108
108
|
- `direct auth login --oauth-token TOKEN` is a manual access-token import and does not auto-refresh.
|
|
109
|
+
- After a successful interactive login, Direct CLI asks whether to save the
|
|
110
|
+
access token and login to the current working directory `.env`; non-interactive
|
|
111
|
+
login flows do not prompt.
|
|
109
112
|
- Alias `auth_login` is not supported.
|
|
110
113
|
|
|
111
114
|
Credential resolution priority:
|
|
@@ -113,22 +116,23 @@ Credential resolution priority:
|
|
|
113
116
|
| Priority | Source | Example |
|
|
114
117
|
|----------|--------|---------|
|
|
115
118
|
| 1 | Explicit CLI options | `direct --token TOKEN --login LOGIN campaigns get` |
|
|
116
|
-
| 2 |
|
|
117
|
-
| 3 |
|
|
118
|
-
| 4 |
|
|
119
|
+
| 2 | Explicit profile credentials | `direct --profile agency1 campaigns get` |
|
|
120
|
+
| 3 | Base env vars or current working directory `.env` | `YANDEX_DIRECT_TOKEN`, `YANDEX_DIRECT_LOGIN` |
|
|
121
|
+
| 4 | Active profile credentials | `direct auth use --profile agency1` |
|
|
119
122
|
| 5 | 1Password references | `--op-token-ref`, `YANDEX_DIRECT_OP_TOKEN_REF` |
|
|
120
123
|
| 6 | Bitwarden references | `--bw-token-ref`, `YANDEX_DIRECT_BW_TOKEN_REF` |
|
|
121
124
|
|
|
122
125
|
Direct CLI automatically loads only the `.env` file from the current working
|
|
123
126
|
directory, i.e. the directory where you run `direct`. It does not search for
|
|
124
|
-
`.env` from the installed package or source-code location.
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
127
|
+
`.env` from the installed package or source-code location. Without an explicit
|
|
128
|
+
`--profile`, base `YANDEX_DIRECT_TOKEN` / `YANDEX_DIRECT_LOGIN` from env or cwd
|
|
129
|
+
`.env` win over the active OAuth profile. With explicit `--profile`, Direct CLI
|
|
130
|
+
uses only that profile's OAuth/profile-env credentials and does not fall back to
|
|
131
|
+
base `YANDEX_DIRECT_LOGIN`; this prevents mixing accounts. `direct auth status`
|
|
132
|
+
without `--profile` reports the effective credential source; with `--profile` it
|
|
133
|
+
reports that profile.
|
|
130
134
|
|
|
131
|
-
> **Tests
|
|
135
|
+
> **Tests follow the safe credential order.** Live-API test suites (e.g. `tests/test_v4_live_contracts.py`) read `YANDEX_DIRECT_TOKEN` / `YANDEX_DIRECT_LOGIN` from the environment first, only then fall back to the active `direct auth` profile, and skip the test if neither is set. This prevents a developer machine with an active profile from silently hitting production on a plain `pytest` invocation. See `CLAUDE.md` for the contract.
|
|
132
136
|
|
|
133
137
|
Install with `pip install direct-cli`, then run commands with `direct`.
|
|
134
138
|
Invoking the deprecated `direct-cli` entrypoint exits with
|
|
@@ -208,6 +212,31 @@ direct v4wordstat get-report --report-id 123 --format table
|
|
|
208
212
|
direct v4wordstat delete-report --report-id 123
|
|
209
213
|
```
|
|
210
214
|
|
|
215
|
+
### V4 Live Keyword Suggestions
|
|
216
|
+
|
|
217
|
+
`get-suggestion` returns up to 20 related phrases for the seed phrases. Repeat
|
|
218
|
+
`--keyword` for multiple seeds. The method consumes API points.
|
|
219
|
+
|
|
220
|
+
```bash
|
|
221
|
+
direct v4keywords get-suggestion --keyword холодильник --keyword камера
|
|
222
|
+
direct v4keywords get-suggestion --keyword "buy laptop" --format table
|
|
223
|
+
direct v4keywords get-suggestion --keyword холодильник --dry-run
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### V4 Live Ad-Image Associations
|
|
227
|
+
|
|
228
|
+
`AdImageAssociation` is exposed as two typed commands. `get` reads ad-to-image
|
|
229
|
+
associations via an optional selection filter (an empty filter returns up to
|
|
230
|
+
10000 associations). `set` attaches or detaches images: `--association AD_ID=HASH`
|
|
231
|
+
attaches an image, `--association AD_ID` (no hash) detaches the current image
|
|
232
|
+
(max 10000 associations per call).
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
direct v4adimage get --ad-ids 123,456 --status-moderate Yes --limit 20
|
|
236
|
+
direct v4adimage get --campaign-ids 789 --format table
|
|
237
|
+
direct v4adimage set --association 123=abc123hash --association 456 --dry-run
|
|
238
|
+
```
|
|
239
|
+
|
|
211
240
|
### V4 Live Budget Forecasts
|
|
212
241
|
|
|
213
242
|
Budget forecasts are asynchronous. Direct CLI makes exactly one API call per
|
|
@@ -233,9 +262,15 @@ per-request token from `--master-token`, `--operation-num`, and
|
|
|
233
262
|
Environment variables are
|
|
234
263
|
`YANDEX_DIRECT_MASTER_TOKEN`, `YANDEX_DIRECT_FINANCE_LOGIN`,
|
|
235
264
|
`YANDEX_DIRECT_FINANCE_TOKEN`, and `YANDEX_DIRECT_OPERATION_NUM`.
|
|
236
|
-
`transfer-money` and `pay-campaigns` are dry-run-only
|
|
237
|
-
always require `--dry-run`; `create-invoice` can be sent
|
|
238
|
-
is omitted. Dry-run output masks the financial token.
|
|
265
|
+
`transfer-money`, `pay-campaigns`, and `pay-campaigns-by-card` are dry-run-only
|
|
266
|
+
in this release and always require `--dry-run`; `create-invoice` can be sent
|
|
267
|
+
live when `--dry-run` is omitted. Dry-run output masks the financial token.
|
|
268
|
+
`pay-campaigns-by-card` has an undocumented request shape; its dry-run body
|
|
269
|
+
mirrors the documented `pay-campaigns` shape as a best-effort preview.
|
|
270
|
+
|
|
271
|
+
> ⚠ **Finance commands have not been tested against the live API.** Treat the
|
|
272
|
+
> request shapes as best-effort and always verify with `--dry-run` before
|
|
273
|
+
> sending anything that runs live (`create-invoice`).
|
|
239
274
|
|
|
240
275
|
```bash
|
|
241
276
|
direct v4finance get-clients-units --logins client-login,other-client --format table
|
|
@@ -244,6 +279,7 @@ direct v4finance create-invoice --payment 123=100.50 --payment 456=25 --currency
|
|
|
244
279
|
direct v4finance check-payment --custom-transaction-id A123456789012345678901234567890B
|
|
245
280
|
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
|
|
246
281
|
direct v4finance pay-campaigns --campaign-ids 123,456 --amount 100.50 --contract-id CONTRACT_ID --pay-method Bank --currency RUB --master-token MASTER_TOKEN --operation-num 123 --finance-login agency-login --dry-run
|
|
282
|
+
direct v4finance pay-campaigns-by-card --campaign-ids 123,456 --amount 100.50 --currency RUB --master-token MASTER_TOKEN --operation-num 128 --finance-login agency-login --dry-run
|
|
247
283
|
```
|
|
248
284
|
|
|
249
285
|
### V4 Live Shared Account
|
|
@@ -272,6 +308,20 @@ direct v4account account-management --action TransferMoney --from-account-id 132
|
|
|
272
308
|
direct --sandbox v4account enable-shared-account --client-login client-login
|
|
273
309
|
```
|
|
274
310
|
|
|
311
|
+
### V4 Live — Intentionally Omitted Methods
|
|
312
|
+
|
|
313
|
+
Some v4 Live methods present in the API registry are intentionally **not**
|
|
314
|
+
exposed as CLI commands:
|
|
315
|
+
|
|
316
|
+
- `DeleteReport` / `DeleteOfflineReport` — disabled by Yandex (the official
|
|
317
|
+
docs list them under "Отключенные методы" / "Метод отключен. Используйте API
|
|
318
|
+
версии 5"). Use the v5 reports API instead.
|
|
319
|
+
- `PingAPI`, `PingAPI_X`, `GetVersion`, `GetAvailableVersions` — service
|
|
320
|
+
diagnostics / version probes with no documented request shape; not useful as
|
|
321
|
+
user-facing CLI commands.
|
|
322
|
+
- `PayCampaignsByCard` is exposed but **dry-run-only** (undocumented,
|
|
323
|
+
financially sensitive — see V4 Live Finance above).
|
|
324
|
+
|
|
275
325
|
### CLI Convention
|
|
276
326
|
|
|
277
327
|
The current CLI convention is defined as follows.
|
|
@@ -1019,27 +1069,32 @@ direct --profile agency1 campaigns get
|
|
|
1019
1069
|
- Если первый non-interactive шаг включает `--client-secret`, secret запоминается для последующего completion step.
|
|
1020
1070
|
- Если profile уже хранит confidential OAuth client, `direct auth login --code CODE --profile NAME` использует сохраненные `client_id` и `client_secret`.
|
|
1021
1071
|
- `direct auth login --oauth-token TOKEN` импортирует access token вручную и не включает auto-refresh.
|
|
1072
|
+
- После успешного интерактивного входа Direct CLI спрашивает, сохранить ли
|
|
1073
|
+
access token и login в `.env` текущей рабочей папки; non-interactive вход этот
|
|
1074
|
+
вопрос не задаёт.
|
|
1022
1075
|
|
|
1023
1076
|
Порядок выбора credentials:
|
|
1024
1077
|
|
|
1025
1078
|
| Приоритет | Источник | Пример |
|
|
1026
1079
|
|-----------|----------|--------|
|
|
1027
1080
|
| 1 | Явные CLI-опции | `direct --token TOKEN --login LOGIN campaigns get` |
|
|
1028
|
-
| 2 |
|
|
1029
|
-
| 3 |
|
|
1030
|
-
| 4 |
|
|
1081
|
+
| 2 | Явно выбранный profile | `direct --profile agency1 campaigns get` |
|
|
1082
|
+
| 3 | Базовые env vars или `.env` из папки запуска | `YANDEX_DIRECT_TOKEN`, `YANDEX_DIRECT_LOGIN` |
|
|
1083
|
+
| 4 | Активный profile | `direct auth use --profile agency1` |
|
|
1031
1084
|
| 5 | 1Password references | `--op-token-ref`, `YANDEX_DIRECT_OP_TOKEN_REF` |
|
|
1032
1085
|
| 6 | Bitwarden references | `--bw-token-ref`, `YANDEX_DIRECT_BW_TOKEN_REF` |
|
|
1033
1086
|
|
|
1034
1087
|
Direct CLI автоматически читает только `.env` из текущей рабочей папки, то есть
|
|
1035
1088
|
из папки, где запущена команда `direct`. Он не ищет `.env` от папки
|
|
1036
|
-
установленного пакета или исходного кода.
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1089
|
+
установленного пакета или исходного кода. Без явного `--profile` базовые
|
|
1090
|
+
`YANDEX_DIRECT_TOKEN` / `YANDEX_DIRECT_LOGIN` из окружения или cwd `.env`
|
|
1091
|
+
побеждают активный OAuth profile. С явным `--profile` Direct CLI использует
|
|
1092
|
+
только OAuth/profile-env credentials этого профиля и не подставляет base
|
|
1093
|
+
`YANDEX_DIRECT_LOGIN`; это защищает от смешивания аккаунтов. `direct auth status`
|
|
1094
|
+
без `--profile` показывает реально выбранный источник credentials, а с
|
|
1095
|
+
`--profile` показывает этот профиль.
|
|
1096
|
+
|
|
1097
|
+
> **Тесты используют безопасный порядок credentials.** Live-API тесты (например `tests/test_v4_live_contracts.py`) сначала читают `YANDEX_DIRECT_TOKEN` / `YANDEX_DIRECT_LOGIN` из окружения, затем падают на активный профиль `direct auth`, и скипают тест если ни того ни другого нет. Это защищает от случайного обращения к production API на машине разработчика с активным profile. Контракт зафиксирован в `CLAUDE.md`.
|
|
1043
1098
|
|
|
1044
1099
|
Установка остаётся через `pip install direct-cli`, а запуск команд теперь идет
|
|
1045
1100
|
через `direct`. Вызов deprecated entrypoint `direct-cli` завершается ошибкой с
|
|
@@ -63,6 +63,9 @@ Notes:
|
|
|
63
63
|
- If the first non-interactive step includes `--client-secret`, the secret is remembered for the matching completion step.
|
|
64
64
|
- If a profile already stores a confidential OAuth client, `direct auth login --code CODE --profile NAME` reuses the saved `client_id` and `client_secret`.
|
|
65
65
|
- `direct auth login --oauth-token TOKEN` is a manual access-token import and does not auto-refresh.
|
|
66
|
+
- After a successful interactive login, Direct CLI asks whether to save the
|
|
67
|
+
access token and login to the current working directory `.env`; non-interactive
|
|
68
|
+
login flows do not prompt.
|
|
66
69
|
- Alias `auth_login` is not supported.
|
|
67
70
|
|
|
68
71
|
Credential resolution priority:
|
|
@@ -70,22 +73,23 @@ Credential resolution priority:
|
|
|
70
73
|
| Priority | Source | Example |
|
|
71
74
|
|----------|--------|---------|
|
|
72
75
|
| 1 | Explicit CLI options | `direct --token TOKEN --login LOGIN campaigns get` |
|
|
73
|
-
| 2 |
|
|
74
|
-
| 3 |
|
|
75
|
-
| 4 |
|
|
76
|
+
| 2 | Explicit profile credentials | `direct --profile agency1 campaigns get` |
|
|
77
|
+
| 3 | Base env vars or current working directory `.env` | `YANDEX_DIRECT_TOKEN`, `YANDEX_DIRECT_LOGIN` |
|
|
78
|
+
| 4 | Active profile credentials | `direct auth use --profile agency1` |
|
|
76
79
|
| 5 | 1Password references | `--op-token-ref`, `YANDEX_DIRECT_OP_TOKEN_REF` |
|
|
77
80
|
| 6 | Bitwarden references | `--bw-token-ref`, `YANDEX_DIRECT_BW_TOKEN_REF` |
|
|
78
81
|
|
|
79
82
|
Direct CLI automatically loads only the `.env` file from the current working
|
|
80
83
|
directory, i.e. the directory where you run `direct`. It does not search for
|
|
81
|
-
`.env` from the installed package or source-code location.
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
84
|
+
`.env` from the installed package or source-code location. Without an explicit
|
|
85
|
+
`--profile`, base `YANDEX_DIRECT_TOKEN` / `YANDEX_DIRECT_LOGIN` from env or cwd
|
|
86
|
+
`.env` win over the active OAuth profile. With explicit `--profile`, Direct CLI
|
|
87
|
+
uses only that profile's OAuth/profile-env credentials and does not fall back to
|
|
88
|
+
base `YANDEX_DIRECT_LOGIN`; this prevents mixing accounts. `direct auth status`
|
|
89
|
+
without `--profile` reports the effective credential source; with `--profile` it
|
|
90
|
+
reports that profile.
|
|
87
91
|
|
|
88
|
-
> **Tests
|
|
92
|
+
> **Tests follow the safe credential order.** Live-API test suites (e.g. `tests/test_v4_live_contracts.py`) read `YANDEX_DIRECT_TOKEN` / `YANDEX_DIRECT_LOGIN` from the environment first, only then fall back to the active `direct auth` profile, and skip the test if neither is set. This prevents a developer machine with an active profile from silently hitting production on a plain `pytest` invocation. See `CLAUDE.md` for the contract.
|
|
89
93
|
|
|
90
94
|
Install with `pip install direct-cli`, then run commands with `direct`.
|
|
91
95
|
Invoking the deprecated `direct-cli` entrypoint exits with
|
|
@@ -165,6 +169,31 @@ direct v4wordstat get-report --report-id 123 --format table
|
|
|
165
169
|
direct v4wordstat delete-report --report-id 123
|
|
166
170
|
```
|
|
167
171
|
|
|
172
|
+
### V4 Live Keyword Suggestions
|
|
173
|
+
|
|
174
|
+
`get-suggestion` returns up to 20 related phrases for the seed phrases. Repeat
|
|
175
|
+
`--keyword` for multiple seeds. The method consumes API points.
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
direct v4keywords get-suggestion --keyword холодильник --keyword камера
|
|
179
|
+
direct v4keywords get-suggestion --keyword "buy laptop" --format table
|
|
180
|
+
direct v4keywords get-suggestion --keyword холодильник --dry-run
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### V4 Live Ad-Image Associations
|
|
184
|
+
|
|
185
|
+
`AdImageAssociation` is exposed as two typed commands. `get` reads ad-to-image
|
|
186
|
+
associations via an optional selection filter (an empty filter returns up to
|
|
187
|
+
10000 associations). `set` attaches or detaches images: `--association AD_ID=HASH`
|
|
188
|
+
attaches an image, `--association AD_ID` (no hash) detaches the current image
|
|
189
|
+
(max 10000 associations per call).
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
direct v4adimage get --ad-ids 123,456 --status-moderate Yes --limit 20
|
|
193
|
+
direct v4adimage get --campaign-ids 789 --format table
|
|
194
|
+
direct v4adimage set --association 123=abc123hash --association 456 --dry-run
|
|
195
|
+
```
|
|
196
|
+
|
|
168
197
|
### V4 Live Budget Forecasts
|
|
169
198
|
|
|
170
199
|
Budget forecasts are asynchronous. Direct CLI makes exactly one API call per
|
|
@@ -190,9 +219,15 @@ per-request token from `--master-token`, `--operation-num`, and
|
|
|
190
219
|
Environment variables are
|
|
191
220
|
`YANDEX_DIRECT_MASTER_TOKEN`, `YANDEX_DIRECT_FINANCE_LOGIN`,
|
|
192
221
|
`YANDEX_DIRECT_FINANCE_TOKEN`, and `YANDEX_DIRECT_OPERATION_NUM`.
|
|
193
|
-
`transfer-money` and `pay-campaigns` are dry-run-only
|
|
194
|
-
always require `--dry-run`; `create-invoice` can be sent
|
|
195
|
-
is omitted. Dry-run output masks the financial token.
|
|
222
|
+
`transfer-money`, `pay-campaigns`, and `pay-campaigns-by-card` are dry-run-only
|
|
223
|
+
in this release and always require `--dry-run`; `create-invoice` can be sent
|
|
224
|
+
live when `--dry-run` is omitted. Dry-run output masks the financial token.
|
|
225
|
+
`pay-campaigns-by-card` has an undocumented request shape; its dry-run body
|
|
226
|
+
mirrors the documented `pay-campaigns` shape as a best-effort preview.
|
|
227
|
+
|
|
228
|
+
> ⚠ **Finance commands have not been tested against the live API.** Treat the
|
|
229
|
+
> request shapes as best-effort and always verify with `--dry-run` before
|
|
230
|
+
> sending anything that runs live (`create-invoice`).
|
|
196
231
|
|
|
197
232
|
```bash
|
|
198
233
|
direct v4finance get-clients-units --logins client-login,other-client --format table
|
|
@@ -201,6 +236,7 @@ direct v4finance create-invoice --payment 123=100.50 --payment 456=25 --currency
|
|
|
201
236
|
direct v4finance check-payment --custom-transaction-id A123456789012345678901234567890B
|
|
202
237
|
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
|
|
203
238
|
direct v4finance pay-campaigns --campaign-ids 123,456 --amount 100.50 --contract-id CONTRACT_ID --pay-method Bank --currency RUB --master-token MASTER_TOKEN --operation-num 123 --finance-login agency-login --dry-run
|
|
239
|
+
direct v4finance pay-campaigns-by-card --campaign-ids 123,456 --amount 100.50 --currency RUB --master-token MASTER_TOKEN --operation-num 128 --finance-login agency-login --dry-run
|
|
204
240
|
```
|
|
205
241
|
|
|
206
242
|
### V4 Live Shared Account
|
|
@@ -229,6 +265,20 @@ direct v4account account-management --action TransferMoney --from-account-id 132
|
|
|
229
265
|
direct --sandbox v4account enable-shared-account --client-login client-login
|
|
230
266
|
```
|
|
231
267
|
|
|
268
|
+
### V4 Live — Intentionally Omitted Methods
|
|
269
|
+
|
|
270
|
+
Some v4 Live methods present in the API registry are intentionally **not**
|
|
271
|
+
exposed as CLI commands:
|
|
272
|
+
|
|
273
|
+
- `DeleteReport` / `DeleteOfflineReport` — disabled by Yandex (the official
|
|
274
|
+
docs list them under "Отключенные методы" / "Метод отключен. Используйте API
|
|
275
|
+
версии 5"). Use the v5 reports API instead.
|
|
276
|
+
- `PingAPI`, `PingAPI_X`, `GetVersion`, `GetAvailableVersions` — service
|
|
277
|
+
diagnostics / version probes with no documented request shape; not useful as
|
|
278
|
+
user-facing CLI commands.
|
|
279
|
+
- `PayCampaignsByCard` is exposed but **dry-run-only** (undocumented,
|
|
280
|
+
financially sensitive — see V4 Live Finance above).
|
|
281
|
+
|
|
232
282
|
### CLI Convention
|
|
233
283
|
|
|
234
284
|
The current CLI convention is defined as follows.
|
|
@@ -976,27 +1026,32 @@ direct --profile agency1 campaigns get
|
|
|
976
1026
|
- Если первый non-interactive шаг включает `--client-secret`, secret запоминается для последующего completion step.
|
|
977
1027
|
- Если profile уже хранит confidential OAuth client, `direct auth login --code CODE --profile NAME` использует сохраненные `client_id` и `client_secret`.
|
|
978
1028
|
- `direct auth login --oauth-token TOKEN` импортирует access token вручную и не включает auto-refresh.
|
|
1029
|
+
- После успешного интерактивного входа Direct CLI спрашивает, сохранить ли
|
|
1030
|
+
access token и login в `.env` текущей рабочей папки; non-interactive вход этот
|
|
1031
|
+
вопрос не задаёт.
|
|
979
1032
|
|
|
980
1033
|
Порядок выбора credentials:
|
|
981
1034
|
|
|
982
1035
|
| Приоритет | Источник | Пример |
|
|
983
1036
|
|-----------|----------|--------|
|
|
984
1037
|
| 1 | Явные CLI-опции | `direct --token TOKEN --login LOGIN campaigns get` |
|
|
985
|
-
| 2 |
|
|
986
|
-
| 3 |
|
|
987
|
-
| 4 |
|
|
1038
|
+
| 2 | Явно выбранный profile | `direct --profile agency1 campaigns get` |
|
|
1039
|
+
| 3 | Базовые env vars или `.env` из папки запуска | `YANDEX_DIRECT_TOKEN`, `YANDEX_DIRECT_LOGIN` |
|
|
1040
|
+
| 4 | Активный profile | `direct auth use --profile agency1` |
|
|
988
1041
|
| 5 | 1Password references | `--op-token-ref`, `YANDEX_DIRECT_OP_TOKEN_REF` |
|
|
989
1042
|
| 6 | Bitwarden references | `--bw-token-ref`, `YANDEX_DIRECT_BW_TOKEN_REF` |
|
|
990
1043
|
|
|
991
1044
|
Direct CLI автоматически читает только `.env` из текущей рабочей папки, то есть
|
|
992
1045
|
из папки, где запущена команда `direct`. Он не ищет `.env` от папки
|
|
993
|
-
установленного пакета или исходного кода.
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1046
|
+
установленного пакета или исходного кода. Без явного `--profile` базовые
|
|
1047
|
+
`YANDEX_DIRECT_TOKEN` / `YANDEX_DIRECT_LOGIN` из окружения или cwd `.env`
|
|
1048
|
+
побеждают активный OAuth profile. С явным `--profile` Direct CLI использует
|
|
1049
|
+
только OAuth/profile-env credentials этого профиля и не подставляет base
|
|
1050
|
+
`YANDEX_DIRECT_LOGIN`; это защищает от смешивания аккаунтов. `direct auth status`
|
|
1051
|
+
без `--profile` показывает реально выбранный источник credentials, а с
|
|
1052
|
+
`--profile` показывает этот профиль.
|
|
1053
|
+
|
|
1054
|
+
> **Тесты используют безопасный порядок credentials.** Live-API тесты (например `tests/test_v4_live_contracts.py`) сначала читают `YANDEX_DIRECT_TOKEN` / `YANDEX_DIRECT_LOGIN` из окружения, затем падают на активный профиль `direct auth`, и скипают тест если ни того ни другого нет. Это защищает от случайного обращения к production API на машине разработчика с активным profile. Контракт зафиксирован в `CLAUDE.md`.
|
|
1000
1055
|
|
|
1001
1056
|
Установка остаётся через `pip install direct-cli`, а запуск команд теперь идет
|
|
1002
1057
|
через `direct`. Вызов deprecated entrypoint `direct-cli` завершается ошибкой с
|