| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335 | 
							- from typing import Optional, Awaitable
 
- import pandas as pd
 
- import numpy as np
 
- import datetime
 
- import pymysql
 
- from sqlalchemy import create_engine
 
- import simplejson
 
- import requests
 
- import tornado.web
 
- import pandas as pd
 
- import json
 
- import numpy as np
 
- import datetime
 
- from sqlalchemy import create_engine
 
- from db_config import *
 
- import traceback
 
- import uuid
 
- class AiStrategyRequestParse(tornado.web.RequestHandler):
 
-     def initialize(self, logger):
 
-         self.logger = logger
 
-     def post(self):
 
-         data = self.request.body
 
-         data = str(data, 'utf8')
 
-         data = json.loads(data, encoding='utf8')
 
-         self.logger.info("***************************************  NEW REQUEST ***************************************")
 
-         self.logger.info("raw data from request is %s" % data)
 
-         create_group_and_creative_response_data = None
 
-         # 1、新增广告组操作
 
-         try:
 
-             if data["operation_type"] == 1:
 
-                 inst = ParseAddCampaignOrAddGroupRequest(data)
 
-                 inst.get_advertiser_strategy_info()
 
-                 inst.write_intelligence_strategy_table()
 
-                 if inst.campaign_id == "" or inst.campaign_id is None:
 
-                     if inst.add_campaign() == -1:
 
-                         self.write(json.dumps({"message": "广告计划创建失败"}))
 
-                         self.flush()
 
-                         return
 
-                 inst.get_group_dict()
 
-                 create_group_and_creative_res = inst.res_data
 
-                 print("create_group_and_creative_res: ", create_group_and_creative_res)
 
-                 request = requests.post(create_group_and_creative_url, create_group_and_creative_res)
 
-                 create_group_and_creative_response_data = simplejson.loads(request.text)
 
-         except Exception:
 
-             self.logger.error(traceback.format_exc())
 
-         # 返回接口结果
 
-         self.write(json.dumps({'account_id': inst.account_id,'ai_strategy_id': inst.ai_strategy_uuid,
 
-                                'message': create_group_and_creative_response_data}))
 
-         self.flush()
 
- # 该类解析的是 手动请求的新增广告计划或者新增广告组的数据
 
- class ParseAddCampaignOrAddGroupRequest(object):
 
-     def __init__(self, request_data):
 
-         self.ai_strategy_uuid = str(uuid.uuid4())
 
-         self.request_data = request_data
 
-         self.video = self.request_data['video']
 
-         self.account_id = self.request_data['account_id']
 
-         self.campaign_info = self.request_data['campaign_info']
 
-         self.campaign_id = self.request_data['campaign_info'].get('campaign_id', None)
 
-         self.group_info = self.request_data['group_info']
 
-         self.creative_info = self.request_data['creative_info']
 
-         self.operation_type = self.request_data['operation_type']
 
-         self.advertiser_strategy_id = None
 
-         self.advertiser_strategy = {}
 
-         self.res_data = {}
 
-     def get_advertiser_strategy_info(self):
 
-         """
 
-         获取指定账户下客户的策略信息
 
-         为后续的写入库表,校验一致性做准备
 
-         :return:
 
-         """
 
-         sql = """
 
-         select * 
 
-         from ctop_ai_kuaishou_advertiser_strategy 
 
-         where account_id = %d 
 
-         and status = 1
 
-         limit 1
 
-         """ % self.account_id
 
-         advertiser_strategy_df = pd.read_sql(sql, engine)
 
-         self.advertiser_strategy_id = advertiser_strategy_df['id'].values[0]
 
-         self.advertiser_strategy = advertiser_strategy_df.T.to_dict()[0]
 
-     def write_intelligence_strategy_table(self):
 
-         """
 
-         请求信息写入 ctop_ai_kuaishou_intelligence_strategy 表中
 
-         :return:
 
-         """
 
-         intelligence_strategy_dict = \
 
-             {
 
-                 'ai_strategy_uuid': self.ai_strategy_uuid,
 
-                 'advertiser_strategy_id': self.advertiser_strategy_id,
 
-                 'account_id': self.account_id,
 
-                 'ai_strategy_request_content': str(self.request_data),
 
-                 'ai_strategy_remark': self.request_data['ai_strategy_remark'],
 
-                 'create_time': datetime.datetime.now()
 
-             }
 
