direct-cli 0.2.9.2__tar.gz → 0.2.11__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.2.9.2 → direct_cli-0.2.11}/.github/copilot-instructions.md +1 -1
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/.gitignore +1 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/CLAUDE.md +14 -5
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/PKG-INFO +220 -61
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/README.md +219 -60
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/direct_cli/_vendor/tapi_yandex_direct/__init__.py +1 -1
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/direct_cli/_vendor/tapi_yandex_direct/resource_mapping.py +38 -1
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/direct_cli/_vendor/tapi_yandex_direct/tapi_yandex_direct.py +2 -2
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/direct_cli/auth.py +19 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/direct_cli/cli.py +46 -31
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/direct_cli/commands/agencyclients.py +32 -14
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/direct_cli/commands/audiencetargets.py +5 -5
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/direct_cli/commands/auth.py +16 -5
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/direct_cli/commands/bidmodifiers.py +22 -20
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/direct_cli/commands/bids.py +5 -5
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/direct_cli/commands/businesses.py +1 -1
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/direct_cli/commands/campaigns.py +8 -8
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/direct_cli/commands/changes.py +5 -8
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/direct_cli/commands/dynamicads.py +9 -9
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/direct_cli/commands/dynamicfeedadtargets.py +9 -9
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/direct_cli/commands/feeds.py +3 -6
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/direct_cli/commands/keywordbids.py +24 -20
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/direct_cli/commands/keywords.py +5 -65
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/direct_cli/commands/keywordsresearch.py +24 -3
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/direct_cli/commands/leads.py +8 -6
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/direct_cli/commands/smartadtargets.py +13 -13
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/direct_cli/commands/strategies.py +1 -1
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/direct_cli/commands/turbopages.py +1 -1
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/direct_cli/reports_coverage.py +15 -5
- direct_cli-0.2.11/direct_cli/smoke_matrix.py +252 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/direct_cli/utils.py +50 -11
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/direct_cli/wsdl_coverage.py +0 -6
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/direct_cli.egg-info/PKG-INFO +220 -61
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/direct_cli.egg-info/SOURCES.txt +9 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/pyproject.toml +1 -1
- direct_cli-0.2.11/scripts/build_api_coverage_checklist.py +444 -0
- direct_cli-0.2.11/scripts/patch_vendor_imports.py +142 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/scripts/release_pypi.sh +1 -1
- direct_cli-0.2.11/scripts/sandbox_write_live.py +1324 -0
- direct_cli-0.2.11/scripts/test_dangerous_commands.sh +50 -0
- direct_cli-0.2.11/scripts/test_safe_commands.sh +231 -0
- direct_cli-0.2.11/scripts/test_sandbox_write.sh +23 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/scripts/update_vendor.sh +11 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/API_COVERAGE.md +34 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/MANUAL_COVERAGE.md +8 -5
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/conftest.py +19 -5
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/test_api_coverage.py +29 -15
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/test_auth_bw.py +14 -7
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/test_auth_op.py +12 -6
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/test_cli.py +36 -3
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/test_comprehensive.py +7 -4
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/test_dry_run.py +119 -79
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/test_integration.py +211 -25
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/test_integration_live_write.py +16 -15
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/test_integration_write.py +8 -4
- direct_cli-0.2.11/tests/test_smoke_matrix.py +224 -0
- direct_cli-0.2.11/tests/test_vendor_imports.py +150 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/.env.example +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/.github/workflows/api-coverage.yml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/.github/workflows/claude-code-review.yml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/.github/workflows/claude.yml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/AGENTS.md +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/MANIFEST.in +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/direct_cli/__init__.py +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/direct_cli/_deprecated.py +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/direct_cli/_vendor/__init__.py +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/direct_cli/_vendor/tapi_yandex_direct/exceptions.py +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/direct_cli/api.py +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/direct_cli/commands/__init__.py +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/direct_cli/commands/adextensions.py +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/direct_cli/commands/adgroups.py +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/direct_cli/commands/adimages.py +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/direct_cli/commands/ads.py +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/direct_cli/commands/advideos.py +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/direct_cli/commands/clients.py +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/direct_cli/commands/creatives.py +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/direct_cli/commands/dictionaries.py +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/direct_cli/commands/negativekeywordsharedsets.py +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/direct_cli/commands/reports.py +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/direct_cli/commands/retargeting.py +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/direct_cli/commands/sitelinks.py +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/direct_cli/commands/vcards.py +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/direct_cli/output.py +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/direct_cli.egg-info/dependency_links.txt +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/direct_cli.egg-info/entry_points.txt +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/direct_cli.egg-info/requires.txt +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/direct_cli.egg-info/top_level.txt +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/docs/superpowers/plans/2026-04-12-issue-32-completion.md +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/docs/superpowers/specs/2026-04-23-vendor-tapi-yandex-direct-design.md +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/scripts/anonymize_cassettes.py +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/scripts/build_api_coverage_report.py +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/scripts/check_reports_drift.py +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/scripts/check_wsdl_drift.py +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/scripts/refresh_reports_cache.py +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/scripts/refresh_wsdl_cache.py +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/setup.cfg +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/setup.py +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/API_ISSUE_AUDIT.md +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/__init__.py +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/cassettes/test_integration_live_write/test_live_draft_adgroups_add_update_delete.yaml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/cassettes/test_integration_live_write/test_live_draft_adimages_add_get_delete.yaml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/cassettes/test_integration_live_write/test_live_draft_ads_add_update_delete.yaml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/cassettes/test_integration_live_write/test_live_draft_ads_suspend_resume_archive_unarchive.yaml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/cassettes/test_integration_live_write/test_live_draft_advideos_add_get.yaml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/cassettes/test_integration_live_write/test_live_draft_audiencetargets_add_delete.yaml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/cassettes/test_integration_live_write/test_live_draft_audiencetargets_suspend_resume.yaml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/cassettes/test_integration_live_write/test_live_draft_bids_set.yaml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/cassettes/test_integration_live_write/test_live_draft_campaign_create_get_delete.yaml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/cassettes/test_integration_live_write/test_live_draft_creatives_chain_advideo_to_creative.yaml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/cassettes/test_integration_live_write/test_live_draft_dynamicads_add_delete.yaml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/cassettes/test_integration_live_write/test_live_draft_dynamicads_suspend_resume.yaml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/cassettes/test_integration_live_write/test_live_draft_keywordbids_set.yaml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/cassettes/test_integration_live_write/test_live_draft_keywords_add_update_delete.yaml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/cassettes/test_integration_live_write/test_live_draft_keywords_suspend_resume.yaml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/cassettes/test_integration_live_write/test_live_draft_sitelinks_add_get_delete.yaml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/cassettes/test_integration_live_write/test_live_draft_smartadtargets_add_update_delete.yaml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/cassettes/test_integration_live_write/test_live_draft_smartadtargets_suspend_resume.yaml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/cassettes/test_integration_write/TestWriteAdExtensions.test_add_delete.yaml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/cassettes/test_integration_write/TestWriteAdGroups.test_add_update_delete.yaml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/cassettes/test_integration_write/TestWriteAdImages.test_add_delete.yaml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/cassettes/test_integration_write/TestWriteAds.test_add_text_ad_update_delete.yaml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/cassettes/test_integration_write/TestWriteAudienceTargets.test_add_delete.yaml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/cassettes/test_integration_write/TestWriteBidModifiersAdd.test_add_delete_mobile.yaml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/cassettes/test_integration_write/TestWriteBidModifiersSet.test_set_without_id_is_rejected.yaml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/cassettes/test_integration_write/TestWriteBids.test_set_bid.yaml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/cassettes/test_integration_write/TestWriteCampaignDraftLifecycle.test_draft_create_get_delete.yaml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/cassettes/test_integration_write/TestWriteCampaigns.test_campaign_lifecycle.yaml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/cassettes/test_integration_write/TestWriteDynamicAds.test_add_update_delete.yaml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/cassettes/test_integration_write/TestWriteFeeds.test_add_update_delete.yaml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/cassettes/test_integration_write/TestWriteKeywordBids.test_set_keyword_bid.yaml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/cassettes/test_integration_write/TestWriteKeywords.test_add_update_delete.yaml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/cassettes/test_integration_write/TestWriteNegativeKeywordSharedSets.test_add_update_delete.yaml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/cassettes/test_integration_write/TestWriteRetargeting.test_add_delete.yaml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/cassettes/test_integration_write/TestWriteSitelinks.test_add_delete.yaml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/cassettes/test_integration_write/TestWriteSmartAdTargets.test_add_update_delete.yaml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/cassettes/test_integration_write/TestWriteVCards.test_add_delete.yaml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/fixtures/test-video.mp4 +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/reports_cache/raw/fields-list.html +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/reports_cache/raw/headers.html +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/reports_cache/raw/spec.html +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/reports_cache/raw/type.html +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/reports_cache/spec.json +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/test_auth_oauth.py +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/test_reports_drift.py +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/test_transport_contract.py +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/wsdl_cache/adextensions.xml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/wsdl_cache/adgroups.xml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/wsdl_cache/adimages.xml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/wsdl_cache/ads.xml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/wsdl_cache/advideos.xml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/wsdl_cache/agencyclients.xml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/wsdl_cache/audiencetargets.xml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/wsdl_cache/bidmodifiers.xml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/wsdl_cache/bids.xml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/wsdl_cache/businesses.xml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/wsdl_cache/campaigns.xml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/wsdl_cache/changes.xml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/wsdl_cache/clients.xml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/wsdl_cache/creatives.xml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/wsdl_cache/dictionaries.xml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/wsdl_cache/dynamicfeedadtargets.xml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/wsdl_cache/dynamictextadtargets.xml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/wsdl_cache/feeds.xml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/wsdl_cache/keywordbids.xml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/wsdl_cache/keywords.xml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/wsdl_cache/keywordsresearch.xml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/wsdl_cache/leads.xml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/wsdl_cache/negativekeywordsharedsets.xml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/wsdl_cache/retargetinglists.xml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/wsdl_cache/sitelinks.xml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/wsdl_cache/smartadtargets.xml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/wsdl_cache/strategies.xml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/wsdl_cache/turbopages.xml +0 -0
- {direct_cli-0.2.9.2 → direct_cli-0.2.11}/tests/wsdl_cache/vcards.xml +0 -0
|
@@ -77,7 +77,7 @@ Never invoke these commands in automated tests against a real account.
|
|
|
77
77
|
| `bidmodifiers set` | Changes bid multipliers (device, region, time, etc.) |
|
|
78
78
|
|
|
79
79
|
### 🟡 Reversible but affect live traffic
|
|
80
|
-
`campaigns suspend/resume/archive/unarchive`, `ads suspend/resume/archive/unarchive`, `keywords suspend/resume
|
|
80
|
+
`campaigns suspend/resume/archive/unarchive`, `ads suspend/resume/archive/unarchive`, `keywords suspend/resume`, `audiencetargets suspend/resume`
|
|
81
81
|
|
|
82
82
|
### 🟡 Account-wide mutations
|
|
83
83
|
`clients update` — modifies account-level settings.
|
|
@@ -52,8 +52,17 @@ Click group-of-groups. Each Yandex Direct API resource = one file in `direct_cli
|
|
|
52
52
|
|
|
53
53
|
## Dangerous Commands — Never Auto-Test
|
|
54
54
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
- **
|
|
59
|
-
- **
|
|
55
|
+
Smoke command safety is tracked in `direct_cli/smoke_matrix.py`. Every CLI
|
|
56
|
+
subcommand belongs to exactly one category:
|
|
57
|
+
|
|
58
|
+
- **SAFE:** production read-only smoke tests in `scripts/test_safe_commands.sh`.
|
|
59
|
+
- **WRITE_SANDBOX:** live mutating smoke tests through
|
|
60
|
+
`scripts/test_sandbox_write.sh`; these must call only `direct --sandbox ...`
|
|
61
|
+
and must not touch production data.
|
|
62
|
+
- **DANGEROUS:** manual-only checklist in `scripts/test_dangerous_commands.sh`;
|
|
63
|
+
the script exits with status 1 by design and must not be used as an
|
|
64
|
+
automated runner.
|
|
65
|
+
|
|
66
|
+
Never auto-test production mutations: agency client changes, live bid changes,
|
|
67
|
+
moderation, lifecycle operations, `clients update`, or any `delete` without
|
|
68
|
+
`--sandbox`.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: direct-cli
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.11
|
|
4
4
|
Summary: Command-line interface for Yandex Direct API
|
|
5
5
|
Author: axisrow
|
|
6
6
|
License: MIT
|
|
@@ -97,6 +97,23 @@ Notes:
|
|
|
97
97
|
- Authorization is performed via `direct auth login`.
|
|
98
98
|
- Alias `auth_login` is not supported.
|
|
99
99
|
|
|
100
|
+
Credential resolution priority:
|
|
101
|
+
|
|
102
|
+
| Priority | Source | Example |
|
|
103
|
+
|----------|--------|---------|
|
|
104
|
+
| 1 | Explicit CLI options | `direct --token TOKEN --login LOGIN campaigns get` |
|
|
105
|
+
| 2 | OAuth profile storage | `direct --profile agency1 campaigns get` |
|
|
106
|
+
| 3 | Profile-specific env vars | `YANDEX_DIRECT_TOKEN_AGENCY1`, `YANDEX_DIRECT_LOGIN_AGENCY1` |
|
|
107
|
+
| 4 | Base env vars or project `.env` | `YANDEX_DIRECT_TOKEN`, `YANDEX_DIRECT_LOGIN` |
|
|
108
|
+
| 5 | 1Password references | `--op-token-ref`, `YANDEX_DIRECT_OP_TOKEN_REF` |
|
|
109
|
+
| 6 | Bitwarden references | `--bw-token-ref`, `YANDEX_DIRECT_BW_TOKEN_REF` |
|
|
110
|
+
|
|
111
|
+
The project `.env` file is loaded automatically. If a profile is selected
|
|
112
|
+
with `--profile` or `direct auth use --profile NAME`, Direct CLI does not
|
|
113
|
+
fall back to base `YANDEX_DIRECT_LOGIN`; this prevents mixing a profile token
|
|
114
|
+
with a login from the project `.env`. For multi-account setups, prefer OAuth
|
|
115
|
+
profiles or profile-specific env vars instead of base credentials.
|
|
116
|
+
|
|
100
117
|
Install with `pip install direct-cli`, then run commands with `direct`.
|
|
101
118
|
Invoking the deprecated `direct-cli` entrypoint exits with
|
|
102
119
|
`use direct instead of direct-cli`.
|
|
@@ -145,6 +162,17 @@ the runtime CLI by default. If compatibility is ever needed, an alias must be
|
|
|
145
162
|
added as an explicit exception with the concrete legacy syntax that still has to
|
|
146
163
|
be supported.
|
|
147
164
|
|
|
165
|
+
#### Removed Legacy Names
|
|
166
|
+
|
|
167
|
+
| Legacy name | Canonical name |
|
|
168
|
+
|----------------------------|------------------------------|
|
|
169
|
+
| `dynamictargets` | `dynamicads` |
|
|
170
|
+
| `smarttargets` | `smartadtargets` |
|
|
171
|
+
| `negativekeywords` | `negativekeywordsharedsets` |
|
|
172
|
+
| `list` | `get` |
|
|
173
|
+
| `checkcamp` | `check-campaigns` |
|
|
174
|
+
| `checkdict` | `check-dictionaries` |
|
|
175
|
+
|
|
148
176
|
#### Input Rules
|
|
149
177
|
|
|
150
178
|
- All user-facing input must be passed only through typed CLI flags.
|
|
@@ -177,7 +205,7 @@ direct dictionaries get-geo-regions \
|
|
|
177
205
|
#### Flag Design Rules
|
|
178
206
|
|
|
179
207
|
- List inputs use comma-separated CLI syntax where appropriate.
|
|
180
|
-
- Money and bid values
|
|
208
|
+
- Money and bid values are passed in micro-rubles (API-native format). Values below 100,000 trigger a validation hint suggesting the correct scale.
|
|
181
209
|
- Selector fields remain explicit flags, for example:
|
|
182
210
|
- `--id`
|
|
183
211
|
- `--campaign-id`
|
|
@@ -221,7 +249,7 @@ direct campaigns get --ids 1,2,3
|
|
|
221
249
|
direct changes check-campaigns --timestamp 2026-04-14T00:00:00
|
|
222
250
|
direct keywordsresearch has-search-volume --keywords "buy laptop,buy desktop"
|
|
223
251
|
direct smartadtargets update --id 456 --priority HIGH
|
|
224
|
-
direct dynamicads set-bids --id 789 --bid
|
|
252
|
+
direct dynamicads set-bids --id 789 --bid 12500000 --context-bid 9000000 --priority HIGH
|
|
225
253
|
direct dictionaries get-geo-regions --name Moscow --region-ids 225,187 --exact-names Москва,Санкт-Петербург --fields GeoRegionId,GeoRegionName
|
|
226
254
|
```
|
|
227
255
|
|
|
@@ -229,7 +257,7 @@ Invalid examples:
|
|
|
229
257
|
|
|
230
258
|
```bash
|
|
231
259
|
direct dictionaries get-geo-regions --json '{"GeoRegionIds":[225]}' --fields GeoRegionId,GeoRegionName
|
|
232
|
-
direct dynamicads set-bids --id 789 --bid
|
|
260
|
+
direct dynamicads set-bids --id 789 --bid 12500000 --json '{"StrategyPriority":"HIGH"}'
|
|
233
261
|
direct dictionaries get-geo-regions \
|
|
234
262
|
--region-ids 225 \
|
|
235
263
|
--fields GeoRegionId,GeoRegionName
|
|
@@ -247,12 +275,12 @@ direct campaigns get --ids 1,2,3 --format table
|
|
|
247
275
|
direct campaigns get --fetch-all --format csv --output campaigns.csv
|
|
248
276
|
|
|
249
277
|
# Create (use --dry-run to preview the request)
|
|
250
|
-
direct campaigns add --name "My Campaign" --start-date 2024-02-01 --type TEXT_CAMPAIGN --budget
|
|
278
|
+
direct campaigns add --name "My Campaign" --start-date 2024-02-01 --type TEXT_CAMPAIGN --budget 1000000000 --setting ADD_METRICA_TAG=YES --search-strategy HIGHEST_POSITION --network-strategy SERVING_OFF --dry-run
|
|
251
279
|
direct campaigns add --name "Dynamic Campaign" --start-date 2024-02-01 --type DYNAMIC_TEXT_CAMPAIGN --setting ADD_METRICA_TAG=NO --search-strategy HIGHEST_POSITION --network-strategy SERVING_OFF --dry-run
|
|
252
|
-
direct campaigns add --name "Smart Campaign" --start-date 2024-02-01 --type SMART_CAMPAIGN --network-strategy AVERAGE_CPC_PER_FILTER --filter-average-cpc
|
|
280
|
+
direct campaigns add --name "Smart Campaign" --start-date 2024-02-01 --type SMART_CAMPAIGN --network-strategy AVERAGE_CPC_PER_FILTER --filter-average-cpc 1000000 --counter-id 123 --dry-run
|
|
253
281
|
|
|
254
282
|
# Update / lifecycle
|
|
255
|
-
direct campaigns update --id 12345 --name "New Name" --status SUSPENDED --budget
|
|
283
|
+
direct campaigns update --id 12345 --name "New Name" --status SUSPENDED --budget 100000000 --start-date 2024-02-10 --end-date 2024-03-01
|
|
256
284
|
direct campaigns suspend --id 12345
|
|
257
285
|
direct campaigns resume --id 12345
|
|
258
286
|
direct campaigns archive --id 12345
|
|
@@ -286,7 +314,7 @@ direct ads delete --id 99999
|
|
|
286
314
|
|
|
287
315
|
```bash
|
|
288
316
|
direct keywords get --campaign-ids 1,2,3
|
|
289
|
-
direct keywords add --adgroup-id 12345 --keyword "buy laptop" --bid
|
|
317
|
+
direct keywords add --adgroup-id 12345 --keyword "buy laptop" --bid 10500000 --context-bid 5250000 --user-param-1 segment-a --user-param-2 segment-b --dry-run
|
|
290
318
|
direct keywords update --id 88888 --keyword "updated keyword text"
|
|
291
319
|
direct keywords delete --id 88888
|
|
292
320
|
```
|
|
@@ -324,22 +352,22 @@ direct retargeting add --name "List A" --type AUDIENCE --rule "ALL:12345:30|6789
|
|
|
324
352
|
direct retargeting update --id 55 --name "Renamed" --rule "ANY:12345:30" --dry-run
|
|
325
353
|
|
|
326
354
|
# Bids and modifiers
|
|
327
|
-
direct bids set --keyword-id 123 --bid
|
|
328
|
-
direct bids set-auto --keyword-id 123 --max-bid
|
|
329
|
-
direct keywordbids set --keyword-id 321 --search-bid
|
|
330
|
-
direct keywordbids set-auto --keyword-id 321 --target-traffic-volume 100 --increase-percent 10 --bid-ceiling
|
|
355
|
+
direct bids set --keyword-id 123 --bid 15000000
|
|
356
|
+
direct bids set-auto --keyword-id 123 --max-bid 20000000 --position PREMIUMBLOCK --scope SEARCH --dry-run
|
|
357
|
+
direct keywordbids set --keyword-id 321 --search-bid 8000000 --network-bid 3000000
|
|
358
|
+
direct keywordbids set-auto --keyword-id 321 --target-traffic-volume 100 --increase-percent 10 --bid-ceiling 12500000 --dry-run
|
|
331
359
|
direct bidmodifiers add --campaign-id 123 --type DEMOGRAPHICS_ADJUSTMENT --value 150 --gender GENDER_MALE --age AGE_25_34 --dry-run
|
|
332
360
|
direct bidmodifiers set --id 99 --value 130 --dry-run
|
|
333
361
|
|
|
334
362
|
# Canonical multiword groups
|
|
335
363
|
direct negativekeywordsharedsets update --id 123 --keywords "foo,bar"
|
|
336
|
-
direct audiencetargets add --adgroup-id 100 --retargeting-list-id 200 --bid
|
|
337
|
-
direct audiencetargets set-bids --id 101 --context-bid
|
|
338
|
-
direct dynamicads add --adgroup-id 33 --name "Webpage A" --condition "URL:CONTAINS_ANY:test|shop" --condition "PAGE_CONTENT:CONTAINS:baz" --bid
|
|
339
|
-
direct smartadtargets add --adgroup-id 55 --name "Audience A" --audience ALL_SEGMENTS --condition "CATEGORY_ID:EQUALS:42" --average-cpc
|
|
364
|
+
direct audiencetargets add --adgroup-id 100 --retargeting-list-id 200 --bid 12000000 --priority HIGH --dry-run
|
|
365
|
+
direct audiencetargets set-bids --id 101 --context-bid 7000000 --priority LOW --dry-run
|
|
366
|
+
direct dynamicads add --adgroup-id 33 --name "Webpage A" --condition "URL:CONTAINS_ANY:test|shop" --condition "PAGE_CONTENT:CONTAINS:baz" --bid 3000000 --context-bid 2000000 --priority HIGH --dry-run
|
|
367
|
+
direct smartadtargets add --adgroup-id 55 --name "Audience A" --audience ALL_SEGMENTS --condition "CATEGORY_ID:EQUALS:42" --average-cpc 3000000 --average-cpa 4000000 --priority HIGH --available-items-only YES --dry-run
|
|
340
368
|
direct smartadtargets update --id 456 --priority HIGH
|
|
341
|
-
direct smartadtargets set-bids --id 456 --average-cpc
|
|
342
|
-
direct dynamicads set-bids --id 789 --bid
|
|
369
|
+
direct smartadtargets set-bids --id 456 --average-cpc 10500000 --average-cpa 15000000 --priority HIGH
|
|
370
|
+
direct dynamicads set-bids --id 789 --bid 12500000 --context-bid 9000000 --priority HIGH
|
|
343
371
|
|
|
344
372
|
# Shared bidding strategies
|
|
345
373
|
direct strategies get --limit 5
|
|
@@ -349,8 +377,8 @@ direct strategies archive --id 42 --dry-run
|
|
|
349
377
|
|
|
350
378
|
# Dynamic feed ad targets
|
|
351
379
|
direct dynamicfeedadtargets get --adgroup-ids 123 --limit 5
|
|
352
|
-
direct dynamicfeedadtargets add --adgroup-id 33 --name "Feed slice A" --condition "CATEGORY:EQUALS:shoes" --bid
|
|
353
|
-
direct dynamicfeedadtargets set-bids --id 789 --bid
|
|
380
|
+
direct dynamicfeedadtargets add --adgroup-id 33 --name "Feed slice A" --condition "CATEGORY:EQUALS:shoes" --bid 5000000 --dry-run
|
|
381
|
+
direct dynamicfeedadtargets set-bids --id 789 --bid 6500000 --context-bid 4000000 --dry-run
|
|
354
382
|
|
|
355
383
|
# Extensions, assets, feeds, and clients
|
|
356
384
|
direct sitelinks add --sitelink "Docs|https://example.com/docs" --sitelink "Help|https://example.com/help|Desk" --dry-run
|
|
@@ -409,7 +437,7 @@ The following commands make **irreversible changes** — use with caution:
|
|
|
409
437
|
| `keywords delete --id` | Permanently deletes a keyword |
|
|
410
438
|
| `audiencetargets delete --id` | Permanently deletes an audience target |
|
|
411
439
|
|
|
412
|
-
Commands that affect live ad delivery: `suspend`, `resume`, `archive`, `unarchive` (available on `campaigns`, `ads`, `keywords`).
|
|
440
|
+
Commands that affect live ad delivery: `suspend`, `resume`, `archive`, `unarchive` (available on `campaigns`, `ads`), `suspend`, `resume` (also on `keywords`).
|
|
413
441
|
|
|
414
442
|
Commands that affect bids and spending: `bids set`, `keywordbids set`, `bidmodifiers set`.
|
|
415
443
|
|
|
@@ -439,6 +467,27 @@ YANDEX_DIRECT_LIVE_WRITE=1 pytest -m integration_live_write -v # live draft cas
|
|
|
439
467
|
YANDEX_DIRECT_LIVE_WRITE=1 pytest -m integration_live_write -v --record-mode=rewrite # re-record live draft cassette
|
|
440
468
|
```
|
|
441
469
|
|
|
470
|
+
#### Smoke command scripts
|
|
471
|
+
|
|
472
|
+
Every CLI subcommand is classified in `direct_cli/smoke_matrix.py`.
|
|
473
|
+
|
|
474
|
+
| Category | Script | When to run |
|
|
475
|
+
|---|---|---|
|
|
476
|
+
| SAFE | `scripts/test_safe_commands.sh` | Production read-only smoke checks; requires `YANDEX_DIRECT_TOKEN` and `YANDEX_DIRECT_LOGIN` |
|
|
477
|
+
| WRITE_SANDBOX | `scripts/test_sandbox_write.sh` | Live sandbox write smoke checks; requires `YANDEX_DIRECT_TOKEN` and `YANDEX_DIRECT_LOGIN`; reports `PASS`, `FAIL`, `SANDBOX_LIMITATION`, or `NOT_COVERED` for each command |
|
|
478
|
+
| DANGEROUS | `scripts/test_dangerous_commands.sh` | Manual checklist only; exits with status 1 by design |
|
|
479
|
+
|
|
480
|
+
Current command surface:
|
|
481
|
+
|
|
482
|
+
| Metric | Count |
|
|
483
|
+
|---|---:|
|
|
484
|
+
| WSDL-backed API services | 29 |
|
|
485
|
+
| Supported API services including Reports | 30 |
|
|
486
|
+
| WSDL operations | 112 |
|
|
487
|
+
| CLI groups including `auth` | 31 |
|
|
488
|
+
| CLI subcommands including `auth` | 122 |
|
|
489
|
+
| API CLI subcommands excluding `auth` | 118 |
|
|
490
|
+
|
|
442
491
|
### API Coverage And Drift Monitoring
|
|
443
492
|
|
|
444
493
|
The project now distinguishes four surfaces:
|
|
@@ -471,24 +520,43 @@ CI runs a scheduled API coverage workflow that:
|
|
|
471
520
|
parity and live-discovered model gap counts;
|
|
472
521
|
- checks the cached WSDL files against the live Yandex Direct API on schedule.
|
|
473
522
|
|
|
474
|
-
####
|
|
523
|
+
#### Live sandbox write smoke
|
|
524
|
+
|
|
525
|
+
`WRITE_SANDBOX` smoke is a live check against the Yandex Direct **sandbox**.
|
|
526
|
+
It does not replay stored HTTP traffic and it does not create new recordings.
|
|
527
|
+
Run it only when you intentionally want to call `api-sandbox.direct.yandex.com`:
|
|
528
|
+
|
|
529
|
+
```bash
|
|
530
|
+
set -a && source .env && set +a
|
|
531
|
+
scripts/test_sandbox_write.sh
|
|
532
|
+
```
|
|
475
533
|
|
|
476
|
-
The
|
|
477
|
-
|
|
478
|
-
|
|
534
|
+
The runner executes matrix commands through `direct --sandbox ...`, creates
|
|
535
|
+
temporary sandbox prerequisites where possible, and cleans them up best-effort.
|
|
536
|
+
The report contains one row per `WRITE_SANDBOX` command:
|
|
479
537
|
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
538
|
+
- `PASS` means the command completed against the live sandbox API.
|
|
539
|
+
- `SANDBOX_LIMITATION` means the request reached the API and hit a known
|
|
540
|
+
sandbox-only limitation such as codes `8800`, `1000`, `3500`, or `5004`.
|
|
541
|
+
- `FAIL` means an unexpected CLI or API error.
|
|
542
|
+
- `NOT_COVERED` means the runner does not yet know how to safely build the
|
|
543
|
+
prerequisites for that command.
|
|
544
|
+
|
|
545
|
+
The same OAuth token works for both production and the sandbox; no separate
|
|
546
|
+
sandbox token is needed.
|
|
547
|
+
|
|
548
|
+
#### Re-recording write cassettes
|
|
549
|
+
|
|
550
|
+
The `integration_write` pytest tier still replays stored write-test traffic
|
|
551
|
+
for regression coverage. If you change those tests or their payloads and
|
|
552
|
+
intentionally need to refresh the fixtures, regenerate them separately:
|
|
483
553
|
|
|
484
554
|
```bash
|
|
485
555
|
set -a && source .env && set +a # load YANDEX_DIRECT_TOKEN / LOGIN
|
|
486
556
|
pytest -m integration_write -v --record-mode=rewrite
|
|
487
557
|
```
|
|
488
558
|
|
|
489
|
-
**
|
|
490
|
-
separate sandbox token is needed. After recording, **always audit the
|
|
491
|
-
generated YAMLs for leaked secrets**:
|
|
559
|
+
After recording, **always audit the generated YAMLs for leaked secrets**:
|
|
492
560
|
|
|
493
561
|
```bash
|
|
494
562
|
grep -r "$YANDEX_DIRECT_TOKEN" tests/cassettes/ # must return nothing
|
|
@@ -583,6 +651,45 @@ YANDEX_DIRECT_LOGIN=ваш_логин_на_яндексе
|
|
|
583
651
|
direct --token ВАШ_ТОКЕН --login ВАШ_ЛОГИН campaigns get
|
|
584
652
|
```
|
|
585
653
|
|
|
654
|
+
Используйте профильные credentials из `.env`:
|
|
655
|
+
|
|
656
|
+
```env
|
|
657
|
+
YANDEX_DIRECT_TOKEN_AGENCY1=token-1
|
|
658
|
+
YANDEX_DIRECT_LOGIN_AGENCY1=client-login-1
|
|
659
|
+
YANDEX_DIRECT_TOKEN_AGENCY2=token-2
|
|
660
|
+
YANDEX_DIRECT_LOGIN_AGENCY2=client-login-2
|
|
661
|
+
```
|
|
662
|
+
|
|
663
|
+
OAuth и profile-команды:
|
|
664
|
+
|
|
665
|
+
```bash
|
|
666
|
+
direct auth login
|
|
667
|
+
direct auth login --profile agency1
|
|
668
|
+
direct auth login --code abc123 --profile agency1
|
|
669
|
+
direct auth login --oauth-token y0_example --profile agency1
|
|
670
|
+
direct auth list
|
|
671
|
+
direct auth use --profile agency1
|
|
672
|
+
direct auth status --profile agency1
|
|
673
|
+
direct --profile agency1 campaigns get
|
|
674
|
+
```
|
|
675
|
+
|
|
676
|
+
Порядок выбора credentials:
|
|
677
|
+
|
|
678
|
+
| Приоритет | Источник | Пример |
|
|
679
|
+
|-----------|----------|--------|
|
|
680
|
+
| 1 | Явные CLI-опции | `direct --token TOKEN --login LOGIN campaigns get` |
|
|
681
|
+
| 2 | OAuth profile storage | `direct --profile agency1 campaigns get` |
|
|
682
|
+
| 3 | Профильные env vars | `YANDEX_DIRECT_TOKEN_AGENCY1`, `YANDEX_DIRECT_LOGIN_AGENCY1` |
|
|
683
|
+
| 4 | Базовые env vars или project `.env` | `YANDEX_DIRECT_TOKEN`, `YANDEX_DIRECT_LOGIN` |
|
|
684
|
+
| 5 | 1Password references | `--op-token-ref`, `YANDEX_DIRECT_OP_TOKEN_REF` |
|
|
685
|
+
| 6 | Bitwarden references | `--bw-token-ref`, `YANDEX_DIRECT_BW_TOKEN_REF` |
|
|
686
|
+
|
|
687
|
+
Файл `.env` в проекте загружается автоматически. Если профиль выбран через
|
|
688
|
+
`--profile` или `direct auth use --profile NAME`, Direct CLI не подставляет
|
|
689
|
+
base `YANDEX_DIRECT_LOGIN`; это защищает от смешивания токена из профиля с
|
|
690
|
+
логином из project `.env`. Для нескольких аккаунтов используйте OAuth profiles
|
|
691
|
+
или профильные env vars, а не базовые credentials.
|
|
692
|
+
|
|
586
693
|
Установка остаётся через `pip install direct-cli`, а запуск команд теперь идет
|
|
587
694
|
через `direct`. Вызов deprecated entrypoint `direct-cli` завершается ошибкой с
|
|
588
695
|
подсказкой `use direct instead of direct-cli`.
|
|
@@ -593,6 +700,7 @@ direct --token ВАШ_ТОКЕН --login ВАШ_ЛОГИН campaigns get
|
|
|
593
700
|
|-------|----------|
|
|
594
701
|
| `--token` | OAuth-токен доступа к API |
|
|
595
702
|
| `--login` | Direct client login |
|
|
703
|
+
| `--profile` | Имя credential profile |
|
|
596
704
|
| `--sandbox` | Использовать тестовое API (песочница) |
|
|
597
705
|
|
|
598
706
|
### Использование
|
|
@@ -624,6 +732,17 @@ Command naming rules:
|
|
|
624
732
|
должен быть добавлен как явное exception-правило с конкретным legacy syntax из
|
|
625
733
|
`tapi-yandex-direct`, который действительно нужно поддержать.
|
|
626
734
|
|
|
735
|
+
Удалённые исторические имена:
|
|
736
|
+
|
|
737
|
+
| Историческое имя | Каноническое имя |
|
|
738
|
+
|----------------------------|------------------------------|
|
|
739
|
+
| `dynamictargets` | `dynamicads` |
|
|
740
|
+
| `smarttargets` | `smartadtargets` |
|
|
741
|
+
| `negativekeywords` | `negativekeywordsharedsets` |
|
|
742
|
+
| `list` | `get` |
|
|
743
|
+
| `checkcamp` | `check-campaigns` |
|
|
744
|
+
| `checkdict` | `check-dictionaries` |
|
|
745
|
+
|
|
627
746
|
`direct` — это канонический transport entrypoint над API Яндекс Директа,
|
|
628
747
|
устанавливаемый пакетом `direct-cli`. Канонические имена CLI-групп следуют
|
|
629
748
|
нормализованным Python-именам из `tapi-yandex-direct`, а имена подкоманд —
|
|
@@ -704,7 +823,7 @@ direct dictionaries get-geo-regions \
|
|
|
704
823
|
#### Flag Design Rules
|
|
705
824
|
|
|
706
825
|
- List inputs use comma-separated CLI syntax where appropriate.
|
|
707
|
-
- Money and bid values
|
|
826
|
+
- Money and bid values are passed in micro-rubles (API-native format). Values below 100,000 trigger a validation hint suggesting the correct scale.
|
|
708
827
|
- Selector fields remain explicit flags, for example:
|
|
709
828
|
- `--id`
|
|
710
829
|
- `--campaign-id`
|
|
@@ -747,7 +866,7 @@ Valid canonical examples:
|
|
|
747
866
|
direct campaigns get --ids 1,2,3
|
|
748
867
|
direct changes check-campaigns --timestamp 2026-04-14T00:00:00
|
|
749
868
|
direct keywordsresearch has-search-volume --keywords "buy laptop,buy desktop"
|
|
750
|
-
direct dynamicads set-bids --id 789 --bid
|
|
869
|
+
direct dynamicads set-bids --id 789 --bid 12500000
|
|
751
870
|
direct dictionaries get-geo-regions --region-ids 225 --fields GeoRegionId,GeoRegionName
|
|
752
871
|
```
|
|
753
872
|
|
|
@@ -755,7 +874,7 @@ Invalid examples:
|
|
|
755
874
|
|
|
756
875
|
```bash
|
|
757
876
|
direct dictionaries get-geo-regions --json '{"GeoRegionIds":[225]}' --fields GeoRegionId,GeoRegionName
|
|
758
|
-
direct dynamicads set-bids --id 789 --bid
|
|
877
|
+
direct dynamicads set-bids --id 789 --bid 12500000 --json '{"StrategyPriority":"HIGH"}'
|
|
759
878
|
direct dictionaries get-geo-regions \
|
|
760
879
|
--region-ids 225 \
|
|
761
880
|
--fields GeoRegionId,GeoRegionName
|
|
@@ -773,12 +892,12 @@ direct campaigns get --ids 1,2,3 --format table
|
|
|
773
892
|
direct campaigns get --fetch-all --format csv --output campaigns.csv
|
|
774
893
|
|
|
775
894
|
# Создать (--dry-run покажет запрос без отправки)
|
|
776
|
-
direct campaigns add --name "Моя кампания" --start-date 2024-02-01 --type TEXT_CAMPAIGN --budget
|
|
895
|
+
direct campaigns add --name "Моя кампания" --start-date 2024-02-01 --type TEXT_CAMPAIGN --budget 1000000000 --setting ADD_METRICA_TAG=YES --search-strategy HIGHEST_POSITION --network-strategy SERVING_OFF --dry-run
|
|
777
896
|
direct campaigns add --name "Динамическая кампания" --start-date 2024-02-01 --type DYNAMIC_TEXT_CAMPAIGN --setting ADD_METRICA_TAG=NO --search-strategy HIGHEST_POSITION --network-strategy SERVING_OFF --dry-run
|
|
778
|
-
direct campaigns add --name "Смарт-кампания" --start-date 2024-02-01 --type SMART_CAMPAIGN --network-strategy AVERAGE_CPC_PER_FILTER --filter-average-cpc
|
|
897
|
+
direct campaigns add --name "Смарт-кампания" --start-date 2024-02-01 --type SMART_CAMPAIGN --network-strategy AVERAGE_CPC_PER_FILTER --filter-average-cpc 1000000 --counter-id 123 --dry-run
|
|
779
898
|
|
|
780
899
|
# Обновление и управление статусом
|
|
781
|
-
direct campaigns update --id 12345 --name "Новое название" --status SUSPENDED --budget
|
|
900
|
+
direct campaigns update --id 12345 --name "Новое название" --status SUSPENDED --budget 100000000 --start-date 2024-02-10 --end-date 2024-03-01
|
|
782
901
|
direct campaigns suspend --id 12345
|
|
783
902
|
direct campaigns resume --id 12345
|
|
784
903
|
direct campaigns archive --id 12345
|
|
@@ -812,7 +931,7 @@ direct ads delete --id 99999
|
|
|
812
931
|
|
|
813
932
|
```bash
|
|
814
933
|
direct keywords get --campaign-ids 1,2,3
|
|
815
|
-
direct keywords add --adgroup-id 12345 --keyword "купить ноутбук" --bid
|
|
934
|
+
direct keywords add --adgroup-id 12345 --keyword "купить ноутбук" --bid 10500000 --context-bid 5250000 --user-param-1 segment-a --user-param-2 segment-b --dry-run
|
|
816
935
|
direct keywords update --id 88888 --keyword "updated keyword text"
|
|
817
936
|
direct keywords delete --id 88888
|
|
818
937
|
```
|
|
@@ -850,22 +969,22 @@ direct retargeting add --name "Список A" --type AUDIENCE --rule "ALL:12345
|
|
|
850
969
|
direct retargeting update --id 55 --name "Переименованный список" --rule "ANY:12345:30" --dry-run
|
|
851
970
|
|
|
852
971
|
# Ставки и модификаторы
|
|
853
|
-
direct bids set --keyword-id 123 --bid
|
|
854
|
-
direct bids set-auto --keyword-id 123 --max-bid
|
|
855
|
-
direct keywordbids set --keyword-id 321 --search-bid
|
|
856
|
-
direct keywordbids set-auto --keyword-id 321 --target-traffic-volume 100 --increase-percent 10 --bid-ceiling
|
|
972
|
+
direct bids set --keyword-id 123 --bid 15000000
|
|
973
|
+
direct bids set-auto --keyword-id 123 --max-bid 20000000 --position PREMIUMBLOCK --scope SEARCH --dry-run
|
|
974
|
+
direct keywordbids set --keyword-id 321 --search-bid 8000000 --network-bid 3000000
|
|
975
|
+
direct keywordbids set-auto --keyword-id 321 --target-traffic-volume 100 --increase-percent 10 --bid-ceiling 12500000 --dry-run
|
|
857
976
|
direct bidmodifiers add --campaign-id 123 --type DEMOGRAPHICS_ADJUSTMENT --value 150 --gender GENDER_MALE --age AGE_25_34 --dry-run
|
|
858
977
|
direct bidmodifiers set --id 99 --value 130 --dry-run
|
|
859
978
|
|
|
860
979
|
# Канонические многословные группы
|
|
861
980
|
direct negativekeywordsharedsets update --id 123 --keywords "foo,bar"
|
|
862
|
-
direct audiencetargets add --adgroup-id 100 --retargeting-list-id 200 --bid
|
|
863
|
-
direct audiencetargets set-bids --id 101 --context-bid
|
|
864
|
-
direct dynamicads add --adgroup-id 33 --name "Webpage A" --condition "URL:CONTAINS_ANY:test|shop" --condition "PAGE_CONTENT:CONTAINS:baz" --bid
|
|
865
|
-
direct smartadtargets add --adgroup-id 55 --name "Audience A" --audience ALL_SEGMENTS --condition "CATEGORY_ID:EQUALS:42" --average-cpc
|
|
981
|
+
direct audiencetargets add --adgroup-id 100 --retargeting-list-id 200 --bid 12000000 --priority HIGH --dry-run
|
|
982
|
+
direct audiencetargets set-bids --id 101 --context-bid 7000000 --priority LOW --dry-run
|
|
983
|
+
direct dynamicads add --adgroup-id 33 --name "Webpage A" --condition "URL:CONTAINS_ANY:test|shop" --condition "PAGE_CONTENT:CONTAINS:baz" --bid 3000000 --context-bid 2000000 --priority HIGH --dry-run
|
|
984
|
+
direct smartadtargets add --adgroup-id 55 --name "Audience A" --audience ALL_SEGMENTS --condition "CATEGORY_ID:EQUALS:42" --average-cpc 3000000 --average-cpa 4000000 --priority HIGH --available-items-only YES --dry-run
|
|
866
985
|
direct smartadtargets update --id 456 --priority HIGH
|
|
867
|
-
direct smartadtargets set-bids --id 456 --average-cpc
|
|
868
|
-
direct dynamicads set-bids --id 789 --bid
|
|
986
|
+
direct smartadtargets set-bids --id 456 --average-cpc 10500000 --average-cpa 15000000 --priority HIGH
|
|
987
|
+
direct dynamicads set-bids --id 789 --bid 12500000 --context-bid 9000000 --priority HIGH
|
|
869
988
|
|
|
870
989
|
# Общие стратегии ставок
|
|
871
990
|
direct strategies get --limit 5
|
|
@@ -875,8 +994,8 @@ direct strategies archive --id 42 --dry-run
|
|
|
875
994
|
|
|
876
995
|
# Динамические таргеты по фиду
|
|
877
996
|
direct dynamicfeedadtargets get --adgroup-ids 123 --limit 5
|
|
878
|
-
direct dynamicfeedadtargets add --adgroup-id 33 --name "Срез фида А" --condition "CATEGORY:EQUALS:shoes" --bid
|
|
879
|
-
direct dynamicfeedadtargets set-bids --id 789 --bid
|
|
997
|
+
direct dynamicfeedadtargets add --adgroup-id 33 --name "Срез фида А" --condition "CATEGORY:EQUALS:shoes" --bid 5000000 --dry-run
|
|
998
|
+
direct dynamicfeedadtargets set-bids --id 789 --bid 6500000 --context-bid 4000000 --dry-run
|
|
880
999
|
|
|
881
1000
|
# Расширения, ассеты, фиды и клиенты
|
|
882
1001
|
direct sitelinks add --sitelink "Docs|https://example.com/docs" --sitelink "Help|https://example.com/help|Desk" --dry-run
|
|
@@ -936,7 +1055,7 @@ direct campaigns get --fetch-all # все страницы
|
|
|
936
1055
|
| `keywords delete --id` | Безвозвратно удаляет ключевое слово |
|
|
937
1056
|
| `audiencetargets delete --id` | Безвозвратно удаляет условие подбора аудитории |
|
|
938
1057
|
|
|
939
|
-
Команды, влияющие на показ рекламы: `suspend`, `resume`, `archive`, `unarchive` (доступны для `campaigns`, `ads`, `keywords`).
|
|
1058
|
+
Команды, влияющие на показ рекламы: `suspend`, `resume`, `archive`, `unarchive` (доступны для `campaigns`, `ads`), `suspend`, `resume` (также для `keywords`).
|
|
940
1059
|
|
|
941
1060
|
Команды, влияющие на ставки и расходы: `bids set`, `keywordbids set`, `bidmodifiers set`.
|
|
942
1061
|
|
|
@@ -966,24 +1085,64 @@ YANDEX_DIRECT_LIVE_WRITE=1 pytest -m integration_live_write -v # replay live dr
|
|
|
966
1085
|
YANDEX_DIRECT_LIVE_WRITE=1 pytest -m integration_live_write -v --record-mode=rewrite # перезапись live draft-кассеты
|
|
967
1086
|
```
|
|
968
1087
|
|
|
969
|
-
####
|
|
1088
|
+
#### Smoke-скрипты команд
|
|
1089
|
+
|
|
1090
|
+
Каждая CLI-подкоманда классифицирована в `direct_cli/smoke_matrix.py`.
|
|
1091
|
+
|
|
1092
|
+
| Категория | Скрипт | Когда запускать |
|
|
1093
|
+
|---|---|---|
|
|
1094
|
+
| SAFE | `scripts/test_safe_commands.sh` | Production smoke-проверки только на чтение; нужны `YANDEX_DIRECT_TOKEN` и `YANDEX_DIRECT_LOGIN` |
|
|
1095
|
+
| WRITE_SANDBOX | `scripts/test_sandbox_write.sh` | Live sandbox write-проверки; нужны `YANDEX_DIRECT_TOKEN` и `YANDEX_DIRECT_LOGIN`; отчёт печатает `PASS`, `FAIL`, `SANDBOX_LIMITATION` или `NOT_COVERED` для каждой команды |
|
|
1096
|
+
| DANGEROUS | `scripts/test_dangerous_commands.sh` | Только ручной checklist; специально завершается с кодом 1 |
|
|
1097
|
+
|
|
1098
|
+
Текущая поверхность команд:
|
|
1099
|
+
|
|
1100
|
+
| Метрика | Количество |
|
|
1101
|
+
|---|---:|
|
|
1102
|
+
| WSDL-backed API services | 29 |
|
|
1103
|
+
| API services с учётом Reports | 30 |
|
|
1104
|
+
| WSDL operations | 112 |
|
|
1105
|
+
| CLI groups с `auth` | 31 |
|
|
1106
|
+
| CLI subcommands с `auth` | 122 |
|
|
1107
|
+
| API CLI subcommands без `auth` | 118 |
|
|
1108
|
+
|
|
1109
|
+
#### Live sandbox write smoke
|
|
1110
|
+
|
|
1111
|
+
`WRITE_SANDBOX` smoke — это live-проверка против **sandbox-окружения**
|
|
1112
|
+
Яндекс Директа. Она не воспроизводит сохранённый HTTP-трафик и не создаёт
|
|
1113
|
+
новые записи. Запускайте её только когда намеренно хотите обратиться к
|
|
1114
|
+
`api-sandbox.direct.yandex.com`:
|
|
970
1115
|
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
1116
|
+
```bash
|
|
1117
|
+
set -a && source .env && set +a
|
|
1118
|
+
scripts/test_sandbox_write.sh
|
|
1119
|
+
```
|
|
1120
|
+
|
|
1121
|
+
Runner выполняет команды matrix через `direct --sandbox ...`, создаёт
|
|
1122
|
+
временные sandbox prerequisites там, где это безопасно, и удаляет их
|
|
1123
|
+
best-effort. Отчёт содержит одну строку на каждую команду `WRITE_SANDBOX`:
|
|
1124
|
+
|
|
1125
|
+
- `PASS`: команда прошла против live sandbox API.
|
|
1126
|
+
- `SANDBOX_LIMITATION`: запрос дошёл до API и получил известное ограничение
|
|
1127
|
+
sandbox, например коды `8800`, `1000`, `3500` или `5004`.
|
|
1128
|
+
- `FAIL`: неожиданный CLI/API error.
|
|
1129
|
+
- `NOT_COVERED`: runner пока не умеет безопасно построить prerequisites.
|
|
1130
|
+
|
|
1131
|
+
Один и тот же OAuth-токен работает и для продакшена, и для sandbox; отдельный
|
|
1132
|
+
sandbox-токен не нужен.
|
|
1133
|
+
|
|
1134
|
+
#### Перезапись write-кассет
|
|
974
1135
|
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
1136
|
+
Уровень `integration_write` в pytest всё ещё воспроизводит сохранённый
|
|
1137
|
+
write-трафик для регрессионного покрытия. Если вы меняете эти тесты или их
|
|
1138
|
+
payload и намеренно хотите обновить fixtures, перезаписывайте их отдельно:
|
|
978
1139
|
|
|
979
1140
|
```bash
|
|
980
1141
|
set -a && source .env && set +a # загрузить YANDEX_DIRECT_TOKEN / LOGIN
|
|
981
1142
|
pytest -m integration_write -v --record-mode=rewrite
|
|
982
1143
|
```
|
|
983
1144
|
|
|
984
|
-
|
|
985
|
-
отдельный sandbox-токен не нужен. После перезаписи **обязательно проверьте
|
|
986
|
-
YAML-ы на утечку секретов**:
|
|
1145
|
+
После перезаписи **обязательно проверьте YAML-ы на утечку секретов**:
|
|
987
1146
|
|
|
988
1147
|
```bash
|
|
989
1148
|
grep -r "$YANDEX_DIRECT_TOKEN" tests/cassettes/ # должно быть пусто
|