{"id":489488,"date":"2026-08-03T06:44:50","date_gmt":"2026-08-03T06:44:50","guid":{"rendered":"https:\/\/savepearlharbor.com\/?p=489488"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=489488","title":{"rendered":"\u0421\u0438\u0441\u0442\u0435\u043c\u0430 \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u043e\u0432 \u043d\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u044f\u0445 Change Stream \u0432 MongoDB"},"content":{"rendered":"<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h2>\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435<\/h2>\n<p>\u041f\u043e\u0447\u0442\u0438 \u043b\u044e\u0431\u0430\u044f \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u0430\u044f \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0430 \u0440\u0430\u043d\u043e \u0438\u043b\u0438 \u043f\u043e\u0437\u0434\u043d\u043e \u0441\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0441 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c\u044e \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u043c\u0435\u0436\u0434\u0443 \u0441\u0432\u043e\u0438\u043c\u0438 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u043c\u0438. \u0418 \u0447\u0435\u043c \u0432\u044b\u0448\u0435 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f \u043a \u043d\u0430\u0434\u0435\u0436\u043d\u043e\u0441\u0442\u0438 \u0438 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439, \u0442\u0435\u043c \u043c\u0435\u043d\u044c\u0448\u0435 \u043e\u0441\u0442\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u0440\u0435\u0448\u0435\u043d\u0438\u0439. \u0411\u0438\u0437\u043d\u0435\u0441-\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c \u043f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u043c \u043e\u0434\u043d\u043e\u0439 \u0438\u0437 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c \u043d\u0443\u0436\u043d\u043e \u0437\u043d\u0430\u0442\u044c \u043e \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044f\u0445, \u0437\u0430\u0432\u0435\u0434\u0451\u043d\u043d\u044b\u0445 \u0432\u043e \u0432\u0442\u043e\u0440\u043e\u0439. \u041f\u0435\u0440\u0432\u0430\u044f \u0445\u0440\u0430\u043d\u0438\u0442 \u0438\u0445 \u0432 \u0440\u0435\u043b\u044f\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u0421\u0423\u0411\u0414 (\u043d\u0435\u0432\u0430\u0436\u043d\u043e, \u043a\u0430\u043a\u043e\u0439 \u0438\u043c\u0435\u043d\u043d\u043e), \u0430 \u0432\u0442\u043e\u0440\u0430\u044f \u2013 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0439 MongoDB. \u0414\u043e \u043a\u0443\u0447\u0438, \u043e\u0431\u0435 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b \u0440\u0430\u0437\u043d\u0435\u0441\u0435\u043d\u044b \u043f\u043e \u0441\u0435\u0442\u0438. \u041c\u043e\u0436\u043d\u043e, \u043a\u043e\u043d\u0435\u0447\u043d\u043e, \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0438\u0442\u044c \u043e\u0442\u043a\u0440\u044b\u0442\u044c \u043e\u0431\u0430 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u0431\u043e\u043a \u043e \u0431\u043e\u043a \u0438 \u0441\u0432\u0435\u0440\u044f\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0433\u043b\u0430\u0437\u0430\u043c\u0438. \u041d\u043e \u044d\u0442\u043e \u0441\u043f\u0440\u0430\u0432\u0435\u0434\u043b\u0438\u0432\u043e \u043d\u0435\u0433\u0430\u0442\u0438\u0432\u043d\u043e \u0441\u043a\u0430\u0436\u0435\u0442\u0441\u044f \u043d\u0430 \u0444\u0438\u043d\u0430\u043d\u0441\u043e\u0432\u043e\u043c \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0435\u043d\u0438\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438, \u0434\u0430 \u0438 \u043a\u0430\u043a-\u0442\u043e \u043d\u0435 \u043f\u043e-\u0447\u0435\u043b\u043e\u0432\u0435\u0447\u0435\u0441\u043a\u0438 \u0442\u0430\u043a \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u044c\u0441\u044f \u043a \u0441\u0432\u043e\u0438\u043c \u043a\u043e\u043b\u043b\u0435\u0433\u0430\u043c. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0437\u0430\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0434\u043e\u0432\u0435\u0440\u0438\u0435 \u0432 \u043a\u043e\u043b\u043b\u0435\u043a\u0442\u0438\u0432\u0435 \u0447\u0435\u0441\u0442\u043d\u044b\u043c \u0442\u0440\u0443\u0434\u043e\u043c.<\/p>\n<p>\u0412\u0441\u0442\u0430\u0451\u0442 \u0432\u043e\u043f\u0440\u043e\u0441: \u043a\u0430\u043a \u0432 \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u0445 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u043d\u0430\u043b\u0430\u0434\u0438\u0442\u044c \u0442\u0440\u0430\u043d\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u0445 \u0441\u0438\u0441\u0442\u0435\u043c? \u041f\u0440\u0438\u043a\u0440\u0443\u0447\u0438\u0432\u0430\u0442\u044c \u043a\u043e \u0432\u0441\u0435\u043c \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u0430\u043c \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0435 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 \u0434\u043e\u0440\u043e\u0433\u043e \u0438 \u043d\u0435\u043f\u0440\u043e\u0434\u0443\u043a\u0442\u0438\u0432\u043d\u043e.\u00a0<\/p>\n<p>\u0425\u043e\u0447\u0435\u0442\u0441\u044f \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c, \u043a\u0430\u043a \u043c\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043b\u0438 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044e \u0434\u0432\u0443\u0445 \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u0445 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c \u0441\u043e \u0441\u0432\u043e\u0438\u043c\u0438 \u0431\u0430\u0437\u0430\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 MongoDB \u0434\u043b\u044f \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u0431\u0440\u043e\u043a\u0435\u0440\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439. \u0412 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u043f\u0443\u0442\u044c \u043e\u0442 \u0441\u0430\u043c\u043e\u0433\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043d\u0430 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043d\u044b\u0445 \u0432\u044b\u0433\u0440\u0443\u0437\u043a\u0430\u0445 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0445 \u043e\u0434\u043d\u043e\u0439 \u043f\u0430\u0447\u043a\u043e\u0439 \u0434\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043d\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u044f\u0445 <a href=\"https:\/\/www.mongodb.com\/docs\/manual\/changeStreams\/\">Change Stream<\/a> \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c \u0431\u0440\u043e\u043a\u0435\u0440\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439.<\/p>\n<h2>\u0412\u0432\u043e\u0434\u043d\u044b\u0435<\/h2>\n<p>\u0423 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c:<\/p>\n<ol>\n<li>\n<p>\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u0434\u0430\u043d\u043d\u044b\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0432\u044b\u0441\u0442\u0443\u043f\u0430\u0435\u0442 MongoDB.<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044c, \u0432\u043d\u0435\u0448\u043d\u044f\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043d\u0443\u0436\u043d\u043e \u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0432 \u043a\u0443\u0440\u0441\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u0432 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0435.<\/p>\n<\/li>\n<\/ol>\n<p>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c, \u0447\u0442\u043e \u0432 MongoDB \u0432 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 &#171;Megafon&#187; \u0435\u0441\u0442\u044c \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044f &#171;default&#187;, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0430\u044f \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0445 \u0431\u0438\u0437\u043d\u0435\u0441-\u043e\u0431\u044a\u0435\u043a\u0442\u044b. \u041e\u043d\u0438 \u0432\u0441\u0435 \u0438\u043c\u0435\u044e\u0442 \u043f\u043e\u043b\u0443-\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u043d\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435: \u0443 \u0432\u0441\u0435\u0445 \u0438\u0437 \u043d\u0438\u0445 \u0435\u0441\u0442\u044c \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b <code>id<\/code> (\u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043e\u0431\u044a\u0435\u043a\u0442\u0430), <code>name<\/code> (\u0438\u043c\u044f), <code>type<\/code> (\u0442\u0438\u043f) \u0438 <code>createdAt<\/code> (\u0434\u0430\u0442\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u0430). \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c &#171;\u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f&#187; \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c \u0441\u043f\u0440\u0430\u0432\u043e\u0447\u043d\u0438\u043a \u0432\u0441\u0435\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0442\u0438\u043f\u0430 <code>\"Rule\"<\/code> \u0432 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0435 \u0434\u0430\u043d\u043d\u044b\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u0432\u044f\u0437\u044b\u0432\u0430\u0435\u0442 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 <code>id<\/code> \u0441 \u0435\u0433\u043e \u0438\u043c\u0435\u043d\u0435\u043c <code>name<\/code>.\u00a0<\/p>\n<p>\u041d\u0435 \u0431\u0443\u0434\u0435\u043c \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0435, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u044d\u0442\u043e \u043d\u0435 \u0442\u0430\u043a \u0432\u0430\u0436\u043d\u043e. \u0414\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0437\u043d\u0430\u0442\u044c, \u0447\u0442\u043e \u043e\u043d \u0443\u043c\u0435\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0438 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u0441\u0438\u0441\u0442\u0435\u043c\u044b-\u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430.<\/p>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0432\u0441\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0443\u0436\u043d\u044b \u0434\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438, \u0441 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u043c\u0438 \u0438 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f\u043c\u0438, \u043e\u0431\u044a\u044f\u0441\u043d\u044f\u044e\u0449\u0438\u043c\u0438 \u043f\u0440\u0438\u0447\u0438\u043d\u044b \u043f\u0440\u0438\u043d\u044f\u0442\u0438\u044f \u0442\u0435\u0445 \u0438\u043b\u0438 \u0438\u043d\u044b\u0445 \u0440\u0435\u0448\u0435\u043d\u0438\u0439.<\/p>\n<h2>GET \/metadata<\/h2>\n<p>\u041d\u0430\u0447\u043d\u0451\u043c \u0441 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043e\u043f\u0438\u0448\u0435\u043c \u043c\u043e\u0434\u0435\u043b\u044c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u044e\u0449\u0438\u0445 \u043d\u0430\u0441 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432. \u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c, \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0435-\u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c\u0438 \u0437\u0430\u0432\u043e\u0434\u044f\u0442\u0441\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u044b, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0435 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440, \u0438\u043c\u044f \u0438 \u0442\u0438\u043f \u043e\u0431\u044a\u0435\u043a\u0442\u0430:<\/p>\n<pre><code class=\"python\">from datetime import datetimefrom typing import Literalfrom uuid import UUIDclass Rule:id: UUIDcreatedAt: datetimename: strtype: Literal[\"Rule\"]<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:87px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0421\u0430\u043c\u0443 \u0437\u0430\u0434\u0430\u0447\u0443 \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0448\u0438\u0442\u044c \u043e\u0434\u043d\u043e\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0432\u044b\u0433\u0440\u0443\u0437\u043a\u043e\u0439. \u0414\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u043e\u0434\u043d\u044f\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441 \u0441 GET-\u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u043e\u043c, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0449\u0438\u043c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0436\u0435\u043b\u0430\u0435\u043c\u043e\u043c \u0444\u043e\u0440\u043c\u0430\u0442\u0435. \u041f\u0443\u0441\u0442\u044c \u043e\u043d \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u043f\u0438\u0441\u043e\u043a \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 JSON \u0441 \u0442\u0440\u0435\u043c\u044f \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u044b\u043c\u0438 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430\u043c\u0438, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u043c\u0438 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440, \u0438\u043c\u044f \u0438 \u0442\u0438\u043f \u043e\u0431\u044a\u0435\u043a\u0442\u0430:<\/p>\n<pre><code class=\"json\">{\"id\": \"23571ab2-2b98-4b5f-a3b1-e4ca19d1031c\",\"name\": \"Example Name\",\"type\": \"Rule\"}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p> \u041a \u043f\u0440\u0438\u043c\u0435\u0440\u0443, \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a GET-\u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u0430\u043a:<\/p>\n<pre><code class=\"python\">from pymongo.asynchronous.collection import AsyncCollectionMDB_CREDS = {\"username\" = \"mdbuser\",\"password\" = \"mdbuser\",}MDB_PROPS = {\"host\" = \"localhost\",\"port\" = 27017,\"uuid_representation\" = \"STANDARD\",\"db\": \"Megafon\",\"collection\": \"default\",}MATCH = {\"type\": \"Rule\"}def get_messages(collection: AsyncCollection) -&gt; tuple[dict]:messages = []await for rule in collection.find(filter=MATCH):messages.append({\"id\": str(rule[\"id\"]),  # \u041a\u043e\u043d\u0432\u0435\u0440\u0442\u0430\u0446\u0438\u044f `uuid.UUID` \u043a `str`.\"name\": rule[\"name\"],\"type\": rule[\"type\"],})return tuple(messages)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0430\u043a \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044c \u0441\u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u0432 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0435 \u0434\u0430\u043d\u043d\u044b\u0435. \u041f\u0440\u043e\u0441\u0442\u043e\u0435 \u043d\u0430\u0447\u0430\u043b\u043e \u0441\u043b\u043e\u0436\u043d\u043e\u0439 \u0444\u0438\u0447\u0438.<\/p>\n<figure class=\"full-width \"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/327\/09c\/5d8\/32709c5d84d969cd6924970bb7dda1e3.png\" width=\"897\" height=\"362\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/327\/09c\/5d8\/32709c5d84d969cd6924970bb7dda1e3.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/327\/09c\/5d8\/32709c5d84d969cd6924970bb7dda1e3.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u041a \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0439 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u044e\u0442 \u0441\u043f\u0440\u0430\u0432\u0435\u0434\u043b\u0438\u0432\u044b\u0435 \u0432\u043e\u043f\u0440\u043e\u0441\u044b: \u0437\u0430\u0447\u0435\u043c \u0433\u043e\u043d\u044f\u0442\u044c \u0442\u0430\u043a\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0434\u0430\u043d\u043d\u044b\u0445, \u0435\u0441\u043b\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044e \u043d\u0443\u0436\u0435\u043d \u043e\u0434\u0438\u043d \u043d\u043e\u0432\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u0438\u0437 \u0442\u044b\u0441\u044f\u0447 \u0443\u0436\u0435 \u0432\u044b\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0445? \u041a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441, \u0441\u043d\u0438\u0437\u0438\u0432 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u043d\u0430 \u0441\u0435\u0442\u044c?<\/p>\n<h2>\u041c\u043d\u0435, \u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e<\/h2>\n<p>\u041c\u043e\u0436\u043d\u043e \u0440\u0430\u0441\u0448\u0438\u0440\u0438\u0442\u044c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u0434\u043e\u0431\u0430\u0432\u0438\u0432 \u0432 \u043d\u0435\u0433\u043e \u0434\u0430\u0442\u0443 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u0430 <code>createdAt<\/code>. \u0422\u0430\u043a \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044c \u0441\u043c\u043e\u0436\u0435\u0442 \u043d\u0430\u0439\u0442\u0438 \u0441\u0430\u043c\u044b\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442 \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0435\u0433\u043e \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043d\u0430 \u0432\u0445\u043e\u0434 \u0437\u0430\u043f\u0440\u043e\u0441\u0443. \u0417\u043d\u0430\u044f \u0434\u0430\u0442\u0443 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u044d\u0442\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430, \u043d\u0435\u0441\u043b\u043e\u0436\u043d\u043e \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u043e\u0442\u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0441\u0440\u0435\u0437 \u0434\u0430\u043d\u043d\u044b\u0445, \u0441\u044d\u043a\u043e\u043d\u043e\u043c\u0438\u0432 \u043d\u0430 \u0442\u0440\u0430\u0444\u0438\u043a\u0435.<\/p>\n<p>\u0420\u0430\u0441\u0448\u0438\u0440\u0438\u043c \u043d\u0430\u0448 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442, \u0434\u043e\u0431\u0430\u0432\u0438\u0432 \u0434\u0430\u0442\u0443 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u0430 <code>createdAt<\/code>:<\/p>\n<pre><code class=\"json\">{\"id\": \"23571ab2-2b98-4b5f-a3b1-e4ca19d1031c\",\"name\": \"Example Name\",\"createdAt\": \"2026-07-12T12:00:00.000\",\"type\": \"Rule\"}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0414\u043e\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a, \u0447\u0442\u043e\u0431\u044b \u043e\u043d \u0441\u0442\u0430\u043b \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"python\">def get_messages(collection: AsyncCollection, return_after: UUID | None = None) -&gt; tuple[dict]:messages = []last_sent = Noneif return_after:await for rule in collection.find(filter=MATCH | {\"id\": return_after}):last_sent = rulebreak_filter = {**MATCH}if last_sent:_filter |= {\"id\": {\"$ne\": last_sent[\"id\"]},\"createdAt\": {\"$gte\": last_sent[\"createdAt\"]},}await for rule in collection.find(filter=_filter):messages.append({\"id\": str(rule[\"id\"]),  # \u041a\u043e\u043d\u0432\u0435\u0440\u0442\u0430\u0446\u0438\u044f `uuid.UUID` \u043a `str`.\"name\": rule[\"name\"],\"createdAt\": rule[\"createdAt\"],\"type\": rule[\"type\"],})return tuple(messages))<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0418 \u0431\u0438\u0437\u043d\u0435\u0441 \u0441\u044b\u0442, \u0438 \u0441\u0435\u0442\u044c \u0446\u0435\u043b\u0430. \u041d\u043e \u0432\u043e\u0442 \u043d\u0435\u0437\u0430\u0434\u0430\u0447\u0430: \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c \u0432 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0435 \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u0438\u0435! \u041a\u0430\u043a \u043e\u0442\u0440\u0430\u0437\u0438\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043d\u0430\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u0438\u0439 \u0443\u0436\u0435 \u0432\u044b\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0445 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439? \u0424\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u044f \u043f\u043e \u0434\u0430\u0442\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0442\u0443\u0442 \u043d\u0438\u0447\u0435\u043c \u043d\u0435 \u043f\u043e\u043c\u043e\u0436\u0435\u0442.<\/p>\n<h2>\u041f\u043e\u0442\u043e\u043a\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439<\/h2>\n<p>\u0414\u043b\u044f \u0442\u0430\u043a\u0438\u0445 \u0437\u0430\u0434\u0430\u0447 \u0432 MongoDB \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u044b \u043f\u043e\u0442\u043e\u043a\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 (<a href=\"https:\/\/www.mongodb.com\/docs\/manual\/changeStreams\/\">Change Streams<\/a>) \u2013 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u043f\u043e \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u044e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0438. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043f\u043e\u0442\u043e\u043a\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439, \u043d\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043c\u043e\u0436\u0435\u0442 \u0441\u043b\u0435\u0434\u0438\u0442\u044c \u0437\u0430 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445, \u043c\u043e\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u043e \u0441\u043e\u043e\u0431\u0449\u0430\u044f \u043e\u0431\u043e \u0432\u0441\u0435\u0445 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u043a\u0430\u0445 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044e.<\/p>\n<p>\u041f\u043e\u0442\u043e\u043a\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u043d\u0430 \u0442\u0440\u0451\u0445 \u0443\u0440\u043e\u0432\u043d\u044f\u0445:<\/p>\n<ul>\n<li>\n<p>\u0432\u0435\u0441\u044c \u0434\u0435\u043f\u043b\u043e\u0439\u043c\u0435\u043d\u0442;<\/p>\n<\/li>\n<li>\n<p>\u0431\u0430\u0437\u0430 \u0434\u0430\u043d\u043d\u044b\u0445;<\/p>\n<\/li>\n<li>\n<p>\u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044f.<\/p>\n<\/li>\n<\/ul>\n<p>\u0422\u0430\u043a\u0436\u0435 \u043f\u043e\u0442\u043e\u043a\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0430 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430 \u0430\u0433\u0440\u0435\u0433\u0430\u0446\u0438\u0439. \u041c\u044b \u043c\u043e\u0436\u0435\u043c \u043e\u0442\u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u043f\u0430\u0434\u0430\u044e\u0442 \u043d\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0432 \u043d\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435. \u042d\u0442\u043e \u043f\u043e\u043b\u0435\u0437\u043d\u043e, \u0435\u0441\u043b\u0438 \u0432 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u0441\u044f \u0434\u0440\u0443\u0433\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b, \u043d\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u044e\u0449\u0438\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f: \u0434\u043e\u0431\u0430\u0432\u0438\u0432 \u0448\u0430\u0433 \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438 <code>$match<\/code>, \u043c\u043e\u0436\u043d\u043e \u0443\u043c\u0435\u043d\u044c\u0448\u0438\u0442\u044c \u043f\u043e\u0442\u043e\u043a \u0441\u043e\u0431\u044b\u0442\u0438\u0439, \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c\u044b\u0439 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c.<\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u043a\u043e\u043d\u0432\u0435\u0439\u0435\u0440 \u0430\u0433\u0440\u0435\u0433\u0430\u0446\u0438\u0438, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0449\u0438\u0439 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0442\u0438\u043f\u0430 <code>\"insert\"<\/code>, <code>\"update\"<\/code> \u0438 <code>\"delete\"<\/code> \u0434\u043b\u044f \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0442\u0438\u043f\u0430 <code>\"Rule\"<\/code>:<\/p>\n<pre><code class=\"python\">WATCH_PIPELINE = [{\"$match\": {\"operationType\": {\"$in\": [\"insert\", \"update\", \"delete\"]},\"fullDocument.type\": \"Rule\",  # \u0415\u0441\u043b\u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434\u0443 `watch` \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 `full_document=\"updateLookup\"`, \u043c\u043e\u0436\u043d\u043e \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u043c\u0443 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430 \u0447\u0435\u0440\u0435\u0437 \u0430\u0442\u0440\u0438\u0431\u0443\u0442 `fullDocument`.},},]<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0442\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438. \u0420\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0439 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u0441\u043e\u0431\u044b\u0442\u0438\u0439:<\/p>\n<pre><code class=\"python\">from pymongo.asynchronous.collection import AsyncCollectionasync def watch_collection(    pipeline: dict,collection: AsyncCollection,    resume_token=None):    async with await coll.watch(pipeline, full_document=\"updateLookup\", resume_after=resume_token) as stream:        async for change in stream:            yield change, stream.resume_token<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412\u043e\u0437\u043d\u0438\u043a\u0430\u0435\u0442 \u0437\u0430\u043a\u043e\u043d\u043e\u043c\u0435\u0440\u043d\u044b\u0439 \u0432\u043e\u043f\u0440\u043e\u0441: \u043a\u0430\u043a \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u044d\u0442\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044e? GET-\u0437\u0430\u043f\u0440\u043e\u0441 \u0434\u043b\u044f \u0442\u0430\u043a\u0438\u0445 \u0437\u0430\u0434\u0430\u0447, \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e, \u043d\u0435 \u043f\u0440\u0438\u0433\u043e\u0434\u0435\u043d. \u041a\u0430\u043a \u0432\u0430\u0440\u0438\u0430\u043d\u0442, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c API \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f, \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u044f \u0435\u043c\u0443 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043f\u043e \u043c\u0435\u0440\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043d\u043e\u0432\u044b\u0445 \u0438\u043b\u0438 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432. \u0410 \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0432 \u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u0435\u0441\u043b\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044c \u0438\u043b\u0438 \u043d\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043e\u043a\u0430\u0437\u0430\u043b\u0438\u0441\u044c \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b?<\/p>\n<h2>\u0410 \u0435\u0441\u043b\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044c \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d?<\/h2>\n<p>\u041c\u043e\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439. \u042d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u044b\u043c \u0440\u0435\u0448\u0435\u043d\u0438\u0435\u043c \u0431\u0435\u0437 \u0443\u0441\u043b\u043e\u0436\u043d\u0435\u043d\u0438\u044f \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b. \u0412\u0441\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c\u044b\u0435 \u0431\u0430\u0437\u043e\u0439 \u0434\u0430\u043d\u043d\u044b\u0445, \u043f\u043e\u043c\u0435\u0449\u0430\u044e\u0442\u0441\u044f \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044e \u043d\u0435 \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u0438\u0442\u0441\u044f \u0434\u043e \u0442\u0435\u0445 \u043f\u043e\u0440, \u043f\u043e\u043a\u0430 \u043e\u043d \u043d\u0435 \u043e\u0431\u044a\u044f\u0432\u0438\u0442\u0441\u044f &#171;\u0432 \u0441\u0435\u0442\u0438&#187;.<\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0433\u043e \u0446\u0438\u043a\u043b\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430 FIFO-\u043e\u0447\u0435\u0440\u0435\u0434\u0438, \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 <code>asyncio<\/code>:<\/p>\n<pre><code class=\"python\">from asyncio import create_task, gather, Queuefrom logging import getLoggerlogger = getLogger()EVENT_QUEUES_DICT: dict[str, Queue] = {}  # \u0422\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0439, \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044f \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0438\u0437\u0432\u043d\u0435: \u043a \u043f\u0440\u0438\u043c\u0435\u0440\u0443, \u0434\u043b\u044f \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u0430 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043e\u0447\u0435\u0440\u0435\u0434\u0435\u0439.def get_listener_label(db: str, collection: str) -&gt; str:\"\"\"\u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043a\u043b\u044e\u0447 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0432 \u0441\u043b\u043e\u0432\u0430\u0440\u0435 `EVENT_QUEUES_DICT` \u0434\u043b\u044f \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0439 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438 `collection` \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 `db`.\"\"\"    return f\"{db}.{coll}\"def get_queue_length(db: str, collection: str) -&gt; int:\"\"\"\u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0440\u0430\u0437\u043c\u0435\u0440 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0434\u043b\u044f \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0439 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438 `collection` \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 `db`.\"\"\"    listener_label = get_listener_label(db, collection)    try:        events_queue = EVENT_QUEUES_DICT[listener_label]    except KeyError as ex:        logger.error(f\"\u041e\u0447\u0435\u0440\u0435\u0434\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0434\u043b\u044f \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438 '{db}.{collection}' \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442.\")        raise ex    return events_queue.qsize()def process_event(event: dict) -&gt; dict | None:\"\"\"\u041e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0441\u043e\u0431\u044b\u0442\u0438\u0435, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044f \u0441\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435.\"\"\"full_document = event.get(\"fullDocument\")if full_document is None:return Nonereturn {\"id\": str(full_document[\"id\"]),  # \u041a\u043e\u043d\u0432\u0435\u0440\u0442\u0430\u0446\u0438\u044f `uuid.UUID` \u043a `str`.\"name\": full_document[\"name\"],\"type\": full_document[\"type\"],}def send_message(message):\"\"\"TODO\"\"\"...async def listen_collection(collection: AsyncCollection, max_event_queue_size: int = 100000):db_name, collection_name = collection.database.name, collection.nameevents_queue = Queue(maxsize=int(max_event_queue_size))EVENT_QUEUES_DICT[get_listener_label(db_name, collection_name)] = events_queueasync def watch_collection_task_wrapper(queue: Queue, resume_token=None):while True:try:async for event, resume_token in watch_collection(WATCH_PIPELINE, params, app, resume_token=resume_token):await queue.put(event)logger.info(f\"\u0420\u0430\u0437\u043c\u0435\u0440 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 '{db_name}.{collection_name}': {queue.qsize()}.\")except Exception as ex:logger.error(f\"\u041f\u0440\u0438 \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u0435 {db_name}.{collection_name} \u0432\u043e\u0437\u043d\u0438\u043a\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430. \"f\"\u041c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433 \u0431\u0443\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0449\u0435\u043d{' \u0441 \u0442\u043e\u043a\u0435\u043d\u043e\u043c \u0432\u043e\u0437\u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f'}.\",exc_info=ex,)logger.debug(f\"\u0422\u043e\u043a\u0435\u043d \u0432\u043e\u0437\u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f: {resume_token}.\")continueawait queue.put(None)    async def event_loop(queue: Queue):        while True:            logger.info(f\"\u041e\u0436\u0438\u0434\u0430\u044e \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u0434\u043b\u044f '{db_name}.{collection_name}'...\")            event = await queue.get()            if event is None:                break            logger.debug(f\"\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u0435:\\n{event}\")message = process_event(event)send_message(message)logger.info(f\"\u0420\u0430\u0437\u043c\u0435\u0440 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 '{db_name}.{collection_name}': {queue.qsize()}.\")watch_task = create_task(watch_collection_task_wrapper(events_queue))    logger.debug(\"\u0417\u0430\u043f\u0443\u0449\u0435\u043d watch_task.\")    process_task = create_task(event_loop(events_queue))    logger.debug(\"\u0417\u0430\u043f\u0443\u0449\u0435\u043d process_task.\")    await gather(watch_task, process_task)    logger.debug(\"\u0417\u0430\u0432\u0435\u0440\u0448\u0451\u043d\u044b `watch_task` \u0438 `process_task`.\")    await events_queue.join()    logger.debug(f\"\u041e\u0447\u0435\u0440\u0435\u0434\u044c '{db_name}.{collection_name}' \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0430.\")<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u044d\u0442\u043e\u0433\u043e \u0431\u044b\u043b\u043e \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e: \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c &#171;\u043d\u0435 \u0433\u043e\u0442\u043e\u0432\u044b&#187; \u043a \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0435 \u0432 \u043c\u043e\u043c\u0435\u043d\u0442 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043d\u0430\u0448\u0435\u0439 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445. \u0414\u043e\u0431\u0430\u0432\u0438\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u043f\u043e\u043c\u0435\u0449\u0430\u0435\u0442\u0441\u044f \u043e\u0431\u0440\u0430\u0442\u043d\u043e \u0432 \u043a\u043e\u043d\u0435\u0446 \u043e\u0447\u0435\u0440\u0435\u0434\u0438, \u0438 \u0442\u0430\u043a \u0434\u043e \u0442\u0435\u0445 \u043f\u043e\u0440, \u043f\u043e\u043a\u0430 \u043e\u043d\u043e \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0433\u043e\u0442\u043e\u0432\u043e \u043a \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0435.<\/p>\n<pre><code class=\"python\">class Rule:...isReady: bool  # \u0423\u0441\u043b\u043e\u0432\u0438\u0435 \u0433\u043e\u0442\u043e\u0432\u043d\u043e\u0441\u0442\u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u0430, \u0434\u043b\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u0430.async def listen_collection(collection: AsyncCollection, max_event_queue_size: int = 100000):...async def event_loop(queue: Queue):        while True:            ...            logger.debug(f\"\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u0435:\\n{event}\")full_document = event[\"fullDocument\"]is_ready = full_document.get(\"isReady\", False)if not is_ready:await queue.put(event)logger.info(f\"\u041e\u0431\u044a\u0435\u043a\u0442 {repr(full_document['id'])} \u043d\u0435 \u0433\u043e\u0442\u043e\u0432 \u043a \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0435 \u0438 \u043f\u043e\u043c\u0435\u0449\u0451\u043d \u0432 \u043a\u043e\u043d\u0435\u0446 \u043e\u0447\u0435\u0440\u0435\u0434\u0438.\")continuemessage = process_event(event)send_message(message)logger.info(f\"\u0420\u0430\u0437\u043c\u0435\u0440 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 '{db_name}.{collection_name}': {queue.qsize()}.\")...<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043a\u043e\u043c \u0442\u0430\u043a\u043e\u0433\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u043e, \u0447\u0442\u043e \u043a\u0440\u0438\u0442\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u043d\u0435\u043f\u043e\u043b\u0430\u0434\u043a\u0430 \u043d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u0435 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430 \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u043e\u0442\u043a\u0430\u0437, \u0447\u0442\u043e \u043e\u0431\u0435\u0440\u043d\u0451\u0442\u0441\u044f \u043f\u043e\u0442\u0435\u0440\u0435\u0439 \u043d\u0430\u043a\u043e\u043f\u043b\u0435\u043d\u043d\u043e\u0439 \u043e\u0447\u0435\u0440\u0435\u0434\u0438. \u0412 \u0442\u0430\u043a\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0435\u0434\u0443\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430 (\u0441\u043c. \u0433\u043b\u0430\u0432\u0443 &#171;\u041c\u043d\u0435, \u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e&#187;), \u0438\u043b\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u0435\u0449\u0451 \u0431\u043e\u043b\u0435\u0435 \u043a\u043e\u043c\u043f\u043b\u0435\u043a\u0441\u043d\u043e\u0435, \u043d\u043e, \u0434\u0430\u0431\u044b \u0440\u0435\u0448\u0438\u0442\u044c \u044d\u0442\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b, \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u043c \u043c\u0435\u0436\u0434\u0443 \u043d\u0430\u0448\u0438\u043c\u0438 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u043c\u0438 \u0431\u0440\u043e\u043a\u0435\u0440 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439.<\/p>\n<h2>\u0411\u0440\u043e\u043a\u0435\u0440 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439<\/h2>\n<p>\u0411\u0440\u043e\u043a\u0435\u0440 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0441\u0442\u043e\u0438\u0442 \u043c\u0435\u0436\u0434\u0443 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u043c \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u0438\u0445 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0435\u043c, \u0432\u044b\u0441\u0442\u0443\u043f\u0430\u044f \u0438\u0445 \u043f\u043e\u0441\u0440\u0435\u0434\u043d\u0438\u043a\u043e\u043c. \u041d\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0432 \u0442\u0435\u0440\u043c\u0438\u043d\u043e\u043b\u043e\u0433\u0438\u0438 \u0431\u0440\u043e\u043a\u0435\u0440\u043e\u0432 \u0431\u0443\u0434\u0435\u0442 \u043d\u0430\u0437\u044b\u0432\u0430\u0442\u044c\u0441\u044f &#171;\u043f\u0440\u043e\u0434\u044e\u0441\u0435\u0440\u043e\u043c&#187;. \u041d\u0435 \u0431\u0443\u0434\u0435\u043c \u0432\u0434\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438, \u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0440\u0435\u0448\u0430\u0435\u0442 \u0431\u0440\u043e\u043a\u0435\u0440 \u0432 \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0439 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438:<\/p>\n<ol>\n<li>\n<p>\u041a\u0430\u043a \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u0440\u0430\u043d\u0441\u043f\u043e\u0440\u0442 \u043c\u0435\u0436\u0434\u0443 \u0434\u0432\u0443\u043c\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u043c\u0438? \u0411\u0440\u043e\u043a\u0435\u0440, \u044f\u0432\u043b\u044f\u044f\u0441\u044c \u043f\u043e\u0441\u0440\u0435\u0434\u043d\u0438\u043a\u043e\u043c, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u043c\u0435\u0442\u043e\u0434\u044b \u0437\u0430\u043f\u0438\u0441\u0438 \u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439. <\/p>\n<\/li>\n<li>\n<p>\u0427\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c, \u0435\u0441\u043b\u0438 \u043e\u0434\u043d\u0430 \u0438\u0437 \u0441\u0438\u0441\u0442\u0435\u043c \u0443\u0448\u043b\u0430 \u043d\u0430 \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u043e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u043d\u0438\u0435? \u0412\u0442\u043e\u0440\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0441\u0432\u043e\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u0440\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u0438 \u0431\u0440\u043e\u043a\u0435\u0440\u0430.<\/p>\n<\/li>\n<li>\n<p>\u041a\u0430\u043a \u043e\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u0438\u0442\u044c \u0441\u0435\u0431\u044f \u043e\u0442 \u043f\u043e\u0442\u0435\u0440\u044c \u0434\u0430\u043d\u043d\u044b\u0445? \u0411\u0440\u043e\u043a\u0435\u0440 \u0440\u0435\u0448\u0430\u0435\u0442 \u0437\u0430\u0434\u0430\u0447\u0438 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0438 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u044b\u0445 \u0432\u044b\u0434\u0430\u0447\u0435\u0439 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043f\u0440\u0438 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f\u0445.<\/p>\n<\/li>\n<\/ol>\n<figure class=\"full-width \"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/49a\/017\/604\/49a01760450d80c1c2574b2030f53b39.png\" width=\"919\" height=\"687\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/49a\/017\/604\/49a01760450d80c1c2574b2030f53b39.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/49a\/017\/604\/49a01760450d80c1c2574b2030f53b39.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f RabbitMQ, \u043e\u043d \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442 \u0434\u043b\u044f \u0441\u0440\u0430\u0432\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u043e\u0431\u044a\u0451\u043c\u043e\u0432 \u0434\u0430\u043d\u043d\u044b\u0445 (\u0431\u0438\u0433-\u0434\u0430\u0442\u043e\u0439 \u043d\u0430\u0441 \u043d\u0435 \u043d\u0430\u0437\u043e\u0432\u0451\u0448\u044c).<\/p>\n<h2>\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f<\/h2>\n<p>\u0414\u043e\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435, \u0434\u043e\u0431\u0430\u0432\u0438\u0432 \u043f\u0440\u043e\u0441\u043b\u0443\u0448\u043a\u0443 \u0441\u043e\u0431\u044b\u0442\u0438\u0439, \u0438\u0445 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0441 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0439 FIFO-\u043e\u0447\u0435\u0440\u0435\u0434\u044c\u044e \u0438 \u0431\u0440\u043e\u043a\u0435\u0440 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439. \u0418\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u0430\u044f \u0432\u044b\u0433\u0440\u0443\u0437\u043a\u0430 GET-\u0437\u0430\u043f\u0440\u043e\u0441\u043e\u043c \u043d\u0438\u043a\u0443\u0434\u0430 \u043d\u0435 \u0434\u0435\u043d\u0435\u0442\u0441\u044f: \u043e\u043d\u0430 \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u0434\u043b\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0441\u043f\u0440\u0430\u0432\u043e\u0447\u043d\u0438\u043a\u043e\u0432. \u041e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e, \u0435\u0451 \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c, \u043f\u0440\u0438\u043a\u0440\u0443\u0442\u0438\u0432 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0443 \u0447\u0435\u0440\u0435\u0437 \u0431\u0440\u043e\u043a\u0435\u0440\u0430, \u0438\u043b\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0434\u043e\u0431\u043d\u0443\u044e \u0444\u0438\u0447\u0443 \u0432\u0442\u043e\u0440\u044b\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u0443 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f \u043e\u0441\u0442\u0430\u043b\u0441\u044f \u0432\u044b\u0431\u043e\u0440 \u043c\u0435\u0436\u0434\u0443 \u0434\u0432\u0443\u043c\u044f \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430\u043c\u0438.<\/p>\n<p>\u0420\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0437\u0430\u043f\u0438\u0441\u0438 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430 \u0432 RMQ:<\/p>\n<pre><code class=\"python\">RMQ_CREDS = {\"username\": \"rmquser\",\"password\": \"rmquser\",}RMQ_PROPS = {\"host\": \"localhost\",\"port\": \"5672\",\"virtual_host\": \"\/\",\"heartbeat\": 36000,}RMQ_QUEUE_PARAMS = {\"queue\": \"integration.events\",\"durable\": True,}RMQ_PUBLISH_PARAMS = {\"exchange\": \"INTEGRATION.EVENTS.EXCHANGE\",\"routing_key\": \"integration.events\",}def send_message(message: dict, rmq_credentials: dict, rmq_properties: dict, rmq_queue_params: dict, rmq_publish_params: dict):    \"\"\"\u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u043b\u043e\u0432\u0430\u0440\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0432 json-\u0441\u0442\u0440\u043e\u043a\u0443 \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0432 RMQ.\"\"\"try:        json_message = json.dumps(message, ensure_ascii=False)        credentials = pika.PlainCredentials(**rmq_credentials)        parameters = pika.ConnectionParameters(            **rmq_properties,            credentials=credentials,        )        connection = pika.BlockingConnection(parameters)        channel = connection.channel()        channel.queue_declare(**rmq_queue_params)        channel.basic_publish(            **rmq_publish_params,            body=json_message,        )        connection.close()    except (Exception, RuntimeError, TimeoutError) as ex:        logger.error(\"\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a RabbitMQ.\", exc_info=ex)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h2>\u0418\u0442\u043e\u0433\u043e<\/h2>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0440\u0435\u0448\u0435\u043d\u0438\u0438 \u043c\u044b \u043f\u043e\u0441\u0442\u0430\u0440\u0430\u043b\u0438\u0441\u044c \u0441\u0444\u043e\u043a\u0443\u0441\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0430:<\/p>\n<ul>\n<li>\n<p>\u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u0438: \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438 \u0438 \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u043d\u043e\u0439 \u0432\u044b\u0433\u0440\u0443\u0437\u043a\u0438 \u043f\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u044f\u043c \u0438\u0441\u043a\u043b\u044e\u0447\u0430\u044e\u0442 \u043b\u0438\u0448\u043d\u044e\u044e \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u043d\u0430 \u0441\u0435\u0442\u044c;<\/p>\n<\/li>\n<li>\n<p>\u0432\u044b\u0441\u043e\u043a\u043e\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u0438: \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u0431\u0440\u043e\u043a\u0435\u0440\u0443 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0435 \u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u0438 \u043f\u0440\u043e\u0434\u044e\u0441\u0435\u0440\u0430 \u0438\u043b\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f, \u0430 \u043e\u0431\u044b\u0447\u043d\u044b\u0435 GET-\u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043e\u0441\u0442\u0430\u044e\u0442\u0441\u044f \u0437\u0430\u043f\u0430\u0441\u043d\u044b\u043c \u043f\u043b\u0430\u043d\u043e\u043c \u043f\u0440\u0438 \u043d\u0435\u043f\u043e\u043b\u0430\u0434\u043a\u0430\u0445 \u043d\u0430 \u0431\u0440\u043e\u043a\u0435\u0440\u0435;<\/p>\n<\/li>\n<li>\n<p>\u043d\u0430\u0434\u0451\u0436\u043d\u043e\u0441\u0442\u0438: \u0432 \u0441\u043b\u0443\u0447\u0430\u0435, \u0435\u0441\u043b\u0438 \u0431\u0440\u043e\u043a\u0435\u0440 \u0441\u0430\u043c \u0441\u0442\u0430\u043d\u0435\u0442 \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u043c, \u0443 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f \u0435\u0441\u0442\u044c \u0437\u0430\u043f\u0430\u0441\u043d\u044b\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u0440\u0430\u0433\u043e\u0446\u0435\u043d\u043d\u044b\u0445 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0445. <\/p>\n<\/li>\n<\/ul>\n<p>\u0421 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b, \u043c\u044b \u0436\u0435\u0440\u0442\u0432\u0443\u0435\u043c:<\/p>\n<ul>\n<li>\n<p>\u043f\u0440\u043e\u0441\u0442\u043e\u0442\u043e\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438: \u0432\u0441\u0451 \u0436\u0435, \u0440\u0430\u0437\u0432\u0451\u0440\u0442\u044b\u0432\u0430\u043d\u0438\u0435 \u0438 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u0431\u0440\u043e\u043a\u0435\u0440\u0430 \u2014 \u044d\u0442\u043e \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0437\u0430\u0442\u0440\u0430\u0442\u044b;<\/p>\n<\/li>\n<li>\n<p>\u043f\u0440\u043e\u0441\u0442\u043e\u0442\u043e\u0439 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438: \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0432\u0441\u0435\u0445 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0445 \u0444\u0438\u0447\u0435\u0439 \u2014 \u044d\u0442\u043e \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0440\u0430\u0431\u043e\u0442\u044b \u0438 \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u0438, \u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c \u0431\u044b, \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0432\u044b\u0433\u0440\u0443\u0437\u043a\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u043e \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044e.<\/p>\n<\/li>\n<\/ul>\n<p>\u041d\u0430\u0434\u0435\u044e\u0441\u044c, \u0434\u0430\u043d\u043d\u0430\u044f \u0441\u0442\u0430\u0442\u044c\u044f \u0441\u0442\u0430\u043d\u0435\u0442 \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0439 \u043f\u0438\u0449\u0435\u0439 \u0434\u043b\u044f \u0440\u0430\u0437\u043c\u044b\u0448\u043b\u0435\u043d\u0438\u0439 \u043f\u0440\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0432\u0430\u0448\u0438\u0445 \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u043e\u0432.<\/p>\n<h2>\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0438<\/h2>\n<p>1. <a href=\"https:\/\/www.mongodb.com\/docs\/manual\/changeStreams\/#open-a-change-stream\">https:\/\/www.mongodb.com\/docs\/manual\/changeStreams\/#open-a-change-stream<\/a>.<\/p>\n<p>2. <a href=\"https:\/\/www.mongodb.com\/resources\/products\/capabilities\/change-streams\">https:\/\/www.mongodb.com\/resources\/products\/capabilities\/change-streams<\/a>.<\/p>\n<p>3. <a href=\"https:\/\/www.mongodb.com\/docs\/languages\/python\/pymongo-driver\/current\/monitoring-and-logging\/change-streams\/\">https:\/\/www.mongodb.com\/docs\/languages\/python\/pymongo-driver\/current\/monitoring-and-logging\/change-streams\/<\/a>.<\/p>\n<\/div>\n<p>\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\/1065904\/\">https:\/\/habr.com\/ru\/articles\/1065904\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435\u041f\u043e\u0447\u0442\u0438 \u043b\u044e\u0431\u0430\u044f \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u0430\u044f \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0430 \u0440\u0430\u043d\u043e \u0438\u043b\u0438 \u043f\u043e\u0437\u0434\u043d\u043e \u0441\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0441 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c\u044e \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u043c\u0435\u0436\u0434\u0443 \u0441\u0432\u043e\u0438\u043c\u0438 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u043c\u0438. \u0418 \u0447\u0435\u043c \u0432\u044b\u0448\u0435 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f \u043a \u043d\u0430\u0434\u0435\u0436\u043d\u043e\u0441\u0442\u0438 \u0438 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439, \u0442\u0435\u043c \u043c\u0435\u043d\u044c\u0448\u0435 \u043e\u0441\u0442\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u0440\u0435\u0448\u0435\u043d\u0438\u0439. \u0411\u0438\u0437\u043d\u0435\u0441-\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c \u043f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u043c \u043e\u0434\u043d\u043e\u0439 \u0438\u0437 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c \u043d\u0443\u0436\u043d\u043e \u0437\u043d\u0430\u0442\u044c \u043e \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044f\u0445, \u0437\u0430\u0432\u0435\u0434\u0451\u043d\u043d\u044b\u0445 \u0432\u043e \u0432\u0442\u043e\u0440\u043e\u0439. \u041f\u0435\u0440\u0432\u0430\u044f \u0445\u0440\u0430\u043d\u0438\u0442 \u0438\u0445 \u0432 \u0440\u0435\u043b\u044f\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u0421\u0423\u0411\u0414 (\u043d\u0435\u0432\u0430\u0436\u043d\u043e, \u043a\u0430\u043a\u043e\u0439 \u0438\u043c\u0435\u043d\u043d\u043e), \u0430 \u0432\u0442\u043e\u0440\u0430\u044f \u2013 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0439 MongoDB. \u0414\u043e \u043a\u0443\u0447\u0438, \u043e\u0431\u0435 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b \u0440\u0430\u0437\u043d\u0435\u0441\u0435\u043d\u044b \u043f\u043e \u0441\u0435\u0442\u0438. \u041c\u043e\u0436\u043d\u043e, \u043a\u043e\u043d\u0435\u0447\u043d\u043e, \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0438\u0442\u044c \u043e\u0442\u043a\u0440\u044b\u0442\u044c \u043e\u0431\u0430 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u0431\u043e\u043a \u043e \u0431\u043e\u043a \u0438 \u0441\u0432\u0435\u0440\u044f\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0433\u043b\u0430\u0437\u0430\u043c\u0438. \u041d\u043e \u044d\u0442\u043e \u0441\u043f\u0440\u0430\u0432\u0435\u0434\u043b\u0438\u0432\u043e \u043d\u0435\u0433\u0430\u0442\u0438\u0432\u043d\u043e \u0441\u043a\u0430\u0436\u0435\u0442\u0441\u044f \u043d\u0430 \u0444\u0438\u043d\u0430\u043d\u0441\u043e\u0432\u043e\u043c \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0435\u043d\u0438\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438, \u0434\u0430 \u0438 \u043a\u0430\u043a-\u0442\u043e \u043d\u0435 \u043f\u043e-\u0447\u0435\u043b\u043e\u0432\u0435\u0447\u0435\u0441\u043a\u0438 \u0442\u0430\u043a \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u044c\u0441\u044f \u043a \u0441\u0432\u043e\u0438\u043c \u043a\u043e\u043b\u043b\u0435\u0433\u0430\u043c. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0437\u0430\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0434\u043e\u0432\u0435\u0440\u0438\u0435 \u0432 \u043a\u043e\u043b\u043b\u0435\u043a\u0442\u0438\u0432\u0435 \u0447\u0435\u0441\u0442\u043d\u044b\u043c \u0442\u0440\u0443\u0434\u043e\u043c.\u0412\u0441\u0442\u0430\u0451\u0442 \u0432\u043e\u043f\u0440\u043e\u0441: \u043a\u0430\u043a \u0432 \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u0445 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u043d\u0430\u043b\u0430\u0434\u0438\u0442\u044c \u0442\u0440\u0430\u043d\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u0445 \u0441\u0438\u0441\u0442\u0435\u043c? \u041f\u0440\u0438\u043a\u0440\u0443\u0447\u0438\u0432\u0430\u0442\u044c \u043a\u043e \u0432\u0441\u0435\u043c \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u0430\u043c \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0435 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 \u0434\u043e\u0440\u043e\u0433\u043e \u0438 \u043d\u0435\u043f\u0440\u043e\u0434\u0443\u043a\u0442\u0438\u0432\u043d\u043e.\u00a0\u0425\u043e\u0447\u0435\u0442\u0441\u044f \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c, \u043a\u0430\u043a \u043c\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043b\u0438 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044e \u0434\u0432\u0443\u0445 \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u0445 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c \u0441\u043e \u0441\u0432\u043e\u0438\u043c\u0438 \u0431\u0430\u0437\u0430\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 MongoDB \u0434\u043b\u044f \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u0431\u0440\u043e\u043a\u0435\u0440\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439. \u0412 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u043f\u0443\u0442\u044c \u043e\u0442 \u0441\u0430\u043c\u043e\u0433\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043d\u0430 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043d\u044b\u0445 \u0432\u044b\u0433\u0440\u0443\u0437\u043a\u0430\u0445 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0445 \u043e\u0434\u043d\u043e\u0439 \u043f\u0430\u0447\u043a\u043e\u0439 \u0434\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043d\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u044f\u0445 Change Stream \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c \u0431\u0440\u043e\u043a\u0435\u0440\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439.\u0412\u0432\u043e\u0434\u043d\u044b\u0435\u0423 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c:\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u0434\u0430\u043d\u043d\u044b\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0432\u044b\u0441\u0442\u0443\u043f\u0430\u0435\u0442 MongoDB.\u041f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044c, \u0432\u043d\u0435\u0448\u043d\u044f\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043d\u0443\u0436\u043d\u043e \u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0432 \u043a\u0443\u0440\u0441\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u0432 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0435.\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c, \u0447\u0442\u043e \u0432 MongoDB \u0432 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 &#171;Megafon&#187; \u0435\u0441\u0442\u044c \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044f &#171;default&#187;, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0430\u044f \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0445 \u0431\u0438\u0437\u043d\u0435\u0441-\u043e\u0431\u044a\u0435\u043a\u0442\u044b. \u041e\u043d\u0438 \u0432\u0441\u0435 \u0438\u043c\u0435\u044e\u0442 \u043f\u043e\u043b\u0443-\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u043d\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435: \u0443 \u0432\u0441\u0435\u0445 \u0438\u0437 \u043d\u0438\u0445 \u0435\u0441\u0442\u044c \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b id (\u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043e\u0431\u044a\u0435\u043a\u0442\u0430), name (\u0438\u043c\u044f), type (\u0442\u0438\u043f) \u0438 createdAt (\u0434\u0430\u0442\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u0430). \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c &#171;\u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f&#187; \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c \u0441\u043f\u0440\u0430\u0432\u043e\u0447\u043d\u0438\u043a \u0432\u0441\u0435\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0442\u0438\u043f\u0430 &#171;Rule&#187; \u0432 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0435 \u0434\u0430\u043d\u043d\u044b\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u0432\u044f\u0437\u044b\u0432\u0430\u0435\u0442 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 id \u0441 \u0435\u0433\u043e \u0438\u043c\u0435\u043d\u0435\u043c name.\u00a0\u041d\u0435 \u0431\u0443\u0434\u0435\u043c \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0435, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u044d\u0442\u043e \u043d\u0435 \u0442\u0430\u043a \u0432\u0430\u0436\u043d\u043e. \u0414\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0437\u043d\u0430\u0442\u044c, \u0447\u0442\u043e \u043e\u043d \u0443\u043c\u0435\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0438 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u0441\u0438\u0441\u0442\u0435\u043c\u044b-\u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430.\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0432\u0441\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0443\u0436\u043d\u044b \u0434\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438, \u0441 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u043c\u0438 \u0438 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f\u043c\u0438, \u043e\u0431\u044a\u044f\u0441\u043d\u044f\u044e\u0449\u0438\u043c\u0438 \u043f\u0440\u0438\u0447\u0438\u043d\u044b \u043f\u0440\u0438\u043d\u044f\u0442\u0438\u044f \u0442\u0435\u0445 \u0438\u043b\u0438 \u0438\u043d\u044b\u0445 \u0440\u0435\u0448\u0435\u043d\u0438\u0439.GET \/metadata\u041d\u0430\u0447\u043d\u0451\u043c \u0441 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043e\u043f\u0438\u0448\u0435\u043c \u043c\u043e\u0434\u0435\u043b\u044c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u044e\u0449\u0438\u0445 \u043d\u0430\u0441 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432. \u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c, \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0435-\u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c\u0438 \u0437\u0430\u0432\u043e\u0434\u044f\u0442\u0441\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u044b, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0435 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440, \u0438\u043c\u044f \u0438 \u0442\u0438\u043f \u043e\u0431\u044a\u0435\u043a\u0442\u0430:from datetime import datetimefrom typing import Literalfrom uuid import UUIDclass Rule:id: UUIDcreatedAt: datetimename: strtype: Literal[&#171;Rule&#187;]\u0421\u0430\u043c\u0443 \u0437\u0430\u0434\u0430\u0447\u0443 \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0448\u0438\u0442\u044c \u043e\u0434\u043d\u043e\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0432\u044b\u0433\u0440\u0443\u0437\u043a\u043e\u0439. \u0414\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u043e\u0434\u043d\u044f\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441 \u0441 GET-\u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u043e\u043c, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0449\u0438\u043c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0436\u0435\u043b\u0430\u0435\u043c\u043e\u043c \u0444\u043e\u0440\u043c\u0430\u0442\u0435. \u041f\u0443\u0441\u0442\u044c \u043e\u043d \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u043f\u0438\u0441\u043e\u043a \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 JSON \u0441 \u0442\u0440\u0435\u043c\u044f \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u044b\u043c\u0438 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430\u043c\u0438, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u043c\u0438 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440, \u0438\u043c\u044f \u0438 \u0442\u0438\u043f \u043e\u0431\u044a\u0435\u043a\u0442\u0430:{&#171;id&#187;: &#171;23571ab2-2b98-4b5f-a3b1-e4ca19d1031c&#187;,&#187;name&#187;: &#171;Example Name&#187;,&#187;type&#187;: &#171;Rule&#187;} \u041a \u043f\u0440\u0438\u043c\u0435\u0440\u0443, \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a GET-\u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u0430\u043a:from pymongo.asynchronous.collection import AsyncCollectionMDB_CREDS = {&#171;username&#187; = &#171;mdbuser&#187;,&#187;password&#187; = &#171;mdbuser&#187;,}MDB_PROPS = {&#171;host&#187; = &#171;localhost&#187;,&#187;port&#187; = 27017,&#187;uuid_representation&#187; = &#171;STANDARD&#187;,&#187;db&#187;: &#171;Megafon&#187;,&#187;collection&#187;: &#171;default&#187;,}MATCH = {&#171;type&#187;: &#171;Rule&#187;}def get_messages(collection: AsyncCollection) -&gt; tuple[dict]:messages = []await for rule in collection.find(filter=MATCH):messages.append({&#171;id&#187;: str(rule[&#171;id&#187;]),  # \u041a\u043e\u043d\u0432\u0435\u0440\u0442\u0430\u0446\u0438\u044f `uuid.UUID` \u043a `str`.&#187;name&#187;: rule[&#171;name&#187;],&#187;type&#187;: rule[&#171;type&#187;],})return tuple(messages)\u0422\u0430\u043a \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044c \u0441\u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u0432 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0435 \u0434\u0430\u043d\u043d\u044b\u0435. \u041f\u0440\u043e\u0441\u0442\u043e\u0435 \u043d\u0430\u0447\u0430\u043b\u043e \u0441\u043b\u043e\u0436\u043d\u043e\u0439 \u0444\u0438\u0447\u0438.\u041a \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0439 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u044e\u0442 \u0441\u043f\u0440\u0430\u0432\u0435\u0434\u043b\u0438\u0432\u044b\u0435 \u0432\u043e\u043f\u0440\u043e\u0441\u044b: \u0437\u0430\u0447\u0435\u043c \u0433\u043e\u043d\u044f\u0442\u044c \u0442\u0430\u043a\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0434\u0430\u043d\u043d\u044b\u0445, \u0435\u0441\u043b\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044e \u043d\u0443\u0436\u0435\u043d \u043e\u0434\u0438\u043d \u043d\u043e\u0432\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u0438\u0437 \u0442\u044b\u0441\u044f\u0447 \u0443\u0436\u0435 \u0432\u044b\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0445? \u041a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441, \u0441\u043d\u0438\u0437\u0438\u0432 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u043d\u0430 \u0441\u0435\u0442\u044c?\u041c\u043d\u0435, \u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e\u041c\u043e\u0436\u043d\u043e \u0440\u0430\u0441\u0448\u0438\u0440\u0438\u0442\u044c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u0434\u043e\u0431\u0430\u0432\u0438\u0432 \u0432 \u043d\u0435\u0433\u043e \u0434\u0430\u0442\u0443 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u0430 createdAt. \u0422\u0430\u043a \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044c \u0441\u043c\u043e\u0436\u0435\u0442 \u043d\u0430\u0439\u0442\u0438 \u0441\u0430\u043c\u044b\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442 \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0435\u0433\u043e \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043d\u0430 \u0432\u0445\u043e\u0434 \u0437\u0430\u043f\u0440\u043e\u0441\u0443. \u0417\u043d\u0430\u044f \u0434\u0430\u0442\u0443 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u044d\u0442\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430, \u043d\u0435\u0441\u043b\u043e\u0436\u043d\u043e \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u043e\u0442\u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0441\u0440\u0435\u0437 \u0434\u0430\u043d\u043d\u044b\u0445, \u0441\u044d\u043a\u043e\u043d\u043e\u043c\u0438\u0432 \u043d\u0430 \u0442\u0440\u0430\u0444\u0438\u043a\u0435.\u0420\u0430\u0441\u0448\u0438\u0440\u0438\u043c \u043d\u0430\u0448 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442, \u0434\u043e\u0431\u0430\u0432\u0438\u0432 \u0434\u0430\u0442\u0443 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u0430 createdAt:{&#171;id&#187;: &#171;23571ab2-2b98-4b5f-a3b1-e4ca19d1031c&#187;,&#187;name&#187;: &#171;Example Name&#187;,&#187;createdAt&#187;: &#171;2026-07-12T12:00:00.000&#8243;,&#187;type&#187;: &#171;Rule&#187;}\u0414\u043e\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a, \u0447\u0442\u043e\u0431\u044b \u043e\u043d \u0441\u0442\u0430\u043b \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:def get_messages(collection: AsyncCollection, return_after: UUID | None = None) -&gt; tuple[dict]:messages = []last_sent = Noneif return_after:await for rule in collection.find(filter=MATCH | {&#171;id&#187;: return_after}):last_sent = rulebreak_filter = {**MATCH}if last_sent:_filter |= {&#171;id&#187;: {&#171;$ne&#187;: last_sent[&#171;id&#187;]},&#187;createdAt&#187;: {&#171;$gte&#187;: last_sent[&#171;createdAt&#187;]},}await for rule in collection.find(filter=_filter):messages.append({&#171;id&#187;: str(rule[&#171;id&#187;]),  # \u041a\u043e\u043d\u0432\u0435\u0440\u0442\u0430\u0446\u0438\u044f `uuid.UUID` \u043a `str`.&#187;name&#187;: rule[&#171;name&#187;],&#187;createdAt&#187;: rule[&#171;createdAt&#187;],&#187;type&#187;: rule[&#171;type&#187;],})return tuple(messages))\u0418 \u0431\u0438\u0437\u043d\u0435\u0441 \u0441\u044b\u0442, \u0438 \u0441\u0435\u0442\u044c \u0446\u0435\u043b\u0430. \u041d\u043e \u0432\u043e\u0442 \u043d\u0435\u0437\u0430\u0434\u0430\u0447\u0430: \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c \u0432 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0435 \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u0438\u0435! \u041a\u0430\u043a \u043e\u0442\u0440\u0430\u0437\u0438\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043d\u0430\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u0438\u0439 \u0443\u0436\u0435 \u0432\u044b\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0445 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439? \u0424\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u044f \u043f\u043e \u0434\u0430\u0442\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0442\u0443\u0442 \u043d\u0438\u0447\u0435\u043c \u043d\u0435 \u043f\u043e\u043c\u043e\u0436\u0435\u0442.\u041f\u043e\u0442\u043e\u043a\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439\u0414\u043b\u044f \u0442\u0430\u043a\u0438\u0445 \u0437\u0430\u0434\u0430\u0447 \u0432 MongoDB \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u044b \u043f\u043e\u0442\u043e\u043a\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 (Change Streams) \u2013 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u043f\u043e \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u044e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0438. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043f\u043e\u0442\u043e\u043a\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439, \u043d\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043c\u043e\u0436\u0435\u0442 \u0441\u043b\u0435\u0434\u0438\u0442\u044c \u0437\u0430 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445, \u043c\u043e\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u043e \u0441\u043e\u043e\u0431\u0449\u0430\u044f \u043e\u0431\u043e \u0432\u0441\u0435\u0445 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u043a\u0430\u0445 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044e.\u041f\u043e\u0442\u043e\u043a\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u043d\u0430 \u0442\u0440\u0451\u0445 \u0443\u0440\u043e\u0432\u043d\u044f\u0445:\u0432\u0435\u0441\u044c \u0434\u0435\u043f\u043b\u043e\u0439\u043c\u0435\u043d\u0442;\u0431\u0430\u0437\u0430 \u0434\u0430\u043d\u043d\u044b\u0445;\u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044f.\u0422\u0430\u043a\u0436\u0435 \u043f\u043e\u0442\u043e\u043a\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0430 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430 \u0430\u0433\u0440\u0435\u0433\u0430\u0446\u0438\u0439. \u041c\u044b \u043c\u043e\u0436\u0435\u043c \u043e\u0442\u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u043f\u0430\u0434\u0430\u044e\u0442 \u043d\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0432 \u043d\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435. \u042d\u0442\u043e \u043f\u043e\u043b\u0435\u0437\u043d\u043e, \u0435\u0441\u043b\u0438 \u0432 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u0441\u044f \u0434\u0440\u0443\u0433\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b, \u043d\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u044e\u0449\u0438\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f: \u0434\u043e\u0431\u0430\u0432\u0438\u0432 \u0448\u0430\u0433 \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438 $match, \u043c\u043e\u0436\u043d\u043e \u0443\u043c\u0435\u043d\u044c\u0448\u0438\u0442\u044c \u043f\u043e\u0442\u043e\u043a \u0441\u043e\u0431\u044b\u0442\u0438\u0439, \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c\u044b\u0439 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c.\u041f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u043a\u043e\u043d\u0432\u0435\u0439\u0435\u0440 \u0430\u0433\u0440\u0435\u0433\u0430\u0446\u0438\u0438, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0449\u0438\u0439 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0442\u0438\u043f\u0430 &#171;insert&#187;, &#171;update&#187; \u0438 &#171;delete&#187; \u0434\u043b\u044f \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0442\u0438\u043f\u0430 &#171;Rule&#187;:WATCH_PIPELINE = [{&#171;$match&#187;: {&#171;operationType&#187;: {&#171;$in&#187;: [&#171;insert&#187;, &#171;update&#187;, &#171;delete&#187;]},&#187;fullDocument.type&#187;: &#171;Rule&#187;,  # \u0415\u0441\u043b\u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434\u0443 `watch` \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 `full_document=&#187;updateLookup&#187;`, \u043c\u043e\u0436\u043d\u043e \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u043c\u0443 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430 \u0447\u0435\u0440\u0435\u0437 \u0430\u0442\u0440\u0438\u0431\u0443\u0442 `fullDocument`.},},]\u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0442\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438. \u0420\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0439 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u0441\u043e\u0431\u044b\u0442\u0438\u0439:from pymongo.asynchronous.collection import AsyncCollectionasync def watch_collection(    pipeline: dict,collection: AsyncCollection,    resume_token=None):    async with await coll.watch(pipeline, full_document=&#187;updateLookup&#187;, resume_after=resume_token) as stream:        async for change in stream:            yield change, stream.resume_token\u0412\u043e\u0437\u043d\u0438\u043a\u0430\u0435\u0442 \u0437\u0430\u043a\u043e\u043d\u043e\u043c\u0435\u0440\u043d\u044b\u0439 \u0432\u043e\u043f\u0440\u043e\u0441: \u043a\u0430\u043a \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u044d\u0442\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044e? GET-\u0437\u0430\u043f\u0440\u043e\u0441 \u0434\u043b\u044f \u0442\u0430\u043a\u0438\u0445 \u0437\u0430\u0434\u0430\u0447, \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e, \u043d\u0435 \u043f\u0440\u0438\u0433\u043e\u0434\u0435\u043d. \u041a\u0430\u043a \u0432\u0430\u0440\u0438\u0430\u043d\u0442, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c API \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f, \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u044f \u0435\u043c\u0443 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043f\u043e \u043c\u0435\u0440\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043d\u043e\u0432\u044b\u0445 \u0438\u043b\u0438 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432. \u0410 \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0432 \u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u0435\u0441\u043b\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044c \u0438\u043b\u0438 \u043d\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043e\u043a\u0430\u0437\u0430\u043b\u0438\u0441\u044c \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b?\u0410 \u0435\u0441\u043b\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044c \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d?\u041c\u043e\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439. \u042d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u044b\u043c \u0440\u0435\u0448\u0435\u043d\u0438\u0435\u043c \u0431\u0435\u0437 \u0443\u0441\u043b\u043e\u0436\u043d\u0435\u043d\u0438\u044f \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b. \u0412\u0441\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c\u044b\u0435 \u0431\u0430\u0437\u043e\u0439 \u0434\u0430\u043d\u043d\u044b\u0445, \u043f\u043e\u043c\u0435\u0449\u0430\u044e\u0442\u0441\u044f \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044e \u043d\u0435 \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u0438\u0442\u0441\u044f \u0434\u043e \u0442\u0435\u0445 \u043f\u043e\u0440, \u043f\u043e\u043a\u0430 \u043e\u043d \u043d\u0435 \u043e\u0431\u044a\u044f\u0432\u0438\u0442\u0441\u044f &#171;\u0432 \u0441\u0435\u0442\u0438&#187;.\u041f\u0440\u0438\u043c\u0435\u0440 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0433\u043e \u0446\u0438\u043a\u043b\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430 FIFO-\u043e\u0447\u0435\u0440\u0435\u0434\u0438, \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 asyncio:from asyncio import create_task, gather, Queuefrom logging import getLoggerlogger = getLogger()EVENT_QUEUES_DICT: dict[str, Queue] = {}  # \u0422\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0439, \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044f \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0438\u0437\u0432\u043d\u0435: \u043a \u043f\u0440\u0438\u043c\u0435\u0440\u0443, \u0434\u043b\u044f \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u0430 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043e\u0447\u0435\u0440\u0435\u0434\u0435\u0439.def get_listener_label(db: str, collection: str) -&gt; str:&#187;&#187;&#187;\u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043a\u043b\u044e\u0447 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0432 \u0441\u043b\u043e\u0432\u0430\u0440\u0435 `EVENT_QUEUES_DICT` \u0434\u043b\u044f \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0439 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438 `collection` \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 `db`.&#187;&#187;&#187;    return f&#187;{db}.{coll}&#187;def get_queue_length(db: str, collection: str) -&gt; int:&#187;&#187;&#187;\u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0440\u0430\u0437\u043c\u0435\u0440 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0434\u043b\u044f \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0439 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438 `collection` \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 `db`.&#187;&#187;&#187;    listener_label = get_listener_label(db, collection)    try:        events_queue = EVENT_QUEUES_DICT[listener_label]    except KeyError as ex:        logger.error(f&#187;\u041e\u0447\u0435\u0440\u0435\u0434\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0434\u043b\u044f \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438 &#8216;{db}.{collection}&#8217; \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442.&#187;)        raise ex    return events_queue.qsize()def process_event(event: dict) -&gt; dict | None:&#187;&#187;&#187;\u041e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0441\u043e\u0431\u044b\u0442\u0438\u0435, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044f \u0441\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435.&#187;&#187;&#187;full_document = event.get(&#171;fullDocument&#187;)if full_document is None:return Nonereturn {&#171;id&#187;: str(full_document[&#171;id&#187;]),  # \u041a\u043e\u043d\u0432\u0435\u0440\u0442\u0430\u0446\u0438\u044f `uuid.UUID` \u043a `str`.&#187;name&#187;: full_document[&#171;name&#187;],&#187;type&#187;: full_document[&#171;type&#187;],}def send_message(message):&#187;&#187;&#187;TODO&#187;&#187;&#187;&#8230;async def listen_collection(collection: AsyncCollection, max_event_queue_size: int = 100000):db_name, collection_name = collection.database.name, collection.nameevents_queue = Queue(maxsize=int(max_event_queue_size))EVENT_QUEUES_DICT[get_listener_label(db_name, collection_name)] = events_queueasync def watch_collection_task_wrapper(queue: Queue, resume_token=None):while True:try:async for event, resume_token in watch_collection(WATCH_PIPELINE, params, app, resume_token=resume_token):await queue.put(event)logger.info(f&#187;\u0420\u0430\u0437\u043c\u0435\u0440 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 &#8216;{db_name}.{collection_name}&#8217;: {queue.qsize()}.&#187;)except Exception as ex:logger.error(f&#187;\u041f\u0440\u0438 \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u0435 {db_name}.{collection_name} \u0432\u043e\u0437\u043d\u0438\u043a\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430. &#171;f&#187;\u041c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433 \u0431\u0443\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0449\u0435\u043d{&#8216; \u0441 \u0442\u043e\u043a\u0435\u043d\u043e\u043c \u0432\u043e\u0437\u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f&#8217;}.&#187;,exc_info=ex,)logger.debug(f&#187;\u0422\u043e\u043a\u0435\u043d \u0432\u043e\u0437\u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f: {resume_token}.&#187;)continueawait queue.put(None)    async def event_loop(queue: Queue):        while True:            logger.info(f&#187;\u041e\u0436\u0438\u0434\u0430\u044e \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u0434\u043b\u044f &#8216;{db_name}.{collection_name}&#8217;&#8230;&#187;)            event = await queue.get()            if event is None:                break            logger.debug(f&#187;\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u0435:\\n{event}&#187;)message =&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-489488","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/489488","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=489488"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/489488\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=489488"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=489488"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=489488"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}