{"id":444057,"date":"2025-01-04T15:00:42","date_gmt":"2025-01-04T15:00:42","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=444057"},"modified":"-0001-11-30T00:00:00","modified_gmt":"2025-01-04T15:00:42","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=444057","title":{"rendered":"<span>\u041a\u043b\u044e\u0447\u0435\u0432\u0430\u043d\u0438\u0435 \u0441\u0442\u043e\u043a\u043e\u0432\u044b\u0445 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Batch API \u043e\u0442 OpenAI<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h2>\u041a\u043b\u044e\u0447\u0435\u0432\u0430\u043d\u0438\u0435 \u0441\u0442\u043e\u043a\u043e\u0432\u044b\u0445 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Batch API \u043e\u0442 OpenAI<\/h2>\n<p>\u0410\u0442\u0440\u0438\u0431\u0443\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u2013 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u044d\u0442\u0430\u043f \u0438\u0445 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0438 \u0434\u043b\u044f \u043f\u0440\u043e\u0434\u0430\u0436\u0438 \u043d\u0430 \u0444\u043e\u0442\u043e\u0441\u0442\u043e\u043a\u0430\u0445. \u0423 \u043a\u0430\u0436\u0434\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b (\u0444\u043e\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u0438 \u0438\u043b\u0438 \u0438\u043b\u043b\u044e\u0441\u0442\u0440\u0430\u0446\u0438\u0438) \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435, \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435, \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0435 \u0441\u043b\u043e\u0432\u0430, \u0438 \u0432\u0441\u0435 \u044d\u0442\u043e \u043d\u0430 \u0430\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u043e\u043c.<\/p>\n<p>\u0421 \u043a\u043b\u044e\u0447\u0435\u0432\u0430\u043d\u0438\u0435\u043c \u043d\u0435\u043f\u043b\u043e\u0445\u043e \u0441\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f ChatGPT. \u041d\u043e \u043f\u0435\u0440\u0435\u0441\u044b\u043b\u0430\u0442\u044c \u0435\u043c\u0443 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0438 \u043f\u043e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438, \u0430 \u043f\u043e\u0442\u043e\u043c \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b \u0432\u0440\u0443\u0447\u043d\u0443\u044e \u2013 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0434\u043e\u043b\u0433\u043e. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u044d\u0442\u043e\u0442 \u043f\u0440\u043e\u0446\u0435\u0441\u0441.<\/p>\n<h3>\u0418\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439<\/h3>\n<p>\u041d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f:<\/p>\n<ol>\n<li>\n<p>PyCharm \u0438\u043b\u0438 \u0434\u0440\u0443\u0433\u0430\u044f IDE \u0434\u043b\u044f Python.<\/p>\n<\/li>\n<li>\n<p>API-\u043a\u043b\u044e\u0447 \u043e\u0442 OpenAI \u0438 \u043f\u0430\u0440\u0430 \u0434\u043e\u043b\u043b\u0430\u0440\u043e\u0432 \u043d\u0430 \u0431\u0430\u043b\u0430\u043d\u0441\u0435.<\/p>\n<\/li>\n<li>\n<p>\u041f\u0430\u0440\u0430 \u0433\u0438\u0433\u0430\u0431\u0430\u0439\u0442 \u043d\u0430 \u043a\u0430\u043a\u043e\u043c-\u043d\u0438\u0431\u0443\u0434\u044c \u0445\u043e\u0441\u0442\u0438\u043d\u0433\u0435.<\/p>\n<\/li>\n<\/ol>\n<p>\u041e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e:<\/p>\n<ol start=\"4\">\n<li>\n<p>\u0414\u043e\u0441\u0442\u0443\u043f \u043a \u0432\u0435\u0431-\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0443 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 OpenAI.<\/p>\n<\/li>\n<li>\n<p>VPS \u0437\u0430 \u043f\u0440\u0435\u0434\u0435\u043b\u0430\u043c\u0438 \u0420\u0424.<\/p>\n<\/li>\n<\/ol>\n<h3>\u041f\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0437\u0430\u0434\u0430\u0447\u0438<\/h3>\n<p>\u042f \u0431\u0443\u0434\u0443 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0432\u043e\u0439 \u0444\u043e\u0442\u043e\u0430\u0440\u0445\u0438\u0432, \u043e\u0442\u0441\u043d\u044f\u0442\u044b\u0439 \u0432 \u043e\u0442\u043f\u0443\u0441\u043a\u0430\u0445 \u0440\u0430\u0437\u043d\u044b\u0445 \u043b\u0435\u0442. \u041d\u0430 \u044f\u0437\u044b\u043a\u0435 \u0441\u0442\u043e\u043a\u0435\u0440\u043e\u0432 \u2013 \u0442\u0440\u0435\u0432\u0435\u043b-\u0444\u043e\u0442\u043e. \u0424\u0430\u0439\u043b\u044b \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u044b \u043f\u043e \u0441\u0442\u0440\u0430\u043d\u0430\u043c \u0438 \u0433\u043e\u0440\u043e\u0434\u0430\u043c, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u044b \u043d\u0430 \u043a\u043e\u043c\u043c\u0435\u0440\u0447\u0435\u0441\u043a\u0438\u0435 \u0438 \u0442\u0430\u043a \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0435 editorial (\u0441 \u043b\u044e\u0434\u044c\u043c\u0438 \u0438\u043b\u0438 \u0443\u0437\u043d\u0430\u0432\u0430\u0435\u043c\u044b\u043c\u0438 \u0434\u043e\u0441\u0442\u043e\u043f\u0440\u0438\u043c\u0435\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044f\u043c\u0438). \u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043f\u0430\u043f\u043e\u043a \u0432\u043e\u0442 \u0442\u0430\u043a\u0430\u044f:<\/p>\n<p><code>photo<\/code><\/p>\n<p><code>\u251c\u2500\u2500 Russia<\/code><\/p>\n<p><code>\u2502\u00a0\u00a0 \u2514\u2500\u2500 Ruskeala<\/code><\/p>\n<p><code>\u2502\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u251c\u2500\u2500 editorial<\/code><\/p>\n<p><code>\u2502\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u2514\u2500\u2500 commercial<\/code><\/p>\n<p><code>\u2514\u2500\u2500 Turkey<\/code><\/p>\n<p><code>\u00a0\u00a0\u00a0 \u2514\u2500\u2500 Istanbul<\/code><\/p>\n<p><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u251c\u2500\u2500 editorial<\/code><\/p>\n<p><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u2514\u2500\u2500 commercial<\/code><\/p>\n<p>\u0414\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430 \u0432 \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0445 \u043f\u0430\u043f\u043a\u0430\u0445 editoral\/commercial, \u044f\u0432\u043b\u044f\u044e\u0449\u0435\u0433\u043e\u0441\u044f \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435\u043c, \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u0434\u043e\u0431\u0440\u0430\u0442\u044c \u0438 \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0432 EXIF \u0435\u0433\u043e \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043d\u0430 \u0430\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u043e\u043c \u044f\u0437\u044b\u043a\u0435 \u0434\u043b\u0438\u043d\u043e\u0439 \u043d\u0435 \u0431\u043e\u043b\u0435\u0435 200 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432, \u0430 \u0442\u0430\u043a\u0436\u0435 50 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0445 \u0441\u043b\u043e\u0432. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0434\u043b\u044f \u0444\u0430\u0439\u043b\u043e\u0432 \u0438\u0437 \u043f\u0430\u043f\u043e\u043a editorial \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0438\u043c\u0435\u0435\u0442 \u0444\u043e\u0440\u043c\u0430\u0442<\/p>\n<p><code>City, Country - Month Day Year: Description<\/code><\/p>\n<p>\u0414\u043b\u044f \u043a\u043e\u043c\u043c\u0435\u0440\u0447\u0435\u0441\u043a\u0438\u0445 \u0444\u043e\u0442\u043e \u0442\u0430\u043a\u0438\u0445 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u0439 \u043d\u0435\u0442, \u043d\u043e \u0436\u0435\u043b\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0433\u043e\u0440\u043e\u0434\u0430 \u0438 \u0441\u0442\u0440\u0430\u043d\u044b \u0432 \u0441\u043f\u0438\u0441\u043a\u0435 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0445 \u0441\u043b\u043e\u0432.<\/p>\n<p>\u0412\u043e\u0442 \u043f\u043b\u0430\u043d \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438:<\/p>\n<ol>\n<li>\n<p>\u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043f\u0430\u043a\u0435\u0442\u0430 \u0437\u0430\u0434\u0430\u043d\u0438\u0439 \u0434\u043b\u044f \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b OpenAI.<\/p>\n<\/li>\n<li>\n<p>\u041e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u043f\u0430\u043a\u0435\u0442\u0430 \u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432.<\/p>\n<\/li>\n<li>\n<p>\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u0438 \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439.<\/p>\n<\/li>\n<\/ol>\n<h3>\u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043f\u0430\u043a\u0435\u0442\u0430 \u0437\u0430\u0434\u0430\u043d\u0438\u0439<\/h3>\n<p>\u041c\u044b \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u043f\u0435\u0440\u0435\u0441\u044b\u043b\u0430\u0442\u044c \u043d\u0435\u0439\u0440\u043e\u0441\u0435\u0442\u0438 \u043a\u0430\u0436\u0434\u043e\u0435 \u0444\u043e\u0442\u043e \u043f\u043e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438. \u0412\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c Batch API. \u0417\u0430\u043f\u0440\u043e\u0441\u044b \u0431\u0443\u0434\u0443\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u044b \u043d\u0435 \u0441\u0440\u0430\u0437\u0443, \u0430 \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 \u0441\u0443\u0442\u043e\u043a, \u0437\u0430\u0442\u043e \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043c 50%-\u043d\u0443\u044e \u0441\u043a\u0438\u0434\u043a\u0443 \u043d\u0430 \u0434\u0438\u0430\u043b\u043e\u0433 \u0441 ChatGPT.<\/p>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u043c\u0441\u044f \u043a \u0432\u0435\u0440\u0441\u0438\u0438 gpt-4o-mini, \u0442\u0430\u043a \u043a\u0430\u043a \u043e\u043d\u0430 \u0438\u043c\u0435\u0435\u0442 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0434\u0435\u043c\u043e\u043a\u0440\u0430\u0442\u0438\u0447\u043d\u044b\u0435 \u043b\u0438\u043c\u0438\u0442\u044b \u0441\u0440\u0430\u0432\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0441 gpt-4o. \u0412\u043e\u0442, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <a href=\"https:\/\/platform.openai.com\/docs\/guides\/rate-limits?context=tier-one\" rel=\"noopener noreferrer nofollow\">\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f <\/a>\u0434\u043b\u044f \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u043e\u0432 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f (\u043c\u0435\u043d\u0435\u0435 50 \u0434\u043e\u043b\u043b\u0430\u0440\u043e\u0432 \u0438\u0437\u0440\u0430\u0441\u0445\u043e\u0434\u043e\u0432\u0430\u043d\u043e \u0437\u0430 \u0432\u0440\u0435\u043c\u044f \u0436\u0438\u0437\u043d\u0438 \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u0430).<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td>\n<p align=\"left\"><strong>\u041c\u043e\u0434\u0435\u043b\u044c<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u0417\u0430\u043f\u0440\u043e\u0441\u044b    \u0432 \u043c\u0438\u043d\u0443\u0442\u0443<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u0417\u0430\u043f\u0440\u043e\u0441\u044b    \u0432 \u0434\u0435\u043d\u044c<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u0422\u043e\u043a\u0435\u043d\u044b    \u0432 \u043c\u0438\u043d\u0443\u0442\u0443<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u041b\u0438\u043c\u0438\u0442    \u043f\u0430\u043a\u0435\u0442\u043d\u043e\u0439 \u043e\u0447\u0435\u0440\u0435\u0434\u0438<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">gpt-4o<\/p>\n<\/td>\n<td>\n<p align=\"left\">500<\/p>\n<\/td>\n<td>\n<p align=\"left\">&#8212;<\/p>\n<\/td>\n<td>\n<p align=\"left\">30,000<\/p>\n<\/td>\n<td>\n<p align=\"left\">90,000<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">gpt-4o-mini<\/p>\n<\/td>\n<td>\n<p align=\"left\">500<\/p>\n<\/td>\n<td>\n<p align=\"left\">10,000<\/p>\n<\/td>\n<td>\n<p align=\"left\">200,000<\/p>\n<\/td>\n<td>\n<p align=\"left\">2,000,000<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u041a\u0430\u043a \u0432\u0438\u0434\u0438\u043c, \u0441 \u0432\u0435\u0440\u0441\u0438\u0435\u0439 gpt-4o-mini \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u043f\u0430\u043a\u0435\u0442\u044b \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u043c \u0434\u043e 200 \u0442\u044b\u0441. \u0442\u043e\u043a\u0435\u043d\u043e\u0432.<\/p>\n<p>\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u043c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043d\u0430\u0448\u0435\u0433\u043e \u0441\u043a\u0440\u0438\u043f\u0442\u0430 \u0432 \u0432\u0438\u0434\u0435 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0445 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445:<\/p>\n<pre><code class=\"python\">valid_extensions = ('.jpg', '.jpeg')  api_key = '\u0412\u0410\u0428_\u041a\u041b\u042e\u0427'  your_site = 'http:\/\/\u0412\u0410\u0428_\u0421\u0410\u0419\u0422\/' photo_dir = 'C:\\\\\u041f\u0423\u0422\u042c\\\\\u041a\\\\\u0424\u041e\u0422\u041e' tasks_path = \"batch_tasks.jsonl\" results_path = \"batch_tasks_output.jsonl\" job_id_path = \"batch_job_id.txt\"  description_length = 200 keywords_count = 50 prompt = f\"Please create a description no more than {description_length} characters long for this image in stock style \" \\          f\"and a list of {keywords_count} popular single-word keywords, separated with commas. \" \\          f\"Tailor the description to a specific niche and target audience. \"\\          f\"Your keywords are to enhance searchability within that niche.\" \\          f\"If there are architectural decoration elements in the image, be sure to include them. \" \\          f\"If there are inscriptions in a language other than English in the photo, include their translation in the description. \" \\          f\"Be sure to separate the description from the list of keywords with a newline character. \" \\          f\"Don't write anything except a description and a list of keywords. \" \\          f\"If there are any plants in the picture, identify their names and weave them into the description and the keywords list. \" \\          f\"Ensure no word is repeated. Be sure to include in both the description and in the keywords list the next words: \"  batch_output_map = {}<\/code><\/pre>\n<p>\u041d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 \u043f\u043e\u043d\u044f\u0442\u043d\u043e \u0438\u0437 \u0435\u0433\u043e \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f. \u042f \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u044e\u0441\u044c \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u043f\u0440\u043e\u043c\u043f\u0442\u0435 \u2013 \u0441\u0435\u0440\u0434\u0446\u0435 \u043d\u0430\u0448\u0435\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b. \u041e\u043d \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u0444\u043e\u043a\u0443\u0441\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0439 \u043d\u0438\u0448\u0435, \u0442\u043e \u0435\u0441\u0442\u044c \u0441\u0442\u043e\u043a\u043e\u0432\u043e\u0439 \u0442\u0435\u043c\u0430\u0442\u0438\u043a\u0435, \u0447\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043f\u043e\u0432\u044b\u0441\u0438\u0442\u044c SEO-\u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440\u0438\u0441\u0442\u0438\u043a\u0438 \u0441\u0442\u043e\u043a\u043e\u0432\u043e\u0433\u043e \u043f\u043e\u0440\u0442\u0444\u0435\u043b\u044f. \u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043c\u044b \u043e\u0436\u0438\u0434\u0430\u0435\u043c \u0432 \u0432\u0438\u0434\u0435 \u0434\u0432\u0443\u0445 \u0430\u0431\u0437\u0430\u0446\u0435\u0432 \u0442\u0435\u043a\u0441\u0442\u0430 \u2013 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0438 \u0441\u043f\u0438\u0441\u043e\u043a \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0445 \u0441\u043b\u043e\u0432. \u041d\u0430\u043c \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u043a \u043f\u0440\u043e\u043c\u043f\u0442\u0443 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0435 \u0441\u043b\u043e\u0432\u0430, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u043d \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0439 \u0444\u0440\u0430\u0437\u043e\u0439 \u0438 \u0434\u0432\u043e\u0435\u0442\u043e\u0447\u0438\u0435\u043c.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043f\u0430\u043a\u0435\u0442 \u0437\u0430\u0434\u0430\u043d\u0438\u0439:<\/p>\n<pre><code class=\"python\">from urllib.parse import quote  def generate_tasks():     with open(tasks_path, 'w') as file:         task_index = 0         for root, dirs, files in os.walk(photo_dir):             path_parts = root.split(os.sep)             # \u0415\u0441\u043b\u0438 \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0442\u0440\u0438 \u0443\u0440\u043e\u0432\u043d\u044f \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0439 \u0438 \u043c\u044b \u043d\u0430\u0445\u043e\u0434\u0438\u043c\u0441\u044f \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 \u0438\u0437 \u043d\u0438\u0445             if len(path_parts) &gt;= 3 and path_parts[-1] in {'editorial', 'commercial'}:                 for filename in files:                     if not filename.lower().endswith(valid_extensions):                         continue                     file_path = os.path.relpath(os.path.join(root, filename), photo_dir).replace('\\\\', '\/')                     image_url = f\"{your_site}photo\/{file_path}\"                     image_url = quote(image_url, safe=':\/')                      path_parts = re.split(r'[\\\\\/]', file_path)                     country, city = path_parts[0], path_parts[1] if len(path_parts) &gt; 1 else (None, None)                      new_prompt = f\"{prompt} {country}, {city}\" if country and city else prompt                      task = {                         \"custom_id\": f\"task-{task_index}\",                         \"method\": \"POST\",                         \"url\": \"\/v1\/chat\/completions\",                         \"body\": {                             \"model\": \"gpt-4o-mini\",                             \"messages\": [                                 {                                     \"role\": \"system\",                                     \"content\": new_prompt                                 },                                 {                                     \"role\": \"user\",                                     \"content\": [                                         {                                             \"type\": \"image_url\",                                             \"image_url\": {                                                 \"url\": image_url                                             }                                         },                                     ],                                 }                             ]                         }                     }                      file.write(json.dumps(task) + '\\n')                     print(f\"\u0414\u043e\u0431\u0430\u0432\u0438\u043b\u0438 \u0437\u0430\u0434\u0430\u043d\u0438\u0435: {image_url}\")                     task_index += 1<\/code><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u043c\u044b \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u043c \u043f\u043e \u0434\u0435\u0440\u0435\u0432\u0443 \u043f\u0430\u043f\u043e\u043a, \u043d\u0430\u0447\u0438\u043d\u0430\u044f \u0441 <code>photo_dir<\/code>, \u0438 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430 <code>\u2026\/editorial\/*.jp(e)g<\/code> \u0438\u043b\u0438 <code>\u2026\/commercial\/*.jp(e)g<\/code> \u0432\u044b\u0434\u0435\u043b\u044f\u0435\u043c \u0438\u0437 \u043f\u0443\u0442\u0438 \u043a \u043d\u0435\u043c\u0443 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0441\u0442\u0440\u0430\u043d\u044b \u0438 \u0433\u043e\u0440\u043e\u0434\u0430, \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u044d\u0442\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043a \u043f\u0440\u043e\u043c\u043f\u0442\u0443 \u0438 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0437\u0430\u0434\u0430\u043d\u0438\u0435 \u0432 \u0432\u0438\u0434\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 JSON. \u0423 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0437\u0430\u0434\u0430\u043d\u0438\u044f \u0435\u0441\u0442\u044c \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u043f\u0430\u043a\u0435\u0442\u0430 <code>custom_id<\/code>, \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043c\u044b \u043f\u043e\u0442\u043e\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c \u0438\u043c\u044f \u0444\u0430\u0439\u043b\u0430. \u0422\u0435\u043b\u043e \u0437\u0430\u0434\u0430\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u0434\u0432\u0443\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u2013 \u043f\u0440\u043e\u043c\u043f\u0442\u0430 \u0438 URL \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0438 \u043d\u0430 \u0445\u043e\u0441\u0442\u0438\u043d\u0433\u0435.<\/p>\n<p>\u041f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u0444\u0430\u0439\u043b\u044b \u043b\u0435\u0436\u0430\u0442 \u043d\u0430 \u0432\u0430\u0448\u0435\u043c \u0445\u043e\u0441\u0442\u0438\u043d\u0433\u0435 \u0432 \u043f\u0430\u043f\u043a\u0435 <code>photo<\/code>. \u041f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c URL \u0447\u0435\u0440\u0435\u0437 \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>quote()<\/code> \u043d\u0430 \u0441\u043b\u0443\u0447\u0430\u0439, \u0435\u0441\u043b\u0438 \u0438\u043c\u044f \u0444\u0430\u0439\u043b\u0430 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0437\u0430\u0440\u0435\u0437\u0435\u0440\u0432\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0441\u0438\u043c\u0432\u043e\u043b\u044b. <a href=\"https:\/\/en.wikipedia.org\/wiki\/Percent-encoding\" rel=\"noopener noreferrer nofollow\">\u041f\u0440\u043e\u0446\u0435\u043d\u0442\u043d\u0430\u044f \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0430<\/a> \u0437\u0430\u043c\u0435\u043d\u0438\u0442 \u0438\u0445 \u043d\u0430 \u0437\u043d\u0430\u043a \u043f\u0440\u043e\u0446\u0435\u043d\u0442\u0430 \u0438 \u043d\u043e\u043c\u0435\u0440. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u0440\u043e\u0431\u0435\u043b \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u0442\u0441\u044f \u0432 <code>%20<\/code>.<\/p>\n<p>\u041a\u0430\u0436\u0434\u043e\u0435 \u0437\u0430\u0434\u0430\u043d\u0438\u0435 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u0444\u0430\u0439\u043b <code>tasks_path<\/code> \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u043e\u0439. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0444\u0430\u0439\u043b \u0438 \u0438\u043c\u0435\u0435\u0442 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 .jsonl (JSON Lines).<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/c54\/e57\/6f7\/c54e576f7ebdc72a759e960a2e3b11e1.png\" alt=\"\u041f\u0430\u043a\u0435\u0442 \u0437\u0430\u0434\u0430\u043d\u0438\u0439\" title=\"\u041f\u0430\u043a\u0435\u0442 \u0437\u0430\u0434\u0430\u043d\u0438\u0439\" width=\"1349\" height=\"660\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/c54\/e57\/6f7\/c54e576f7ebdc72a759e960a2e3b11e1.png\"\/><\/p>\n<div><figcaption>\u041f\u0430\u043a\u0435\u0442 \u0437\u0430\u0434\u0430\u043d\u0438\u0439<\/figcaption><\/div>\n<\/figure>\n<p>\u041d\u0443\u0436\u043d\u043e \u0441\u043b\u0435\u0434\u0438\u0442\u044c \u0437\u0430 \u043e\u0431\u044a\u0435\u043c\u043e\u043c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430, \u0442\u0430\u043a \u043a\u0430\u043a \u0435\u0441\u0442\u044c \u0440\u0438\u0441\u043a \u043f\u0440\u0435\u0432\u044b\u0441\u0438\u0442\u044c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0442\u043e\u043a\u0435\u043d\u043e\u0432 \u0432 \u043e\u0434\u043d\u043e\u043c \u043f\u0430\u043a\u0435\u0442\u0435. \u041a\u0430\u043a \u0443\u0436\u0435 \u0433\u043e\u0432\u043e\u0440\u0438\u043b\u043e\u0441\u044c, \u0434\u043b\u044f \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u043e\u0432 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f \u0438 \u0432\u0435\u0440\u0441\u0438\u0438 gpt-4o-mini \u043f\u0430\u043a\u0435\u0442 \u043d\u0435 \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u0440\u0435\u0432\u044b\u0448\u0430\u0442\u044c 200 \u0442\u044b\u0441. \u0442\u043e\u043a\u0435\u043d\u043e\u0432. \u0427\u0442\u043e\u0431\u044b \u0441\u043b\u0435\u0434\u0438\u0442\u044c \u0437\u0430 \u043b\u0438\u043c\u0438\u0442\u043e\u043c, \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <a href=\"https:\/\/quizgecko.com\/tools\/token-counter\" rel=\"noopener noreferrer nofollow\">\u0442\u043e\u043a\u0435\u043d\u0438\u0437\u0430\u0442\u043e\u0440<\/a>. \u041f\u043e \u043e\u043f\u044b\u0442\u0443, \u043f\u0440\u0438 \u043f\u0440\u043e\u043c\u043f\u0442\u0435 \u0442\u0430\u043a\u043e\u0439 \u0434\u043b\u0438\u043d\u044b \u0432 \u043b\u0438\u043c\u0438\u0442 \u0443\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0434\u043e 800 \u0441\u0442\u0440\u043e\u043a=JSON-\u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432.<\/p>\n<h3>\u041e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u043f\u0430\u043a\u0435\u0442\u0430 \u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432<\/h3>\n<p>\u041e\u0442\u043f\u0440\u0430\u0432\u0438\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0432\u0448\u0438\u0439\u0441\u044f \u0444\u0430\u0439\u043b \u043d\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443.<\/p>\n<pre><code class=\"python\">from openai import OpenAI  def send_batch():     client = OpenAI(         api_key=api_key     )      batch_file = client.files.create(         file=open(tasks_path, \"rb\"),         purpose=\"batch\"     )     batch_job = client.batches.create(         input_file_id=batch_file.id,         endpoint=\"\/v1\/chat\/completions\",         completion_window=\"24h\"     )     print(f\"\u0421\u043e\u0437\u0434\u0430\u043b\u0438 \u043f\u0430\u043a\u0435\u0442\u043d\u043e\u0435 \u0437\u0430\u0434\u0430\u043d\u0438\u0435 \u0441 ID {batch_job.id}\")      with open(job_id_path, 'w') as f:         f.write(batch_job.id)      return batch_job.id<\/code><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c \u0444\u0430\u0439\u043b \u0441 \u0437\u0430\u0434\u0430\u043d\u0438\u044f\u043c \u0432 \u0441\u0432\u043e\u0435 <a href=\"https:\/\/platform.openai.com\/storage\/files\" rel=\"noopener noreferrer nofollow\">\u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435<\/a>, \u0443\u043a\u0430\u0437\u0430\u0432 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 <code>purpose=\"batch\"<\/code>. \u0424\u0430\u0439\u043b\u0443 \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 ID, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0437\u0430\u0442\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043f\u0430\u043a\u0435\u0442\u043d\u043e\u0433\u043e \u0437\u0430\u0434\u0430\u043d\u0438\u044f. \u0417\u0430\u0434\u0430\u043d\u0438\u0435 \u0442\u043e\u0436\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442 \u0441\u0432\u043e\u0439 ID, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u043d\u0430 \u0432\u0441\u044f\u043a\u0438\u0439 \u0441\u043b\u0443\u0447\u0430\u0439 \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u043c \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0444\u0430\u0439\u043b, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u043f\u043e\u0442\u0435\u0440\u044f\u0442\u044c, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0432\u0435\u0440\u043d\u0435\u043c \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0432\u044b\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438.<\/p>\n<p>\u041f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442:<\/p>\n<pre><code class=\"python\">def try_get_results():     client = OpenAI(         api_key=api_key     )      with open(job_id_path, 'r') as f:         batch_job_id = f.read().strip()      batch_job = client.batches.retrieve(batch_job_id)     print(f\"\u0421\u0442\u0430\u0442\u0443\u0441 \u043f\u0430\u043a\u0435\u0442\u043d\u043e\u0433\u043e \u0437\u0430\u0434\u0430\u043d\u0438\u044f: {batch_job.status}\")     if batch_job.status == 'completed':         result = client.files.content(batch_job.output_file_id).content         with open(results_path, 'wb') as file:             file.write(result)         print(f\"\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u044b \u0432 \u0444\u0430\u0439\u043b {results_path}\")     else:         print(batch_job)<\/code><\/pre>\n<p>\u0412\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0432 ID \u0437\u0430\u0434\u0430\u043d\u0438\u044f, \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0435\u0433\u043e \u0441\u0442\u0430\u0442\u0443\u0441 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>retrieve()<\/code>. \u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u0443\u0441\u043f\u0435\u0445\u0430 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432 \u0444\u0430\u0439\u043b <code>results_path<\/code>.<\/p>\n<p>\u0422\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435 \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0432\u0435\u0431-\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430, \u0433\u0434\u0435 \u0443\u0434\u043e\u0431\u043d\u043e \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0441 \u043f\u0430\u043a\u0435\u0442\u0430\u043c\u0438.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/d33\/ee4\/69b\/d33ee469b5e5622a89121104f95f292f.jpg\" alt=\"\u041c\u043e\u0438 \u043f\u0430\u043a\u0435\u0442\u044b \u0437\u0430\u0434\u0430\u043d\u0438\u0439\" title=\"\u041c\u043e\u0438 \u043f\u0430\u043a\u0435\u0442\u044b \u0437\u0430\u0434\u0430\u043d\u0438\u0439\" width=\"1362\" height=\"648\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/d33\/ee4\/69b\/d33ee469b5e5622a89121104f95f292f.jpg\" data-blurred=\"true\"\/><\/p>\n<div><figcaption>\u041c\u043e\u0438 \u043f\u0430\u043a\u0435\u0442\u044b \u0437\u0430\u0434\u0430\u043d\u0438\u0439<\/figcaption><\/div>\n<\/figure>\n<h3>\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0445 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432<\/h3>\n<p>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u0432 \u0442\u043e\u043c \u0436\u0435 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 JSON Lines.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/37f\/495\/aa3\/37f495aa3de1bbdb369f5e30ac468b8c.png\" alt=\"\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043f\u0430\u043a\u0435\u0442\u0430\" title=\"\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043f\u0430\u043a\u0435\u0442\u0430\" width=\"1361\" height=\"634\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/37f\/495\/aa3\/37f495aa3de1bbdb369f5e30ac468b8c.png\"\/><\/p>\n<div><figcaption>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043f\u0430\u043a\u0435\u0442\u0430<\/figcaption><\/div>\n<\/figure>\n<p>\u041e\u0442\u0432\u0435\u0442 \u043d\u0430 \u043a\u0430\u0436\u0434\u043e\u0435 \u0437\u0430\u0434\u0430\u043d\u0438\u0435 \u0437\u0430\u043f\u0438\u0441\u0430\u043d \u0432 \u0432\u0438\u0434\u0435 JSON-\u043e\u0431\u044a\u0435\u043a\u0442\u0430:<\/p>\n<pre><code class=\"json\">{   \"id\": \"batch_req_6771\u2026\",   \"custom_id\": \"task-0\",   \"response\": {     \"status_code\": 200,     \"request_id\": \"b247\u2026\",     \"body\": {       \"id\": \"chatcmpl-Ajt\u2026\",       \"object\": \"chat.completion\",       \"created\": 1735500227,       \"model\": \"gpt-4o-mini-2024-07-18\",       \"choices\": [         {           \"index\": 0,           \"message\": {             \"role\": \"assistant\",             \"content\": \"Elegant interior showcasing intricate metalwork and lush green drapery. Ideal for modern design enthusiasts. Explore the charm of Ruskeala, Russia through this stylish setting.\\n\\nRussia, Ruskeala, interior, design, elegance, green, drapery, metalwork, decoration, style, modern, seating, artistic, ambiance, wood, vintage, upholstery, tranquility, cozy, decor, booth, pattern, texture, illumination, hospitality, creativity, aesthetic, luxurious, charming, refinement, sophistication, boutique, comfort, travel, cultural, picturesque, artisan, heritage, classic, unique, rustic, classy, inviting, traditional, fashionable, ornate.\",             \"refusal\": null           },           \"logprobs\": null,           \"finish_reason\": \"stop\"         }       ],       \"usage\": {         \"prompt_tokens\": 1331,         \"completion_tokens\": 131,         \"total_tokens\": 1462,         \"prompt_tokens_details\": {           \"cached_tokens\": 0,           \"audio_tokens\": 0         },         \"completion_tokens_details\": {           \"reasoning_tokens\": 0,           \"audio_tokens\": 0,           \"accepted_prediction_tokens\": 0,           \"rejected_prediction_tokens\": 0         }       },       \"system_fingerprint\": \"fp_d\u2026\"     }   },   \"error\": null } <\/code><\/pre>\n<p>\u041a\u0430\u043a \u043c\u044b \u0432\u0438\u0434\u0438\u043c, \u0434\u043b\u044f \u0437\u0430\u0434\u0430\u043d\u0438\u044f <code>task-0<\/code> \u0438 \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u0445 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0445 \u0441\u043b\u043e\u0432 \u00abRussia, Ruskeala\u00bb \u043d\u0435\u0439\u0440\u043e\u0441\u0435\u0442\u044c \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043b\u0430 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0434\u043b\u0438\u043d\u043e\u0439 177 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u0438 \u0440\u043e\u0432\u043d\u043e 50 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0445 \u0441\u043b\u043e\u0432, \u0432\u043a\u043b\u044e\u0447\u0430\u044f \u0438 \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u0435. \u0422\u0435\u043f\u0435\u0440\u044c \u0432\u0441\u0435 \u044d\u0442\u043e \u043d\u0430\u0434\u043e \u0432\u043d\u0435\u0441\u0442\u0438 \u0432 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435.<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0434\u043b\u044f \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u043d\u0438\u044f \u0444\u0430\u0439\u043b\u0430 \u0444\u043e\u0440\u043c\u0430\u0442\u0430 JSON Lines \u0432 \u0441\u043f\u0438\u0441\u043e\u043a:<\/p>\n<pre><code class=\"python\">def load_jsonl(filepath):     with open(filepath, 'r', encoding='utf-8') as file:         return [json.loads(line) for line in file]<\/code><\/pre>\n<p>\u0421\u0447\u0438\u0442\u0430\u0435\u043c \u0441\u0440\u0430\u0437\u0443 \u0434\u0432\u0430 \u0444\u0430\u0439\u043b\u0430 \u2013 \u0437\u0430\u0434\u0430\u043d\u0438\u044f \u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442:<\/p>\n<pre><code class=\"python\">def load_batch_output(tasks_file, outputs_file):     global batch_output_map      tasks_data = load_jsonl(tasks_file)     outputs_data = load_jsonl(outputs_file)      batch_output_map = {}      tasks_index = {task['custom_id']: task for task in tasks_data}      for output in outputs_data:         custom_id = output.get('custom_id')         if custom_id in tasks_index:             task = tasks_index[custom_id]             try:                 image_url = task['body']['messages'][1]['content'][0]['image_url']['url']                 image_url = image_url.replace(your_site, '', 1)                 content = output['response']['body']['choices'][0]['message']['content']                 batch_output_map[image_url] = content             except (IndexError, KeyError, TypeError) as e:                 print(f'\u041e\u0448\u0438\u0431\u043a\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0437\u0430\u0434\u0430\u0447\u0438 {custom_id}: {e}')<\/code><\/pre>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u0432 \u043e\u0442\u0432\u0435\u0442\u0435 \u043d\u0430 \u043f\u0430\u043a\u0435\u0442\u043d\u043e\u0435 \u0437\u0430\u0434\u0430\u043d\u0438\u0435 \u043d\u0435 \u0443\u043a\u0430\u0437\u0430\u043d\u044b URL \u0444\u043e\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u0439, \u043a \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u044d\u0442\u0438 \u043e\u0442\u0432\u0435\u0442\u044b \u043e\u0442\u043d\u043e\u0441\u044f\u0442\u0441\u044f, \u043d\u0430\u043c \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u0441\u0440\u0430\u0437\u0443 \u0434\u0432\u0430 \u0444\u0430\u0439\u043b\u0430 \u2013 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u043e\u0442 API. \u0421\u0432\u044f\u0437\u044b\u0432\u0430\u044f \u0438\u0445 \u043f\u043e <code>custom_id<\/code>, \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u0445\u044d\u0448-\u0442\u0430\u0431\u043b\u0438\u0446\u0443 <code>batch_output_map<\/code>, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e URL \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u043e\u0442\u0432\u0435\u0442 \u043d\u0435\u0439\u0440\u043e\u0441\u0435\u0442\u0438.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/6f1\/7ea\/02b\/6f17ea02b81ecd9d65f4a13bf7cef3bc.png\" alt=\"\u0417\u0430\u0434\u0430\u043d\u0438\u0435 \u0438 \u043e\u0442\u0432\u0435\u0442\" title=\"\u0417\u0430\u0434\u0430\u043d\u0438\u0435 \u0438 \u043e\u0442\u0432\u0435\u0442\" width=\"695\" height=\"295\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/6f1\/7ea\/02b\/6f17ea02b81ecd9d65f4a13bf7cef3bc.png\"\/><\/p>\n<div><figcaption>\u0417\u0430\u0434\u0430\u043d\u0438\u0435 \u0438 \u043e\u0442\u0432\u0435\u0442<\/figcaption><\/div>\n<\/figure>\n<p>\u0412 \u043c\u043e\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0441\u043a\u0440\u0438\u043f\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0443\u0436\u043d\u043e \u0438\u0441\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0434\u043e\u043c\u0435\u043d \u0438\u0437 URL.<\/p>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u0437\u0430\u043f\u0438\u0441\u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u0432 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u0445\u043e\u0436\u0430 \u043d\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0437\u0430\u0434\u0430\u043d\u0438\u0439. \u0422\u043e\u0447\u043d\u043e \u0442\u0430\u043a \u0436\u0435 \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u043c \u043f\u043e \u043f\u0430\u043f\u043a\u0435 <code>photos<\/code> \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>os.walk()<\/code>.<\/p>\n<pre><code class=\"python\">def process_directory(root_path):     global batch_output_map      if not batch_output_map:         print(\"\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u043f\u0430\u043a\u0435\u0442\u043d\u043e\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438!\")         return      for root, dirs, files in os.walk(root_path):         path_parts = root.split(os.sep)         # \u0415\u0441\u043b\u0438 \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0442\u0440\u0438 \u0443\u0440\u043e\u0432\u043d\u044f \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0439 \u0438 \u043c\u044b \u043d\u0430\u0445\u043e\u0434\u0438\u043c\u0441\u044f \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 \u0438\u0437 \u043d\u0438\u0445         if len(path_parts) &gt;= 3 and (path_parts[-1] == 'editorial' or path_parts[-1] == 'commercial'):             country = path_parts[-3]  # \u0442\u0440\u0435\u0442\u0438\u0439 \u0441 \u043a\u043e\u043d\u0446\u0430 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0432 \u0441\u043f\u0438\u0441\u043a\u0435             city = path_parts[-2]  # \u043f\u0440\u0435\u0434\u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0432 \u0441\u043f\u0438\u0441\u043a\u0435             category = path_parts[-1]  # \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0432 \u0441\u043f\u0438\u0441\u043a\u0435              print(f\"\u0410\u043d\u0430\u043b\u0438\u0437 \u043f\u0430\u043f\u043a\u0438 {root}\")             for file in files:                 if file.lower().endswith(valid_extensions):                     relative_file_path = os.path.join(os.path.relpath(root, root_path), file)                     relative_file_path = relative_file_path.replace(os.sep, '\/')                     relative_file_path = f\"photo\/{relative_file_path}\"                     relative_file_path = quote(relative_file_path)                      if not relative_file_path in batch_output_map:                         print(f\"\u0414\u043b\u044f {relative_file_path} \u043d\u0435 \u043d\u0430\u0448\u043b\u043e\u0441\u044c \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0445!!!\")                         continue                      file_path = os.path.join(root, file)                     year, month, day = extract_date_taken(file_path)                      response = batch_output_map[relative_file_path].split(\"\\n\\n\")                     if len(response) &lt; 2:                         print(\"\u0412 \u043e\u0442\u0432\u0435\u0442\u0435 \u043c\u0435\u043d\u044c\u0448\u0435 2 \u0440\u0430\u0437\u0434\u0435\u043b\u043e\u0432!\")                     else:                         default_title, tags = response[:2] # \u0438\u043d\u043e\u0433\u0434\u0430 \u043d\u0435\u0439\u0440\u043e\u0441\u0435\u0442\u044c \u0441\u0442\u0430\u0432\u0438\u0442 \u043b\u0438\u0448\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u044b \u0441\u0442\u0440\u043e\u043a \u043f\u043e\u0441\u043b\u0435 \u0441\u043f\u0438\u0441\u043a\u0430 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0445 \u0441\u043b\u043e\u0432                         add_metadata(file_path, default_title, category, make_tag_list(tags), month, day, year, country,                                  city)         else:             print(f\"{root} \u043d\u0435 commercial \u0438 \u043d\u0435 editorial, \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u044e \u0435\u0433\u043e :-(\")<\/code><\/pre>\n<p>\u0414\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430 \u0441 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435\u043c \u043c\u044b \u0438\u0449\u0435\u043c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0443\u044e \u0437\u0430\u043f\u0438\u0441\u044c \u0432 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0439 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 <code>batch_output_map<\/code>, \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u043c \u043e\u0442\u0442\u0443\u0434\u0430 \u0434\u0432\u0430 \u0430\u0431\u0437\u0430\u0446\u0430 \u0442\u0435\u043a\u0441\u0442\u0430, \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u0435\u043c \u0438\u0445 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>split()<\/code> \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0432 <code>add_metadata()<\/code> \u043a\u0430\u043a \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0438 \u0441\u043f\u0438\u0441\u043e\u043a \u0442\u0435\u0433\u043e\u0432.<\/p>\n<p>\u0422\u0435\u0433\u0438 \u0437\u0430\u043f\u0438\u0441\u0430\u043d\u044b \u0447\u0435\u0440\u0435\u0437 \u0437\u0430\u043f\u044f\u0442\u0443\u044e, \u043a\u0430\u043a \u043c\u044b \u0438 \u043f\u0440\u043e\u0441\u0438\u043b\u0438. \u041e\u0431\u044b\u0447\u043d\u043e \u0438\u0445 \u0441\u043f\u0438\u0441\u043e\u043a \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0437\u043d\u0430\u043a\u043e\u043c \u0442\u043e\u0447\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0430\u043c \u043d\u0435 \u043d\u0443\u0436\u0435\u043d, \u0440\u0430\u0432\u043d\u043e \u043a\u0430\u043a \u0438 \u043f\u0440\u043e\u0431\u0435\u043b\u044b:<\/p>\n<pre><code class=\"python\">def make_tag_list(tags):     if tags.endswith('.'):         tags = tags[:-1]     tags_list = tags.split(',')     tags_list = [tag.strip() for tag in tags_list]     return tags_list<\/code><\/pre>\n<h3>\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439<\/h3>\n<p>\u0412 \u0446\u0438\u0444\u0440\u043e\u0432\u043e\u0439 \u0444\u043e\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0442\u0440\u0438 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u0444\u043e\u0440\u043c\u0430\u0442\u0430 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0445:<\/p>\n<ul>\n<li>\n<p><strong>EXIF (Exchangeable Image File)<\/strong> \u2013 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f, \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u0430\u044f \u0432 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043a\u0430\u043c\u0435\u0440\u043e\u0439: \u0432\u0440\u0435\u043c\u044f \u0438 \u043c\u0435\u0441\u0442\u043e \u0441\u044a\u0435\u043c\u043a\u0438, \u043c\u043e\u0434\u0435\u043b\u044c \u043a\u0430\u043c\u0435\u0440\u044b \u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u0438\u0432\u0430, \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0441\u044a\u0435\u043c\u043a\u0438 (\u0444\u043e\u043a\u0443\u0441\u043d\u043e\u0435 \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0435, \u044d\u043a\u0441\u043f\u043e\u0437\u0438\u0446\u0438\u044f, ISO), <s>\u0430 \u0442\u0430\u043a\u0436\u0435 \u043f\u0440\u043e\u0431\u0435\u0433 \u043a\u0430\u043c\u0435\u0440\u044b, \u043d\u0435\u0437\u0430\u043c\u0435\u043d\u0438\u043c\u043e\u0435 \u043f\u043e\u043b\u0435 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u043b\u044e\u0431\u0438\u0442\u0435\u043b\u0435\u0439 \u043f\u043e\u043a\u0443\u043f\u0430\u0442\u044c \u0444\u043e\u0442\u043e\u0442\u0435\u0445\u043d\u0438\u043a\u0443 \u0441 \u0440\u0443\u043a<\/s>;<\/p>\n<\/li>\n<li>\n<p><strong>IPTC (International Press Telecommunications Council)<\/strong> \u2013 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f, \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u0430\u044f \u0432 \u0444\u0430\u0439\u043b \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c \u041f\u041e. \u042d\u0442\u043e\u0442 \u0444\u043e\u0440\u043c\u0430\u0442 \u0441\u043e\u0437\u0434\u0430\u043d \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0421\u041c\u0418 \u0438 \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0432 \u0441\u0435\u0431\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u0443\u044e \u0434\u043b\u044f \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u0444\u043e\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u0438 &#8212; \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435, \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435, \u043c\u0435\u0441\u0442\u043e\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e \u0444\u043e\u0442\u043e\u0433\u0440\u0430\u0444\u0435 \u0438 \u0430\u0432\u0442\u043e\u0440\u0441\u043a\u0438\u0445 \u043f\u0440\u0430\u0432\u0430\u0445, \u0441\u043f\u0438\u0441\u043e\u043a \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0445 \u0441\u043b\u043e\u0432;<\/p>\n<\/li>\n<li>\n<p><strong>XMP (Extensible Metadata Platform)<\/strong> \u2013 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e\u0431 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f\u0445, \u0432\u043d\u0435\u0441\u0435\u043d\u043d\u044b\u0445 \u0432 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043f\u0440\u0438 \u043f\u043e\u0441\u0442\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432 Lightroom.<\/p>\n<\/li>\n<\/ul>\n<p>\u0414\u043b\u044f editorial-\u0444\u043e\u0442\u043e \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u044f\u0442\u0441\u044f \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0441\u044a\u0435\u043c\u043a\u0438 \u2013 \u043c\u0435\u0441\u0442\u043e \u0438 \u0432\u0440\u0435\u043c\u044f. \u0421\u043b\u0435\u0434\u043e\u0432\u0430\u043b\u043e \u0431\u044b \u0441\u0447\u0438\u0442\u0430\u0442\u044c GPS-\u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0438\u0437 EXIF, \u043d\u043e \u044f \u043f\u043e\u043a\u0430 \u043e\u0431\u043e\u0439\u0434\u0443\u0441\u044c \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u043d\u0438\u0435\u043c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u0441\u0442\u0440\u0430\u043d\u044b\/\u0433\u043e\u0440\u043e\u0434\u0430 \u0438\u0437 \u043f\u0430\u043f\u043a\u0438, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043b\u0435\u0436\u0438\u0442 \u0444\u0430\u0439\u043b. \u0427\u0442\u043e \u043a\u0430\u0441\u0430\u0435\u0442\u0441\u044f \u0432\u0440\u0435\u043c\u0435\u043d\u0438, \u0442\u043e \u0435\u0433\u043e \u043b\u0435\u0433\u043a\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0438\u0437 EXIF. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 <code>piexif<\/code>:<\/p>\n<pre><code class=\"python\">import piexif  def extract_date_taken(image_path):     exif_dict = piexif.load(image_path)     date_taken_str = exif_dict['Exif'].get(piexif.ExifIFD.DateTimeOriginal)      if date_taken_str:         try:             # string parse time             date_taken = datetime.strptime(date_taken_str.decode('utf-8'), '%Y:%m:%d %H:%M:%S')             return date_taken.year, date_taken.month, date_taken.day         except ValueError:             return None, None, None     return None, None, None<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0445 \u044f \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u043b\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u0443 \u0436\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 <code>piexif<\/code>.<\/p>\n<pre><code class=\"python\">exif_dict[\"0th\"][piexif.ImageIFD.ImageDescription] = title exif_dict[\"0th\"][piexif.ImageIFD.XPKeywords] = (','.join(combined_tags)).encode('utf-16') exif_bytes = piexif.dump(exif_dict) piexif.insert(exif_bytes, image_path)<\/code><\/pre>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e \u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c, \u0447\u0442\u043e Shutterstock \u043d\u0435 \u0432\u0438\u0434\u0438\u0442 \u0442\u0435\u043a\u0441\u0442, \u0437\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u0432 <code>exif_dict[\"0th\"][piexif.ImageIFD.ImageDescription]<\/code>. \u0417\u0430\u043c\u0435\u043d\u0430 \u043d\u0430 <code>exif_dict[\"0th\"][piexif.ImageIFD.XPSubject]<\/code> \u043d\u0435 \u043f\u043e\u043c\u043e\u0433\u043b\u0430. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0442\u0435\u0433\u0438, \u0437\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0435 \u0432 <code>piexif.ImageIFD.XPKeywords<\/code>, \u043e\u0442\u043b\u0438\u0447\u043d\u043e \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u043b\u0438\u0441\u044c.<\/p>\n<p>\u0422\u043e\u0433\u0434\u0430 \u0432 \u0445\u043e\u0434 \u043f\u043e\u0448\u043b\u0430 \u0442\u044f\u0436\u0435\u043b\u0430\u044f \u0430\u0440\u0442\u0438\u043b\u043b\u0435\u0440\u0438\u044f \u2013 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442 IPTC, \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <a href=\"https:\/\/exiftool.org\" rel=\"noopener noreferrer nofollow\">ExifTool<\/a>.<\/p>\n<p>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c ExifTool \u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0430\u043c\u0438 \u041e\u0421 \u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043c \u0435\u0433\u043e \u0438\u0437 \u043d\u0430\u0448\u0435\u0433\u043e \u0441\u043a\u0440\u0438\u043f\u0442\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 <code>subprocess<\/code>:<\/p>\n<pre><code class=\"python\">def add_metadata(image_path: str, title, category, tags, month, day, year, country, city):     if category == \"editorial\" and country and city and day and month and year:         title = f\"{city}, {country} - {month}.{day}.{year}: \" + title      try:         commands = [             'C:\\\\Program Files\\\\exiftool\\\\exiftool.exe',             '-overwrite_original',             f'-Headline={title}',             f'-Keywords={\",\".join(tags)}'             image_path         ]          subprocess.run(commands, check=True)              except subprocess.CalledProcessError as e:         print(f\"\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0438 ExifTool \u0434\u043b\u044f \u0444\u0430\u0439\u043b\u0430 {image_path}: {e}\")     except Exception as e:         print(f\"\u041d\u0435\u043f\u0440\u0435\u0434\u0432\u0438\u0434\u0435\u043d\u043d\u0430\u044f \u043e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0444\u0430\u0439\u043b\u0430 {image_path}: {e}\")<\/code><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u043c\u044b \u0438\u043c\u0435\u0435\u043c \u0434\u0435\u043b\u043e \u0441 editorial \u0444\u0430\u0439\u043b\u043e\u043c, \u0442\u043e \u0441\u0440\u0430\u0437\u0443 \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u043c \u0435\u0433\u043e \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0435 \u0441 \u0444\u043e\u0440\u043c\u0430\u0442\u043e\u043c, \u043f\u0440\u0438\u043d\u044f\u0442\u044b\u043c \u043d\u0430 Shutterstock. \u0417\u0430\u0442\u0435\u043c \u0433\u043e\u0442\u043e\u0432\u0438\u043c \u043a\u043e\u043c\u0430\u043d\u0434\u0443 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0441\u0438 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f. \u041e\u043f\u044b\u0442\u043d\u044b\u043c \u043f\u0443\u0442\u0435\u043c \u044f \u0432\u044b\u044f\u0441\u043d\u0438\u043b\u0430, \u0447\u0442\u043e \u0434\u043b\u044f \u0441\u0442\u043e\u043a\u043e\u0432 \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 <code>-Headline<\/code>. \u0418\u043c\u0435\u044e\u0449\u0438\u0435\u0441\u044f \u0432 ExifTool \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b <code>-Title<\/code> \u0438 <code>-ImageDescription<\/code> \u0441\u0442\u043e\u043a\u0438 \u043d\u0435 \u0432\u0438\u0434\u044f\u0442.<\/p>\n<p>\u041d\u043e, \u043a\u0430\u043a \u0447\u0430\u0441\u0442\u043e \u0431\u044b\u0432\u0430\u0435\u0442, \u043a\u043e\u0433\u0434\u0430 \u0447\u0438\u043d\u0438\u0448\u044c \u043e\u0434\u043d\u043e \u2013 \u043b\u043e\u043c\u0430\u0435\u0442\u0441\u044f \u0434\u0440\u0443\u0433\u043e\u0435. \u0422\u0435\u0433\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u0442\u043b\u0438\u0447\u043d\u043e \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u043b\u0438\u0441\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>piexif<\/code>, \u043d\u0435 \u0432\u044b\u0434\u0435\u0440\u0436\u0430\u043b\u0438 \u0438\u0441\u043f\u044b\u0442\u0430\u043d\u0438\u044f ExifTool:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/2bf\/5c8\/6b5\/2bf5c86b51589845330c366a95de137c.png\" alt=\"\u0421\u0442\u0440\u043e\u043a\u0430, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0430\u044f \u0442\u0435\u0433\u0438, \u043e\u0431\u0440\u0435\u0437\u0430\u043b\u0430\u0441\u044c \u0434\u043e 64 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432\" title=\"\u0421\u0442\u0440\u043e\u043a\u0430, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0430\u044f \u0442\u0435\u0433\u0438, \u043e\u0431\u0440\u0435\u0437\u0430\u043b\u0430\u0441\u044c \u0434\u043e 64 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432\" width=\"1127\" height=\"504\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/2bf\/5c8\/6b5\/2bf5c86b51589845330c366a95de137c.png\"\/><\/p>\n<div><figcaption>\u0421\u0442\u0440\u043e\u043a\u0430, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0430\u044f \u0442\u0435\u0433\u0438, \u043e\u0431\u0440\u0435\u0437\u0430\u043b\u0430\u0441\u044c \u0434\u043e 64 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432<\/figcaption><\/div>\n<\/figure>\n<p>\u041f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0442\u0435\u0433\u0438 \u043f\u043e\u0448\u0442\u0443\u0447\u043d\u043e:<\/p>\n<pre><code class=\"python\">       commands = [             'C:\\\\Program Files\\\\exiftool\\\\exiftool.exe',             '-overwrite_original'             f'-Headline={title}'         ]         if tags:             for tag in tags:                 commands.append(f'-Keywords={tag}')          commands.append(image_path)<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043e\u0441\u0442\u0430\u0435\u0442\u0441\u044f \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0441\u043a\u0440\u0438\u043f\u0442 \u0438 \u043b\u044e\u0431\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u043c \u043f\u0440\u0438\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/aa9\/089\/537\/aa9089537aa7fecaa02877df7e0073eb.png\" alt=\"\u0421\u043c. \u043f\u0440\u0430\u0432\u0443\u044e \u043a\u043e\u043b\u043e\u043d\u043a\u0443\" title=\"\u0421\u043c. \u043f\u0440\u0430\u0432\u0443\u044e \u043a\u043e\u043b\u043e\u043d\u043a\u0443\" width=\"1029\" height=\"324\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/aa9\/089\/537\/aa9089537aa7fecaa02877df7e0073eb.png\"\/><\/p>\n<div><figcaption>\u0421\u043c. \u043f\u0440\u0430\u0432\u0443\u044e \u043a\u043e\u043b\u043e\u043d\u043a\u0443<\/figcaption><\/div>\n<\/figure>\n<h3>\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438<\/h3>\n<p>\u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043a\u0440\u0438\u043f\u0442\u0435 \u0435\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u043d\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0432\u0441\u0435\u0433\u0434\u0430 \u043d\u0443\u0436\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u043d\u0443 \u0438\u0437 \u043d\u0438\u0445. \u041c\u043e\u0436\u043d\u043e, \u043a\u043e\u043d\u0435\u0447\u043d\u043e, \u043f\u0435\u0440\u0435\u0434 \u043a\u0430\u0436\u0434\u044b\u043c \u0432\u044b\u0437\u043e\u0432\u043e\u043c \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u044b\u0437\u043e\u0432 \u043b\u0438\u0448\u043d\u0438\u0445, \u043d\u043e \u044d\u0442\u043e \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0434\u043e\u043b\u0433\u043e. \u0414\u043e\u0431\u0430\u0432\u0438\u043c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438, \u0447\u0442\u043e \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u0443\u0434\u043e\u0431\u043d\u043e, \u0435\u0441\u043b\u0438 \u0441\u043a\u0440\u0438\u043f\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043d\u0430 VPS.<\/p>\n<pre><code class=\"python\">import argparse  if __name__ == '__main__':     choices = {         'generate_tasks': generate_tasks,         'send_batch': send_batch,         'try_get_results': try_get_results,         'process_output': process_output     }     parser = argparse.ArgumentParser(description=\"\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0448\u0430\u0433\u043e\u0432.\")     parser.add_argument('-s', '--step', choices=choices.keys(),                         required=True, help=\"\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0448\u0430\u0433 \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438\")      args = parser.parse_args()      step_function = choices.get(args.step)     if step_function:         step_function()     else:         print(f\"\u041d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u0439 \u0448\u0430\u0433. \u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u043e\u0434\u043d\u043e \u0438\u0437 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 {', '.join(choices.keys())}\")<\/code><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438 <code>-s<\/code> (<code>--step<\/code>) \u0441\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u043c\u0438, \u043e\u0434\u043d\u043e\u0438\u043c\u0435\u043d\u043d\u044b\u043c\u0438 \u043d\u0430\u0448\u0438\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c. \u041f\u0440\u0430\u0432\u0434\u0430, \u0437\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0432\u044b\u0432\u043e\u0434\u0430 \u0443 \u043d\u0430\u0441 \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0442 \u0441\u0440\u0430\u0437\u0443 \u0434\u0432\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0434\u043b\u044f \u043d\u0438\u0445 \u043e\u0431\u0435\u0440\u0442\u043a\u0443:<\/p>\n<pre><code class=\"python\">def process_output():     load_batch_output(tasks_path, results_path)     process_directory(photo_dir)<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0441\u043a\u0440\u0438\u043f\u0442, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0438\u043d\u0442\u0443\u0438\u0442\u0438\u0432\u043d\u043e \u043f\u043e\u043d\u044f\u0442\u043d\u044b\u0435 <s>\u0442\u043e\u043c\u0443, \u043a\u0442\u043e \u043f\u0440\u043e\u0447\u0435\u043b \u0441\u0442\u0430\u0442\u044c\u044e \u0432\u043d\u0438\u043c\u0430\u0442\u0435\u043b\u044c\u043d\u043e,<\/s> \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430 <code>-s<\/code>:<\/p>\n<pre><code class=\"bash\">main.py -s generate_tasks main.py -s process_output \u2026<\/code><\/pre>\n<p>\u0410 \u0447\u0442\u043e \u0435\u0441\u043b\u0438 \u043c\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e, \u0438\u0437 IDE? \u0412 PyCharm \u043d\u0430\u043c \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0439 \u0437\u0430\u043f\u0443\u0441\u043a\u0430.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/7e0\/b6d\/6f2\/7e0b6d6f20dda9318d4141dba213590a.png\" alt=\"\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0439\" title=\"\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0439\" width=\"364\" height=\"475\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/7e0\/b6d\/6f2\/7e0b6d6f20dda9318d4141dba213590a.png\"\/><\/p>\n<div><figcaption>\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0439<\/figcaption><\/div>\n<\/figure>\n<p>\u0417\u0430\u0445\u043e\u0434\u0438\u043c \u0432 \u043c\u0435\u043d\u044e <code>Run -&gt; Edit Configurations\u2026<\/code>, \u043d\u0430\u0436\u0438\u043c\u0430\u0435\u043c \u043d\u0430 \u0437\u043d\u0430\u043a \u00ab<code>+<\/code>\u00bb, \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043f\u0443\u0442\u044c \u043a \u0441\u043a\u0440\u0438\u043f\u0442\u0443 <code>main.py<\/code> \u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b: <code>-s generate_tasks<\/code>. \u041f\u043e\u0432\u0442\u043e\u0440\u044f\u0435\u043c \u0434\u043b\u044f \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0438\u0437 \u0441\u043f\u0438\u0441\u043a\u0430 <code>choices<\/code>.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u043b\u044e\u0431\u0443\u044e \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e \u0449\u0435\u043b\u0447\u043a\u043e\u043c \u043c\u044b\u0448\u0438.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/470\/d1d\/eaa\/470d1deaa0675716314766aba184c2a6.png\" alt=\"\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e \u043d\u0430\u0436\u0430\u0442\u0438\u0435\u043c \u043d\u0430 \u0437\u0435\u043b\u0435\u043d\u044b\u0439 \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\" title=\"\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e \u043d\u0430\u0436\u0430\u0442\u0438\u0435\u043c \u043d\u0430 \u0437\u0435\u043b\u0435\u043d\u044b\u0439 \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\" width=\"1366\" height=\"279\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/470\/d1d\/eaa\/470d1deaa0675716314766aba184c2a6.png\"\/><\/p>\n<div><figcaption>\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e \u043d\u0430\u0436\u0430\u0442\u0438\u0435\u043c \u043d\u0430 \u0437\u0435\u043b\u0435\u043d\u044b\u0439 \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a<\/figcaption><\/div>\n<\/figure>\n<h3>\u0414\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0430\u044f \u0440\u0430\u0431\u043e\u0442\u0430<\/h3>\n<p>\u042d\u0442\u043e\u0433\u043e \u0441\u043a\u0440\u0438\u043f\u0442\u0430 \u043c\u043d\u0435 \u0432\u043f\u043e\u043b\u043d\u0435 \u0445\u0432\u0430\u0442\u0438\u043b\u043e \u0434\u043b\u044f \u043f\u0440\u043e\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u0432\u043e\u0435\u0433\u043e \u0444\u043e\u0442\u043e\u0430\u0440\u0445\u0438\u0432\u0430 \u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0442\u044b\u0441\u044f\u0447 \u0444\u043e\u0442\u043e, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u043d\u0435\u043c\u043d\u043e\u0433\u0443 \u043d\u0430\u0447\u0430\u043b\u0438 \u043f\u0435\u0440\u0435\u0435\u0437\u0436\u0430\u0442\u044c \u043d\u0430 \u0441\u0442\u043e\u043a\u0438. \u0417\u0430 \u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u043d\u0430\u0434 \u0441\u0442\u0430\u0442\u044c\u0435\u0439 \u0443\u0436\u0435 \u0434\u0430\u0436\u0435 \u043a\u0430\u043f\u043d\u0443\u043b\u0430 \u043f\u0435\u0440\u0432\u0430\u044f \u043f\u0440\u043e\u0434\u0430\u0436\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0437\u0430 \u0442\u0440\u0430\u0434\u0438\u0446\u0438\u043e\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u0428\u0430\u0442\u0442\u0435\u0440\u0441\u0442\u043e\u043a\u0430 10 \u0446\u0435\u043d\u0442\u043e\u0432 \ud83d\ude0a<\/p>\n<p><a href=\"https:\/\/github.com\/AstFreelancer\/shutterstock\" rel=\"noopener noreferrer nofollow\">\u041f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 \u0441\u043a\u0440\u0438\u043f\u0442\u0430<\/a> \u043b\u0435\u0436\u0438\u0442 \u043d\u0430 \u0413\u0438\u0442\u0445\u0430\u0431. <\/p>\n<p>\u0427\u0442\u043e \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043b\u043e \u0431\u044b \u0434\u043e\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0432 \u0441\u043a\u0440\u0438\u043f\u0442\u0435?<\/p>\n<ol>\n<li>\n<p>\u0422\u043e\u043a\u0435\u043d\u0438\u0437\u0430\u0442\u043e\u0440 \u0438 \u0440\u0430\u0437\u0431\u0438\u0435\u043d\u0438\u0435 \u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u043f\u0430\u043a\u0435\u0442\u043e\u0432 \u0437\u0430\u0434\u0430\u043d\u0438\u0439 \u043d\u0430 \u0431\u043e\u043b\u0435\u0435 \u043c\u0435\u043b\u043a\u0438\u0435, \u0447\u0442\u043e\u0431\u044b \u0443\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u043b\u0438\u043c\u0438\u0442.<\/p>\n<\/li>\n<li>\n<p>\u0427\u0442\u0435\u043d\u0438\u0435 GPS \u0438\u0437 EXIF \u0438 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043d\u0430\u0441\u0435\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u043f\u0443\u043d\u043a\u0442\u0430, \u0433\u0434\u0435 \u0441\u043d\u044f\u0442\u043e \u0444\u043e\u0442\u043e.<\/p>\n<\/li>\n<li>\n<p>\u041a\u043b\u0430\u0441\u0441\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u0444\u043e\u0442\u043e \u043d\u0430 commercial \u0438 editorial \u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0430\u043c\u0438 \u043e\u043f\u044f\u0442\u044c \u0436\u0435 \u043d\u0435\u0439\u0440\u043e\u0441\u0435\u0442\u0438.<\/p>\n<\/li>\n<li>\n<p>\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0440\u0435\u0441\u0430\u0439\u0437 \u0444\u043e\u0442\u043e \u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u043d\u044b\u0445 \u043a\u043e\u043f\u0438\u0439 \u043d\u0430 \u0445\u043e\u0441\u0442\u0438\u043d\u0433.<\/p>\n<\/li>\n<\/ol>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/871418\/\"> https:\/\/habr.com\/ru\/articles\/871418\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h2>\u041a\u043b\u044e\u0447\u0435\u0432\u0430\u043d\u0438\u0435 \u0441\u0442\u043e\u043a\u043e\u0432\u044b\u0445 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Batch API \u043e\u0442 OpenAI<\/h2>\n<p>\u0410\u0442\u0440\u0438\u0431\u0443\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u2013 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u044d\u0442\u0430\u043f \u0438\u0445 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0438 \u0434\u043b\u044f \u043f\u0440\u043e\u0434\u0430\u0436\u0438 \u043d\u0430 \u0444\u043e\u0442\u043e\u0441\u0442\u043e\u043a\u0430\u0445. \u0423 \u043a\u0430\u0436\u0434\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b (\u0444\u043e\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u0438 \u0438\u043b\u0438 \u0438\u043b\u043b\u044e\u0441\u0442\u0440\u0430\u0446\u0438\u0438) \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435, \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435, \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0435 \u0441\u043b\u043e\u0432\u0430, \u0438 \u0432\u0441\u0435 \u044d\u0442\u043e \u043d\u0430 \u0430\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u043e\u043c.<\/p>\n<p>\u0421 \u043a\u043b\u044e\u0447\u0435\u0432\u0430\u043d\u0438\u0435\u043c \u043d\u0435\u043f\u043b\u043e\u0445\u043e \u0441\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f ChatGPT. \u041d\u043e \u043f\u0435\u0440\u0435\u0441\u044b\u043b\u0430\u0442\u044c \u0435\u043c\u0443 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0438 \u043f\u043e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438, \u0430 \u043f\u043e\u0442\u043e\u043c \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b \u0432\u0440\u0443\u0447\u043d\u0443\u044e \u2013 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0434\u043e\u043b\u0433\u043e. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u044d\u0442\u043e\u0442 \u043f\u0440\u043e\u0446\u0435\u0441\u0441.<\/p>\n<h3>\u0418\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439<\/h3>\n<p>\u041d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f:<\/p>\n<ol>\n<li>\n<p>PyCharm \u0438\u043b\u0438 \u0434\u0440\u0443\u0433\u0430\u044f IDE \u0434\u043b\u044f Python.<\/p>\n<\/li>\n<li>\n<p>API-\u043a\u043b\u044e\u0447 \u043e\u0442 OpenAI \u0438 \u043f\u0430\u0440\u0430 \u0434\u043e\u043b\u043b\u0430\u0440\u043e\u0432 \u043d\u0430 \u0431\u0430\u043b\u0430\u043d\u0441\u0435.<\/p>\n<\/li>\n<li>\n<p>\u041f\u0430\u0440\u0430 \u0433\u0438\u0433\u0430\u0431\u0430\u0439\u0442 \u043d\u0430 \u043a\u0430\u043a\u043e\u043c-\u043d\u0438\u0431\u0443\u0434\u044c \u0445\u043e\u0441\u0442\u0438\u043d\u0433\u0435.<\/p>\n<\/li>\n<\/ol>\n<p>\u041e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e:<\/p>\n<ol start=\"4\">\n<li>\n<p>\u0414\u043e\u0441\u0442\u0443\u043f \u043a \u0432\u0435\u0431-\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0443 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 OpenAI.<\/p>\n<\/li>\n<li>\n<p>VPS \u0437\u0430 \u043f\u0440\u0435\u0434\u0435\u043b\u0430\u043c\u0438 \u0420\u0424.<\/p>\n<\/li>\n<\/ol>\n<h3>\u041f\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0437\u0430\u0434\u0430\u0447\u0438<\/h3>\n<p>\u042f \u0431\u0443\u0434\u0443 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0432\u043e\u0439 \u0444\u043e\u0442\u043e\u0430\u0440\u0445\u0438\u0432, \u043e\u0442\u0441\u043d\u044f\u0442\u044b\u0439 \u0432 \u043e\u0442\u043f\u0443\u0441\u043a\u0430\u0445 \u0440\u0430\u0437\u043d\u044b\u0445 \u043b\u0435\u0442. \u041d\u0430 \u044f\u0437\u044b\u043a\u0435 \u0441\u0442\u043e\u043a\u0435\u0440\u043e\u0432 \u2013 \u0442\u0440\u0435\u0432\u0435\u043b-\u0444\u043e\u0442\u043e. \u0424\u0430\u0439\u043b\u044b \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u044b \u043f\u043e \u0441\u0442\u0440\u0430\u043d\u0430\u043c \u0438 \u0433\u043e\u0440\u043e\u0434\u0430\u043c, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u044b \u043d\u0430 \u043a\u043e\u043c\u043c\u0435\u0440\u0447\u0435\u0441\u043a\u0438\u0435 \u0438 \u0442\u0430\u043a \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0435 editorial (\u0441 \u043b\u044e\u0434\u044c\u043c\u0438 \u0438\u043b\u0438 \u0443\u0437\u043d\u0430\u0432\u0430\u0435\u043c\u044b\u043c\u0438 \u0434\u043e\u0441\u0442\u043e\u043f\u0440\u0438\u043c\u0435\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044f\u043c\u0438). \u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043f\u0430\u043f\u043e\u043a \u0432\u043e\u0442 \u0442\u0430\u043a\u0430\u044f:<\/p>\n<p><code>photo<\/code><\/p>\n<p><code>\u251c\u2500\u2500 Russia<\/code><\/p>\n<p><code>\u2502\u00a0\u00a0 \u2514\u2500\u2500 Ruskeala<\/code><\/p>\n<p><code>\u2502\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u251c\u2500\u2500 editorial<\/code><\/p>\n<p><code>\u2502\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u2514\u2500\u2500 commercial<\/code><\/p>\n<p><code>\u2514\u2500\u2500 Turkey<\/code><\/p>\n<p><code>\u00a0\u00a0\u00a0 \u2514\u2500\u2500 Istanbul<\/code><\/p>\n<p><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u251c\u2500\u2500 editorial<\/code><\/p>\n<p><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u2514\u2500\u2500 commercial<\/code><\/p>\n<p>\u0414\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430 \u0432 \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0445 \u043f\u0430\u043f\u043a\u0430\u0445 editoral\/commercial, \u044f\u0432\u043b\u044f\u044e\u0449\u0435\u0433\u043e\u0441\u044f \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435\u043c, \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u0434\u043e\u0431\u0440\u0430\u0442\u044c \u0438 \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0432 EXIF \u0435\u0433\u043e \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043d\u0430 \u0430\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u043e\u043c \u044f\u0437\u044b\u043a\u0435 \u0434\u043b\u0438\u043d\u043e\u0439 \u043d\u0435 \u0431\u043e\u043b\u0435\u0435 200 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432, \u0430 \u0442\u0430\u043a\u0436\u0435 50 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0445 \u0441\u043b\u043e\u0432. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0434\u043b\u044f \u0444\u0430\u0439\u043b\u043e\u0432 \u0438\u0437 \u043f\u0430\u043f\u043e\u043a editorial \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0438\u043c\u0435\u0435\u0442 \u0444\u043e\u0440\u043c\u0430\u0442<\/p>\n<p><code>City, Country - Month Day Year: Description<\/code><\/p>\n<p>\u0414\u043b\u044f \u043a\u043e\u043c\u043c\u0435\u0440\u0447\u0435\u0441\u043a\u0438\u0445 \u0444\u043e\u0442\u043e \u0442\u0430\u043a\u0438\u0445 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u0439 \u043d\u0435\u0442, \u043d\u043e \u0436\u0435\u043b\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0433\u043e\u0440\u043e\u0434\u0430 \u0438 \u0441\u0442\u0440\u0430\u043d\u044b \u0432 \u0441\u043f\u0438\u0441\u043a\u0435 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0445 \u0441\u043b\u043e\u0432.<\/p>\n<p>\u0412\u043e\u0442 \u043f\u043b\u0430\u043d \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438:<\/p>\n<ol>\n<li>\n<p>\u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043f\u0430\u043a\u0435\u0442\u0430 \u0437\u0430\u0434\u0430\u043d\u0438\u0439 \u0434\u043b\u044f \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b OpenAI.<\/p>\n<\/li>\n<li>\n<p>\u041e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u043f\u0430\u043a\u0435\u0442\u0430 \u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432.<\/p>\n<\/li>\n<li>\n<p>\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u0438 \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439.<\/p>\n<\/li>\n<\/ol>\n<h3>\u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043f\u0430\u043a\u0435\u0442\u0430 \u0437\u0430\u0434\u0430\u043d\u0438\u0439<\/h3>\n<p>\u041c\u044b \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u043f\u0435\u0440\u0435\u0441\u044b\u043b\u0430\u0442\u044c \u043d\u0435\u0439\u0440\u043e\u0441\u0435\u0442\u0438 \u043a\u0430\u0436\u0434\u043e\u0435 \u0444\u043e\u0442\u043e \u043f\u043e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438. \u0412\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c Batch API. \u0417\u0430\u043f\u0440\u043e\u0441\u044b \u0431\u0443\u0434\u0443\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u044b \u043d\u0435 \u0441\u0440\u0430\u0437\u0443, \u0430 \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 \u0441\u0443\u0442\u043e\u043a, \u0437\u0430\u0442\u043e \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043c 50%-\u043d\u0443\u044e \u0441\u043a\u0438\u0434\u043a\u0443 \u043d\u0430 \u0434\u0438\u0430\u043b\u043e\u0433 \u0441 ChatGPT.<\/p>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u043c\u0441\u044f \u043a \u0432\u0435\u0440\u0441\u0438\u0438 gpt-4o-mini, \u0442\u0430\u043a \u043a\u0430\u043a \u043e\u043d\u0430 \u0438\u043c\u0435\u0435\u0442 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0434\u0435\u043c\u043e\u043a\u0440\u0430\u0442\u0438\u0447\u043d\u044b\u0435 \u043b\u0438\u043c\u0438\u0442\u044b \u0441\u0440\u0430\u0432\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0441 gpt-4o. \u0412\u043e\u0442, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <a href=\"https:\/\/platform.openai.com\/docs\/guides\/rate-limits?context=tier-one\" rel=\"noopener noreferrer nofollow\">\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f <\/a>\u0434\u043b\u044f \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u043e\u0432 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f (\u043c\u0435\u043d\u0435\u0435 50 \u0434\u043e\u043b\u043b\u0430\u0440\u043e\u0432 \u0438\u0437\u0440\u0430\u0441\u0445\u043e\u0434\u043e\u0432\u0430\u043d\u043e \u0437\u0430 \u0432\u0440\u0435\u043c\u044f \u0436\u0438\u0437\u043d\u0438 \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u0430).<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td>\n<p align=\"left\"><strong>\u041c\u043e\u0434\u0435\u043b\u044c<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u0417\u0430\u043f\u0440\u043e\u0441\u044b    \u0432 \u043c\u0438\u043d\u0443\u0442\u0443<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u0417\u0430\u043f\u0440\u043e\u0441\u044b    \u0432 \u0434\u0435\u043d\u044c<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u0422\u043e\u043a\u0435\u043d\u044b    \u0432 \u043c\u0438\u043d\u0443\u0442\u0443<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u041b\u0438\u043c\u0438\u0442    \u043f\u0430\u043a\u0435\u0442\u043d\u043e\u0439 \u043e\u0447\u0435\u0440\u0435\u0434\u0438<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">gpt-4o<\/p>\n<\/td>\n<td>\n<p align=\"left\">500<\/p>\n<\/td>\n<td>\n<p align=\"left\">&#8212;<\/p>\n<\/td>\n<td>\n<p align=\"left\">30,000<\/p>\n<\/td>\n<td>\n<p align=\"left\">90,000<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">gpt-4o-mini<\/p>\n<\/td>\n<td>\n<p align=\"left\">500<\/p>\n<\/td>\n<td>\n<p align=\"left\">10,000<\/p>\n<\/td>\n<td>\n<p align=\"left\">200,000<\/p>\n<\/td>\n<td>\n<p align=\"left\">2,000,000<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u041a\u0430\u043a \u0432\u0438\u0434\u0438\u043c, \u0441 \u0432\u0435\u0440\u0441\u0438\u0435\u0439 gpt-4o-mini \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u043f\u0430\u043a\u0435\u0442\u044b \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u043c \u0434\u043e 200 \u0442\u044b\u0441. \u0442\u043e\u043a\u0435\u043d\u043e\u0432.<\/p>\n<p>\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u043c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043d\u0430\u0448\u0435\u0433\u043e \u0441\u043a\u0440\u0438\u043f\u0442\u0430 \u0432 \u0432\u0438\u0434\u0435 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0445 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445:<\/p>\n<pre><code class=\"python\">valid_extensions = ('.jpg', '.jpeg')  api_key = '\u0412\u0410\u0428_\u041a\u041b\u042e\u0427'  your_site = 'http:\/\/\u0412\u0410\u0428_\u0421\u0410\u0419\u0422\/' photo_dir = 'C:\\\\\u041f\u0423\u0422\u042c\\\\\u041a\\\\\u0424\u041e\u0422\u041e' tasks_path = \"batch_tasks.jsonl\" results_path = \"batch_tasks_output.jsonl\" job_id_path = \"batch_job_id.txt\"  description_length = 200 keywords_count = 50 prompt = f\"Please create a description no more than {description_length} characters long for this image in stock style \" \\          f\"and a list of {keywords_count} popular single-word keywords, separated with commas. \" \\          f\"Tailor the description to a specific niche and target audience. \"\\          f\"Your keywords are to enhance searchability within that niche.\" \\          f\"If there are architectural decoration elements in the image, be sure to include them. \" \\          f\"If there are inscriptions in a language other than English in the photo, include their translation in the description. \" \\          f\"Be sure to separate the description from the list of keywords with a newline character. \" \\          f\"Don't write anything except a description and a list of keywords. \" \\          f\"If there are any plants in the picture, identify their names and weave them into the description and the keywords list. \" \\          f\"Ensure no word is repeated. Be sure to include in both the description and in the keywords list the next words: \"  batch_output_map = {}<\/code><\/pre>\n<p>\u041d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 \u043f\u043e\u043d\u044f\u0442\u043d\u043e \u0438\u0437 \u0435\u0433\u043e \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f. \u042f \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u044e\u0441\u044c \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u043f\u0440\u043e\u043c\u043f\u0442\u0435 \u2013 \u0441\u0435\u0440\u0434\u0446\u0435 \u043d\u0430\u0448\u0435\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b. \u041e\u043d \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u0444\u043e\u043a\u0443\u0441\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0439 \u043d\u0438\u0448\u0435, \u0442\u043e \u0435\u0441\u0442\u044c \u0441\u0442\u043e\u043a\u043e\u0432\u043e\u0439 \u0442\u0435\u043c\u0430\u0442\u0438\u043a\u0435, \u0447\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043f\u043e\u0432\u044b\u0441\u0438\u0442\u044c SEO-\u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440\u0438\u0441\u0442\u0438\u043a\u0438 \u0441\u0442\u043e\u043a\u043e\u0432\u043e\u0433\u043e \u043f\u043e\u0440\u0442\u0444\u0435\u043b\u044f. \u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043c\u044b \u043e\u0436\u0438\u0434\u0430\u0435\u043c \u0432 \u0432\u0438\u0434\u0435 \u0434\u0432\u0443\u0445 \u0430\u0431\u0437\u0430\u0446\u0435\u0432 \u0442\u0435\u043a\u0441\u0442\u0430 \u2013 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0438 \u0441\u043f\u0438\u0441\u043e\u043a \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0445 \u0441\u043b\u043e\u0432. \u041d\u0430\u043c \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u043a \u043f\u0440\u043e\u043c\u043f\u0442\u0443 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0435 \u0441\u043b\u043e\u0432\u0430, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u043d \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0439 \u0444\u0440\u0430\u0437\u043e\u0439 \u0438 \u0434\u0432\u043e\u0435\u0442\u043e\u0447\u0438\u0435\u043c.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043f\u0430\u043a\u0435\u0442 \u0437\u0430\u0434\u0430\u043d\u0438\u0439:<\/p>\n<pre><code class=\"python\">from urllib.parse import quote  def generate_tasks():     with open(tasks_path, 'w') as file:         task_index = 0         for root, dirs, files in os.walk(photo_dir):             path_parts = root.split(os.sep)             # \u0415\u0441\u043b\u0438 \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0442\u0440\u0438 \u0443\u0440\u043e\u0432\u043d\u044f \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0439 \u0438 \u043c\u044b \u043d\u0430\u0445\u043e\u0434\u0438\u043c\u0441\u044f \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 \u0438\u0437 \u043d\u0438\u0445             if len(path_parts) &gt;= 3 and path_parts[-1] in {'editorial', 'commercial'}:                 for filename in files:                     if not filename.lower().endswith(valid_extensions):                         continue                     file_path = os.path.relpath(os.path.join(root, filename), photo_dir).replace('\\\\', '\/')                     image_url = f\"{your_site}photo\/{file_path}\"                     image_url = quote(image_url, safe=':\/')                      path_parts = re.split(r'[\\\\\/]', file_path)                     country, city = path_parts[0], path_parts[1] if len(path_parts) &gt; 1 else (None, None)                      new_prompt = f\"{prompt} {country}, {city}\" if country and city else prompt                      task = {                         \"custom_id\": f\"task-{task_index}\",                         \"method\": \"POST\",                         \"url\": \"\/v1\/chat\/completions\",                         \"body\": {                             \"model\": \"gpt-4o-mini\",                             \"messages\": [                                 {                                     \"role\": \"system\",                                     \"content\": new_prompt                                 },                                 {                                     \"role\": \"user\",                                     \"content\": [                                         {                                             \"type\": \"image_url\",                                             \"image_url\": {                                                 \"url\": image_url                                             }                                         },                                     ],                                 }                             ]                         }                     }                      file.write(json.dumps(task) + '\\n')                     print(f\"\u0414\u043e\u0431\u0430\u0432\u0438\u043b\u0438 \u0437\u0430\u0434\u0430\u043d\u0438\u0435: {image_url}\")                     task_index += 1<\/code><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u043c\u044b \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u043c \u043f\u043e \u0434\u0435\u0440\u0435\u0432\u0443 \u043f\u0430\u043f\u043e\u043a, \u043d\u0430\u0447\u0438\u043d\u0430\u044f \u0441 <code>photo_dir<\/code>, \u0438 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430 <code>\u2026\/editorial\/*.jp(e)g<\/code> \u0438\u043b\u0438 <code>\u2026\/commercial\/*.jp(e)g<\/code> \u0432\u044b\u0434\u0435\u043b\u044f\u0435\u043c \u0438\u0437 \u043f\u0443\u0442\u0438 \u043a \u043d\u0435\u043c\u0443 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0441\u0442\u0440\u0430\u043d\u044b \u0438 \u0433\u043e\u0440\u043e\u0434\u0430, \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u044d\u0442\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043a \u043f\u0440\u043e\u043c\u043f\u0442\u0443 \u0438 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0437\u0430\u0434\u0430\u043d\u0438\u0435 \u0432 \u0432\u0438\u0434\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 JSON. \u0423 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0437\u0430\u0434\u0430\u043d\u0438\u044f \u0435\u0441\u0442\u044c \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u043f\u0430\u043a\u0435\u0442\u0430 <code>custom_id<\/code>, \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043c\u044b \u043f\u043e\u0442\u043e\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c \u0438\u043c\u044f \u0444\u0430\u0439\u043b\u0430. \u0422\u0435\u043b\u043e \u0437\u0430\u0434\u0430\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u0434\u0432\u0443\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u2013 \u043f\u0440\u043e\u043c\u043f\u0442\u0430 \u0438 URL \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0438 \u043d\u0430 \u0445\u043e\u0441\u0442\u0438\u043d\u0433\u0435.<\/p>\n<p>\u041f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u0444\u0430\u0439\u043b\u044b \u043b\u0435\u0436\u0430\u0442 \u043d\u0430 \u0432\u0430\u0448\u0435\u043c \u0445\u043e\u0441\u0442\u0438\u043d\u0433\u0435 \u0432 \u043f\u0430\u043f\u043a\u0435 <code>photo<\/code>. \u041f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c URL \u0447\u0435\u0440\u0435\u0437 \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>quote()<\/code> \u043d\u0430 \u0441\u043b\u0443\u0447\u0430\u0439, \u0435\u0441\u043b\u0438 \u0438\u043c\u044f \u0444\u0430\u0439\u043b\u0430 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0437\u0430\u0440\u0435\u0437\u0435\u0440\u0432\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0441\u0438\u043c\u0432\u043e\u043b\u044b. <a href=\"https:\/\/en.wikipedia.org\/wiki\/Percent-encoding\" rel=\"noopener noreferrer nofollow\">\u041f\u0440\u043e\u0446\u0435\u043d\u0442\u043d\u0430\u044f \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0430<\/a> \u0437\u0430\u043c\u0435\u043d\u0438\u0442 \u0438\u0445 \u043d\u0430 \u0437\u043d\u0430\u043a \u043f\u0440\u043e\u0446\u0435\u043d\u0442\u0430 \u0438 \u043d\u043e\u043c\u0435\u0440. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u0440\u043e\u0431\u0435\u043b \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u0442\u0441\u044f \u0432 <code>%20<\/code>.<\/p>\n<p>\u041a\u0430\u0436\u0434\u043e\u0435 \u0437\u0430\u0434\u0430\u043d\u0438\u0435 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u0444\u0430\u0439\u043b <code>tasks_path<\/code> \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u043e\u0439. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0444\u0430\u0439\u043b \u0438 \u0438\u043c\u0435\u0435\u0442 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 .jsonl (JSON Lines).<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u041f\u0430\u043a\u0435\u0442 \u0437\u0430\u0434\u0430\u043d\u0438\u0439<\/figcaption><\/div>\n<\/figure>\n<p>\u041d\u0443\u0436\u043d\u043e \u0441\u043b\u0435\u0434\u0438\u0442\u044c \u0437\u0430 \u043e\u0431\u044a\u0435\u043c\u043e\u043c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430, \u0442\u0430\u043a \u043a\u0430\u043a \u0435\u0441\u0442\u044c \u0440\u0438\u0441\u043a \u043f\u0440\u0435\u0432\u044b\u0441\u0438\u0442\u044c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0442\u043e\u043a\u0435\u043d\u043e\u0432 \u0432 \u043e\u0434\u043d\u043e\u043c \u043f\u0430\u043a\u0435\u0442\u0435. \u041a\u0430\u043a \u0443\u0436\u0435 \u0433\u043e\u0432\u043e\u0440\u0438\u043b\u043e\u0441\u044c, \u0434\u043b\u044f \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u043e\u0432 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f \u0438 \u0432\u0435\u0440\u0441\u0438\u0438 gpt-4o-mini \u043f\u0430\u043a\u0435\u0442 \u043d\u0435 \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u0440\u0435\u0432\u044b\u0448\u0430\u0442\u044c 200 \u0442\u044b\u0441. \u0442\u043e\u043a\u0435\u043d\u043e\u0432. \u0427\u0442\u043e\u0431\u044b \u0441\u043b\u0435\u0434\u0438\u0442\u044c \u0437\u0430 \u043b\u0438\u043c\u0438\u0442\u043e\u043c, \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <a href=\"https:\/\/quizgecko.com\/tools\/token-counter\" rel=\"noopener noreferrer nofollow\">\u0442\u043e\u043a\u0435\u043d\u0438\u0437\u0430\u0442\u043e\u0440<\/a>. \u041f\u043e \u043e\u043f\u044b\u0442\u0443, \u043f\u0440\u0438 \u043f\u0440\u043e\u043c\u043f\u0442\u0435 \u0442\u0430\u043a\u043e\u0439 \u0434\u043b\u0438\u043d\u044b \u0432 \u043b\u0438\u043c\u0438\u0442 \u0443\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0434\u043e 800 \u0441\u0442\u0440\u043e\u043a=JSON-\u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432.<\/p>\n<h3>\u041e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u043f\u0430\u043a\u0435\u0442\u0430 \u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432<\/h3>\n<p>\u041e\u0442\u043f\u0440\u0430\u0432\u0438\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0432\u0448\u0438\u0439\u0441\u044f \u0444\u0430\u0439\u043b \u043d\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443.<\/p>\n<pre><code class=\"python\">from openai import OpenAI  def send_batch():     client = OpenAI(         api_key=api_key     )      batch_file = client.files.create(         file=open(tasks_path, \"rb\"),         purpose=\"batch\"     )     batch_job = client.batches.create(         input_file_id=batch_file.id,         endpoint=\"\/v1\/chat\/completions\",         completion_window=\"24h\"     )     print(f\"\u0421\u043e\u0437\u0434\u0430\u043b\u0438 \u043f\u0430\u043a\u0435\u0442\u043d\u043e\u0435 \u0437\u0430\u0434\u0430\u043d\u0438\u0435 \u0441 ID {batch_job.id}\")      with open(job_id_path, 'w') as f:         f.write(batch_job.id)      return batch_job.id<\/code><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c \u0444\u0430\u0439\u043b \u0441 \u0437\u0430\u0434\u0430\u043d\u0438\u044f\u043c \u0432 \u0441\u0432\u043e\u0435 <a href=\"https:\/\/platform.openai.com\/storage\/files\" rel=\"noopener noreferrer nofollow\">\u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435<\/a>, \u0443\u043a\u0430\u0437\u0430\u0432 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 <code>purpose=\"batch\"<\/code>. \u0424\u0430\u0439\u043b\u0443 \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 ID, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0437\u0430\u0442\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043f\u0430\u043a\u0435\u0442\u043d\u043e\u0433\u043e \u0437\u0430\u0434\u0430\u043d\u0438\u044f. \u0417\u0430\u0434\u0430\u043d\u0438\u0435 \u0442\u043e\u0436\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442 \u0441\u0432\u043e\u0439 ID, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u043d\u0430 \u0432\u0441\u044f\u043a\u0438\u0439 \u0441\u043b\u0443\u0447\u0430\u0439 \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u043c \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0444\u0430\u0439\u043b, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u043f\u043e\u0442\u0435\u0440\u044f\u0442\u044c, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0432\u0435\u0440\u043d\u0435\u043c \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0432\u044b\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438.<\/p>\n<p>\u041f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442:<\/p>\n<pre><code class=\"python\">def try_get_results():     client = OpenAI(         api_key=api_key     )      with open(job_id_path, 'r') as f:         batch_job_id = f.read().strip()      batch_job = client.batches.retrieve(batch_job_id)     print(f\"\u0421\u0442\u0430\u0442\u0443\u0441 \u043f\u0430\u043a\u0435\u0442\u043d\u043e\u0433\u043e \u0437\u0430\u0434\u0430\u043d\u0438\u044f: {batch_job.status}\")     if batch_job.status == 'completed':         result = client.files.content(batch_job.output_file_id).content         with open(results_path, 'wb') as file:             file.write(result)         print(f\"\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u044b \u0432 \u0444\u0430\u0439\u043b {results_path}\")     else:         print(batch_job)<\/code><\/pre>\n<p>\u0412\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0432 ID \u0437\u0430\u0434\u0430\u043d\u0438\u044f, \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0435\u0433\u043e \u0441\u0442\u0430\u0442\u0443\u0441 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>retrieve()<\/code>. \u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u0443\u0441\u043f\u0435\u0445\u0430 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432 \u0444\u0430\u0439\u043b <code>results_path<\/code>.<\/p>\n<p>\u0422\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435 \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0432\u0435\u0431-\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430, \u0433\u0434\u0435 \u0443\u0434\u043e\u0431\u043d\u043e \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0441 \u043f\u0430\u043a\u0435\u0442\u0430\u043c\u0438.<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u041c\u043e\u0438 \u043f\u0430\u043a\u0435\u0442\u044b \u0437\u0430\u0434\u0430\u043d\u0438\u0439<\/figcaption><\/div>\n<\/figure>\n<h3>\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0445 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432<\/h3>\n<p>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u0432 \u0442\u043e\u043c \u0436\u0435 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 JSON Lines.<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043f\u0430\u043a\u0435\u0442\u0430<\/figcaption><\/div>\n<\/figure>\n<p>\u041e\u0442\u0432\u0435\u0442 \u043d\u0430 \u043a\u0430\u0436\u0434\u043e\u0435 \u0437\u0430\u0434\u0430\u043d\u0438\u0435 \u0437\u0430\u043f\u0438\u0441\u0430\u043d \u0432 \u0432\u0438\u0434\u0435 JSON-\u043e\u0431\u044a\u0435\u043a\u0442\u0430:<\/p>\n<pre><code class=\"json\">{   \"id\": \"batch_req_6771\u2026\",   \"custom_id\": \"task-0\",   \"response\": {     \"status_code\": 200,     \"request_id\": \"b247\u2026\",     \"body\": {       \"id\": \"chatcmpl-Ajt\u2026\",       \"object\": \"chat.completion\",       \"created\": 1735500227,       \"model\": \"gpt-4o-mini-2024-07-18\",<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-444057","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/444057","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=444057"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/444057\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=444057"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=444057"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=444057"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}