python-amazon-ad-api 1.1.5__py3-none-any.whl → 1.1.7__py3-none-any.whl

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.
ad_api/api/sb/__init__.py CHANGED
@@ -23,6 +23,7 @@ from .themes import Themes
23
23
  from .budget_rules import BudgetRules
24
24
  from .optimization_rules import OptimizationRules
25
25
  from .targeting_categories import TargetingCategories
26
+ from .migration import Migration
26
27
 
27
28
  __all__ = [
28
29
  "Brands",
@@ -50,4 +51,5 @@ __all__ = [
50
51
  "BudgetRules",
51
52
  "OptimizationRules",
52
53
  "TargetingCategories",
54
+ "Migration",
53
55
  ]
@@ -128,6 +128,92 @@ class AdCreativesV4(Client):
128
128
 
129
129
  return self._request(kwargs.pop('path'), data=Utils.convert_body(kwargs.pop('body'), False), params=kwargs, headers=headers)
130
130
 
131
+ @sp_endpoint('/sb/ads/creatives/autoCollection', method='POST')
132
+ def create_auto_collection_ad_creative(self, version: int = 4, **kwargs) -> ApiResponse:
133
+ """
134
+ Creates a new version of an auto collection creative for an existing ad.
135
+
136
+ Request Body [Required]
137
+ | **ads** (array): [required] One entry per ad.
138
+ | **adId** (string): [required] Sponsored Brands ad identifier.
139
+ | **creative** ({}): [required]
140
+ | **brandName** (string): [required]
141
+ | **brandLogoAssetID** (string): [optional]
142
+ | **brandLogoCrop** ({}): [optional] ``top``, ``left``,
143
+ ``width`` and ``height``.
144
+ | **asinExclusions** (array of string): [optional]
145
+
146
+ Returns:
147
+ | ApiResponse
148
+
149
+ .. note::
150
+ This route takes ``application/vnd.sbadresource.v4+json``, the same
151
+ media type as the ads family, not the creative one.
152
+ """
153
+ json_version = 'application/vnd.sbadresource.v' + str(version) + "+json"
154
+ headers = {'Accept': json_version}
155
+
156
+ return self._request(kwargs.pop('path'), data=Utils.convert_body(kwargs.pop('body'), False), params=kwargs, headers=headers)
157
+
158
+ @sp_endpoint('/sb/ads/creatives/manualCollection', method='POST')
159
+ def create_manual_collection_ad_creative(self, version: int = 4, **kwargs) -> ApiResponse:
160
+ """
161
+ Creates a new version of a manual collection creative for an existing ad.
162
+
163
+ Request Body [Required]
164
+ | **ads** (array): [required] One entry per ad, each with ``adId``
165
+ and a ``creative`` block.
166
+
167
+ Returns:
168
+ | ApiResponse
169
+
170
+ .. note::
171
+ Also takes ``application/vnd.sbadresource.v4+json``.
172
+ """
173
+ json_version = 'application/vnd.sbadresource.v' + str(version) + "+json"
174
+ headers = {'Accept': json_version}
175
+
176
+ return self._request(kwargs.pop('path'), data=Utils.convert_body(kwargs.pop('body'), False), params=kwargs, headers=headers)
177
+
178
+ @sp_endpoint('/sb/ads/creatives/productCollectionExtended', method='POST')
179
+ @Utils.deprecated
180
+ def create_new_version_product_collection_extended_ad_creative(self, version: int = 4, **kwargs) -> ApiResponse:
181
+ """
182
+ Creates a new version of an extended product collection creative.
183
+
184
+ This route is flagged deprecated in the 4.0 contract. It still answers on
185
+ the live service, which is why it stays available, but new integrations
186
+ should use ``create_auto_collection_ad_creative`` or
187
+ ``create_manual_collection_ad_creative``.
188
+
189
+ Request Body [Required]
190
+ | **adId** (string): [required] Sponsored Brands ad identifier.
191
+ | **creative** ({}): [required]
192
+ | **asins** (array of string): [required]
193
+ | **brandName** (string): [required]
194
+ | **brandLogoAssetId** (string): [required]
195
+ | **headline** (string): [required]
196
+ | **landingPage** ({}): [optional] ``type``, ``url`` or ``asins``.
197
+ | **brandLogoCrop** ({}): [optional] ``top``, ``left``,
198
+ ``width`` and ``height``.
199
+ | **customImages** (array): [optional] Each with ``assetId``,
200
+ ``url`` and a ``crop``.
201
+ | **consentToTranslate** (boolean): [optional]
202
+
203
+ Returns:
204
+ | ApiResponse
205
+
206
+ .. note::
207
+ Unlike its siblings this route takes a single ``adId`` and
208
+ ``creative``, not an ``ads`` list, and it uses
209
+ ``application/vnd.sbAdCreativeResource.v4+json``. An empty body names
210
+ both required members.
211
+ """
212
+ json_version = 'application/vnd.sbAdCreativeResource.v' + str(version) + "+json"
213
+ headers = {'Accept': json_version}
214
+
215
+ return self._request(kwargs.pop('path'), data=Utils.convert_body(kwargs.pop('body'), False), params=kwargs, headers=headers)
216
+
131
217
  @sp_endpoint('/sb/ads/creatives/list', method='POST')
132
218
  def list_ad_creatives(self, version: int = 4, **kwargs) -> ApiResponse:
133
219
  """
ad_api/api/sb/ads_v4.py CHANGED
@@ -165,6 +165,85 @@ class AdsV4(Client):
165
165
 
166
166
  return self._request(kwargs.pop('path'), data=Utils.convert_body(kwargs.pop('body'), False), params=kwargs, headers=headers)
167
167
 
168
+ @sp_endpoint('/sb/v4/ads/autoCollection', method='POST')
169
+ def create_auto_collection_ads(self, version: int = 4, **kwargs) -> ApiResponse:
170
+ """
171
+ Creates Sponsored Brands auto collection ads.
172
+
173
+ Request Body [Required]
174
+ | **ads** (array): [required] One entry per ad.
175
+ | **adGroupId** (string): [required] Ad group the ad belongs to.
176
+ | **name** (string): [required] Ad name.
177
+ | **state** (string): [required] ``ENABLED``, ``PAUSED`` or
178
+ ``ARCHIVED``.
179
+ | **creative** ({}): [required]
180
+ | **brandName** (string): [required]
181
+ | **brandLogoAssetID** (string): [optional]
182
+ | **brandLogoCrop** ({}): [optional] ``top``, ``left``,
183
+ ``width`` and ``height``.
184
+ | **asinExclusions** (array of string): [optional]
185
+
186
+ Returns:
187
+ | ApiResponse
188
+
189
+ .. note::
190
+ An empty body answers ``400 INVALID_ARGUMENT`` with
191
+ *"Ad list cannot be empty."*, and ``application/json`` answers
192
+ ``404 Could not find resource``, so the versioned media type is what
193
+ routes the call.
194
+ """
195
+ json_version = 'application/vnd.sbadresource.v' + str(version) + "+json"
196
+ headers = {'Accept': json_version}
197
+
198
+ return self._request(kwargs.pop('path'), data=Utils.convert_body(kwargs.pop('body'), False), params=kwargs, headers=headers)
199
+
200
+ @sp_endpoint('/sb/v4/ads/manualCollection', method='POST')
201
+ def create_manual_collection_ads(self, version: int = 4, **kwargs) -> ApiResponse:
202
+ """
203
+ Creates Sponsored Brands manual collection ads.
204
+
205
+ Request Body [Required]
206
+ | **ads** (array): [required] One entry per ad, each with
207
+ ``adGroupId``, ``name``, ``state`` and a ``creative`` block.
208
+
209
+ Returns:
210
+ | ApiResponse
211
+
212
+ .. note::
213
+ An empty body answers ``400 INVALID_ARGUMENT`` with
214
+ *"Ad list cannot be empty."*
215
+ """
216
+ json_version = 'application/vnd.sbadresource.v' + str(version) + "+json"
217
+ headers = {'Accept': json_version}
218
+
219
+ return self._request(kwargs.pop('path'), data=Utils.convert_body(kwargs.pop('body'), False), params=kwargs, headers=headers)
220
+
221
+ @sp_endpoint('/sb/v4/ads/productCollectionExtended', method='POST')
222
+ @Utils.deprecated
223
+ def create_product_collection_extended_ads(self, version: int = 4, **kwargs) -> ApiResponse:
224
+ """
225
+ Creates Sponsored Brands extended product collection ads.
226
+
227
+ This route is flagged deprecated in the 4.0 contract, together with the
228
+ creative side of the same name. It still answers on the live service,
229
+ which is why it stays available, but new integrations should use
230
+ ``create_auto_collection_ads`` or ``create_manual_collection_ads``.
231
+
232
+ Request Body [Required]
233
+ | **ads** (array): [required] One entry per ad.
234
+
235
+ Returns:
236
+ | ApiResponse
237
+
238
+ .. note::
239
+ An empty body answers ``400 INVALID_ARGUMENT`` with
240
+ *"Ad list cannot be empty."*
241
+ """
242
+ json_version = 'application/vnd.sbadresource.v' + str(version) + "+json"
243
+ headers = {'Accept': json_version}
244
+
245
+ return self._request(kwargs.pop('path'), data=Utils.convert_body(kwargs.pop('body'), False), params=kwargs, headers=headers)
246
+
168
247
  @sp_endpoint('/sb/v4/ads/delete', method='POST')
169
248
  def delete_ads(self, version: int = 4, **kwargs) -> ApiResponse:
170
249
  """
@@ -0,0 +1,154 @@
1
+ from ad_api.base import Client, sp_endpoint, ApiResponse, Utils
2
+
3
+
4
+ class Migration(Client):
5
+ """Sponsored Brands legacy campaign migration from 3.0 to 4.0.
6
+
7
+ Documentation: https://advertising.amazon.com/API/docs/en-us/sponsored-brands/4-0/openapi
8
+
9
+ Two media types live in this family, both versioned and both required:
10
+
11
+ ======================================== ==========================================================
12
+ Route Media type
13
+ ======================================== ==========================================================
14
+ ``/sb/v4/legacyCampaigns/*`` ``vnd.SponsoredBrands.SponsoredBrandsMigrationApi.v4``
15
+ ``/sb/v4/migrations/list`` ``vnd.sbAdMigration.v4``
16
+ ======================================== ==========================================================
17
+
18
+ .. warning::
19
+ ``list_migrations`` answers ``404 Could not find resource`` when sent
20
+ ``application/json``, the same behaviour already recorded for forecasts,
21
+ budget recommendations and optimization rules. Amazon routes on media
22
+ type; a wrong one reads exactly like a missing route.
23
+
24
+ .. note::
25
+ ``migration_job_status`` and ``migration_job_results`` answer ``500
26
+ INTERNAL_ERROR`` for a job identifier that does not exist, instead of a
27
+ 400 or a 404. The routes are live; the service trips over an unknown id.
28
+ """
29
+
30
+ _MEDIA_LEGACY = ('application/vnd.SponsoredBrands.'
31
+ 'SponsoredBrandsMigrationApi.v4+json')
32
+ _MEDIA_ADMIG = 'application/vnd.sbAdMigration.v4+json'
33
+
34
+ @sp_endpoint('/sb/v4/legacyCampaigns/migrationJob', method='POST')
35
+ def start_migration_job(self, campaignIds, enableThemeTargeting, **kwargs) -> ApiResponse:
36
+ """
37
+ Starts a migration job for 3.0 campaigns.
38
+
39
+ Request Body [Required]
40
+ | **campaignIds** (array of string): [required] Campaigns to migrate.
41
+ | **enableThemeTargeting** (boolean): [required] Carry theme targets
42
+ into the new campaigns.
43
+ | **isStagedMigration** (boolean): [optional]
44
+ | **newCampaignState** (string): [optional] State for the migrated
45
+ campaigns.
46
+ | **brandEntityId** (string): [optional]
47
+
48
+ Returns:
49
+ | ApiResponse, ``200``.
50
+
51
+ .. warning::
52
+ **This changes the account.** It starts a real migration of 3.0
53
+ campaigns into 4.0, which is not something a probe or a retry should
54
+ trigger by accident. Because of that it was never exercised here: the
55
+ shape comes from the contract only.
56
+
57
+ .. note::
58
+ Do not treat a timeout as a failed migration. The job may be running;
59
+ check ``migration_job_status`` before trying again.
60
+ """
61
+ body = {'campaignIds': campaignIds, 'enableThemeTargeting': enableThemeTargeting}
62
+ for key in ('isStagedMigration', 'newCampaignState', 'brandEntityId'):
63
+ if key in kwargs:
64
+ body[key] = kwargs.pop(key)
65
+ return self._request(kwargs.pop('path'), data=Utils.convert_body(body, False),
66
+ params=kwargs, headers={'Accept': self._MEDIA_LEGACY,
67
+ 'Content-Type': self._MEDIA_LEGACY})
68
+
69
+ @sp_endpoint('/sb/v4/legacyCampaigns/migrationJob/status', method='POST')
70
+ def migration_job_status(self, jobId, **kwargs) -> ApiResponse:
71
+ """
72
+ Gets the status of a migration job.
73
+
74
+ Request Body [Required]
75
+ | **jobId** (string): [required]
76
+
77
+ Returns:
78
+ | ApiResponse, ``200``.
79
+
80
+ .. note::
81
+ An unknown ``jobId`` answers ``500 INTERNAL_ERROR`` rather than a
82
+ business error. Not a sign that the route is missing.
83
+ """
84
+ return self._request(kwargs.pop('path'),
85
+ data=Utils.convert_body({'jobId': jobId}, False),
86
+ params=kwargs, headers={'Accept': self._MEDIA_LEGACY,
87
+ 'Content-Type': self._MEDIA_LEGACY})
88
+
89
+ @sp_endpoint('/sb/v4/legacyCampaigns/migrationJob/results', method='POST')
90
+ def migration_job_results(self, jobId, **kwargs) -> ApiResponse:
91
+ """
92
+ Lists the per-campaign results of a migration job.
93
+
94
+ Request Body [Required]
95
+ | **jobId** (string): [required]
96
+ | **nextToken** (string): [optional]
97
+
98
+ Returns:
99
+ | ApiResponse, ``200``.
100
+
101
+ .. note::
102
+ An unknown ``jobId`` answers ``500 INTERNAL_ERROR``, as with the
103
+ status route.
104
+ """
105
+ return self._request(kwargs.pop('path'),
106
+ data=Utils.convert_body({'jobId': jobId}, False),
107
+ params=kwargs, headers={'Accept': self._MEDIA_LEGACY,
108
+ 'Content-Type': self._MEDIA_LEGACY})
109
+
110
+ @sp_endpoint('/sb/v4/legacyCampaigns/overallMigrationResults', method='POST')
111
+ def overall_migration_results(self, **kwargs) -> ApiResponse:
112
+ """
113
+ Lists every campaign migration result for the advertiser.
114
+
115
+ Request Body [Optional]
116
+ | **nextToken** (string): [optional]
117
+
118
+ Returns:
119
+ | ApiResponse, ``200``. With nothing migrated yet the service answers
120
+ an empty object rather than a list, so do not assume a ``migrations``
121
+ key is always present.
122
+ """
123
+ return self._request(kwargs.pop('path'),
124
+ data=Utils.convert_body(kwargs.pop('body', {}), False),
125
+ params=kwargs, headers={'Accept': self._MEDIA_LEGACY,
126
+ 'Content-Type': self._MEDIA_LEGACY})
127
+
128
+ @sp_endpoint('/sb/v4/migrations/list', method='POST')
129
+ def list_migrations(self, **kwargs) -> ApiResponse:
130
+ """
131
+ Lists ad migrations.
132
+
133
+ Request Body [Optional]
134
+ | **adGroupIdFilter** ({}): ``include``, a list of ad group ids.
135
+ | **adIdFilter** ({}): ``include``, a list of ad ids.
136
+ | **campaignIdFilter** ({}): ``include``, a list of campaign ids.
137
+ | **adStateFilter** ({}): ``include`` with ``ENABLED``, ``PAUSED``
138
+ or ``ARCHIVED``.
139
+ | **migrationStatusFilter** ({}): ``include`` with ``ACCEPTED``,
140
+ ``ELIGIBLE``, ``MIGRATED`` or ``MIGRATION_FAILED``.
141
+ | **maxResults** (number): Page size.
142
+ | **nextToken** (string): Pagination token.
143
+
144
+ Returns:
145
+ | ApiResponse, ``200``, with ``migrations`` and ``totalCount``.
146
+
147
+ Example::
148
+
149
+ {"migrations": [], "totalCount": 0}
150
+ """
151
+ return self._request(kwargs.pop('path'),
152
+ data=Utils.convert_body(kwargs.pop('body', {}), False),
153
+ params=kwargs, headers={'Accept': self._MEDIA_ADMIG,
154
+ 'Content-Type': self._MEDIA_ADMIG})
ad_api/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "1.1.5"
1
+ __version__ = "1.1.7"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-amazon-ad-api
3
- Version: 1.1.5
3
+ Version: 1.1.7
4
4
  Summary: Python wrapper for the Amazon Advertising API
5
5
  Home-page: https://github.com/denisneuf/python-amazon-ad-api
6
6
  Author: Daniel Alvaro
@@ -1,5 +1,5 @@
1
1
  ad_api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- ad_api/version.py,sha256=KlgaVSJ1AQxCDJZgh4wFk-gpem-k9PfebW8U3hiKJD4,22
2
+ ad_api/version.py,sha256=p2qAfdU7zHOShJi2f1FW-_7Tbm0-KCPE7CI7284QiHg,22
3
3
  ad_api/api/__init__.py,sha256=E9c0ZyK4vplMlKKEBF8CV5u7P4uSkTMSQsAuSQu5bfY,1514
4
4
  ad_api/api/account.py,sha256=CmOvCfHoPWaeTUJvtB0pNoNulZVSz4oMMCKIpVTpHos,2931
5
5
  ad_api/api/advertising_test_account.py,sha256=btOVbdk2tBDmyKSJaQbcIFyzNG8KFJVUmTe4p9xMhpU,1507
@@ -24,11 +24,11 @@ ad_api/api/reports.py,sha256=gNmDHLULD2uaJgsMpIbCX9kabwhMXRr9WfZBtHUdsOY,6043
24
24
  ad_api/api/stores.py,sha256=7W3RJKZyZOQ3nHzInvK9FDhWTXCH6Xe9a6dCBatEZ-o,2484
25
25
  ad_api/api/stream.py,sha256=JpnF8SKniOAHiEnEq1RPrh6tNy-Q2-8GPBTmnlxEXqQ,2989
26
26
  ad_api/api/validation_configurations.py,sha256=V3o06uWGwvA_Ly1x2lAiCk35Wo7DC_k8AtHgMdpm6wU,3830
27
- ad_api/api/sb/__init__.py,sha256=O5D20u5EZdftFRLJLaVmkaLo_Ucs0f52ZEL5b1gkfW0,1488
28
- ad_api/api/sb/ad_creatives_v4.py,sha256=86sF2lhSc3AC6d4P5TXyEnJMBjn9HvsJe4bbCQbSWK0,10508
27
+ ad_api/api/sb/__init__.py,sha256=APbCAkWM1gzYuhpEUU98XDIKJKJx1NXALjLBXA9zdBU,1538
28
+ ad_api/api/sb/ad_creatives_v4.py,sha256=zQzTivDkGzX3I5ZfCWIlzRUGWfTRsXJZCKQrKMaMDpc,14512
29
29
  ad_api/api/sb/ad_groups.py,sha256=W06Fk0CCsuEYen1Bd8obR6aHpOMhk6tGWNWApecw59c,2882
30
30
  ad_api/api/sb/ad_groups_v4.py,sha256=f6KpOrJ2RsCa4aznP8vdGbXp0HGsCmLOvC9yXX2pESc,3669
31
- ad_api/api/sb/ads_v4.py,sha256=EOn-ts0cPqCwt5vdGq6rkDHyYPoT6vbDP8UQE-TFjmE,7931
31
+ ad_api/api/sb/ads_v4.py,sha256=s31OYVO6nyyKRgQAvMc4YtCcHhCo-Anx-r2kq22rPG8,11373
32
32
  ad_api/api/sb/benchmarks.py,sha256=eeWv2rrRf4ttK-oI1EEEiui_rl_sxJk9yXcu6sDSfhg,3645
33
33
  ad_api/api/sb/bid_recommendations.py,sha256=ssO9XwYC9wK2GFaLtcsC-D3cZhDpCclcu1r01LTkZAw,2297
34
34
  ad_api/api/sb/brands.py,sha256=XIMDzV0tJoPiOcY0KoCKcyIwYLPMlJ-zkB2SeRVMF4Q,1376
@@ -40,6 +40,7 @@ ad_api/api/sb/keywords.py,sha256=P1dGqcLia349O0CwpBRURlIzgRc0cbFotkAGTSrErt4,763
40
40
  ad_api/api/sb/keywords_recommendations.py,sha256=oA4FRBwDtk52SZK0RgWvjNQ7K2GX0G2zSoisJGiEYDw,629
41
41
  ad_api/api/sb/landing_page_asins.py,sha256=j3qi2-KccuEzGLZrl6EfZBSikW2R4B4l7TixpkAnTq8,1259
42
42
  ad_api/api/sb/media.py,sha256=5LTeM4AHSDKw_58aTB2nEZhIYdWkztH0syBXaovS1rs,2529
43
+ ad_api/api/sb/migration.py,sha256=2Pse2ixv73ZzqKhoCq6hAHzilAXwP8iphuIzTIOWIUE,7091
43
44
  ad_api/api/sb/negative_keywords.py,sha256=ww3IRbawidDHAaYIkX5SsH2OZKJj4UnCylqqFeq3OoY,6918
44
45
  ad_api/api/sb/negative_product_targeting.py,sha256=QbK1EhhzmnNOzGtbkrAZ4HS5OqiLU3nZBmsl1scd2D0,5085
45
46
  ad_api/api/sb/optimization_rules.py,sha256=aj9tZwKdaOzjnAN-8FHb49aiejNZKCCCcR8fjffH4k0,6802
@@ -107,8 +108,8 @@ ad_api/base/exceptions.py,sha256=9D3M40ZIlLS0fA-aQh1BTWPOW-Nvf0tRhbA85jFnDJ4,438
107
108
  ad_api/base/helpers.py,sha256=naUkDLK466x_OBCPXxMlzRc2nPC6iQ6H_vyUji0MJJ0,2282
108
109
  ad_api/base/marketplaces.py,sha256=44lvCcluXNpqTprWQ80e3weSQmQbJoWL-WDSOWVbCyQ,4657
109
110
  ad_api/base/utils.py,sha256=_qnCBOvyJTLgaZjJzUWTi38GGLHkQszXELs79133Rb4,5618
110
- python_amazon_ad_api-1.1.5.dist-info/licenses/LICENSE,sha256=h2rpqlmmLy-4l1tN6KpWAFxx1JEMYeEFrMrZUbx_B_o,1105
111
- python_amazon_ad_api-1.1.5.dist-info/METADATA,sha256=Bv5SRj3TNj5OvxigNtRz_LataskuZX8W2VsBcKGrz_U,20486
112
- python_amazon_ad_api-1.1.5.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
113
- python_amazon_ad_api-1.1.5.dist-info/top_level.txt,sha256=nN9twUos-8pkP514ZwpvRU9YL9L2XyQyHsMQFfudGTU,7
114
- python_amazon_ad_api-1.1.5.dist-info/RECORD,,
111
+ python_amazon_ad_api-1.1.7.dist-info/licenses/LICENSE,sha256=h2rpqlmmLy-4l1tN6KpWAFxx1JEMYeEFrMrZUbx_B_o,1105
112
+ python_amazon_ad_api-1.1.7.dist-info/METADATA,sha256=ySlzzw2eMqLcY38Pk2d32nnEH-zGKjcnpoB-PQ5fz2E,20486
113
+ python_amazon_ad_api-1.1.7.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
114
+ python_amazon_ad_api-1.1.7.dist-info/top_level.txt,sha256=nN9twUos-8pkP514ZwpvRU9YL9L2XyQyHsMQFfudGTU,7
115
+ python_amazon_ad_api-1.1.7.dist-info/RECORD,,