-         df = pd.DataFrame.from_dict(intelligence_strategy_dict, orient='index').T
 
-         df.to_sql(name="ctop_ai_kuaishou_intelligence_strategy", con=engine, if_exists='append', index=False)
 
-     # 如果手动请求的数据结构中,"campaign" 中的 campaign_id 为空则调用该新增计划方法
 
-     def add_campaign(self):
 
-         """
 
-         新增广告计划
 
-         :return:
 
-         """
 
-         # 1、校验请求信息中 有没有 与客户策略信息 中存在冲突的地方 -- 计划层级只判断 campaign_type
 
-         if self.campaign_info['campaign_type'] != self.advertiser_strategy['campaign_type']:
 
-             self.logger.info("客户策略的campaign_type: %d 和 AI策略的campaign_type:%d 不一致!" %
 
-                              (self.advertiser_strategy['campaign_type'],
 
-                               self.campaign_info['campaign_type']))
 
-             return -1
 
-         # TODO 待联调测试
 
-         # create_campaign_req_data = {
 
-         #                             'account_id': self.account_id,
 
-         #                             'campaign_name': self.campaign_info['campaign_name'],
 
-         #                             'type': self.campaign_info['campaign_type']
 
-         #                             }
 
-         # request = requests.post(create_campaign_url, create_campaign_req_data)
 
-         # res_data = simplejson.loads(request.text)
 
-         res_data = {
 
-             "code": 0,
 
-             "data": {
 
-                 "account_id": 23212,
 
-                 "campaign_id": 30956133,
 
-                 "campaign_create_time": "2021-01-13 13:50:16"
 
-             },
 
-             "message": "SUCCESS"}
 
-         if res_data['code'] == 0:
 
-             self.campaign_id = res_data['data']['campaign_id']
 
-             campaign_info_to_db = {
 
-                                    'campaign_uuid': str(uuid.uuid4()),
 
-                                    'account_id': self.account_id,
 
-                                    'ai_strategy_uuid': self.ai_strategy_uuid,
 
-                                    'campaign_name': self.campaign_info['campaign_name'],
 
-                                    'campaign_id': self.campaign_id,
 
-                                    'campaign_type': self.campaign_info['campaign_type'],
 
-                                    'operation_type': self.operation_type,
 
-                                    'campaign_create_time': res_data['data']['campaign_create_time'],
 
-                                    'create_time': datetime.datetime.now()
 
-                                    }
 
-             df = pd.DataFrame.from_dict(campaign_info_to_db, orient='index').T
 
-             df.to_sql(name="ctop_ai_kuaishou_campaign_level_operation_record", con=engine, if_exists='append', index=False)
 
-         else:
 
-             self.logger.info("广告计划创建失败:%s" % res_data['message'])
 
-             return -1
 
-     def get_group_dict(self):
 
-         """
 
-         拼接组和创意层级参数
 
-         写入数据库
 
-         返回 table_id
 
-         :return:
 
-         """
 
-         # 1、TODO 校验请求信息中 有没有 与客户策略信息 中存在冲突的地方 -- 暂时不实现
 
-         # 客户策略 和 请求信息 都有值 才会进行校验比对操作 -- 不得高于,不得不等于,不得超过集合
 
-         # 因此分为3类 字段
 
-         # is_equal_cols = ['template_id','bid_type']
 
-         # is_less_than_cols = []
 
-         # is_contain_cols = []
 
-         #
 
-         # for col in is_equal_cols:
 
-         #     if (self.advertiser_strategy[col] is not None) and \
 
-         #             (self.group_info.get(col, None) is not None) and \
 
-         #             (self.group_info.get(col) != self.advertiser_strategy[col]):
 
-         #         return -1
 
-         #
 
-         # for col in is_less_than_cols:
 
-         #     if (self.advertiser_strategy[col] is not None) and \
 
-         #             (self.group_info.get(col, None) is not None) and \
 
-         #             (self.group_info.get(col) > self.advertiser_strategy[col]):
 
-         #         return -1
 
-         #
 
-         # for col in is_contain_cols:
 
-         #     if (self.advertiser_strategy[col] is not None) and \
 
-         #             (self.group_info.get(col, None) is not None) and \
 
-         #             (self.group_info.get(col) > self.advertiser_strategy[col]):
 
-         #         return -1
 
