direct-cli 0.3.1__tar.gz → 0.3.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.3.1 → direct_cli-0.3.2}/PKG-INFO +42 -7
- {direct_cli-0.3.1 → direct_cli-0.3.2}/README.md +41 -6
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/_vendor/tapi_yandex_direct/v4/adapter.py +12 -5
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/_vendor/tapi_yandex_direct/v4/adapter.pyi +2 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/api.py +6 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/cli.py +3 -3
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/commands/adextensions.py +27 -2
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/commands/adgroups.py +36 -1
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/commands/adimages.py +27 -6
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/commands/ads.py +55 -4
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/commands/advideos.py +11 -6
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/commands/audiencetargets.py +18 -1
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/commands/bidmodifiers.py +16 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/commands/bids.py +10 -1
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/commands/businesses.py +9 -2
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/commands/campaigns.py +40 -20
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/commands/creatives.py +11 -1
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/commands/dynamicads.py +26 -1
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/commands/dynamicfeedadtargets.py +22 -2
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/commands/feeds.py +9 -2
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/commands/keywordbids.py +18 -2
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/commands/keywords.py +50 -13
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/commands/leads.py +23 -1
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/commands/negativekeywordsharedsets.py +10 -5
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/commands/reports.py +124 -22
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/commands/sitelinks.py +9 -2
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/commands/smartadtargets.py +26 -1
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/commands/turbopages.py +16 -2
- direct_cli-0.3.2/direct_cli/commands/v4account.py +218 -0
- direct_cli-0.3.2/direct_cli/commands/v4events.py +118 -0
- direct_cli-0.3.2/direct_cli/commands/v4finance.py +298 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/commands/v4shells.py +0 -15
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/commands/vcards.py +13 -3
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/reports_coverage.py +113 -15
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/smoke_matrix.py +7 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/utils.py +25 -0
- direct_cli-0.3.2/direct_cli/v4/money.py +35 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/v4_contracts.py +83 -22
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli.egg-info/PKG-INFO +42 -7
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli.egg-info/SOURCES.txt +11 -1
- {direct_cli-0.3.1 → direct_cli-0.3.2}/pyproject.toml +2 -2
- {direct_cli-0.3.1 → direct_cli-0.3.2}/scripts/build_api_coverage_report.py +1 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/scripts/test_dangerous_commands.sh +4 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/scripts/test_safe_commands.sh +30 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/API_COVERAGE.md +22 -2
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/MANUAL_COVERAGE.md +12 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/api_coverage_payloads.py +28 -0
- direct_cli-0.3.1/tests/reports_cache/raw/spec.html → direct_cli-0.3.2/tests/reports_cache/raw/period.html +9 -9
- direct_cli-0.3.2/tests/reports_cache/raw/spec.html +660 -0
- direct_cli-0.3.2/tests/reports_cache/spec.json +1645 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/test_api_coverage.py +210 -19
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/test_dry_run.py +316 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/test_smoke_matrix.py +6 -2
- direct_cli-0.3.2/tests/test_v4_contracts.py +292 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/test_v4_foundation.py +4 -0
- direct_cli-0.3.2/tests/test_v4_live_contracts.py +154 -0
- direct_cli-0.3.2/tests/test_v4_safety.py +15 -0
- direct_cli-0.3.2/tests/test_v4account.py +304 -0
- direct_cli-0.3.2/tests/test_v4events.py +162 -0
- direct_cli-0.3.2/tests/test_v4finance_money.py +320 -0
- direct_cli-0.3.2/tests/test_v4finance_read.py +202 -0
- direct_cli-0.3.1/tests/reports_cache/spec.json +0 -583
- direct_cli-0.3.1/tests/test_v4_contracts.py +0 -141
- direct_cli-0.3.1/tests/test_v4_live_contracts.py +0 -79
- {direct_cli-0.3.1 → direct_cli-0.3.2}/.env.example +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/.github/copilot-instructions.md +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/.github/workflows/api-coverage.yml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/.github/workflows/claude-code-review.yml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/.github/workflows/claude.yml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/.gitignore +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/AGENTS.md +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/CLAUDE.md +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/MANIFEST.in +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/__init__.py +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/_deprecated.py +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/_smoke_probes.py +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/_vendor/__init__.py +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/_vendor/tapi_yandex_direct/__init__.py +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/_vendor/tapi_yandex_direct/exceptions.py +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/_vendor/tapi_yandex_direct/resource_mapping.py +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/_vendor/tapi_yandex_direct/tapi_yandex_direct.py +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/_vendor/tapi_yandex_direct/tapi_yandex_direct.pyi +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/_vendor/tapi_yandex_direct/v4/__init__.py +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/_vendor/tapi_yandex_direct/v4/resource_mapping.py +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/auth.py +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/commands/__init__.py +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/commands/agencyclients.py +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/commands/auth.py +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/commands/balance.py +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/commands/changes.py +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/commands/clients.py +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/commands/dictionaries.py +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/commands/keywordsresearch.py +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/commands/retargeting.py +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/commands/strategies.py +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/commands/v4goals.py +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/output.py +0 -0
- /direct_cli-0.3.1/direct_cli/v4.py → /direct_cli-0.3.2/direct_cli/v4/__init__.py +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli/wsdl_coverage.py +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli.egg-info/dependency_links.txt +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli.egg-info/entry_points.txt +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli.egg-info/requires.txt +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/direct_cli.egg-info/top_level.txt +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/docs/superpowers/plans/2026-04-12-issue-32-completion.md +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/docs/superpowers/specs/2026-04-23-vendor-tapi-yandex-direct-design.md +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/scripts/anonymize_cassettes.py +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/scripts/build_api_coverage_checklist.py +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/scripts/check_reports_drift.py +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/scripts/check_wsdl_drift.py +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/scripts/patch_vendor_imports.py +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/scripts/refresh_reports_cache.py +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/scripts/refresh_wsdl_cache.py +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/scripts/release_pypi.sh +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/scripts/sandbox_write_live.py +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/scripts/test_sandbox_write.sh +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/scripts/update_vendor.sh +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/setup.cfg +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/setup.py +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/API_ISSUE_AUDIT.md +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/__init__.py +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/cassettes/test_integration_live_write/test_live_draft_adgroups_add_update_delete.yaml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/cassettes/test_integration_live_write/test_live_draft_adimages_add_get_delete.yaml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/cassettes/test_integration_live_write/test_live_draft_ads_add_update_delete.yaml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/cassettes/test_integration_live_write/test_live_draft_ads_suspend_resume_archive_unarchive.yaml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/cassettes/test_integration_live_write/test_live_draft_advideos_add_get.yaml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/cassettes/test_integration_live_write/test_live_draft_audiencetargets_add_delete.yaml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/cassettes/test_integration_live_write/test_live_draft_audiencetargets_suspend_resume.yaml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/cassettes/test_integration_live_write/test_live_draft_bids_set.yaml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/cassettes/test_integration_live_write/test_live_draft_campaign_create_get_delete.yaml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/cassettes/test_integration_live_write/test_live_draft_creatives_chain_advideo_to_creative.yaml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/cassettes/test_integration_live_write/test_live_draft_dynamicads_add_delete.yaml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/cassettes/test_integration_live_write/test_live_draft_dynamicads_suspend_resume.yaml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/cassettes/test_integration_live_write/test_live_draft_keywordbids_set.yaml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/cassettes/test_integration_live_write/test_live_draft_keywords_add_update_delete.yaml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/cassettes/test_integration_live_write/test_live_draft_keywords_suspend_resume.yaml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/cassettes/test_integration_live_write/test_live_draft_sitelinks_add_get_delete.yaml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/cassettes/test_integration_live_write/test_live_draft_smartadtargets_add_update_delete.yaml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/cassettes/test_integration_live_write/test_live_draft_smartadtargets_suspend_resume.yaml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/cassettes/test_integration_write/TestWriteAdExtensions.test_add_delete.yaml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/cassettes/test_integration_write/TestWriteAdGroups.test_add_update_delete.yaml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/cassettes/test_integration_write/TestWriteAdImages.test_add_delete.yaml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/cassettes/test_integration_write/TestWriteAds.test_add_text_ad_update_delete.yaml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/cassettes/test_integration_write/TestWriteAudienceTargets.test_add_delete.yaml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/cassettes/test_integration_write/TestWriteBidModifiersAdd.test_add_delete_mobile.yaml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/cassettes/test_integration_write/TestWriteBidModifiersSet.test_set_without_id_is_rejected.yaml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/cassettes/test_integration_write/TestWriteBids.test_set_bid.yaml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/cassettes/test_integration_write/TestWriteCampaignDraftLifecycle.test_draft_create_get_delete.yaml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/cassettes/test_integration_write/TestWriteCampaigns.test_campaign_lifecycle.yaml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/cassettes/test_integration_write/TestWriteDynamicAds.test_add_update_delete.yaml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/cassettes/test_integration_write/TestWriteFeeds.test_add_update_delete.yaml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/cassettes/test_integration_write/TestWriteKeywordBids.test_set_keyword_bid.yaml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/cassettes/test_integration_write/TestWriteKeywords.test_add_update_delete.yaml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/cassettes/test_integration_write/TestWriteNegativeKeywordSharedSets.test_add_update_delete.yaml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/cassettes/test_integration_write/TestWriteRetargeting.test_add_delete.yaml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/cassettes/test_integration_write/TestWriteSitelinks.test_add_delete.yaml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/cassettes/test_integration_write/TestWriteSmartAdTargets.test_add_update_delete.yaml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/cassettes/test_integration_write/TestWriteVCards.test_add_delete.yaml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/conftest.py +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/fixtures/test-video.mp4 +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/reports_cache/raw/fields-list.html +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/reports_cache/raw/headers.html +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/reports_cache/raw/type.html +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/test_auth_bw.py +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/test_auth_oauth.py +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/test_auth_op.py +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/test_balance.py +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/test_cli.py +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/test_comprehensive.py +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/test_integration.py +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/test_integration_live_write.py +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/test_integration_write.py +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/test_reports_drift.py +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/test_transport_contract.py +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/test_v4goals.py +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/test_vendor_imports.py +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/wsdl_cache/adextensions.xml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/wsdl_cache/adgroups.xml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/wsdl_cache/adimages.xml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/wsdl_cache/ads.xml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/wsdl_cache/advideos.xml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/wsdl_cache/agencyclients.xml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/wsdl_cache/audiencetargets.xml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/wsdl_cache/bidmodifiers.xml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/wsdl_cache/bids.xml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/wsdl_cache/businesses.xml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/wsdl_cache/campaigns.xml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/wsdl_cache/changes.xml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/wsdl_cache/clients.xml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/wsdl_cache/creatives.xml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/wsdl_cache/dictionaries.xml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/wsdl_cache/dynamicfeedadtargets.xml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/wsdl_cache/dynamictextadtargets.xml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/wsdl_cache/feeds.xml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/wsdl_cache/imports/adextensiontypes.xsd +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/wsdl_cache/imports/general.xsd +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/wsdl_cache/imports/generalclients.xsd +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/wsdl_cache/keywordbids.xml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/wsdl_cache/keywords.xml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/wsdl_cache/keywordsresearch.xml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/wsdl_cache/leads.xml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/wsdl_cache/negativekeywordsharedsets.xml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/wsdl_cache/retargetinglists.xml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/wsdl_cache/sitelinks.xml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/wsdl_cache/smartadtargets.xml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/wsdl_cache/strategies.xml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/wsdl_cache/turbopages.xml +0 -0
- {direct_cli-0.3.1 → direct_cli-0.3.2}/tests/wsdl_cache/vcards.xml +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: direct-cli
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.2
|
|
4
4
|
Summary: Command-line interface for Yandex Direct API
|
|
5
5
|
Author: axisrow
|
|
6
6
|
License: MIT
|
|
@@ -147,6 +147,39 @@ direct v4goals get-retargeting-goals --campaign-ids 123,456 --format table
|
|
|
147
147
|
direct v4goals get-stat-goals --campaign-ids 123 --dry-run
|
|
148
148
|
```
|
|
149
149
|
|
|
150
|
+
### V4 Live Events
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
direct v4events get-events-log --from 2026-04-14T00:00:00 --to 2026-04-15T00:00:00
|
|
154
|
+
direct v4events get-events-log --from 2026-04-14T00:00:00 --to 2026-04-15T00:00:00 --currency RUB --limit 100 --offset 0 --format table
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### V4 Live Finance
|
|
158
|
+
|
|
159
|
+
`get-credit-limits` requires a financial token and operation number. Pass them
|
|
160
|
+
with `--finance-token` and `--operation-num`, or set
|
|
161
|
+
`YANDEX_DIRECT_FINANCE_TOKEN` and `YANDEX_DIRECT_OPERATION_NUM`.
|
|
162
|
+
Money mutation commands are dry-run-only in this release and always require
|
|
163
|
+
`--dry-run`; dry-run output masks the financial token.
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
direct v4finance get-credit-limits --logins client-login --finance-token FINANCE_TOKEN --operation-num 123
|
|
167
|
+
direct v4finance get-credit-limits --logins client-login,other-client --format table
|
|
168
|
+
direct v4finance check-payment --custom-transaction-id A123456789012345678901234567890B
|
|
169
|
+
direct v4finance transfer-money --from-campaign-id 123 --to-campaign-id 456 --amount 100.50 --finance-token FINANCE_TOKEN --operation-num 123 --dry-run
|
|
170
|
+
direct v4finance pay-campaigns --campaign-id 123 --amount 100.50 --contract-id CONTRACT_ID --pay-method CREDIT --finance-token FINANCE_TOKEN --operation-num 123 --dry-run
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### V4 Live Shared Account
|
|
174
|
+
|
|
175
|
+
Shared-account mutations are dry-run-only in this release and always require
|
|
176
|
+
`--dry-run`.
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
direct v4account enable-shared-account --client-login client-login --dry-run
|
|
180
|
+
direct v4account account-management --action Update --account-id 1327944 --day-budget 100.50 --spend-mode Default --money-in-sms Yes --money-out-sms No --email ops@example.com --money-warning-value 25 --dry-run
|
|
181
|
+
```
|
|
182
|
+
|
|
150
183
|
### CLI Convention
|
|
151
184
|
|
|
152
185
|
The current CLI convention is defined as follows.
|
|
@@ -344,6 +377,7 @@ direct keywords delete --id 88888
|
|
|
344
377
|
```bash
|
|
345
378
|
# Get a report (saved to file)
|
|
346
379
|
direct reports get --type CAMPAIGN_PERFORMANCE_REPORT --from 2024-01-01 --to 2024-01-31 --name "January Report" --fields "Date,CampaignId,Clicks,Cost" --format csv --output report.csv
|
|
380
|
+
direct reports get --type CUSTOM_REPORT --from 2024-01-01 --to 2024-01-31 --name "Goals Report" --fields "Date,CampaignId,GoalsRoi" --goals 12345,67890 --attribution-models AUTO --format csv --output goals-report.csv
|
|
347
381
|
|
|
348
382
|
# List available report types
|
|
349
383
|
direct reports list-types
|
|
@@ -509,9 +543,9 @@ Current command surface:
|
|
|
509
543
|
| WSDL-backed API services | 29 |
|
|
510
544
|
| Supported API services including Reports | 30 |
|
|
511
545
|
| WSDL operations | 112 |
|
|
512
|
-
| CLI groups including `auth` |
|
|
513
|
-
| CLI subcommands including `auth` |
|
|
514
|
-
| API CLI subcommands excluding `auth` |
|
|
546
|
+
| CLI groups including `auth` | 39 |
|
|
547
|
+
| CLI subcommands including `auth` | 130 |
|
|
548
|
+
| API CLI subcommands excluding `auth` | 126 |
|
|
515
549
|
|
|
516
550
|
### API Coverage And Drift Monitoring
|
|
517
551
|
|
|
@@ -966,6 +1000,7 @@ direct keywords delete --id 88888
|
|
|
966
1000
|
```bash
|
|
967
1001
|
# Сформировать отчёт (сохраняется в файл)
|
|
968
1002
|
direct reports get --type CAMPAIGN_PERFORMANCE_REPORT --from 2024-01-01 --to 2024-01-31 --name "Отчёт за январь" --fields "Date,CampaignId,Clicks,Cost" --format csv --output report.csv
|
|
1003
|
+
direct reports get --type CUSTOM_REPORT --from 2024-01-01 --to 2024-01-31 --name "Отчёт по целям" --fields "Date,CampaignId,GoalsRoi" --goals 12345,67890 --attribution-models AUTO --format csv --output goals-report.csv
|
|
969
1004
|
|
|
970
1005
|
# Список доступных типов отчётов
|
|
971
1006
|
direct reports list-types
|
|
@@ -1132,9 +1167,9 @@ YANDEX_DIRECT_LIVE_WRITE=1 pytest -m integration_live_write -v --record-mode=rew
|
|
|
1132
1167
|
| WSDL-backed API services | 29 |
|
|
1133
1168
|
| API services с учётом Reports | 30 |
|
|
1134
1169
|
| WSDL operations | 112 |
|
|
1135
|
-
| CLI groups с `auth` |
|
|
1136
|
-
| CLI subcommands с `auth` |
|
|
1137
|
-
| API CLI subcommands без `auth` |
|
|
1170
|
+
| CLI groups с `auth` | 39 |
|
|
1171
|
+
| CLI subcommands с `auth` | 130 |
|
|
1172
|
+
| API CLI subcommands без `auth` | 126 |
|
|
1138
1173
|
|
|
1139
1174
|
#### Live sandbox write smoke
|
|
1140
1175
|
|
|
@@ -108,6 +108,39 @@ direct v4goals get-retargeting-goals --campaign-ids 123,456 --format table
|
|
|
108
108
|
direct v4goals get-stat-goals --campaign-ids 123 --dry-run
|
|
109
109
|
```
|
|
110
110
|
|
|
111
|
+
### V4 Live Events
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
direct v4events get-events-log --from 2026-04-14T00:00:00 --to 2026-04-15T00:00:00
|
|
115
|
+
direct v4events get-events-log --from 2026-04-14T00:00:00 --to 2026-04-15T00:00:00 --currency RUB --limit 100 --offset 0 --format table
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### V4 Live Finance
|
|
119
|
+
|
|
120
|
+
`get-credit-limits` requires a financial token and operation number. Pass them
|
|
121
|
+
with `--finance-token` and `--operation-num`, or set
|
|
122
|
+
`YANDEX_DIRECT_FINANCE_TOKEN` and `YANDEX_DIRECT_OPERATION_NUM`.
|
|
123
|
+
Money mutation commands are dry-run-only in this release and always require
|
|
124
|
+
`--dry-run`; dry-run output masks the financial token.
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
direct v4finance get-credit-limits --logins client-login --finance-token FINANCE_TOKEN --operation-num 123
|
|
128
|
+
direct v4finance get-credit-limits --logins client-login,other-client --format table
|
|
129
|
+
direct v4finance check-payment --custom-transaction-id A123456789012345678901234567890B
|
|
130
|
+
direct v4finance transfer-money --from-campaign-id 123 --to-campaign-id 456 --amount 100.50 --finance-token FINANCE_TOKEN --operation-num 123 --dry-run
|
|
131
|
+
direct v4finance pay-campaigns --campaign-id 123 --amount 100.50 --contract-id CONTRACT_ID --pay-method CREDIT --finance-token FINANCE_TOKEN --operation-num 123 --dry-run
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### V4 Live Shared Account
|
|
135
|
+
|
|
136
|
+
Shared-account mutations are dry-run-only in this release and always require
|
|
137
|
+
`--dry-run`.
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
direct v4account enable-shared-account --client-login client-login --dry-run
|
|
141
|
+
direct v4account account-management --action Update --account-id 1327944 --day-budget 100.50 --spend-mode Default --money-in-sms Yes --money-out-sms No --email ops@example.com --money-warning-value 25 --dry-run
|
|
142
|
+
```
|
|
143
|
+
|
|
111
144
|
### CLI Convention
|
|
112
145
|
|
|
113
146
|
The current CLI convention is defined as follows.
|
|
@@ -305,6 +338,7 @@ direct keywords delete --id 88888
|
|
|
305
338
|
```bash
|
|
306
339
|
# Get a report (saved to file)
|
|
307
340
|
direct reports get --type CAMPAIGN_PERFORMANCE_REPORT --from 2024-01-01 --to 2024-01-31 --name "January Report" --fields "Date,CampaignId,Clicks,Cost" --format csv --output report.csv
|
|
341
|
+
direct reports get --type CUSTOM_REPORT --from 2024-01-01 --to 2024-01-31 --name "Goals Report" --fields "Date,CampaignId,GoalsRoi" --goals 12345,67890 --attribution-models AUTO --format csv --output goals-report.csv
|
|
308
342
|
|
|
309
343
|
# List available report types
|
|
310
344
|
direct reports list-types
|
|
@@ -470,9 +504,9 @@ Current command surface:
|
|
|
470
504
|
| WSDL-backed API services | 29 |
|
|
471
505
|
| Supported API services including Reports | 30 |
|
|
472
506
|
| WSDL operations | 112 |
|
|
473
|
-
| CLI groups including `auth` |
|
|
474
|
-
| CLI subcommands including `auth` |
|
|
475
|
-
| API CLI subcommands excluding `auth` |
|
|
507
|
+
| CLI groups including `auth` | 39 |
|
|
508
|
+
| CLI subcommands including `auth` | 130 |
|
|
509
|
+
| API CLI subcommands excluding `auth` | 126 |
|
|
476
510
|
|
|
477
511
|
### API Coverage And Drift Monitoring
|
|
478
512
|
|
|
@@ -927,6 +961,7 @@ direct keywords delete --id 88888
|
|
|
927
961
|
```bash
|
|
928
962
|
# Сформировать отчёт (сохраняется в файл)
|
|
929
963
|
direct reports get --type CAMPAIGN_PERFORMANCE_REPORT --from 2024-01-01 --to 2024-01-31 --name "Отчёт за январь" --fields "Date,CampaignId,Clicks,Cost" --format csv --output report.csv
|
|
964
|
+
direct reports get --type CUSTOM_REPORT --from 2024-01-01 --to 2024-01-31 --name "Отчёт по целям" --fields "Date,CampaignId,GoalsRoi" --goals 12345,67890 --attribution-models AUTO --format csv --output goals-report.csv
|
|
930
965
|
|
|
931
966
|
# Список доступных типов отчётов
|
|
932
967
|
direct reports list-types
|
|
@@ -1093,9 +1128,9 @@ YANDEX_DIRECT_LIVE_WRITE=1 pytest -m integration_live_write -v --record-mode=rew
|
|
|
1093
1128
|
| WSDL-backed API services | 29 |
|
|
1094
1129
|
| API services с учётом Reports | 30 |
|
|
1095
1130
|
| WSDL operations | 112 |
|
|
1096
|
-
| CLI groups с `auth` |
|
|
1097
|
-
| CLI subcommands с `auth` |
|
|
1098
|
-
| API CLI subcommands без `auth` |
|
|
1131
|
+
| CLI groups с `auth` | 39 |
|
|
1132
|
+
| CLI subcommands с `auth` | 130 |
|
|
1133
|
+
| API CLI subcommands без `auth` | 126 |
|
|
1099
1134
|
|
|
1100
1135
|
#### Live sandbox write smoke
|
|
1101
1136
|
|
|
@@ -43,11 +43,14 @@ class V4LiveClientAdapter(JSONAdapterMixin, TapiAdapter):
|
|
|
43
43
|
token = api_params.get("access_token")
|
|
44
44
|
login = api_params.get("login")
|
|
45
45
|
language = api_params.get("language", "en")
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
#
|
|
50
|
-
#
|
|
46
|
+
finance_token = api_params.get("finance_token")
|
|
47
|
+
operation_num = api_params.get("operation_num")
|
|
48
|
+
|
|
49
|
+
# Enrich the JSON body with top-level v4 Live fields.
|
|
50
|
+
# format_data_to_request does not see api_params, so we do this here,
|
|
51
|
+
# after super() has already serialised the user data. Agency/client
|
|
52
|
+
# selection is transport-level (Client-Login header); method params
|
|
53
|
+
# must stay schema-shaped.
|
|
51
54
|
raw = params.get("data")
|
|
52
55
|
if raw:
|
|
53
56
|
if isinstance(raw, (bytes, bytearray)):
|
|
@@ -67,6 +70,10 @@ class V4LiveClientAdapter(JSONAdapterMixin, TapiAdapter):
|
|
|
67
70
|
body.setdefault("token", token)
|
|
68
71
|
if language:
|
|
69
72
|
body.setdefault("locale", language)
|
|
73
|
+
if finance_token:
|
|
74
|
+
body.setdefault("finance_token", finance_token)
|
|
75
|
+
if operation_num is not None:
|
|
76
|
+
body.setdefault("operation_num", operation_num)
|
|
70
77
|
|
|
71
78
|
params["data"] = orjson.dumps(body)
|
|
72
79
|
|
|
@@ -49,6 +49,8 @@ class YandexDirectV4Live:
|
|
|
49
49
|
language: str = "en",
|
|
50
50
|
retry_if_exceeded_limit: bool = True,
|
|
51
51
|
retries_if_server_error: int = 5,
|
|
52
|
+
finance_token: Optional[str] = None,
|
|
53
|
+
operation_num: Optional[int] = None,
|
|
52
54
|
) -> None: ...
|
|
53
55
|
|
|
54
56
|
def v4live(self) -> V4LiveExecutor: ...
|
|
@@ -80,6 +80,8 @@ def create_v4_client(
|
|
|
80
80
|
language: Optional[str] = None,
|
|
81
81
|
retry_if_exceeded_limit: bool = True,
|
|
82
82
|
retries_if_server_error: int = 5,
|
|
83
|
+
finance_token: Optional[str] = None,
|
|
84
|
+
operation_num: Optional[int] = None,
|
|
83
85
|
) -> YandexDirectV4Live:
|
|
84
86
|
"""
|
|
85
87
|
Create YandexDirect v4 Live client.
|
|
@@ -96,6 +98,8 @@ def create_v4_client(
|
|
|
96
98
|
language: API locale
|
|
97
99
|
retry_if_exceeded_limit: Retry when the API limit is exceeded
|
|
98
100
|
retries_if_server_error: Number of retries for server errors
|
|
101
|
+
finance_token: Financial token for v4 Live finance methods
|
|
102
|
+
operation_num: Financial operation number for v4 Live finance methods
|
|
99
103
|
|
|
100
104
|
Returns:
|
|
101
105
|
YandexDirect v4 Live client instance
|
|
@@ -117,6 +121,8 @@ def create_v4_client(
|
|
|
117
121
|
language=language or "en",
|
|
118
122
|
retry_if_exceeded_limit=retry_if_exceeded_limit,
|
|
119
123
|
retries_if_server_error=retries_if_server_error,
|
|
124
|
+
finance_token=finance_token,
|
|
125
|
+
operation_num=operation_num,
|
|
120
126
|
)
|
|
121
127
|
|
|
122
128
|
|
|
@@ -42,10 +42,10 @@ from .commands.dynamicfeedadtargets import dynamicfeedadtargets
|
|
|
42
42
|
from .commands.strategies import strategies
|
|
43
43
|
from .commands.auth import auth
|
|
44
44
|
from .commands.balance import balance
|
|
45
|
+
from .commands.v4events import v4events
|
|
46
|
+
from .commands.v4finance import v4finance
|
|
47
|
+
from .commands.v4account import v4account
|
|
45
48
|
from .commands.v4shells import (
|
|
46
|
-
v4account,
|
|
47
|
-
v4events,
|
|
48
|
-
v4finance,
|
|
49
49
|
v4forecast,
|
|
50
50
|
v4meta,
|
|
51
51
|
v4wordstat,
|
|
@@ -6,7 +6,7 @@ import click
|
|
|
6
6
|
|
|
7
7
|
from ..api import create_client
|
|
8
8
|
from ..output import format_output, print_error
|
|
9
|
-
from ..utils import get_default_fields, parse_ids
|
|
9
|
+
from ..utils import add_criteria_csv, get_default_fields, parse_ids
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
@click.group()
|
|
@@ -17,13 +17,30 @@ def adextensions():
|
|
|
17
17
|
@adextensions.command()
|
|
18
18
|
@click.option("--ids", help="Comma-separated extension IDs")
|
|
19
19
|
@click.option("--types", help="Filter by types")
|
|
20
|
+
@click.option("--states", help="Comma-separated states")
|
|
21
|
+
@click.option("--statuses", help="Comma-separated statuses")
|
|
22
|
+
@click.option("--modified-since", help="ModifiedSince datetime")
|
|
20
23
|
@click.option("--limit", type=int, help="Limit number of results")
|
|
21
24
|
@click.option("--fetch-all", is_flag=True, help="Fetch all pages")
|
|
22
25
|
@click.option("--format", "output_format", default="json", help="Output format")
|
|
23
26
|
@click.option("--output", help="Output file")
|
|
24
27
|
@click.option("--fields", help="Comma-separated field names")
|
|
28
|
+
@click.option("--dry-run", is_flag=True, help="Show request without sending")
|
|
25
29
|
@click.pass_context
|
|
26
|
-
def get(
|
|
30
|
+
def get(
|
|
31
|
+
ctx,
|
|
32
|
+
ids,
|
|
33
|
+
types,
|
|
34
|
+
states,
|
|
35
|
+
statuses,
|
|
36
|
+
modified_since,
|
|
37
|
+
limit,
|
|
38
|
+
fetch_all,
|
|
39
|
+
output_format,
|
|
40
|
+
output,
|
|
41
|
+
fields,
|
|
42
|
+
dry_run,
|
|
43
|
+
):
|
|
27
44
|
"""Get ad extensions"""
|
|
28
45
|
try:
|
|
29
46
|
client = create_client(
|
|
@@ -41,6 +58,10 @@ def get(ctx, ids, types, limit, fetch_all, output_format, output, fields):
|
|
|
41
58
|
criteria["Ids"] = parse_ids(ids)
|
|
42
59
|
if types:
|
|
43
60
|
criteria["Types"] = types.split(",")
|
|
61
|
+
add_criteria_csv(criteria, "States", states, upper=True)
|
|
62
|
+
add_criteria_csv(criteria, "Statuses", statuses, upper=True)
|
|
63
|
+
if modified_since:
|
|
64
|
+
criteria["ModifiedSince"] = modified_since
|
|
44
65
|
|
|
45
66
|
params = {"SelectionCriteria": criteria, "FieldNames": field_names}
|
|
46
67
|
|
|
@@ -49,6 +70,10 @@ def get(ctx, ids, types, limit, fetch_all, output_format, output, fields):
|
|
|
49
70
|
|
|
50
71
|
body = {"method": "get", "params": params}
|
|
51
72
|
|
|
73
|
+
if dry_run:
|
|
74
|
+
format_output(body, "json", None)
|
|
75
|
+
return
|
|
76
|
+
|
|
52
77
|
result = client.adextensions().post(data=body)
|
|
53
78
|
|
|
54
79
|
if fetch_all:
|
|
@@ -6,7 +6,7 @@ import click
|
|
|
6
6
|
|
|
7
7
|
from ..api import create_client
|
|
8
8
|
from ..output import format_output, print_error
|
|
9
|
-
from ..utils import get_default_fields, parse_ids
|
|
9
|
+
from ..utils import add_criteria_csv, get_default_fields, parse_ids
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
@click.group()
|
|
@@ -18,26 +18,46 @@ def adgroups():
|
|
|
18
18
|
@click.option("--ids", help="Comma-separated ad group IDs")
|
|
19
19
|
@click.option("--campaign-ids", help="Comma-separated campaign IDs")
|
|
20
20
|
@click.option("--status", help="Filter by status")
|
|
21
|
+
@click.option("--statuses", help="Comma-separated statuses")
|
|
21
22
|
@click.option("--types", help="Filter by types")
|
|
23
|
+
@click.option("--tag-ids", help="Comma-separated tag IDs")
|
|
24
|
+
@click.option("--tags", help="Comma-separated tag names")
|
|
25
|
+
@click.option("--app-icon-statuses", help="Comma-separated app icon statuses")
|
|
26
|
+
@click.option("--serving-statuses", help="Comma-separated serving statuses")
|
|
27
|
+
@click.option(
|
|
28
|
+
"--negative-keyword-shared-set-ids",
|
|
29
|
+
help="Comma-separated negative keyword shared set IDs",
|
|
30
|
+
)
|
|
22
31
|
@click.option("--limit", type=int, help="Limit number of results")
|
|
23
32
|
@click.option("--fetch-all", is_flag=True, help="Fetch all pages")
|
|
24
33
|
@click.option("--format", "output_format", default="json", help="Output format")
|
|
25
34
|
@click.option("--output", help="Output file")
|
|
26
35
|
@click.option("--fields", help="Comma-separated field names")
|
|
36
|
+
@click.option("--dry-run", is_flag=True, help="Show request without sending")
|
|
27
37
|
@click.pass_context
|
|
28
38
|
def get(
|
|
29
39
|
ctx,
|
|
30
40
|
ids,
|
|
31
41
|
campaign_ids,
|
|
32
42
|
status,
|
|
43
|
+
statuses,
|
|
33
44
|
types,
|
|
45
|
+
tag_ids,
|
|
46
|
+
tags,
|
|
47
|
+
app_icon_statuses,
|
|
48
|
+
serving_statuses,
|
|
49
|
+
negative_keyword_shared_set_ids,
|
|
34
50
|
limit,
|
|
35
51
|
fetch_all,
|
|
36
52
|
output_format,
|
|
37
53
|
output,
|
|
38
54
|
fields,
|
|
55
|
+
dry_run,
|
|
39
56
|
):
|
|
40
57
|
"""Get ad groups"""
|
|
58
|
+
if status and statuses:
|
|
59
|
+
raise click.UsageError("--status and --statuses are mutually exclusive")
|
|
60
|
+
|
|
41
61
|
try:
|
|
42
62
|
client = create_client(
|
|
43
63
|
token=ctx.obj.get("token"),
|
|
@@ -54,8 +74,19 @@ def get(
|
|
|
54
74
|
criteria["CampaignIds"] = parse_ids(campaign_ids)
|
|
55
75
|
if status:
|
|
56
76
|
criteria["Statuses"] = [status]
|
|
77
|
+
add_criteria_csv(criteria, "Statuses", statuses, upper=True)
|
|
57
78
|
if types:
|
|
58
79
|
criteria["Types"] = types.split(",")
|
|
80
|
+
add_criteria_csv(criteria, "TagIds", tag_ids, integers=True)
|
|
81
|
+
add_criteria_csv(criteria, "Tags", tags)
|
|
82
|
+
add_criteria_csv(criteria, "AppIconStatuses", app_icon_statuses, upper=True)
|
|
83
|
+
add_criteria_csv(criteria, "ServingStatuses", serving_statuses, upper=True)
|
|
84
|
+
add_criteria_csv(
|
|
85
|
+
criteria,
|
|
86
|
+
"NegativeKeywordSharedSetIds",
|
|
87
|
+
negative_keyword_shared_set_ids,
|
|
88
|
+
integers=True,
|
|
89
|
+
)
|
|
59
90
|
|
|
60
91
|
params = {"SelectionCriteria": criteria, "FieldNames": field_names}
|
|
61
92
|
|
|
@@ -64,6 +95,10 @@ def get(
|
|
|
64
95
|
|
|
65
96
|
body = {"method": "get", "params": params}
|
|
66
97
|
|
|
98
|
+
if dry_run:
|
|
99
|
+
format_output(body, "json", None)
|
|
100
|
+
return
|
|
101
|
+
|
|
67
102
|
result = client.adgroups().post(data=body)
|
|
68
103
|
|
|
69
104
|
if fetch_all:
|
|
@@ -6,7 +6,7 @@ import click
|
|
|
6
6
|
|
|
7
7
|
from ..api import create_client
|
|
8
8
|
from ..output import format_output, print_error
|
|
9
|
-
from ..utils import get_default_fields, load_base64_file, parse_ids
|
|
9
|
+
from ..utils import add_criteria_csv, get_default_fields, load_base64_file, parse_ids
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
@click.group()
|
|
@@ -16,13 +16,27 @@ def adimages():
|
|
|
16
16
|
|
|
17
17
|
@adimages.command()
|
|
18
18
|
@click.option("--ids", help="Comma-separated image IDs")
|
|
19
|
+
@click.option("--image-hashes", help="Comma-separated ad image hashes")
|
|
20
|
+
@click.option("--associated", type=click.Choice(["YES", "NO"], case_sensitive=False))
|
|
19
21
|
@click.option("--limit", type=int, help="Limit number of results")
|
|
20
22
|
@click.option("--fetch-all", is_flag=True, help="Fetch all pages")
|
|
21
23
|
@click.option("--format", "output_format", default="json", help="Output format")
|
|
22
24
|
@click.option("--output", help="Output file")
|
|
23
25
|
@click.option("--fields", help="Comma-separated field names")
|
|
26
|
+
@click.option("--dry-run", is_flag=True, help="Show request without sending")
|
|
24
27
|
@click.pass_context
|
|
25
|
-
def get(
|
|
28
|
+
def get(
|
|
29
|
+
ctx,
|
|
30
|
+
ids,
|
|
31
|
+
image_hashes,
|
|
32
|
+
associated,
|
|
33
|
+
limit,
|
|
34
|
+
fetch_all,
|
|
35
|
+
output_format,
|
|
36
|
+
output,
|
|
37
|
+
fields,
|
|
38
|
+
dry_run,
|
|
39
|
+
):
|
|
26
40
|
"""Get ad images"""
|
|
27
41
|
try:
|
|
28
42
|
client = create_client(
|
|
@@ -31,21 +45,28 @@ def get(ctx, ids, limit, fetch_all, output_format, output, fields):
|
|
|
31
45
|
sandbox=ctx.obj.get("sandbox"),
|
|
32
46
|
)
|
|
33
47
|
|
|
34
|
-
field_names = (
|
|
35
|
-
fields.split(",") if fields else get_default_fields("adimages")
|
|
36
|
-
)
|
|
48
|
+
field_names = fields.split(",") if fields else get_default_fields("adimages")
|
|
37
49
|
|
|
38
50
|
criteria = {}
|
|
39
51
|
if ids:
|
|
40
52
|
criteria["Ids"] = parse_ids(ids)
|
|
53
|
+
add_criteria_csv(criteria, "AdImageHashes", image_hashes)
|
|
54
|
+
if associated:
|
|
55
|
+
criteria["Associated"] = associated.upper()
|
|
41
56
|
|
|
42
|
-
params = {"
|
|
57
|
+
params = {"FieldNames": field_names}
|
|
58
|
+
if criteria:
|
|
59
|
+
params["SelectionCriteria"] = criteria
|
|
43
60
|
|
|
44
61
|
if limit:
|
|
45
62
|
params["Page"] = {"Limit": limit}
|
|
46
63
|
|
|
47
64
|
body = {"method": "get", "params": params}
|
|
48
65
|
|
|
66
|
+
if dry_run:
|
|
67
|
+
format_output(body, "json", None)
|
|
68
|
+
return
|
|
69
|
+
|
|
49
70
|
result = client.adimages().post(data=body)
|
|
50
71
|
|
|
51
72
|
if fetch_all:
|
|
@@ -6,7 +6,7 @@ import click
|
|
|
6
6
|
|
|
7
7
|
from ..api import create_client
|
|
8
8
|
from ..output import format_output, print_error
|
|
9
|
-
from ..utils import get_default_fields, parse_ids
|
|
9
|
+
from ..utils import add_criteria_csv, get_default_fields, parse_ids
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
@click.group()
|
|
@@ -19,6 +19,24 @@ def ads():
|
|
|
19
19
|
@click.option("--campaign-ids", help="Comma-separated campaign IDs")
|
|
20
20
|
@click.option("--adgroup-ids", help="Comma-separated ad group IDs")
|
|
21
21
|
@click.option("--status", help="Filter by status")
|
|
22
|
+
@click.option("--statuses", help="Comma-separated statuses")
|
|
23
|
+
@click.option("--states", help="Comma-separated states")
|
|
24
|
+
@click.option("--types", help="Comma-separated ad types")
|
|
25
|
+
@click.option("--mobile", type=click.Choice(["YES", "NO"], case_sensitive=False))
|
|
26
|
+
@click.option("--vcard-ids", help="Comma-separated vCard IDs")
|
|
27
|
+
@click.option("--sitelink-set-ids", help="Comma-separated sitelink set IDs")
|
|
28
|
+
@click.option("--image-hashes", help="Comma-separated ad image hashes")
|
|
29
|
+
@click.option(
|
|
30
|
+
"--vcard-moderation-statuses", help="Comma-separated vCard moderation statuses"
|
|
31
|
+
)
|
|
32
|
+
@click.option(
|
|
33
|
+
"--sitelinks-moderation-statuses",
|
|
34
|
+
help="Comma-separated sitelinks moderation statuses",
|
|
35
|
+
)
|
|
36
|
+
@click.option(
|
|
37
|
+
"--image-moderation-statuses", help="Comma-separated image moderation statuses"
|
|
38
|
+
)
|
|
39
|
+
@click.option("--adextension-ids", help="Comma-separated ad extension IDs")
|
|
22
40
|
@click.option("--limit", type=int, help="Limit number of results")
|
|
23
41
|
@click.option("--fetch-all", is_flag=True, help="Fetch all pages")
|
|
24
42
|
@click.option("--format", "output_format", default="json", help="Output format")
|
|
@@ -35,6 +53,17 @@ def get(
|
|
|
35
53
|
campaign_ids,
|
|
36
54
|
adgroup_ids,
|
|
37
55
|
status,
|
|
56
|
+
statuses,
|
|
57
|
+
states,
|
|
58
|
+
types,
|
|
59
|
+
mobile,
|
|
60
|
+
vcard_ids,
|
|
61
|
+
sitelink_set_ids,
|
|
62
|
+
image_hashes,
|
|
63
|
+
vcard_moderation_statuses,
|
|
64
|
+
sitelinks_moderation_statuses,
|
|
65
|
+
image_moderation_statuses,
|
|
66
|
+
adextension_ids,
|
|
38
67
|
limit,
|
|
39
68
|
fetch_all,
|
|
40
69
|
output_format,
|
|
@@ -44,6 +73,9 @@ def get(
|
|
|
44
73
|
dry_run,
|
|
45
74
|
):
|
|
46
75
|
"""Get ads"""
|
|
76
|
+
if status and statuses:
|
|
77
|
+
raise click.UsageError("--status and --statuses are mutually exclusive")
|
|
78
|
+
|
|
47
79
|
try:
|
|
48
80
|
field_names = (
|
|
49
81
|
fields.split(",") if fields else get_default_fields("ads", "FieldNames")
|
|
@@ -64,6 +96,27 @@ def get(
|
|
|
64
96
|
criteria["AdGroupIds"] = parse_ids(adgroup_ids)
|
|
65
97
|
if status:
|
|
66
98
|
criteria["Statuses"] = [status]
|
|
99
|
+
add_criteria_csv(criteria, "Statuses", statuses, upper=True)
|
|
100
|
+
add_criteria_csv(criteria, "States", states, upper=True)
|
|
101
|
+
add_criteria_csv(criteria, "Types", types, upper=True)
|
|
102
|
+
if mobile:
|
|
103
|
+
criteria["Mobile"] = mobile.upper()
|
|
104
|
+
add_criteria_csv(criteria, "VCardIds", vcard_ids, integers=True)
|
|
105
|
+
add_criteria_csv(criteria, "SitelinkSetIds", sitelink_set_ids, integers=True)
|
|
106
|
+
add_criteria_csv(criteria, "AdImageHashes", image_hashes)
|
|
107
|
+
add_criteria_csv(
|
|
108
|
+
criteria, "VCardModerationStatuses", vcard_moderation_statuses, upper=True
|
|
109
|
+
)
|
|
110
|
+
add_criteria_csv(
|
|
111
|
+
criteria,
|
|
112
|
+
"SitelinksModerationStatuses",
|
|
113
|
+
sitelinks_moderation_statuses,
|
|
114
|
+
upper=True,
|
|
115
|
+
)
|
|
116
|
+
add_criteria_csv(
|
|
117
|
+
criteria, "AdImageModerationStatuses", image_moderation_statuses, upper=True
|
|
118
|
+
)
|
|
119
|
+
add_criteria_csv(criteria, "AdExtensionIds", adextension_ids, integers=True)
|
|
67
120
|
|
|
68
121
|
params = {
|
|
69
122
|
"SelectionCriteria": criteria,
|
|
@@ -139,9 +192,7 @@ def add(ctx, adgroup_id, ad_type, title, text, href, image_hash, dry_run):
|
|
|
139
192
|
if not value
|
|
140
193
|
]
|
|
141
194
|
if missing_fields:
|
|
142
|
-
raise click.UsageError(
|
|
143
|
-
"TEXT_AD requires " + ", ".join(missing_fields)
|
|
144
|
-
)
|
|
195
|
+
raise click.UsageError("TEXT_AD requires " + ", ".join(missing_fields))
|
|
145
196
|
ad_data["TextAd"] = {
|
|
146
197
|
"Mobile": "NO",
|
|
147
198
|
"Title": title,
|
|
@@ -15,14 +15,15 @@ def advideos():
|
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
@advideos.command()
|
|
18
|
-
@click.option("--ids", help="Comma-separated video IDs")
|
|
18
|
+
@click.option("--ids", required=True, help="Comma-separated video IDs")
|
|
19
19
|
@click.option("--limit", type=int, help="Limit number of results")
|
|
20
20
|
@click.option("--fetch-all", is_flag=True, help="Fetch all pages")
|
|
21
21
|
@click.option("--format", "output_format", default="json", help="Output format")
|
|
22
22
|
@click.option("--output", help="Output file")
|
|
23
23
|
@click.option("--fields", help="Comma-separated field names")
|
|
24
|
+
@click.option("--dry-run", is_flag=True, help="Show request without sending")
|
|
24
25
|
@click.pass_context
|
|
25
|
-
def get(ctx, ids, limit, fetch_all, output_format, output, fields):
|
|
26
|
+
def get(ctx, ids, limit, fetch_all, output_format, output, fields, dry_run):
|
|
26
27
|
"""Get ad videos"""
|
|
27
28
|
try:
|
|
28
29
|
client = create_client(
|
|
@@ -33,9 +34,7 @@ def get(ctx, ids, limit, fetch_all, output_format, output, fields):
|
|
|
33
34
|
|
|
34
35
|
field_names = fields.split(",") if fields else get_default_fields("advideos")
|
|
35
36
|
|
|
36
|
-
criteria = {}
|
|
37
|
-
if ids:
|
|
38
|
-
criteria["Ids"] = [x.strip() for x in ids.split(",")]
|
|
37
|
+
criteria = {"Ids": [x.strip() for x in ids.split(",") if x.strip()]}
|
|
39
38
|
|
|
40
39
|
params = {
|
|
41
40
|
"SelectionCriteria": criteria,
|
|
@@ -47,6 +46,10 @@ def get(ctx, ids, limit, fetch_all, output_format, output, fields):
|
|
|
47
46
|
|
|
48
47
|
body = {"method": "get", "params": params}
|
|
49
48
|
|
|
49
|
+
if dry_run:
|
|
50
|
+
format_output(body, "json", None)
|
|
51
|
+
return
|
|
52
|
+
|
|
50
53
|
result = client.advideos().post(data=body)
|
|
51
54
|
|
|
52
55
|
if fetch_all:
|
|
@@ -64,7 +67,9 @@ def get(ctx, ids, limit, fetch_all, output_format, output, fields):
|
|
|
64
67
|
|
|
65
68
|
|
|
66
69
|
@advideos.command()
|
|
67
|
-
@click.option(
|
|
70
|
+
@click.option(
|
|
71
|
+
"--url", help="Video URL (mutually exclusive with --video-data/--video-file)"
|
|
72
|
+
)
|
|
68
73
|
@click.option("--video-data", help="Base64-encoded video binary")
|
|
69
74
|
@click.option("--video-file", help="Path to a video file to base64-encode")
|
|
70
75
|
@click.option("--name", help="Video name")
|