direct-cli 0.2.7__tar.gz → 0.2.9__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.7 → direct_cli-0.2.9}/.github/workflows/api-coverage.yml +12 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/AGENTS.md +1 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/PKG-INFO +166 -34
- {direct_cli-0.2.7 → direct_cli-0.2.9}/README.md +162 -32
- {direct_cli-0.2.7 → direct_cli-0.2.9}/direct_cli/__init__.py +4 -3
- direct_cli-0.2.9/direct_cli/_deprecated.py +11 -0
- direct_cli-0.2.9/direct_cli/_vendor/__init__.py +0 -0
- direct_cli-0.2.9/direct_cli/_vendor/tapi_yandex_direct/__init__.py +8 -0
- direct_cli-0.2.9/direct_cli/_vendor/tapi_yandex_direct/exceptions.py +78 -0
- direct_cli-0.2.9/direct_cli/_vendor/tapi_yandex_direct/resource_mapping.py +127 -0
- direct_cli-0.2.9/direct_cli/_vendor/tapi_yandex_direct/tapi_yandex_direct.py +387 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/direct_cli/api.py +8 -2
- direct_cli-0.2.9/direct_cli/auth.py +450 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/direct_cli/cli.py +30 -4
- {direct_cli-0.2.7 → direct_cli-0.2.9}/direct_cli/commands/advideos.py +14 -10
- direct_cli-0.2.9/direct_cli/commands/auth.py +125 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/direct_cli/commands/bidmodifiers.py +0 -61
- {direct_cli-0.2.7 → direct_cli-0.2.9}/direct_cli/commands/creatives.py +2 -5
- direct_cli-0.2.9/direct_cli/commands/dynamicfeedadtargets.py +280 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/direct_cli/commands/keywords.py +35 -11
- {direct_cli-0.2.7 → direct_cli-0.2.9}/direct_cli/commands/keywordsresearch.py +2 -2
- direct_cli-0.2.9/direct_cli/commands/strategies.py +307 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/direct_cli/wsdl_coverage.py +21 -3
- {direct_cli-0.2.7 → direct_cli-0.2.9}/direct_cli.egg-info/PKG-INFO +166 -34
- {direct_cli-0.2.7 → direct_cli-0.2.9}/direct_cli.egg-info/SOURCES.txt +40 -0
- direct_cli-0.2.9/direct_cli.egg-info/entry_points.txt +3 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/direct_cli.egg-info/requires.txt +3 -1
- direct_cli-0.2.9/docs/superpowers/specs/2026-04-23-vendor-tapi-yandex-direct-design.md +85 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/pyproject.toml +10 -4
- direct_cli-0.2.9/scripts/anonymize_cassettes.py +155 -0
- direct_cli-0.2.9/scripts/build_api_coverage_report.py +236 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/scripts/release_pypi.sh +3 -0
- direct_cli-0.2.9/scripts/update_vendor.sh +50 -0
- direct_cli-0.2.9/tests/API_COVERAGE.md +92 -0
- direct_cli-0.2.9/tests/API_ISSUE_AUDIT.md +60 -0
- direct_cli-0.2.9/tests/MANUAL_COVERAGE.md +75 -0
- direct_cli-0.2.9/tests/cassettes/test_integration_live_write/test_live_draft_adgroups_add_update_delete.yaml +374 -0
- direct_cli-0.2.9/tests/cassettes/test_integration_live_write/test_live_draft_adimages_add_get_delete.yaml +68 -0
- direct_cli-0.2.9/tests/cassettes/test_integration_live_write/test_live_draft_ads_add_update_delete.yaml +502 -0
- direct_cli-0.2.9/tests/cassettes/test_integration_live_write/test_live_draft_ads_suspend_resume_archive_unarchive.yaml +628 -0
- direct_cli-0.2.9/tests/cassettes/test_integration_live_write/test_live_draft_advideos_add_get.yaml +126 -0
- direct_cli-0.2.9/tests/cassettes/test_integration_live_write/test_live_draft_audiencetargets_add_delete.yaml +313 -0
- direct_cli-0.2.9/tests/cassettes/test_integration_live_write/test_live_draft_audiencetargets_suspend_resume.yaml +313 -0
- direct_cli-0.2.9/tests/cassettes/test_integration_live_write/test_live_draft_bids_set.yaml +437 -0
- direct_cli-0.2.9/tests/cassettes/test_integration_live_write/test_live_draft_campaign_create_get_delete.yaml +250 -0
- direct_cli-0.2.9/tests/cassettes/test_integration_live_write/test_live_draft_creatives_chain_advideo_to_creative.yaml +189 -0
- direct_cli-0.2.9/tests/cassettes/test_integration_live_write/test_live_draft_dynamicads_add_delete.yaml +67 -0
- direct_cli-0.2.9/tests/cassettes/test_integration_live_write/test_live_draft_dynamicads_suspend_resume.yaml +67 -0
- direct_cli-0.2.9/tests/cassettes/test_integration_live_write/test_live_draft_keywordbids_set.yaml +439 -0
- direct_cli-0.2.9/tests/cassettes/test_integration_live_write/test_live_draft_keywords_add_update_delete.yaml +439 -0
- direct_cli-0.2.9/tests/cassettes/test_integration_live_write/test_live_draft_keywords_suspend_resume.yaml +499 -0
- direct_cli-0.2.9/tests/cassettes/test_integration_live_write/test_live_draft_sitelinks_add_get_delete.yaml +191 -0
- direct_cli-0.2.9/tests/cassettes/test_integration_live_write/test_live_draft_smartadtargets_add_update_delete.yaml +191 -0
- direct_cli-0.2.9/tests/cassettes/test_integration_live_write/test_live_draft_smartadtargets_suspend_resume.yaml +191 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/cassettes/test_integration_write/TestWriteAdExtensions.test_add_delete.yaml +11 -11
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/cassettes/test_integration_write/TestWriteAdGroups.test_add_update_delete.yaml +27 -27
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/cassettes/test_integration_write/TestWriteAdImages.test_add_delete.yaml +6 -6
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/cassettes/test_integration_write/TestWriteAds.test_add_text_ad_update_delete.yaml +27 -27
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/cassettes/test_integration_write/TestWriteAudienceTargets.test_add_delete.yaml +38 -38
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/cassettes/test_integration_write/TestWriteBidModifiersAdd.test_add_delete_mobile.yaml +22 -22
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/cassettes/test_integration_write/TestWriteBidModifiersSet.test_set_without_id_is_rejected.yaml +18 -18
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/cassettes/test_integration_write/TestWriteBids.test_set_bid.yaml +27 -27
- direct_cli-0.2.9/tests/cassettes/test_integration_write/TestWriteCampaignDraftLifecycle.test_draft_create_get_delete.yaml +218 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/cassettes/test_integration_write/TestWriteCampaigns.test_campaign_lifecycle.yaml +33 -33
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/cassettes/test_integration_write/TestWriteDynamicAds.test_add_update_delete.yaml +4 -4
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/cassettes/test_integration_write/TestWriteFeeds.test_add_update_delete.yaml +16 -16
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/cassettes/test_integration_write/TestWriteKeywordBids.test_set_keyword_bid.yaml +27 -27
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/cassettes/test_integration_write/TestWriteKeywords.test_add_update_delete.yaml +27 -27
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/cassettes/test_integration_write/TestWriteNegativeKeywordSharedSets.test_add_update_delete.yaml +17 -17
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/cassettes/test_integration_write/TestWriteRetargeting.test_add_delete.yaml +10 -10
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/cassettes/test_integration_write/TestWriteSitelinks.test_add_delete.yaml +5 -5
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/cassettes/test_integration_write/TestWriteSmartAdTargets.test_add_update_delete.yaml +15 -15
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/cassettes/test_integration_write/TestWriteVCards.test_add_delete.yaml +23 -23
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/conftest.py +26 -1
- direct_cli-0.2.9/tests/fixtures/test-video.mp4 +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/test_api_coverage.py +182 -43
- direct_cli-0.2.9/tests/test_auth_oauth.py +206 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/test_cli.py +46 -4
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/test_comprehensive.py +3 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/test_dry_run.py +125 -27
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/test_integration.py +150 -30
- direct_cli-0.2.9/tests/test_integration_live_write.py +1252 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/test_integration_write.py +369 -197
- direct_cli-0.2.9/tests/test_transport_contract.py +23 -0
- direct_cli-0.2.9/tests/wsdl_cache/dynamicfeedadtargets.xml +328 -0
- direct_cli-0.2.9/tests/wsdl_cache/strategies.xml +1100 -0
- direct_cli-0.2.7/direct_cli/auth.py +0 -167
- direct_cli-0.2.7/direct_cli.egg-info/entry_points.txt +0 -3
- direct_cli-0.2.7/scripts/build_api_coverage_report.py +0 -108
- {direct_cli-0.2.7 → direct_cli-0.2.9}/.env.example +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/.github/copilot-instructions.md +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/.github/workflows/claude-code-review.yml +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/.github/workflows/claude.yml +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/.gitignore +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/CLAUDE.md +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/MANIFEST.in +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/direct_cli/commands/__init__.py +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/direct_cli/commands/adextensions.py +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/direct_cli/commands/adgroups.py +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/direct_cli/commands/adimages.py +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/direct_cli/commands/ads.py +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/direct_cli/commands/agencyclients.py +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/direct_cli/commands/audiencetargets.py +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/direct_cli/commands/bids.py +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/direct_cli/commands/businesses.py +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/direct_cli/commands/campaigns.py +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/direct_cli/commands/changes.py +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/direct_cli/commands/clients.py +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/direct_cli/commands/dictionaries.py +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/direct_cli/commands/dynamicads.py +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/direct_cli/commands/feeds.py +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/direct_cli/commands/keywordbids.py +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/direct_cli/commands/leads.py +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/direct_cli/commands/negativekeywordsharedsets.py +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/direct_cli/commands/reports.py +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/direct_cli/commands/retargeting.py +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/direct_cli/commands/sitelinks.py +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/direct_cli/commands/smartadtargets.py +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/direct_cli/commands/turbopages.py +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/direct_cli/commands/vcards.py +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/direct_cli/output.py +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/direct_cli/reports_coverage.py +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/direct_cli/utils.py +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/direct_cli.egg-info/dependency_links.txt +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/direct_cli.egg-info/top_level.txt +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/docs/superpowers/plans/2026-04-12-issue-32-completion.md +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/scripts/check_reports_drift.py +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/scripts/check_wsdl_drift.py +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/scripts/refresh_reports_cache.py +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/scripts/refresh_wsdl_cache.py +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/setup.cfg +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/setup.py +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/__init__.py +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/reports_cache/raw/fields-list.html +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/reports_cache/raw/headers.html +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/reports_cache/raw/spec.html +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/reports_cache/raw/type.html +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/reports_cache/spec.json +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/test_auth_bw.py +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/test_auth_op.py +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/test_reports_drift.py +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/wsdl_cache/adextensions.xml +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/wsdl_cache/adgroups.xml +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/wsdl_cache/adimages.xml +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/wsdl_cache/ads.xml +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/wsdl_cache/advideos.xml +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/wsdl_cache/agencyclients.xml +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/wsdl_cache/audiencetargets.xml +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/wsdl_cache/bidmodifiers.xml +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/wsdl_cache/bids.xml +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/wsdl_cache/businesses.xml +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/wsdl_cache/campaigns.xml +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/wsdl_cache/changes.xml +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/wsdl_cache/clients.xml +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/wsdl_cache/creatives.xml +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/wsdl_cache/dictionaries.xml +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/wsdl_cache/dynamictextadtargets.xml +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/wsdl_cache/feeds.xml +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/wsdl_cache/keywordbids.xml +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/wsdl_cache/keywords.xml +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/wsdl_cache/keywordsresearch.xml +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/wsdl_cache/leads.xml +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/wsdl_cache/negativekeywordsharedsets.xml +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/wsdl_cache/retargetinglists.xml +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/wsdl_cache/sitelinks.xml +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/wsdl_cache/smartadtargets.xml +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/wsdl_cache/turbopages.xml +0 -0
- {direct_cli-0.2.7 → direct_cli-0.2.9}/tests/wsdl_cache/vcards.xml +0 -0
|
@@ -45,12 +45,24 @@ jobs:
|
|
|
45
45
|
|
|
46
46
|
report = json.loads(Path("api_coverage_report.json").read_text())
|
|
47
47
|
summary = report["summary"]
|
|
48
|
+
model_gaps = report["model_gaps"]
|
|
48
49
|
print("## API coverage summary")
|
|
49
50
|
print()
|
|
50
51
|
print(f"- Services checked: {summary['services_checked']}")
|
|
51
52
|
print(f"- Missing methods: {summary['missing_service_methods']}")
|
|
52
53
|
print(f"- Unexpected methods: {summary['unexpected_service_methods']}")
|
|
53
54
|
print(f"- Strict parity OK: {summary['strict_parity_ok']}")
|
|
55
|
+
print(f"- Live model parity OK: {summary['live_model_parity_ok']}")
|
|
56
|
+
print(f"- Declared WSDL services: {model_gaps['declared_wsdl_services_count']}")
|
|
57
|
+
print(f"- Declared WSDL methods: {model_gaps['declared_wsdl_methods_count']}")
|
|
58
|
+
print(f"- Live-discovered services: {model_gaps['live_discovered_services_count']}")
|
|
59
|
+
print(f"- Total known methods: {model_gaps['total_known_methods_count']}")
|
|
60
|
+
print(f"- Model gaps: {model_gaps['live_model_gap_count']}")
|
|
61
|
+
for item in model_gaps["live_discovered_missing_services"][:10]:
|
|
62
|
+
methods = ", ".join(item["api_methods"])
|
|
63
|
+
print(f"- Missing service: {item['api_service']} ({methods})")
|
|
64
|
+
for item in model_gaps["live_discovery_errors"][:10]:
|
|
65
|
+
print(f"- Live discovery error: {item['api_service']}: {item['error']}")
|
|
54
66
|
print(f"- Non-WSDL services: {len(report['non_wsdl_services'])}")
|
|
55
67
|
print(f"- CLI helpers: {len(report['cli_helpers'])}")
|
|
56
68
|
PY
|
|
@@ -106,6 +106,7 @@ Valid canonical examples:
|
|
|
106
106
|
direct campaigns get --ids 1,2,3
|
|
107
107
|
direct changes check-campaigns --timestamp 2026-04-14T00:00:00
|
|
108
108
|
direct keywordsresearch has-search-volume --keywords "buy laptop,buy desktop"
|
|
109
|
+
direct smartadtargets update --id 456 --priority HIGH
|
|
109
110
|
direct dynamicads set-bids --id 789 --bid 12.5
|
|
110
111
|
direct dictionaries get-geo-regions --region-ids 225 --fields GeoRegionId,GeoRegionName
|
|
111
112
|
```
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: direct-cli
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.9
|
|
4
4
|
Summary: Command-line interface for Yandex Direct API
|
|
5
5
|
Author: axisrow
|
|
6
6
|
License: MIT
|
|
@@ -18,7 +18,9 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
18
18
|
Classifier: Programming Language :: Python :: 3.13
|
|
19
19
|
Requires-Python: >=3.9
|
|
20
20
|
Description-Content-Type: text/markdown
|
|
21
|
-
Requires-Dist:
|
|
21
|
+
Requires-Dist: orjson
|
|
22
|
+
Requires-Dist: requests
|
|
23
|
+
Requires-Dist: tapi-wrapper2
|
|
22
24
|
Requires-Dist: click>=8.0.0
|
|
23
25
|
Requires-Dist: python-dotenv>=0.19.0
|
|
24
26
|
Requires-Dist: tabulate>=0.8.0
|
|
@@ -66,14 +68,46 @@ Or pass credentials directly per command:
|
|
|
66
68
|
direct --token YOUR_TOKEN --login YOUR_LOGIN campaigns get
|
|
67
69
|
```
|
|
68
70
|
|
|
71
|
+
Use profile-specific credentials from `.env`:
|
|
72
|
+
|
|
73
|
+
```env
|
|
74
|
+
YANDEX_DIRECT_TOKEN_AGENCY1=token-1
|
|
75
|
+
YANDEX_DIRECT_LOGIN_AGENCY1=client-login-1
|
|
76
|
+
YANDEX_DIRECT_TOKEN_AGENCY2=token-2
|
|
77
|
+
YANDEX_DIRECT_LOGIN_AGENCY2=client-login-2
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
OAuth and profile commands:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
direct auth login
|
|
84
|
+
direct auth login --profile agency1
|
|
85
|
+
direct auth login --code abc123 --profile agency1
|
|
86
|
+
direct auth login --oauth-token y0_example --profile agency1
|
|
87
|
+
direct auth list
|
|
88
|
+
direct auth use --profile agency1
|
|
89
|
+
direct auth status --profile agency1
|
|
90
|
+
direct --profile agency1 campaigns get
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Notes:
|
|
94
|
+
- Legacy profile environment variable is not used.
|
|
95
|
+
- Select credentials with `--profile`.
|
|
96
|
+
- `--login` remains Direct client login.
|
|
97
|
+
- Authorization is performed via `direct auth login`.
|
|
98
|
+
- Alias `auth_login` is not supported.
|
|
99
|
+
|
|
69
100
|
Install with `pip install direct-cli`, then run commands with `direct`.
|
|
101
|
+
Invoking the deprecated `direct-cli` entrypoint exits with
|
|
102
|
+
`use direct instead of direct-cli`.
|
|
70
103
|
|
|
71
104
|
### Global Options
|
|
72
105
|
|
|
73
106
|
| Option | Description |
|
|
74
107
|
|--------|-------------|
|
|
75
108
|
| `--token` | API access token |
|
|
76
|
-
| `--login` |
|
|
109
|
+
| `--login` | Direct client login |
|
|
110
|
+
| `--profile` | Credential profile name |
|
|
77
111
|
| `--sandbox` | Use sandbox API |
|
|
78
112
|
|
|
79
113
|
### CLI Convention
|
|
@@ -101,9 +135,10 @@ Naming rules:
|
|
|
101
135
|
- multiword commands use kebab-case
|
|
102
136
|
- examples: `get`, `set-bids`, `check-campaigns`, `has-search-volume`
|
|
103
137
|
|
|
104
|
-
direct
|
|
105
|
-
|
|
106
|
-
names.
|
|
138
|
+
The `direct` executable defines the public naming contract. The
|
|
139
|
+
`direct-cli` package name and deprecated shim do not define canonical CLI
|
|
140
|
+
names. `tapi-yandex-direct` may influence the internal transport layer, but it
|
|
141
|
+
does not define canonical CLI names.
|
|
107
142
|
|
|
108
143
|
The current policy is canonical-only. Historical aliases are not preserved in
|
|
109
144
|
the runtime CLI by default. If compatibility is ever needed, an alias must be
|
|
@@ -120,6 +155,7 @@ be supported.
|
|
|
120
155
|
- If the API requires a complex object, the CLI must expose explicit flags or subcommands instead of forwarding raw JSON.
|
|
121
156
|
|
|
122
157
|
#### Command Formatting Rules
|
|
158
|
+
|
|
123
159
|
- Every canonical CLI command must be written strictly on a single line.
|
|
124
160
|
- Multi-line command formatting is not allowed.
|
|
125
161
|
- Shell line continuation using `\` is forbidden in canonical documentation, help text, tests, and examples.
|
|
@@ -184,6 +220,7 @@ Valid canonical examples:
|
|
|
184
220
|
direct campaigns get --ids 1,2,3
|
|
185
221
|
direct changes check-campaigns --timestamp 2026-04-14T00:00:00
|
|
186
222
|
direct keywordsresearch has-search-volume --keywords "buy laptop,buy desktop"
|
|
223
|
+
direct smartadtargets update --id 456 --priority HIGH
|
|
187
224
|
direct dynamicads set-bids --id 789 --bid 12.5 --context-bid 9 --priority HIGH
|
|
188
225
|
direct dictionaries get-geo-regions --name Moscow --region-ids 225,187 --exact-names Москва,Санкт-Петербург --fields GeoRegionId,GeoRegionName
|
|
189
226
|
```
|
|
@@ -250,7 +287,7 @@ direct ads delete --id 99999
|
|
|
250
287
|
```bash
|
|
251
288
|
direct keywords get --campaign-ids 1,2,3
|
|
252
289
|
direct keywords add --adgroup-id 12345 --keyword "buy laptop" --bid 10.50 --context-bid 5.25 --user-param-1 segment-a --user-param-2 segment-b --dry-run
|
|
253
|
-
direct keywords update --id 88888 --
|
|
290
|
+
direct keywords update --id 88888 --keyword "updated keyword text"
|
|
254
291
|
direct keywords delete --id 88888
|
|
255
292
|
```
|
|
256
293
|
|
|
@@ -272,10 +309,14 @@ Available report types: `CAMPAIGN_PERFORMANCE_REPORT`, `ADGROUP_PERFORMANCE_REPO
|
|
|
272
309
|
# Reference dictionaries and changes
|
|
273
310
|
direct dictionaries get --names Currencies,GeoRegions
|
|
274
311
|
direct dictionaries get-geo-regions --name Moscow --region-ids 225,187 --exact-names Москва,Санкт-Петербург --fields GeoRegionId,GeoRegionName
|
|
312
|
+
|
|
313
|
+
# Client info
|
|
314
|
+
direct clients get --fields ClientId,Login,Currency
|
|
315
|
+
|
|
316
|
+
# Changes
|
|
275
317
|
direct changes check --campaign-ids 1,2,3 --timestamp 2026-04-14T00:00:00
|
|
276
318
|
direct changes check-campaigns --timestamp 2026-04-14T00:00:00
|
|
277
319
|
direct changes check-dictionaries
|
|
278
|
-
direct clients get --fields ClientId,Login,Currency
|
|
279
320
|
|
|
280
321
|
# Keyword research and retargeting
|
|
281
322
|
direct keywordsresearch has-search-volume --keywords "buy laptop,buy desktop"
|
|
@@ -300,6 +341,17 @@ direct smartadtargets update --id 456 --priority HIGH
|
|
|
300
341
|
direct smartadtargets set-bids --id 456 --average-cpc 10.5 --average-cpa 15 --priority HIGH
|
|
301
342
|
direct dynamicads set-bids --id 789 --bid 12.5 --context-bid 9 --priority HIGH
|
|
302
343
|
|
|
344
|
+
# Shared bidding strategies
|
|
345
|
+
direct strategies get --limit 5
|
|
346
|
+
direct strategies add --name "Shared Clicks" --type WbMaximumClicks --params '{"SpendLimit":1000000000,"AverageCpc":30000000}' --dry-run
|
|
347
|
+
direct strategies update --id 42 --params '{"AverageCpc":35000000}' --dry-run
|
|
348
|
+
direct strategies archive --id 42 --dry-run
|
|
349
|
+
|
|
350
|
+
# Dynamic feed ad targets
|
|
351
|
+
direct dynamicfeedadtargets get --adgroup-ids 123 --limit 5
|
|
352
|
+
direct dynamicfeedadtargets add --adgroup-id 33 --name "Feed slice A" --condition "CATEGORY:EQUALS:shoes" --bid 5 --dry-run
|
|
353
|
+
direct dynamicfeedadtargets set-bids --id 789 --bid 6.5 --context-bid 4 --dry-run
|
|
354
|
+
|
|
303
355
|
# Extensions, assets, feeds, and clients
|
|
304
356
|
direct sitelinks add --sitelink "Docs|https://example.com/docs" --sitelink "Help|https://example.com/help|Desk" --dry-run
|
|
305
357
|
direct vcards add --campaign-id 555 --country "Russia" --city "Moscow" --company-name "Acme" --work-time 1#5#9#0#18#0 --phone-country-code +7 --phone-city-code 495 --phone-number 1234567 --dry-run
|
|
@@ -315,12 +367,12 @@ direct agencyclients add-passport-organization-member --passport-organization-lo
|
|
|
315
367
|
direct agencyclients update --client-id 42 --phone +70000000000 --email user@example.com --grant EDIT_CAMPAIGNS --grant IMPORT_XLS --dry-run
|
|
316
368
|
```
|
|
317
369
|
|
|
318
|
-
### Known
|
|
370
|
+
### Known Unsupported API Operation
|
|
319
371
|
|
|
320
|
-
`dynamicads update` is
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
372
|
+
`dynamicads update` is unsupported by API. The Yandex Direct
|
|
373
|
+
`dynamictextadtargets` service exposes `add`, `get`, `delete`, `suspend`,
|
|
374
|
+
`resume`, and `setBids`, but no `update` operation. Do not add or rely on
|
|
375
|
+
`direct dynamicads update` unless Yandex exposes a real API method.
|
|
324
376
|
|
|
325
377
|
### Output Formats
|
|
326
378
|
|
|
@@ -369,19 +421,22 @@ direct campaigns add --name "Test" --start-date 2024-01-01 --dry-run
|
|
|
369
421
|
|
|
370
422
|
### Testing
|
|
371
423
|
|
|
372
|
-
|
|
424
|
+
Four tiers of tests live under `tests/`:
|
|
373
425
|
|
|
374
426
|
| Tier | Marker | Network | Token required |
|
|
375
427
|
|---|---|---|---|
|
|
376
428
|
| Unit / CLI wiring / dry-run | *(none)* | No | No |
|
|
377
429
|
| Read-only integration | `-m integration` | Yes (production API, read-only) | Yes |
|
|
378
430
|
| Write integration | `-m integration_write` | No (replays VCR cassettes) | No |
|
|
431
|
+
| Live draft write integration | `-m integration_live_write` | Yes when recording, otherwise VCR replay | Yes + `YANDEX_DIRECT_LIVE_WRITE=1` |
|
|
379
432
|
|
|
380
433
|
```bash
|
|
381
434
|
pip install -e ".[dev]"
|
|
382
435
|
pytest # fast tier — no token
|
|
383
436
|
pytest -m integration -v # read-only integration tests (needs token)
|
|
384
437
|
pytest -m integration_write -v # write cassette replay (no token needed)
|
|
438
|
+
YANDEX_DIRECT_LIVE_WRITE=1 pytest -m integration_live_write -v # live draft cassette replay
|
|
439
|
+
YANDEX_DIRECT_LIVE_WRITE=1 pytest -m integration_live_write -v --record-mode=rewrite # re-record live draft cassette
|
|
385
440
|
```
|
|
386
441
|
|
|
387
442
|
### API Coverage And Drift Monitoring
|
|
@@ -391,13 +446,16 @@ The project now distinguishes four surfaces:
|
|
|
391
446
|
| Surface | Coverage strategy |
|
|
392
447
|
|---|---|
|
|
393
448
|
| Canonical WSDL-backed SOAP services | `tests/test_api_coverage.py` verifies strict service/method parity and dry-run request-schema coverage or explicit exclusions |
|
|
449
|
+
| Live-discovered WSDL model gaps | `scripts/build_api_coverage_report.py` reports services seen in the audited live API surface but not yet declared in the CLI coverage model |
|
|
394
450
|
| Non-WSDL services (`reports`) | Explicit contract tests |
|
|
395
451
|
| Historical aliases retained by exception | None currently retained |
|
|
396
452
|
| Intentional CLI-only helpers | Explicitly allowlisted with reasons in `direct_cli/wsdl_coverage.py` |
|
|
397
453
|
|
|
398
454
|
`100% coverage` in this project means full coverage of the supported
|
|
399
|
-
**canonical API surface**.
|
|
400
|
-
|
|
455
|
+
**declared canonical API surface**. The API coverage report also includes a
|
|
456
|
+
`model_gaps` section for live-discovered Yandex Direct services that are not
|
|
457
|
+
yet part of that declared model. Alias groups and CLI-only helpers remain
|
|
458
|
+
supported, but they are tracked outside the strict parity metric.
|
|
401
459
|
|
|
402
460
|
Useful maintenance commands:
|
|
403
461
|
|
|
@@ -409,7 +467,8 @@ python scripts/check_wsdl_drift.py
|
|
|
409
467
|
|
|
410
468
|
CI runs a scheduled API coverage workflow that:
|
|
411
469
|
- runs the fast coverage suites;
|
|
412
|
-
- uploads a machine-readable API coverage report artifact
|
|
470
|
+
- uploads a machine-readable API coverage report artifact, including declared
|
|
471
|
+
parity and live-discovered model gap counts;
|
|
413
472
|
- checks the cached WSDL files against the live Yandex Direct API on schedule.
|
|
414
473
|
|
|
415
474
|
#### Re-recording write cassettes
|
|
@@ -440,6 +499,29 @@ The VCR config in `tests/conftest.py` already strips `Authorization`,
|
|
|
440
499
|
`Client-Login`, cookies and any response header containing the substring
|
|
441
500
|
`login`, but manual verification is mandatory before committing.
|
|
442
501
|
|
|
502
|
+
#### Live draft write tests
|
|
503
|
+
|
|
504
|
+
The `integration_live_write` tier is manual-only and intentionally separate
|
|
505
|
+
from sandbox cassette tests. In rewrite mode it runs against the production
|
|
506
|
+
Yandex Direct API, but it may only create disposable draft resources and
|
|
507
|
+
delete the exact IDs it created in the same test run. Current coverage is
|
|
508
|
+
limited to a guarded campaign draft create -> get -> delete check.
|
|
509
|
+
|
|
510
|
+
Replay the checked-in cassette:
|
|
511
|
+
|
|
512
|
+
```bash
|
|
513
|
+
YANDEX_DIRECT_LIVE_WRITE=1 pytest -m integration_live_write -v
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
Re-record it only when you intentionally want to verify live draft behavior:
|
|
517
|
+
|
|
518
|
+
```bash
|
|
519
|
+
YANDEX_DIRECT_LIVE_WRITE=1 pytest -m integration_live_write -v --record-mode=rewrite
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
Do not add tests to this tier that accept external IDs, resume/suspend/archive
|
|
523
|
+
existing resources, mutate bids, or touch serving campaigns.
|
|
524
|
+
|
|
443
525
|
### Release Process
|
|
444
526
|
|
|
445
527
|
Build, validate and upload to PyPI:
|
|
@@ -501,14 +583,16 @@ YANDEX_DIRECT_LOGIN=ваш_логин_на_яндексе
|
|
|
501
583
|
direct --token ВАШ_ТОКЕН --login ВАШ_ЛОГИН campaigns get
|
|
502
584
|
```
|
|
503
585
|
|
|
504
|
-
Установка остаётся через `pip install direct-cli`, а запуск команд теперь идет
|
|
586
|
+
Установка остаётся через `pip install direct-cli`, а запуск команд теперь идет
|
|
587
|
+
через `direct`. Вызов deprecated entrypoint `direct-cli` завершается ошибкой с
|
|
588
|
+
подсказкой `use direct instead of direct-cli`.
|
|
505
589
|
|
|
506
590
|
### Глобальные опции
|
|
507
591
|
|
|
508
592
|
| Опция | Описание |
|
|
509
593
|
|-------|----------|
|
|
510
594
|
| `--token` | OAuth-токен доступа к API |
|
|
511
|
-
| `--login` |
|
|
595
|
+
| `--login` | Direct client login |
|
|
512
596
|
| `--sandbox` | Использовать тестовое API (песочница) |
|
|
513
597
|
|
|
514
598
|
### Использование
|
|
@@ -530,17 +614,20 @@ Command naming rules:
|
|
|
530
614
|
- в документации и примерах каноническими считаются `get`,
|
|
531
615
|
`check-dictionaries` и `has-search-volume`
|
|
532
616
|
|
|
533
|
-
|
|
534
|
-
|
|
617
|
+
Публичный naming contract задаёт исполняемый файл `direct`. Имя пакета
|
|
618
|
+
`direct-cli` и deprecated shim не определяют канонические CLI-имена.
|
|
619
|
+
`tapi-yandex-direct` может влиять на внутренний transport layer, но не
|
|
620
|
+
определяет канонические CLI-имена.
|
|
535
621
|
|
|
536
622
|
Текущая политика — canonical-only. Исторические aliases по умолчанию не
|
|
537
623
|
сохраняются в runtime CLI. Если совместимость когда-нибудь понадобится, alias
|
|
538
624
|
должен быть добавлен как явное exception-правило с конкретным legacy syntax из
|
|
539
625
|
`tapi-yandex-direct`, который действительно нужно поддержать.
|
|
540
626
|
|
|
541
|
-
`direct
|
|
542
|
-
имена CLI-групп следуют
|
|
543
|
-
`tapi-yandex-direct`, а имена подкоманд —
|
|
627
|
+
`direct` — это канонический transport entrypoint над API Яндекс Директа,
|
|
628
|
+
устанавливаемый пакетом `direct-cli`. Канонические имена CLI-групп следуют
|
|
629
|
+
нормализованным Python-именам из `tapi-yandex-direct`, а имена подкоманд —
|
|
630
|
+
это kebab-case проекции API-методов.
|
|
544
631
|
|
|
545
632
|
Базовые соответствия:
|
|
546
633
|
|
|
@@ -575,8 +662,10 @@ Naming rules:
|
|
|
575
662
|
- multiword commands use kebab-case
|
|
576
663
|
- examples: `get`, `set-bids`, `check-campaigns`, `has-search-volume`
|
|
577
664
|
|
|
578
|
-
|
|
579
|
-
|
|
665
|
+
Публичный naming contract задаёт исполняемый файл `direct`. Имя пакета
|
|
666
|
+
`direct-cli` и deprecated shim не определяют канонические CLI-имена.
|
|
667
|
+
`tapi-yandex-direct` может влиять на внутренний transport layer, но не
|
|
668
|
+
определяет канонические CLI-имена.
|
|
580
669
|
|
|
581
670
|
Текущая политика — canonical-only. Исторические aliases по умолчанию не
|
|
582
671
|
сохраняются в runtime CLI. Если совместимость когда-нибудь понадобится, alias
|
|
@@ -724,7 +813,7 @@ direct ads delete --id 99999
|
|
|
724
813
|
```bash
|
|
725
814
|
direct keywords get --campaign-ids 1,2,3
|
|
726
815
|
direct keywords add --adgroup-id 12345 --keyword "купить ноутбук" --bid 10.50 --context-bid 5.25 --user-param-1 segment-a --user-param-2 segment-b --dry-run
|
|
727
|
-
direct keywords update --id 88888 --
|
|
816
|
+
direct keywords update --id 88888 --keyword "updated keyword text"
|
|
728
817
|
direct keywords delete --id 88888
|
|
729
818
|
```
|
|
730
819
|
|
|
@@ -746,10 +835,14 @@ direct reports list-types
|
|
|
746
835
|
# Справочники и изменения
|
|
747
836
|
direct dictionaries get --names Currencies,GeoRegions
|
|
748
837
|
direct dictionaries get-geo-regions --name Москва --region-ids 225,187 --exact-names Москва,Санкт-Петербург --fields GeoRegionId,GeoRegionName
|
|
838
|
+
|
|
839
|
+
# Информация о клиенте
|
|
840
|
+
direct clients get --fields ClientId,Login,Currency
|
|
841
|
+
|
|
842
|
+
# Изменения
|
|
749
843
|
direct changes check --campaign-ids 1,2,3 --timestamp 2026-04-14T00:00:00
|
|
750
844
|
direct changes check-campaigns --timestamp 2026-04-14T00:00:00
|
|
751
845
|
direct changes check-dictionaries
|
|
752
|
-
direct clients get --fields ClientId,Login,Currency
|
|
753
846
|
|
|
754
847
|
# Исследование ключевых слов и ретаргетинг
|
|
755
848
|
direct keywordsresearch has-search-volume --keywords "купить ноутбук,купить компьютер"
|
|
@@ -774,6 +867,17 @@ direct smartadtargets update --id 456 --priority HIGH
|
|
|
774
867
|
direct smartadtargets set-bids --id 456 --average-cpc 10.5 --average-cpa 15 --priority HIGH
|
|
775
868
|
direct dynamicads set-bids --id 789 --bid 12.5 --context-bid 9 --priority HIGH
|
|
776
869
|
|
|
870
|
+
# Общие стратегии ставок
|
|
871
|
+
direct strategies get --limit 5
|
|
872
|
+
direct strategies add --name "Общая стратегия" --type WbMaximumClicks --params '{"SpendLimit":1000000000,"AverageCpc":30000000}' --dry-run
|
|
873
|
+
direct strategies update --id 42 --params '{"AverageCpc":35000000}' --dry-run
|
|
874
|
+
direct strategies archive --id 42 --dry-run
|
|
875
|
+
|
|
876
|
+
# Динамические таргеты по фиду
|
|
877
|
+
direct dynamicfeedadtargets get --adgroup-ids 123 --limit 5
|
|
878
|
+
direct dynamicfeedadtargets add --adgroup-id 33 --name "Срез фида А" --condition "CATEGORY:EQUALS:shoes" --bid 5 --dry-run
|
|
879
|
+
direct dynamicfeedadtargets set-bids --id 789 --bid 6.5 --context-bid 4 --dry-run
|
|
880
|
+
|
|
777
881
|
# Расширения, ассеты, фиды и клиенты
|
|
778
882
|
direct sitelinks add --sitelink "Docs|https://example.com/docs" --sitelink "Help|https://example.com/help|Desk" --dry-run
|
|
779
883
|
direct vcards add --campaign-id 555 --country "Россия" --city "Москва" --company-name "Acme" --work-time 1#5#9#0#18#0 --phone-country-code +7 --phone-city-code 495 --phone-number 1234567 --dry-run
|
|
@@ -789,12 +893,13 @@ direct agencyclients add-passport-organization-member --passport-organization-lo
|
|
|
789
893
|
direct agencyclients update --client-id 42 --phone +70000000000 --email user@example.com --grant EDIT_CAMPAIGNS --grant IMPORT_XLS --dry-run
|
|
790
894
|
```
|
|
791
895
|
|
|
792
|
-
###
|
|
896
|
+
### Известная неподдерживаемая API-операция
|
|
793
897
|
|
|
794
|
-
`dynamicads update`
|
|
795
|
-
|
|
796
|
-
экспортирует `
|
|
797
|
-
|
|
898
|
+
`dynamicads update` unsupported by API. Сервис Яндекс Директа
|
|
899
|
+
`dynamictextadtargets` экспортирует `add`, `get`, `delete`, `suspend`,
|
|
900
|
+
`resume` и `setBids`, но не экспортирует `update`. Не добавляйте и не
|
|
901
|
+
используйте `direct dynamicads update`, пока Яндекс не предоставит реальный
|
|
902
|
+
API-метод.
|
|
798
903
|
|
|
799
904
|
### Форматы вывода
|
|
800
905
|
|
|
@@ -843,19 +948,22 @@ direct campaigns add --name "Тест" --start-date 2024-01-01 --dry-run
|
|
|
843
948
|
|
|
844
949
|
### Тестирование
|
|
845
950
|
|
|
846
|
-
В `tests/`
|
|
951
|
+
В `tests/` четыре уровня тестов:
|
|
847
952
|
|
|
848
953
|
| Уровень | Маркер | Сеть | Нужен токен |
|
|
849
954
|
|---|---|---|---|
|
|
850
955
|
| Юнит / CLI / dry-run | *(без маркера)* | Нет | Нет |
|
|
851
956
|
| Read-only интеграция | `-m integration` | Да (prod API, только чтение) | Да |
|
|
852
957
|
| Write интеграция | `-m integration_write` | Нет (replay VCR-кассет) | Нет |
|
|
958
|
+
| Live draft write интеграция | `-m integration_live_write` | Да при записи, иначе VCR replay | Да + `YANDEX_DIRECT_LIVE_WRITE=1` |
|
|
853
959
|
|
|
854
960
|
```bash
|
|
855
961
|
pip install -e ".[dev]"
|
|
856
962
|
pytest # быстрый уровень — без токена
|
|
857
963
|
pytest -m integration -v # read-only интеграция (нужен токен)
|
|
858
964
|
pytest -m integration_write -v # replay write-кассет (токен не нужен)
|
|
965
|
+
YANDEX_DIRECT_LIVE_WRITE=1 pytest -m integration_live_write -v # replay live draft-кассеты
|
|
966
|
+
YANDEX_DIRECT_LIVE_WRITE=1 pytest -m integration_live_write -v --record-mode=rewrite # перезапись live draft-кассеты
|
|
859
967
|
```
|
|
860
968
|
|
|
861
969
|
#### Перезапись write-кассет
|
|
@@ -886,6 +994,30 @@ VCR-конфиг в `tests/conftest.py` уже стрипает `Authorization`,
|
|
|
886
994
|
куки и любые response-заголовки с подстрокой `login`, но ручная проверка
|
|
887
995
|
перед коммитом обязательна.
|
|
888
996
|
|
|
997
|
+
#### Live write только на черновиках
|
|
998
|
+
|
|
999
|
+
Уровень `integration_live_write` запускается только вручную и отделен от
|
|
1000
|
+
sandbox/VCR-тестов. В rewrite-режиме он ходит в production API Яндекс Директа,
|
|
1001
|
+
но может только создавать одноразовые черновики и удалять ровно те ID, которые
|
|
1002
|
+
были созданы в этом же тестовом прогоне. Текущее покрытие: guarded create ->
|
|
1003
|
+
get -> delete для draft-кампании.
|
|
1004
|
+
|
|
1005
|
+
Replay закоммиченной кассеты:
|
|
1006
|
+
|
|
1007
|
+
```bash
|
|
1008
|
+
YANDEX_DIRECT_LIVE_WRITE=1 pytest -m integration_live_write -v
|
|
1009
|
+
```
|
|
1010
|
+
|
|
1011
|
+
Перезапись после явного решения проверить live draft-поведение:
|
|
1012
|
+
|
|
1013
|
+
```bash
|
|
1014
|
+
YANDEX_DIRECT_LIVE_WRITE=1 pytest -m integration_live_write -v --record-mode=rewrite
|
|
1015
|
+
```
|
|
1016
|
+
|
|
1017
|
+
В этот уровень нельзя добавлять тесты, которые принимают внешние ID,
|
|
1018
|
+
возобновляют/останавливают/архивируют существующие ресурсы, меняют ставки или
|
|
1019
|
+
трогают кампании, которые могут показываться.
|
|
1020
|
+
|
|
889
1021
|
### Публикация на PyPI
|
|
890
1022
|
|
|
891
1023
|
Сборка, проверка и загрузка на PyPI:
|