-         basic_group_info = {'template_id': self.advertiser_strategy['template_id'],
 
-                                  'bid_type': self.advertiser_strategy['bid_type'],
 
-                                  'use_app_market': self.advertiser_strategy['use_app_market'],
 
-                                  'app_store': self.advertiser_strategy['app_store'],
 
-                                  'bid': self.advertiser_strategy['bid'],
 
-                                  'cpa_bid': self.advertiser_strategy['cpa_bid'],
 
-                                  'smart_bid': self.advertiser_strategy['smart_bid'],
 
-                                  'ocpx_action_type': self.advertiser_strategy['ocpx_action_type'],
 
-                                  'deep_conversion_type': self.advertiser_strategy['deep_conversion_type'],
 
-                                  'roi_ratio': self.advertiser_strategy['roi_ratio'],
 
-                                  'scene_id': self.advertiser_strategy['scene_id'],
 
-                                  'unit_type': self.advertiser_strategy['unit_type'],
 
-                                  'begin_time': self.advertiser_strategy['begin_time'],
 
-                                  'end_time': self.advertiser_strategy['end_time'],
 
-                                  'schedule_time': self.advertiser_strategy['schedule_time'],
 
-                                  'convert_id': self.advertiser_strategy['convert_id'],
 
-                                  'url_type': self.advertiser_strategy['url_type'],
 
-                                  'web_uri_type': self.advertiser_strategy['web_uri_type'],
 
-                                  'url': self.advertiser_strategy['url'],
 
-                                  'schema_uri': self.advertiser_strategy['schema_uri'],
 
-                                  'app_id': self.advertiser_strategy['app_id'],
 
-                                  'show_mode': self.advertiser_strategy['show_mode'],
 
-                                  'speed': self.advertiser_strategy['speed'],
 
-                                  'site_type': self.advertiser_strategy['site_type'],
 
-                                  'gift_data': self.advertiser_strategy['gift_data'],
 
-                                  'video_landing_page': self.advertiser_strategy['video_landing_page'],
 
-                                  'auto_target': self.advertiser_strategy['auto_target'],
 
-                                  'auto_create_photo': self.advertiser_strategy['auto_create_photo'],
 
-                                  'region': self.advertiser_strategy['region'],
 
-                                  'district_ids': self.advertiser_strategy['district_ids'],
 
-                                  'user_type': self.advertiser_strategy['user_type'],
 
-                                  'age_min': self.advertiser_strategy['age_min'],
 
-                                  'age_max': self.advertiser_strategy['age_max'],
 
-                                  'ages_range': self.advertiser_strategy['ages_range'],
 
-                                  'gender': self.advertiser_strategy['gender'],
 
-                                  'platform_os': self.advertiser_strategy['platform_os'],
 
-                                  'android_osv': self.advertiser_strategy['android_osv'],
 
-                                  'ios_osv': self.advertiser_strategy['ios_osv'],
 
-                                  'network': self.advertiser_strategy['network'],
 
-                                  'device_brand': self.advertiser_strategy['device_brand'],
 
-                                  'device_price': self.advertiser_strategy['device_price'],
 
-                                  'business_interest_type': self.advertiser_strategy['business_interest_type'],
 
-                                  'business_interest': self.advertiser_strategy['business_interest'],
 
-                                  'fans_star': self.advertiser_strategy['fans_star'],
 
-                                  'interest_video': self.advertiser_strategy['interest_video'],
 
-                                  'app_interest': self.advertiser_strategy['app_interest'],
 
-                                  'app_ids': self.advertiser_strategy['app_ids'],
 
-                                  'filter_converted_level': self.advertiser_strategy['filter_converted_level'],
 
-                                  'population': self.advertiser_strategy['population'],
 
-                                  'exclude_population': self.advertiser_strategy['exclude_population'],
 
-                                  'paid_audience': self.advertiser_strategy['paid_audience'],
 
-                                  'is_open': self.advertiser_strategy['is_open'],
 
-                                  'no_age_break': self.advertiser_strategy['no_age_break'],
 
-                                  'no_gender_break': self.advertiser_strategy['no_gender_break'],
 
-                                  'no_area_break': self.advertiser_strategy['no_area_break'],
 
-                                  'behavior_interest': self.advertiser_strategy['behavior_interest']}
 
-         # 3、从请求的信息中更新计划层级信息
 
-         if len(self.group_info) > 0:
 
-             for key, value in self.group_info.items():
 
-                 basic_group_info.update({key: value})
 
-         self.res_data['group_list'] = []
 
-         group_cnt = 1
 
-         for video in self.video:
 
-             single_group_info = {'group_uuid': str(uuid.uuid4())}
 
-             single_group_info.update(basic_group_info)
 
-             single_group_info['unit_name'] = self.group_info['unit_name'] + '-' + str(group_cnt)
 
-             # 组信息写入数据表中
 
-             single_group_info_to_db = single_group_info.copy()
 
-             single_group_info_to_db['ai_strategy_uuid'] = self.ai_strategy_uuid
 
-             single_group_info_to_db['account_id'] = self.account_id
 
-             single_group_info_to_db['campaign_id'] = self.campaign_id
 
-             single_group_info_to_db['create_time'] = datetime.datetime.now()
 
-             single_group_info_to_db['operation_type'] = self.operation_type
 
-             df = pd.DataFrame.from_dict(single_group_info_to_db, orient='index').T
 
-             engine = create_engine(db_con_str, connect_args={'charset': 'utf8'})
 
-             df.to_sql(name="ctop_ai_kuaishou_unit_level_operation_record",
 
-                       con=engine,
 
-                       if_exists='append',
 
-                       index=False)
 
-             single_group_info['creative_list'] = []
 
-             group_cnt += 1
 
-             creative_cnt = 1
 
-             for image in video['imageList']:
 
-                 single_creative_info = {
 
-                     'creative_uuid': str(uuid.uuid4()),
 
-                     'is_sticky': 0,
 
-                     'creative_name': self.creative_info['creative_name'] + '_' + str(creative_cnt),
 
-                     'photo_id': video['photo_id'],
 
-                     'image_md5': image,  # TODO 需要和蒙蒙确认字段名称
 
-                     'image_tokens': self.creative_info.get('image_tokens'),
 
-                     'action_bar_text': self.creative_info['action_bar_text'],
 
-                     'description': self.creative_info['description'],
 
-                     'short_slogan': self.creative_info.get('short_slogan'),
 
-                     'sticker_title': self.creative_info.get('sticker_title'),
 
-                     'overlay_type': self.creative_info.get('overlay_type'),
 
-                     'expose_tag': self.creative_info.get('expose_tag'),
 
-                     'new_expose_tag': self.creative_info.get('new_expose_tag'),
 
-                     'site_id': self.creative_info.get('site_id'),
 
-                     'click_track_url': self.advertiser_strategy.get('click_track_url'),
 
-                     'impression_url': self.advertiser_strategy.get('impression_url'),
 
-                     'ad_photo_played_t3s_url': self.advertiser_strategy.get('ad_photo_played_t3s_url'),
 
-                     'actionbar_click_url': self.advertiser_strategy.get('actionbar_click_url'),
 
-                     'creative_category': self.creative_info.get('creative_category'),
 
-                     'creative_tag': self.creative_info.get('creative_tag')}
 
-                 single_group_info['creative_list'].append(single_creative_info)
 
-                 # 创意层级写入数据表中
 
-                 single_creative_info_to_db = single_creative_info.copy()
 
-                 single_creative_info_to_db['ai_strategy_uuid'] = self.ai_strategy_uuid
 
-                 single_creative_info_to_db['account_id'] = self.account_id
 
-                 single_creative_info_to_db['campaign_id'] = self.campaign_id
 
-                 single_creative_info_to_db['create_time'] = datetime.datetime.now()
 
-                 single_creative_info_to_db['operation_type'] = self.operation_type
 
-                 df = pd.DataFrame.from_dict(single_creative_info_to_db, orient='index').T
 
-                 engine = create_engine(db_con_str, connect_args={'charset': 'utf8'})
 
-                 df.to_sql(name="ctop_ai_kuaishou_creative_level_operation_record",
 
-                           con=engine,
 
-                           if_exists='append',
 
-                           index=False)
 
-                 creative_cnt += 1
 
-             # 组和创意信息添加到最终返回数据 group_list 中
 
-             self.res_data['group_list'].append(single_group_info)
 
-         self.res_data['account_id'] = self.account_id
 
-         self.res_data['campaign_id'] = self.campaign_id
 
- # TODO 修改操作
 
- class ParseModifyRequest(object):
 
-     def __init__(self):
 
-         pass
 
- # TODO 关停操作
 
- class ParseShutDownRequest(object):
 
-     def __init__(self):
 
-         pass
 
 
  |