tencentcloud-sdk-python 3.0.1491__py2.py3-none-any.whl → 3.1.6__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tencentcloud/__init__.py +1 -1
- tencentcloud/aai/v20180522/aai_client_async.py +100 -0
- tencentcloud/aca/v20210323/aca_client_async.py +170 -0
- tencentcloud/acp/v20220105/acp_client_async.py +170 -0
- tencentcloud/advisor/v20200721/advisor_client_async.py +62 -0
- tencentcloud/af/v20200226/af_client_async.py +86 -0
- tencentcloud/afc/v20200226/afc_client_async.py +82 -0
- tencentcloud/ags/v20250920/ags_client_async.py +243 -0
- tencentcloud/ai3d/v20250513/ai3d_client_async.py +102 -0
- tencentcloud/aiart/v20221229/aiart_client_async.py +513 -0
- tencentcloud/ame/v20190916/ame_client_async.py +586 -0
- tencentcloud/ams/v20200608/ams_client_async.py +179 -0
- tencentcloud/ams/v20201229/ams_client_async.py +169 -0
- tencentcloud/anicloud/v20220923/anicloud_client_async.py +80 -0
- tencentcloud/antiddos/v20200309/antiddos_client_async.py +1718 -0
- tencentcloud/ape/v20200513/ape_client_async.py +170 -0
- tencentcloud/api/v20201106/api_client_async.py +80 -0
- tencentcloud/apigateway/v20180808/apigateway_client_async.py +1830 -0
- tencentcloud/apm/v20210622/apm_client_async.py +495 -0
- tencentcloud/asr/v20190614/asr_client_async.py +647 -0
- tencentcloud/asw/v20200722/asw_client_async.py +188 -0
- tencentcloud/autoscaling/v20180419/autoscaling_client.py +1 -0
- tencentcloud/autoscaling/v20180419/autoscaling_client_async.py +1230 -0
- tencentcloud/autoscaling/v20180419/models.py +36 -0
- tencentcloud/ba/v20200720/ba_client_async.py +81 -0
- tencentcloud/batch/v20170312/batch_client_async.py +582 -0
- tencentcloud/bda/v20200324/bda_client_async.py +116 -0
- tencentcloud/bh/v20230418/bh_client.py +230 -0
- tencentcloud/bh/v20230418/bh_client_async.py +1844 -0
- tencentcloud/bh/v20230418/models.py +1677 -216
- tencentcloud/bi/v20220105/bi_client_async.py +548 -0
- tencentcloud/billing/v20180709/billing_client_async.py +1149 -0
- tencentcloud/bizlive/v20190313/bizlive_client_async.py +134 -0
- tencentcloud/bm/v20180423/bm_client_async.py +1012 -0
- tencentcloud/bma/v20210624/bma_client_async.py +530 -0
- tencentcloud/bma/v20221115/bma_client_async.py +224 -0
- tencentcloud/bmeip/v20180625/bmeip_client_async.py +386 -0
- tencentcloud/bmlb/v20180625/bmlb_client_async.py +908 -0
- tencentcloud/bmvpc/v20180625/bmvpc_client_async.py +1171 -0
- tencentcloud/bpaas/v20181217/bpaas_client_async.py +62 -0
- tencentcloud/bri/v20190328/bri_client_async.py +58 -0
- tencentcloud/bsca/v20210811/bsca_client_async.py +152 -0
- tencentcloud/btoe/v20210303/btoe_client_async.py +267 -0
- tencentcloud/btoe/v20210514/btoe_client_async.py +287 -0
- tencentcloud/ca/v20230228/ca_client_async.py +80 -0
- tencentcloud/cam/v20190116/cam_client_async.py +1684 -0
- tencentcloud/captcha/v20190722/captcha_client_async.py +350 -0
- tencentcloud/car/v20220110/car_client_async.py +134 -0
- tencentcloud/cat/v20180409/cat_client_async.py +279 -0
- tencentcloud/cbs/v20170312/cbs_client_async.py +959 -0
- tencentcloud/ccc/v20200210/ccc_client_async.py +1494 -0
- tencentcloud/ccc/v20200210/models.py +15 -0
- tencentcloud/cdb/v20170320/cdb_client_async.py +3254 -0
- tencentcloud/cdb/v20170320/models.py +74 -44
- tencentcloud/cdc/v20201214/cdc_client_async.py +440 -0
- tencentcloud/cdn/v20180606/cdn_client_async.py +1090 -0
- tencentcloud/cds/v20180420/cds_client_async.py +116 -0
- tencentcloud/cdwch/v20200915/cdwch_client_async.py +548 -0
- tencentcloud/cdwch/v20200915/models.py +34 -4
- tencentcloud/cdwdoris/v20211228/cdwdoris_client_async.py +1106 -0
- tencentcloud/cdwpg/v20201230/cdwpg_client_async.py +458 -0
- tencentcloud/cdz/v20221123/cdz_client_async.py +62 -0
- tencentcloud/cfg/v20210820/cfg_client_async.py +332 -0
- tencentcloud/cfs/v20190719/cfs_client_async.py +1054 -0
- tencentcloud/cfs/v20190719/models.py +40 -0
- tencentcloud/cfw/v20190904/cfw_client.py +23 -0
- tencentcloud/cfw/v20190904/cfw_client_async.py +2067 -0
- tencentcloud/cfw/v20190904/models.py +784 -8
- tencentcloud/chc/v20230418/chc_client_async.py +710 -0
- tencentcloud/chdfs/v20190718/chdfs_client_async.py +546 -0
- tencentcloud/chdfs/v20201112/chdfs_client_async.py +548 -0
- tencentcloud/ciam/v20220331/ciam_client_async.py +440 -0
- tencentcloud/cii/v20201210/cii_client_async.py +80 -0
- tencentcloud/cii/v20210408/cii_client_async.py +262 -0
- tencentcloud/cim/v20190318/cim_client_async.py +44 -0
- tencentcloud/ckafka/v20190819/ckafka_client.py +92 -0
- tencentcloud/ckafka/v20190819/ckafka_client_async.py +1701 -0
- tencentcloud/ckafka/v20190819/errorcodes.py +3 -0
- tencentcloud/ckafka/v20190819/models.py +741 -62
- tencentcloud/clb/v20180317/clb_client_async.py +1683 -0
- tencentcloud/cloudapp/v20220530/cloudapp_client_async.py +175 -0
- tencentcloud/cloudaudit/v20190319/cloudaudit_client_async.py +372 -0
- tencentcloud/cloudhsm/v20191112/cloudhsm_client_async.py +278 -0
- tencentcloud/cloudhsm/v20191112/models.py +49 -0
- tencentcloud/cloudstudio/v20230508/cloudstudio_client_async.py +188 -0
- tencentcloud/cls/v20201016/cls_client.py +92 -0
- tencentcloud/cls/v20201016/cls_client_async.py +2362 -0
- tencentcloud/cls/v20201016/models.py +1427 -74
- tencentcloud/cme/v20191029/cme_client_async.py +983 -0
- tencentcloud/cmq/v20190304/cmq_client_async.py +62 -0
- tencentcloud/cms/v20190321/cms_client_async.py +134 -0
- tencentcloud/common/abstract_client_async.py +654 -0
- tencentcloud/common/common_client_async.py +45 -0
- tencentcloud/common/http/request_async.py +62 -0
- tencentcloud/common/retry_async.py +87 -0
- tencentcloud/config/v20220802/config_client_async.py +152 -0
- tencentcloud/controlcenter/v20230110/controlcenter_client_async.py +116 -0
- tencentcloud/cpdp/v20190820/cpdp_client_async.py +3979 -0
- tencentcloud/csip/v20221121/csip_client.py +1 -1
- tencentcloud/csip/v20221121/csip_client_async.py +1502 -0
- tencentcloud/csip/v20221121/models.py +105 -0
- tencentcloud/csxg/v20230303/csxg_client_async.py +116 -0
- tencentcloud/ctem/v20231128/ctem_client.py +644 -0
- tencentcloud/ctem/v20231128/ctem_client_async.py +1124 -0
- tencentcloud/ctem/v20231128/models.py +4999 -711
- tencentcloud/ctsdb/v20230202/ctsdb_client_async.py +69 -0
- tencentcloud/cvm/v20170312/cvm_client.py +1 -1
- tencentcloud/cvm/v20170312/cvm_client_async.py +2025 -0
- tencentcloud/cvm/v20170312/errorcodes.py +3 -0
- tencentcloud/cvm/v20170312/models.py +14 -14
- tencentcloud/cwp/v20180228/cwp_client_async.py +9288 -0
- tencentcloud/cws/v20180312/cws_client_async.py +368 -0
- tencentcloud/cynosdb/v20190107/cynosdb_client_async.py +3068 -0
- tencentcloud/cynosdb/v20190107/models.py +99 -2
- tencentcloud/dasb/v20191018/dasb_client_async.py +1160 -0
- tencentcloud/dataagent/v20250513/dataagent_client_async.py +224 -0
- tencentcloud/dataagent/v20250513/models.py +15 -0
- tencentcloud/dayu/v20180709/dayu_client_async.py +2042 -0
- tencentcloud/dbbrain/v20191016/dbbrain_client_async.py +530 -0
- tencentcloud/dbbrain/v20210527/dbbrain_client.py +23 -0
- tencentcloud/dbbrain/v20210527/dbbrain_client_async.py +1538 -0
- tencentcloud/dbbrain/v20210527/models.py +463 -12
- tencentcloud/dbdc/v20201029/dbdc_client_async.py +134 -0
- tencentcloud/dc/v20180410/dc_client_async.py +425 -0
- tencentcloud/dcdb/v20180411/dcdb_client_async.py +1541 -0
- tencentcloud/dlc/v20210125/dlc_client.py +23 -0
- tencentcloud/dlc/v20210125/dlc_client_async.py +3322 -0
- tencentcloud/dlc/v20210125/errorcodes.py +9 -0
- tencentcloud/dlc/v20210125/models.py +1424 -17
- tencentcloud/dnspod/v20210323/dnspod_client_async.py +1710 -0
- tencentcloud/dnspod/v20210323/errorcodes.py +3 -0
- tencentcloud/dnspod/v20210323/models.py +2 -2
- tencentcloud/domain/v20180808/domain_client_async.py +1022 -0
- tencentcloud/drm/v20181115/drm_client_async.py +231 -0
- tencentcloud/ds/v20180523/ds_client_async.py +244 -0
- tencentcloud/dsgc/v20190723/dsgc_client_async.py +2452 -0
- tencentcloud/dsgc/v20190723/models.py +36 -36
- tencentcloud/dts/v20180330/dts_client_async.py +438 -0
- tencentcloud/dts/v20211206/dts_client.py +184 -0
- tencentcloud/dts/v20211206/dts_client_async.py +1480 -0
- tencentcloud/dts/v20211206/models.py +1275 -98
- tencentcloud/eb/v20210416/eb_client_async.py +602 -0
- tencentcloud/ecc/v20181213/ecc_client_async.py +100 -0
- tencentcloud/ecdn/v20191012/ecdn_client_async.py +162 -0
- tencentcloud/ecm/v20190719/ecm_client_async.py +2602 -0
- tencentcloud/eiam/v20210420/eiam_client_async.py +782 -0
- tencentcloud/eis/v20200715/eis_client_async.py +80 -0
- tencentcloud/eis/v20210601/eis_client_async.py +116 -0
- tencentcloud/emr/v20190103/emr_client.py +23 -0
- tencentcloud/emr/v20190103/emr_client_async.py +1659 -0
- tencentcloud/emr/v20190103/models.py +395 -0
- tencentcloud/es/v20180416/es_client_async.py +1209 -0
- tencentcloud/es/v20250101/es_client.py +6 -5
- tencentcloud/es/v20250101/es_client_async.py +216 -0
- tencentcloud/es/v20250101/models.py +6 -6
- tencentcloud/ess/v20201111/ess_client.py +6 -2
- tencentcloud/ess/v20201111/ess_client_async.py +3406 -0
- tencentcloud/ess/v20201111/models.py +468 -19
- tencentcloud/essbasic/v20201222/essbasic_client_async.py +1029 -0
- tencentcloud/essbasic/v20210526/essbasic_client.py +1 -1
- tencentcloud/essbasic/v20210526/essbasic_client_async.py +2757 -0
- tencentcloud/essbasic/v20210526/models.py +320 -6
- tencentcloud/evt/__init__.py +0 -0
- tencentcloud/evt/v20250217/__init__.py +0 -0
- tencentcloud/evt/v20250217/errorcodes.py +15 -0
- tencentcloud/evt/v20250217/evt_client.py +49 -0
- tencentcloud/evt/v20250217/evt_client_async.py +44 -0
- tencentcloud/evt/v20250217/models.py +228 -0
- tencentcloud/facefusion/v20181201/facefusion_client_async.py +86 -0
- tencentcloud/facefusion/v20220927/facefusion_client_async.py +83 -0
- tencentcloud/faceid/v20180301/errorcodes.py +0 -6
- tencentcloud/faceid/v20180301/faceid_client.py +0 -23
- tencentcloud/faceid/v20180301/faceid_client_async.py +674 -0
- tencentcloud/faceid/v20180301/models.py +45 -195
- tencentcloud/fmu/v20191213/fmu_client_async.py +161 -0
- tencentcloud/ft/v20200304/ft_client_async.py +134 -0
- tencentcloud/gaap/v20180529/gaap_client_async.py +1865 -0
- tencentcloud/gme/v20180711/gme_client_async.py +865 -0
- tencentcloud/goosefs/v20220519/goosefs_client_async.py +514 -0
- tencentcloud/gs/v20191118/gs_client.py +46 -0
- tencentcloud/gs/v20191118/gs_client_async.py +1527 -0
- tencentcloud/gs/v20191118/models.py +227 -0
- tencentcloud/gwlb/v20240906/gwlb_client_async.py +373 -0
- tencentcloud/habo/v20181203/habo_client_async.py +62 -0
- tencentcloud/hai/v20230812/hai_client_async.py +316 -0
- tencentcloud/hasim/v20210716/hasim_client_async.py +422 -0
- tencentcloud/hcm/v20181106/hcm_client_async.py +44 -0
- tencentcloud/hunyuan/v20230901/hunyuan_client_async.py +469 -0
- tencentcloud/iai/v20180301/iai_client.py +0 -44
- tencentcloud/iai/v20180301/iai_client_async.py +728 -0
- tencentcloud/iai/v20180301/models.py +0 -171
- tencentcloud/iai/v20200303/iai_client.py +1 -35
- tencentcloud/iai/v20200303/iai_client_async.py +802 -0
- tencentcloud/iai/v20200303/models.py +0 -175
- tencentcloud/iap/v20240713/iap_client_async.py +134 -0
- tencentcloud/ic/v20190307/ic_client_async.py +193 -0
- tencentcloud/icr/v20211014/icr_client_async.py +44 -0
- tencentcloud/ie/v20200304/ie_client_async.py +206 -0
- tencentcloud/ig/v20210518/ig_client_async.py +44 -0
- tencentcloud/igtm/v20231024/igtm_client_async.py +494 -0
- tencentcloud/igtm/v20231024/models.py +110 -0
- tencentcloud/ims/v20200713/ims_client_async.py +60 -0
- tencentcloud/ims/v20201229/ims_client_async.py +132 -0
- tencentcloud/ioa/v20220601/ioa_client_async.py +512 -0
- tencentcloud/iot/v20180123/iot_client_async.py +838 -0
- tencentcloud/iotcloud/v20180614/iotcloud_client_async.py +1268 -0
- tencentcloud/iotcloud/v20210408/iotcloud_client_async.py +1340 -0
- tencentcloud/iotexplorer/v20190423/iotexplorer_client.py +161 -0
- tencentcloud/iotexplorer/v20190423/iotexplorer_client_async.py +3632 -0
- tencentcloud/iotexplorer/v20190423/models.py +1669 -337
- tencentcloud/iotvideo/v20191126/iotvideo_client_async.py +1278 -0
- tencentcloud/iotvideo/v20201215/iotvideo_client_async.py +1448 -0
- tencentcloud/iotvideo/v20211125/iotvideo_client_async.py +1970 -0
- tencentcloud/iotvideoindustry/v20201201/iotvideoindustry_client_async.py +1921 -0
- tencentcloud/irp/v20220324/irp_client_async.py +98 -0
- tencentcloud/irp/v20220805/irp_client_async.py +152 -0
- tencentcloud/iss/v20230517/iss_client_async.py +1686 -0
- tencentcloud/iss/v20230517/models.py +2 -2
- tencentcloud/ivld/v20210903/ivld_client_async.py +636 -0
- tencentcloud/keewidb/v20220308/keewidb_client_async.py +711 -0
- tencentcloud/kms/v20190118/kms_client_async.py +1252 -0
- tencentcloud/lcic/v20220817/lcic_client_async.py +1331 -0
- tencentcloud/lighthouse/v20200324/lighthouse_client_async.py +2331 -0
- tencentcloud/live/v20180801/live_client.py +0 -25
- tencentcloud/live/v20180801/live_client_async.py +3758 -0
- tencentcloud/live/v20180801/models.py +0 -282
- tencentcloud/lke/v20231130/lke_client_async.py +1923 -0
- tencentcloud/lke/v20231130/models.py +82 -0
- tencentcloud/lkeap/v20240522/lkeap_client.py +3 -13
- tencentcloud/lkeap/v20240522/lkeap_client_async.py +618 -0
- tencentcloud/lowcode/v20210108/lowcode_client_async.py +332 -0
- tencentcloud/mall/v20230518/mall_client_async.py +44 -0
- tencentcloud/mariadb/v20170312/mariadb_client_async.py +1505 -0
- tencentcloud/market/v20191010/market_client_async.py +62 -0
- tencentcloud/memcached/v20190318/memcached_client_async.py +44 -0
- tencentcloud/mmps/v20200710/mmps_client_async.py +296 -0
- tencentcloud/mna/v20210119/mna_client_async.py +764 -0
- tencentcloud/mongodb/v20180408/mongodb_client_async.py +260 -0
- tencentcloud/mongodb/v20190725/errorcodes.py +3 -0
- tencentcloud/mongodb/v20190725/models.py +390 -2
- tencentcloud/mongodb/v20190725/mongodb_client.py +46 -0
- tencentcloud/mongodb/v20190725/mongodb_client_async.py +1220 -0
- tencentcloud/monitor/v20180724/monitor_client_async.py +3099 -0
- tencentcloud/monitor/v20230616/monitor_client_async.py +44 -0
- tencentcloud/mps/v20190612/errorcodes.py +9 -0
- tencentcloud/mps/v20190612/models.py +2329 -290
- tencentcloud/mps/v20190612/mps_client.py +232 -0
- tencentcloud/mps/v20190612/mps_client_async.py +2729 -0
- tencentcloud/mqtt/v20240516/mqtt_client_async.py +1153 -0
- tencentcloud/mrs/v20200910/mrs_client_async.py +231 -0
- tencentcloud/ms/v20180408/ms_client_async.py +450 -0
- tencentcloud/msp/v20180319/msp_client_async.py +154 -0
- tencentcloud/nlp/v20190408/nlp_client_async.py +140 -0
- tencentcloud/npp/v20190823/npp_client_async.py +170 -0
- tencentcloud/oceanus/v20190422/oceanus_client_async.py +844 -0
- tencentcloud/ocr/v20181119/models.py +232 -0
- tencentcloud/ocr/v20181119/ocr_client_async.py +2228 -0
- tencentcloud/omics/v20221128/omics_client_async.py +386 -0
- tencentcloud/organization/v20181225/organization_client_async.py +386 -0
- tencentcloud/organization/v20210331/organization_client_async.py +2348 -0
- tencentcloud/partners/v20180321/partners_client_async.py +444 -0
- tencentcloud/postgres/v20170312/errorcodes.py +6 -0
- tencentcloud/postgres/v20170312/postgres_client_async.py +1908 -0
- tencentcloud/privatedns/v20201028/errorcodes.py +9 -0
- tencentcloud/privatedns/v20201028/models.py +783 -17
- tencentcloud/privatedns/v20201028/privatedns_client.py +93 -1
- tencentcloud/privatedns/v20201028/privatedns_client_async.py +746 -0
- tencentcloud/pts/v20210728/pts_client_async.py +890 -0
- tencentcloud/rce/v20201103/rce_client_async.py +224 -0
- tencentcloud/redis/v20180412/redis_client_async.py +2008 -0
- tencentcloud/region/v20220627/region_client_async.py +80 -0
- tencentcloud/rum/v20210622/rum_client_async.py +999 -0
- tencentcloud/scf/v20180416/errorcodes.py +6 -0
- tencentcloud/scf/v20180416/models.py +263 -0
- tencentcloud/scf/v20180416/scf_client_async.py +984 -0
- tencentcloud/securitylake/v20240117/securitylake_client_async.py +44 -0
- tencentcloud/ses/v20201002/ses_client_async.py +657 -0
- tencentcloud/smh/v20210712/smh_client_async.py +296 -0
- tencentcloud/smop/v20201203/smop_client_async.py +46 -0
- tencentcloud/sms/v20190711/sms_client_async.py +326 -0
- tencentcloud/sms/v20210111/sms_client_async.py +365 -0
- tencentcloud/soe/v20180724/soe_client_async.py +98 -0
- tencentcloud/sqlserver/v20180328/sqlserver_client_async.py +2693 -0
- tencentcloud/ssa/v20180608/ssa_client_async.py +440 -0
- tencentcloud/ssl/v20191205/ssl_client_async.py +1257 -0
- tencentcloud/sslpod/v20190605/sslpod_client_async.py +206 -0
- tencentcloud/ssm/v20190923/ssm_client_async.py +468 -0
- tencentcloud/sts/v20180813/sts_client_async.py +205 -0
- tencentcloud/svp/v20240125/svp_client_async.py +116 -0
- tencentcloud/taf/v20200210/taf_client_async.py +44 -0
- tencentcloud/tag/v20180813/tag_client_async.py +584 -0
- tencentcloud/tat/v20201028/tat_client_async.py +565 -0
- tencentcloud/tbaas/v20180416/tbaas_client_async.py +458 -0
- tencentcloud/tbp/v20190311/tbp_client_async.py +98 -0
- tencentcloud/tbp/v20190627/tbp_client_async.py +62 -0
- tencentcloud/tcaplusdb/v20190823/tcaplusdb_client_async.py +986 -0
- tencentcloud/tcb/v20180608/tcb_client_async.py +1632 -0
- tencentcloud/tcbr/v20220217/models.py +15 -0
- tencentcloud/tcbr/v20220217/tcbr_client_async.py +206 -0
- tencentcloud/tccatalog/v20241024/tccatalog_client_async.py +98 -0
- tencentcloud/tchd/v20230306/tchd_client_async.py +65 -0
- tencentcloud/tcm/v20210413/tcm_client_async.py +242 -0
- tencentcloud/tcr/v20190924/tcr_client_async.py +2008 -0
- tencentcloud/tcss/v20201101/tcss_client_async.py +6169 -0
- tencentcloud/tdai/v20250717/models.py +55 -10
- tencentcloud/tdai/v20250717/tdai_client.py +1 -1
- tencentcloud/tdai/v20250717/tdai_client_async.py +350 -0
- tencentcloud/tdcpg/v20211118/tdcpg_client_async.py +482 -0
- tencentcloud/tdid/v20210519/tdid_client_async.py +353 -0
- tencentcloud/tdmq/v20200217/errorcodes.py +3 -0
- tencentcloud/tdmq/v20200217/models.py +636 -904
- tencentcloud/tdmq/v20200217/tdmq_client.py +44 -73
- tencentcloud/tdmq/v20200217/tdmq_client_async.py +2732 -0
- tencentcloud/tds/v20220801/tds_client_async.py +116 -0
- tencentcloud/tem/v20201221/tem_client_async.py +332 -0
- tencentcloud/tem/v20210701/tem_client_async.py +949 -0
- tencentcloud/teo/v20220106/teo_client_async.py +120 -0
- tencentcloud/teo/v20220901/models.py +267 -4
- tencentcloud/teo/v20220901/teo_client_async.py +3609 -0
- tencentcloud/thpc/v20211109/thpc_client_async.py +98 -0
- tencentcloud/thpc/v20220401/thpc_client_async.py +321 -0
- tencentcloud/thpc/v20230321/models.py +30 -0
- tencentcloud/thpc/v20230321/thpc_client_async.py +591 -0
- tencentcloud/tia/v20180226/tia_client_async.py +206 -0
- tencentcloud/tiia/v20190529/tiia_client_async.py +536 -0
- tencentcloud/tione/v20191022/tione_client_async.py +422 -0
- tencentcloud/tione/v20211111/tione_client_async.py +1003 -0
- tencentcloud/tiw/v20190919/tiw_client_async.py +656 -0
- tencentcloud/tke/v20180525/errorcodes.py +3 -0
- tencentcloud/tke/v20180525/models.py +3129 -288
- tencentcloud/tke/v20180525/tke_client.py +414 -0
- tencentcloud/tke/v20180525/tke_client_async.py +4562 -0
- tencentcloud/tke/v20220501/tke_client_async.py +343 -0
- tencentcloud/tkgdq/v20190411/tkgdq_client_async.py +80 -0
- tencentcloud/tms/v20200713/tms_client_async.py +98 -0
- tencentcloud/tms/v20201229/tms_client_async.py +97 -0
- tencentcloud/tmt/v20180321/tmt_client_async.py +183 -0
- tencentcloud/tourism/v20230215/tourism_client_async.py +44 -0
- tencentcloud/trabbit/v20230418/trabbit_client_async.py +548 -0
- tencentcloud/trocket/v20230308/trocket_client_async.py +1390 -0
- tencentcloud/trp/v20210515/trp_client_async.py +1002 -0
- tencentcloud/trro/v20220325/trro_client_async.py +588 -0
- tencentcloud/trtc/v20190722/errorcodes.py +3 -0
- tencentcloud/trtc/v20190722/models.py +21 -6
- tencentcloud/trtc/v20190722/trtc_client.py +1 -0
- tencentcloud/trtc/v20190722/trtc_client_async.py +1516 -0
- tencentcloud/tse/v20201207/tse_client_async.py +2240 -0
- tencentcloud/tsf/v20180326/models.py +4 -4
- tencentcloud/tsf/v20180326/tsf_client_async.py +4143 -0
- tencentcloud/tsi/v20210325/tsi_client_async.py +104 -0
- tencentcloud/tsw/v20200924/tsw_client_async.py +44 -0
- tencentcloud/tsw/v20210412/tsw_client_async.py +80 -0
- tencentcloud/tts/v20190823/tts_client_async.py +107 -0
- tencentcloud/vcg/v20240404/vcg_client_async.py +62 -0
- tencentcloud/vclm/v20240523/errorcodes.py +27 -0
- tencentcloud/vclm/v20240523/models.py +415 -16
- tencentcloud/vclm/v20240523/vclm_client.py +47 -0
- tencentcloud/vclm/v20240523/vclm_client_async.py +263 -0
- tencentcloud/vcube/v20220410/models.py +98 -0
- tencentcloud/vcube/v20220410/vcube_client.py +46 -0
- tencentcloud/vcube/v20220410/vcube_client_async.py +674 -0
- tencentcloud/vdb/v20230616/vdb_client_async.py +278 -0
- tencentcloud/vm/v20200709/vm_client_async.py +120 -0
- tencentcloud/vm/v20201229/vm_client_async.py +139 -0
- tencentcloud/vm/v20210922/models.py +2 -2
- tencentcloud/vm/v20210922/vm_client_async.py +148 -0
- tencentcloud/vms/v20200902/vms_client_async.py +62 -0
- tencentcloud/vod/v20180717/models.py +6 -2
- tencentcloud/vod/v20180717/vod_client_async.py +3712 -0
- tencentcloud/vod/v20240718/vod_client_async.py +160 -0
- tencentcloud/vpc/v20170312/vpc_client_async.py +8139 -0
- tencentcloud/vrs/v20200824/vrs_client_async.py +182 -0
- tencentcloud/vtc/v20240223/vtc_client_async.py +132 -0
- tencentcloud/waf/v20180125/models.py +3924 -0
- tencentcloud/waf/v20180125/waf_client.py +230 -0
- tencentcloud/waf/v20180125/waf_client_async.py +3542 -0
- tencentcloud/wav/v20210129/wav_client_async.py +494 -0
- tencentcloud/wedata/v20210820/wedata_client_async.py +5384 -0
- tencentcloud/wedata/v20250806/wedata_client_async.py +2168 -0
- tencentcloud/weilingwith/v20230427/weilingwith_client_async.py +1180 -0
- tencentcloud/wsa/v20250508/wsa_client_async.py +44 -0
- tencentcloud/wss/v20180426/wss_client_async.py +80 -0
- tencentcloud/yinsuda/v20220527/yinsuda_client_async.py +386 -0
- tencentcloud/yunjing/v20180228/yunjing_client_async.py +1826 -0
- tencentcloud/yunsou/v20180504/yunsou_client_async.py +62 -0
- tencentcloud/yunsou/v20191115/yunsou_client_async.py +62 -0
- {tencentcloud_sdk_python-3.0.1491.dist-info → tencentcloud_sdk_python-3.1.6.dist-info}/METADATA +3 -1
- {tencentcloud_sdk_python-3.0.1491.dist-info → tencentcloud_sdk_python-3.1.6.dist-info}/RECORD +391 -103
- {tencentcloud_sdk_python-3.0.1491.dist-info → tencentcloud_sdk_python-3.1.6.dist-info}/LICENSE +0 -0
- {tencentcloud_sdk_python-3.0.1491.dist-info → tencentcloud_sdk_python-3.1.6.dist-info}/WHEEL +0 -0
- {tencentcloud_sdk_python-3.0.1491.dist-info → tencentcloud_sdk_python-3.1.6.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,654 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Copyright 2017-2021 Tencent Ltd.
|
|
4
|
+
#
|
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
# you may not use this file except in compliance with the License.
|
|
7
|
+
# You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
# See the License for the specific language governing permissions and
|
|
15
|
+
# limitations under the License.
|
|
16
|
+
import copy
|
|
17
|
+
import hashlib
|
|
18
|
+
import json
|
|
19
|
+
import logging
|
|
20
|
+
import logging.handlers
|
|
21
|
+
import random
|
|
22
|
+
import sys
|
|
23
|
+
import time
|
|
24
|
+
import uuid
|
|
25
|
+
import warnings
|
|
26
|
+
from datetime import datetime
|
|
27
|
+
from typing import Dict, Type, Union, List, Callable, Awaitable, Optional
|
|
28
|
+
|
|
29
|
+
import httpx
|
|
30
|
+
|
|
31
|
+
import tencentcloud
|
|
32
|
+
from tencentcloud.common.abstract_client import logger, urlparse, urlencode
|
|
33
|
+
from tencentcloud.common.abstract_model import AbstractModel
|
|
34
|
+
from tencentcloud.common.circuit_breaker import CircuitBreaker
|
|
35
|
+
from tencentcloud.common.credential import Credential
|
|
36
|
+
from tencentcloud.common.exception import TencentCloudSDKException
|
|
37
|
+
from tencentcloud.common.http.request_async import ApiRequest, ApiResponse, ResponsePrettyFormatter, \
|
|
38
|
+
RequestPrettyFormatter
|
|
39
|
+
from tencentcloud.common.profile.client_profile import ClientProfile, RegionBreakerProfile
|
|
40
|
+
from tencentcloud.common.retry_async import NoopRetryer
|
|
41
|
+
from tencentcloud.common.sign import Sign
|
|
42
|
+
|
|
43
|
+
warnings.filterwarnings("ignore", module="tencentcloud", category=UserWarning)
|
|
44
|
+
|
|
45
|
+
_json_content = 'application/json'
|
|
46
|
+
_multipart_content = 'multipart/form-data'
|
|
47
|
+
_form_urlencoded_content = 'application/x-www-form-urlencoded'
|
|
48
|
+
_octet_stream = "application/octet-stream"
|
|
49
|
+
|
|
50
|
+
LOGGER_NAME = "tencentcloud_sdk_common"
|
|
51
|
+
|
|
52
|
+
InterceptorType = Callable[["RequestChain"], Awaitable]
|
|
53
|
+
ParamsType = Union[Dict, str, bytes]
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class RequestChain(object):
|
|
57
|
+
def __init__(self):
|
|
58
|
+
self.request: Optional[ApiRequest] = None
|
|
59
|
+
|
|
60
|
+
self._inters: List[InterceptorType] = []
|
|
61
|
+
self._idx = 0
|
|
62
|
+
|
|
63
|
+
async def proceed(self):
|
|
64
|
+
interceptor = self._inters[self._idx]
|
|
65
|
+
snapshot = self._new_snapshot()
|
|
66
|
+
snapshot._idx += 1
|
|
67
|
+
return await interceptor(snapshot)
|
|
68
|
+
|
|
69
|
+
def add_interceptor(self, inter: InterceptorType, idx=sys.maxsize):
|
|
70
|
+
self._inters.insert(idx, inter)
|
|
71
|
+
return self
|
|
72
|
+
|
|
73
|
+
def _new_snapshot(self) -> 'RequestChain':
|
|
74
|
+
new_chain = RequestChain()
|
|
75
|
+
new_chain.request = self.request
|
|
76
|
+
new_chain._inters = self._inters
|
|
77
|
+
new_chain._idx = self._idx
|
|
78
|
+
return new_chain
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class AbstractClient(object):
|
|
82
|
+
_requestPath = '/'
|
|
83
|
+
_params = {}
|
|
84
|
+
_apiVersion = ''
|
|
85
|
+
_endpoint = ''
|
|
86
|
+
_service = ''
|
|
87
|
+
_sdkVersion = 'SDK_PYTHON_%s' % tencentcloud.__version__
|
|
88
|
+
_default_content_type = _form_urlencoded_content
|
|
89
|
+
FMT = '%(asctime)s %(process)d %(filename)s L%(lineno)s %(levelname)s %(message)s'
|
|
90
|
+
|
|
91
|
+
def __init__(self, credential: Credential, region: str, profile: ClientProfile = None):
|
|
92
|
+
self.credential = credential
|
|
93
|
+
self.region = region
|
|
94
|
+
self.profile = profile or ClientProfile()
|
|
95
|
+
self.circuit_breaker = None
|
|
96
|
+
|
|
97
|
+
kwargs: Dict = {"timeout": self.profile.httpProfile.reqTimeout}
|
|
98
|
+
|
|
99
|
+
if not self.profile.httpProfile.keepAlive:
|
|
100
|
+
kwargs["limits"] = httpx.Limits(max_keepalive_connections=0)
|
|
101
|
+
|
|
102
|
+
if self.profile.httpProfile.proxy:
|
|
103
|
+
kwargs["proxies"] = self.profile.httpProfile.proxy
|
|
104
|
+
|
|
105
|
+
if self.profile.httpProfile.certification is False:
|
|
106
|
+
kwargs["verify"] = False
|
|
107
|
+
elif isinstance(self.profile.httpProfile.certification, str) and self.profile.httpProfile.certification != "":
|
|
108
|
+
kwargs["cert"] = self.profile.httpProfile.certification
|
|
109
|
+
|
|
110
|
+
self.http_client = httpx.AsyncClient(**kwargs)
|
|
111
|
+
|
|
112
|
+
if not self.profile.disable_region_breaker:
|
|
113
|
+
if self.profile.region_breaker_profile is None:
|
|
114
|
+
self.profile.region_breaker_profile = RegionBreakerProfile()
|
|
115
|
+
self.circuit_breaker = CircuitBreaker(self.profile.region_breaker_profile)
|
|
116
|
+
if self.profile.request_client:
|
|
117
|
+
self.request_client = self._sdkVersion + "; " + self.profile.request_client
|
|
118
|
+
else:
|
|
119
|
+
self.request_client = self._sdkVersion
|
|
120
|
+
|
|
121
|
+
async def __aenter__(self):
|
|
122
|
+
return self
|
|
123
|
+
|
|
124
|
+
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
|
125
|
+
await self.close()
|
|
126
|
+
|
|
127
|
+
async def close(self):
|
|
128
|
+
await self.http_client.aclose()
|
|
129
|
+
|
|
130
|
+
async def call_and_deserialize(
|
|
131
|
+
self,
|
|
132
|
+
action: str,
|
|
133
|
+
params: ParamsType,
|
|
134
|
+
resp_cls: Type = dict,
|
|
135
|
+
headers: Dict[str, str] = None,
|
|
136
|
+
opts: Dict = None,
|
|
137
|
+
):
|
|
138
|
+
opts = opts or {}
|
|
139
|
+
headers = headers or {}
|
|
140
|
+
chain = self._create_default_chain(action, params, resp_cls, headers, opts)
|
|
141
|
+
return await chain.proceed()
|
|
142
|
+
|
|
143
|
+
def _create_default_chain(
|
|
144
|
+
self,
|
|
145
|
+
action: str,
|
|
146
|
+
params: ParamsType,
|
|
147
|
+
resp_cls: Type,
|
|
148
|
+
headers: Dict[str, str],
|
|
149
|
+
opts: Dict,
|
|
150
|
+
):
|
|
151
|
+
chain = RequestChain()
|
|
152
|
+
chain.add_interceptor(self._inter_retry)
|
|
153
|
+
chain.add_interceptor(self._inter_deserialize_resp(resp_cls))
|
|
154
|
+
if self.circuit_breaker:
|
|
155
|
+
chain.add_interceptor(self._inter_breaker(opts))
|
|
156
|
+
chain.add_interceptor(self._inter_build_request(action, params, headers, opts))
|
|
157
|
+
chain.add_interceptor(self._inter_send_request)
|
|
158
|
+
return chain
|
|
159
|
+
|
|
160
|
+
async def _inter_retry(self, chain: RequestChain):
|
|
161
|
+
retryer = self.profile.retryer or NoopRetryer()
|
|
162
|
+
return await retryer.send_request(chain.proceed)
|
|
163
|
+
|
|
164
|
+
def _inter_build_request(
|
|
165
|
+
self,
|
|
166
|
+
action: str,
|
|
167
|
+
params: ParamsType,
|
|
168
|
+
headers: Dict[str, str],
|
|
169
|
+
opts: Dict,
|
|
170
|
+
):
|
|
171
|
+
async def inter(chain: RequestChain):
|
|
172
|
+
nonlocal action, params, opts, headers
|
|
173
|
+
|
|
174
|
+
if headers is None:
|
|
175
|
+
headers = {}
|
|
176
|
+
|
|
177
|
+
if not isinstance(headers, dict):
|
|
178
|
+
raise TencentCloudSDKException("ClientError", "headers must be a dict.")
|
|
179
|
+
|
|
180
|
+
if "x-tc-traceid" not in (k.lower() for k in headers.keys()):
|
|
181
|
+
headers["X-TC-TraceId"] = str(uuid.uuid4())
|
|
182
|
+
|
|
183
|
+
req = self._build_req(action, params, headers, opts)
|
|
184
|
+
|
|
185
|
+
if self.profile.httpProfile.apigw_endpoint:
|
|
186
|
+
req.host = self.profile.httpProfile.apigw_endpoint
|
|
187
|
+
req.headers["Host"] = req.host
|
|
188
|
+
|
|
189
|
+
# 低版本的 httpx 不会使用 Client.timeout, 需要 per request setup
|
|
190
|
+
req.extensions["timeout"] = self.http_client.timeout.as_dict()
|
|
191
|
+
chain.request = req
|
|
192
|
+
|
|
193
|
+
logger.debug("SendRequest:\n%s", RequestPrettyFormatter(req))
|
|
194
|
+
|
|
195
|
+
return await chain.proceed()
|
|
196
|
+
|
|
197
|
+
return inter
|
|
198
|
+
|
|
199
|
+
def _inter_breaker(self, opts: Dict):
|
|
200
|
+
async def inter(chain: RequestChain):
|
|
201
|
+
generation, need_break = self.circuit_breaker.before_requests()
|
|
202
|
+
|
|
203
|
+
endpoint = self._get_endpoint(opts=opts)
|
|
204
|
+
if need_break:
|
|
205
|
+
endpoint = self._service + "." + self.profile.region_breaker_profile.backup_endpoint
|
|
206
|
+
|
|
207
|
+
url = self.profile.httpProfile.scheme + endpoint + self._requestPath
|
|
208
|
+
chain.request.url = url
|
|
209
|
+
|
|
210
|
+
resp = None
|
|
211
|
+
try:
|
|
212
|
+
resp = await chain.proceed()
|
|
213
|
+
self.circuit_breaker.after_requests(generation, True)
|
|
214
|
+
return resp
|
|
215
|
+
except httpx.TransportError:
|
|
216
|
+
self.circuit_breaker.after_requests(generation, False)
|
|
217
|
+
raise
|
|
218
|
+
except TencentCloudSDKException as e:
|
|
219
|
+
success = resp and "RequestId" in (await resp.aread()) and e.code != "InternalError"
|
|
220
|
+
self.circuit_breaker.after_requests(generation, success)
|
|
221
|
+
raise
|
|
222
|
+
|
|
223
|
+
return inter
|
|
224
|
+
|
|
225
|
+
@staticmethod
|
|
226
|
+
def _inter_deserialize_resp(resp_cls: Type):
|
|
227
|
+
async def inter(chain: RequestChain):
|
|
228
|
+
resp = await chain.proceed()
|
|
229
|
+
|
|
230
|
+
await check_err(resp)
|
|
231
|
+
|
|
232
|
+
content_type = resp.headers["Content-Type"]
|
|
233
|
+
if content_type == "text/event-stream":
|
|
234
|
+
return deserialize_sse(resp)
|
|
235
|
+
|
|
236
|
+
return await deserialize_json(resp)
|
|
237
|
+
|
|
238
|
+
async def check_err(resp: ApiResponse):
|
|
239
|
+
if resp.status_code != 200:
|
|
240
|
+
if logger.isEnabledFor(logging.DEBUG):
|
|
241
|
+
logger.debug("GetResponse: %s", await ResponsePrettyFormatter(resp, format_body=True).astr())
|
|
242
|
+
raise TencentCloudSDKException("ServerNetworkError", await resp.aread())
|
|
243
|
+
|
|
244
|
+
ct = resp.headers.get('Content-Type')
|
|
245
|
+
if ct not in ('text/plain', _json_content):
|
|
246
|
+
return
|
|
247
|
+
|
|
248
|
+
content = await resp.aread()
|
|
249
|
+
data = json.loads(content)
|
|
250
|
+
if "Error" in data["Response"]:
|
|
251
|
+
code = data["Response"]["Error"]["Code"]
|
|
252
|
+
message = data["Response"]["Error"]["Message"]
|
|
253
|
+
reqid = data["Response"]["RequestId"]
|
|
254
|
+
if logger.isEnabledFor(logging.DEBUG):
|
|
255
|
+
logger.debug("GetResponse: %s", await ResponsePrettyFormatter(resp, format_body=True).astr())
|
|
256
|
+
raise TencentCloudSDKException(code, message, reqid)
|
|
257
|
+
if "DeprecatedWarning" in data["Response"]:
|
|
258
|
+
import warnings
|
|
259
|
+
warnings.filterwarnings("default")
|
|
260
|
+
warnings.warn("This action is deprecated, detail: %s" % data["Response"]["DeprecatedWarning"],
|
|
261
|
+
DeprecationWarning)
|
|
262
|
+
|
|
263
|
+
async def deserialize_json(resp: ApiResponse):
|
|
264
|
+
try:
|
|
265
|
+
if logger.isEnabledFor(logging.DEBUG):
|
|
266
|
+
logger.debug("GetResponse: %s", await ResponsePrettyFormatter(resp, format_body=True).astr())
|
|
267
|
+
|
|
268
|
+
content = await resp.aread()
|
|
269
|
+
if resp_cls == dict:
|
|
270
|
+
return json.loads(content)
|
|
271
|
+
|
|
272
|
+
if issubclass(resp_cls, AbstractModel):
|
|
273
|
+
resp_model = resp_cls()
|
|
274
|
+
resp_model._deserialize(json.loads(content)["Response"])
|
|
275
|
+
return resp_model
|
|
276
|
+
|
|
277
|
+
raise TencentCloudSDKException("ClientParamsError", "invalid resp_cls %s" % resp_cls)
|
|
278
|
+
finally:
|
|
279
|
+
await resp.aclose()
|
|
280
|
+
|
|
281
|
+
async def deserialize_sse(resp: ApiResponse):
|
|
282
|
+
logger.debug("GetResponse:\n%s", ResponsePrettyFormatter(resp, format_body=False))
|
|
283
|
+
e = {}
|
|
284
|
+
|
|
285
|
+
try:
|
|
286
|
+
async for line in resp.aiter_lines():
|
|
287
|
+
line = line.strip()
|
|
288
|
+
if not line:
|
|
289
|
+
yield e
|
|
290
|
+
e = {}
|
|
291
|
+
continue
|
|
292
|
+
|
|
293
|
+
logger.debug("GetResponse.Readline: %s", line)
|
|
294
|
+
|
|
295
|
+
# comment
|
|
296
|
+
if line[0] == ':':
|
|
297
|
+
continue
|
|
298
|
+
|
|
299
|
+
colon_idx = line.find(':')
|
|
300
|
+
key = line[:colon_idx]
|
|
301
|
+
val = line[colon_idx + 1:]
|
|
302
|
+
# If value starts with a U+0020 SPACE character, remove it from value.
|
|
303
|
+
if val and val[0] == " ":
|
|
304
|
+
val = val[1:]
|
|
305
|
+
if key == 'data':
|
|
306
|
+
# The spec allows for multiple data fields per event, concatenated them with "\n".
|
|
307
|
+
if 'data' not in e:
|
|
308
|
+
e['data'] = val
|
|
309
|
+
else:
|
|
310
|
+
e['data'] += '\n' + val
|
|
311
|
+
elif key in ('event', 'id'):
|
|
312
|
+
e[key] = val
|
|
313
|
+
elif key == 'retry':
|
|
314
|
+
e[key] = int(val)
|
|
315
|
+
finally:
|
|
316
|
+
await resp.aclose()
|
|
317
|
+
|
|
318
|
+
return inter
|
|
319
|
+
|
|
320
|
+
async def _inter_send_request(self, chain: RequestChain):
|
|
321
|
+
return await self.http_client.send(chain.request, stream=True)
|
|
322
|
+
|
|
323
|
+
def _get_service_domain(self):
|
|
324
|
+
root_domain = self.profile.httpProfile.rootDomain
|
|
325
|
+
return self._service + "." + root_domain
|
|
326
|
+
|
|
327
|
+
def _get_endpoint(self, opts=None):
|
|
328
|
+
endpoint = self.profile.httpProfile.endpoint
|
|
329
|
+
if not endpoint and opts:
|
|
330
|
+
endpoint = urlparse(opts.get("Endpoint", "")).hostname
|
|
331
|
+
if endpoint is None:
|
|
332
|
+
endpoint = self._get_service_domain()
|
|
333
|
+
return endpoint
|
|
334
|
+
|
|
335
|
+
def _build_req(self, action: str, params: ParamsType, headers: Dict[str, str], opts: Dict) -> ApiRequest:
|
|
336
|
+
if opts.get('SkipSign'):
|
|
337
|
+
return self._build_req_without_signature(action, params, headers, opts)
|
|
338
|
+
elif self.profile.signMethod == "TC3-HMAC-SHA256" or opts.get("IsMultipart") is True:
|
|
339
|
+
return self._build_req_with_tc3_signature(action, params, headers, opts)
|
|
340
|
+
elif self.profile.signMethod in ("HmacSHA1", "HmacSHA256"):
|
|
341
|
+
return self._build_req_with_old_signature(action, params, headers, opts)
|
|
342
|
+
else:
|
|
343
|
+
raise TencentCloudSDKException("ClientError", "Invalid signature method.")
|
|
344
|
+
|
|
345
|
+
def _build_req_without_signature(
|
|
346
|
+
self, action: str, params: ParamsType, headers: Dict[str, str], opts: Dict) -> ApiRequest:
|
|
347
|
+
method = self.profile.httpProfile.reqMethod
|
|
348
|
+
endpoint = self._get_endpoint(opts=opts)
|
|
349
|
+
url = "%s://%s%s" % (self.profile.httpProfile.scheme, endpoint, self._requestPath)
|
|
350
|
+
query = {}
|
|
351
|
+
body = ""
|
|
352
|
+
|
|
353
|
+
content_type = self._default_content_type
|
|
354
|
+
if method == 'GET':
|
|
355
|
+
content_type = _form_urlencoded_content
|
|
356
|
+
elif method == 'POST':
|
|
357
|
+
content_type = _json_content
|
|
358
|
+
if opts.get("IsMultipart"):
|
|
359
|
+
content_type = _multipart_content
|
|
360
|
+
if opts.get("IsOctetStream"):
|
|
361
|
+
content_type = _octet_stream
|
|
362
|
+
headers["Content-Type"] = content_type
|
|
363
|
+
|
|
364
|
+
if method == "GET" and content_type == _multipart_content:
|
|
365
|
+
raise TencentCloudSDKException("ClientError", "Invalid request method GET for multipart.")
|
|
366
|
+
|
|
367
|
+
endpoint = self._get_endpoint(opts=opts)
|
|
368
|
+
timestamp = int(time.time())
|
|
369
|
+
headers["Host"] = endpoint
|
|
370
|
+
headers["X-TC-Action"] = action[0].upper() + action[1:]
|
|
371
|
+
headers["X-TC-RequestClient"] = self.request_client
|
|
372
|
+
headers["X-TC-Timestamp"] = str(timestamp)
|
|
373
|
+
headers["X-TC-Version"] = self._apiVersion
|
|
374
|
+
if self.profile.unsignedPayload is True:
|
|
375
|
+
headers["X-TC-Content-SHA256"] = "UNSIGNED-PAYLOAD"
|
|
376
|
+
if self.region:
|
|
377
|
+
headers['X-TC-Region'] = self.region
|
|
378
|
+
if self.profile.language:
|
|
379
|
+
headers['X-TC-Language'] = self.profile.language
|
|
380
|
+
|
|
381
|
+
if method == 'GET':
|
|
382
|
+
params = copy.deepcopy(self._fix_params(params))
|
|
383
|
+
url += "?" + urlencode(params)
|
|
384
|
+
elif content_type == _json_content:
|
|
385
|
+
body = json.dumps(params)
|
|
386
|
+
elif content_type == _multipart_content:
|
|
387
|
+
boundary = uuid.uuid4().hex
|
|
388
|
+
headers["Content-Type"] = content_type + "; boundary=" + boundary
|
|
389
|
+
body = self._get_multipart_body(params, boundary, opts)
|
|
390
|
+
|
|
391
|
+
headers["Authorization"] = "SKIP"
|
|
392
|
+
return ApiRequest(method, url, params=query, content=body, headers=headers)
|
|
393
|
+
|
|
394
|
+
def _build_req_with_tc3_signature(
|
|
395
|
+
self, action: str, params: ParamsType, headers: Dict[str, str], opts: Dict) -> ApiRequest:
|
|
396
|
+
method = self.profile.httpProfile.reqMethod
|
|
397
|
+
endpoint = self._get_endpoint(opts=opts)
|
|
398
|
+
host = headers.get("Host", endpoint)
|
|
399
|
+
url = "%s://%s%s" % (self.profile.httpProfile.scheme, endpoint, self._requestPath)
|
|
400
|
+
query = ""
|
|
401
|
+
body = ""
|
|
402
|
+
|
|
403
|
+
content_type = self._default_content_type
|
|
404
|
+
if method == 'GET':
|
|
405
|
+
content_type = _form_urlencoded_content
|
|
406
|
+
elif method == 'POST':
|
|
407
|
+
content_type = _json_content
|
|
408
|
+
if opts.get("IsMultipart"):
|
|
409
|
+
content_type = _multipart_content
|
|
410
|
+
elif opts.get("IsOctetStream"):
|
|
411
|
+
if method != "POST":
|
|
412
|
+
raise TencentCloudSDKException("ClientError", "Invalid request method.")
|
|
413
|
+
content_type = _octet_stream
|
|
414
|
+
headers["Content-Type"] = content_type
|
|
415
|
+
|
|
416
|
+
if method == "GET" and content_type == _multipart_content:
|
|
417
|
+
raise TencentCloudSDKException("ClientError", "Invalid request method GET for multipart.")
|
|
418
|
+
|
|
419
|
+
timestamp = int(time.time())
|
|
420
|
+
cred_secret_id, cred_secret_key, cred_token = self.credential.get_credential_info()
|
|
421
|
+
headers["Host"] = host
|
|
422
|
+
headers["X-TC-Action"] = action[0].upper() + action[1:]
|
|
423
|
+
headers["X-TC-RequestClient"] = self.request_client
|
|
424
|
+
headers["X-TC-Timestamp"] = str(timestamp)
|
|
425
|
+
headers["X-TC-Version"] = self._apiVersion
|
|
426
|
+
if self.profile.unsignedPayload is True:
|
|
427
|
+
headers["X-TC-Content-SHA256"] = "UNSIGNED-PAYLOAD"
|
|
428
|
+
if self.region:
|
|
429
|
+
headers['X-TC-Region'] = self.region
|
|
430
|
+
if cred_token:
|
|
431
|
+
headers['X-TC-Token'] = cred_token
|
|
432
|
+
if self.profile.language:
|
|
433
|
+
headers['X-TC-Language'] = self.profile.language
|
|
434
|
+
|
|
435
|
+
if method == 'GET':
|
|
436
|
+
query = urlencode(copy.deepcopy(self._fix_params(params)))
|
|
437
|
+
elif content_type == _json_content:
|
|
438
|
+
body = json.dumps(params)
|
|
439
|
+
elif content_type == _multipart_content:
|
|
440
|
+
boundary = uuid.uuid4().hex
|
|
441
|
+
headers["Content-Type"] = content_type + "; boundary=" + boundary
|
|
442
|
+
body = self._get_multipart_body(params, boundary, opts)
|
|
443
|
+
elif content_type == _octet_stream:
|
|
444
|
+
body = params
|
|
445
|
+
|
|
446
|
+
if isinstance(body, str):
|
|
447
|
+
body = body.encode("utf-8")
|
|
448
|
+
|
|
449
|
+
service = self._service
|
|
450
|
+
date = datetime.utcfromtimestamp(timestamp).strftime('%Y-%m-%d')
|
|
451
|
+
signature = self._get_tc3_signature(
|
|
452
|
+
method, self._requestPath, query, body, headers, date, service, cred_secret_key, opts)
|
|
453
|
+
|
|
454
|
+
auth = "TC3-HMAC-SHA256 Credential=%s/%s/%s/tc3_request, SignedHeaders=content-type;host, Signature=%s" % (
|
|
455
|
+
cred_secret_id, date, service, signature)
|
|
456
|
+
headers["Authorization"] = auth
|
|
457
|
+
# httpx 0.22.0 版本会过滤掉空 value 的 params 如 "a=&b=2"
|
|
458
|
+
# 不能使用 params 参数, 需要用 url 绕过, 后续版本已经修复, 但是 py36 最高只能安装 0.22.0
|
|
459
|
+
url += "?" + query
|
|
460
|
+
return ApiRequest(method, url, content=body, headers=headers)
|
|
461
|
+
|
|
462
|
+
def _build_req_with_old_signature(
|
|
463
|
+
self, action: str, params: ParamsType, headers: Dict[str, str], opts: Dict) -> ApiRequest:
|
|
464
|
+
|
|
465
|
+
if opts.get("IsOctetStream"):
|
|
466
|
+
raise TencentCloudSDKException("ClientError", "Invalid signature method.")
|
|
467
|
+
|
|
468
|
+
method = self.profile.httpProfile.reqMethod
|
|
469
|
+
endpoint = self._get_endpoint(opts=opts)
|
|
470
|
+
url = "%s://%s%s" % (self.profile.httpProfile.scheme, endpoint, self._requestPath)
|
|
471
|
+
query = {}
|
|
472
|
+
body = ""
|
|
473
|
+
|
|
474
|
+
params = copy.deepcopy(self._fix_params(params))
|
|
475
|
+
params['Action'] = action[0].upper() + action[1:]
|
|
476
|
+
params['RequestClient'] = self.request_client
|
|
477
|
+
params['Nonce'] = random.randint(1, sys.maxsize)
|
|
478
|
+
params['Timestamp'] = int(time.time())
|
|
479
|
+
params['Version'] = self._apiVersion
|
|
480
|
+
|
|
481
|
+
cred_secret_id, cred_secret_key, cred_token = self.credential.get_credential_info()
|
|
482
|
+
|
|
483
|
+
if self.region:
|
|
484
|
+
params['Region'] = self.region
|
|
485
|
+
|
|
486
|
+
if cred_token:
|
|
487
|
+
params['Token'] = cred_token
|
|
488
|
+
|
|
489
|
+
if cred_secret_id:
|
|
490
|
+
params['SecretId'] = cred_secret_id
|
|
491
|
+
|
|
492
|
+
if self.profile.signMethod:
|
|
493
|
+
params['SignatureMethod'] = self.profile.signMethod
|
|
494
|
+
|
|
495
|
+
if self.profile.language:
|
|
496
|
+
params['Language'] = self.profile.language
|
|
497
|
+
|
|
498
|
+
signInParam = self._format_sign_string(params, opts)
|
|
499
|
+
params['Signature'] = Sign.sign(str(cred_secret_key),
|
|
500
|
+
str(signInParam),
|
|
501
|
+
str(self.profile.signMethod))
|
|
502
|
+
if method == "GET":
|
|
503
|
+
query = params
|
|
504
|
+
else:
|
|
505
|
+
body = urlencode(params)
|
|
506
|
+
|
|
507
|
+
headers["Content-Type"] = "application/x-www-form-urlencoded"
|
|
508
|
+
return ApiRequest(method, url, params=query, content=body, headers=headers)
|
|
509
|
+
|
|
510
|
+
def _format_sign_string(self, params, opts=None):
|
|
511
|
+
formatParam = {}
|
|
512
|
+
for k in params:
|
|
513
|
+
formatParam[k.replace('_', '.')] = params[k]
|
|
514
|
+
strParam = '&'.join('%s=%s' % (k, formatParam[k]) for k in sorted(formatParam))
|
|
515
|
+
msg = '%s%s%s?%s' % (
|
|
516
|
+
self.profile.httpProfile.reqMethod, self._get_endpoint(opts=opts), self._requestPath, strParam)
|
|
517
|
+
return msg
|
|
518
|
+
|
|
519
|
+
def _fix_params(self, params):
|
|
520
|
+
if not isinstance(params, (dict,)):
|
|
521
|
+
return params
|
|
522
|
+
return self._format_params(None, params)
|
|
523
|
+
|
|
524
|
+
def _format_params(self, prefix, params):
|
|
525
|
+
d = {}
|
|
526
|
+
if params is None:
|
|
527
|
+
return d
|
|
528
|
+
|
|
529
|
+
if not isinstance(params, (tuple, list, dict)):
|
|
530
|
+
d[prefix] = params
|
|
531
|
+
return d
|
|
532
|
+
|
|
533
|
+
if isinstance(params, (list, tuple)):
|
|
534
|
+
for idx, item in enumerate(params):
|
|
535
|
+
if prefix:
|
|
536
|
+
key = "{0}.{1}".format(prefix, idx)
|
|
537
|
+
else:
|
|
538
|
+
key = "{0}".format(idx)
|
|
539
|
+
d.update(self._format_params(key, item))
|
|
540
|
+
return d
|
|
541
|
+
|
|
542
|
+
if isinstance(params, dict):
|
|
543
|
+
for k, v in params.items():
|
|
544
|
+
if prefix:
|
|
545
|
+
key = '{0}.{1}'.format(prefix, k)
|
|
546
|
+
else:
|
|
547
|
+
key = '{0}'.format(k)
|
|
548
|
+
d.update(self._format_params(key, v))
|
|
549
|
+
return d
|
|
550
|
+
|
|
551
|
+
raise TencentCloudSDKException("ClientParamsError", "some params type error")
|
|
552
|
+
|
|
553
|
+
def _get_multipart_body(self, params, boundary, options=None):
|
|
554
|
+
if options is None:
|
|
555
|
+
options = {}
|
|
556
|
+
# boundary and params key will never contain unicode characters
|
|
557
|
+
boundary = boundary.encode()
|
|
558
|
+
binparas = options.get("BinaryParams", [])
|
|
559
|
+
body = b''
|
|
560
|
+
for k, v in params.items():
|
|
561
|
+
kbytes = k.encode()
|
|
562
|
+
body += b'--%s\r\n' % boundary
|
|
563
|
+
body += b'Content-Disposition: form-data; name="%s"' % kbytes
|
|
564
|
+
if k in binparas:
|
|
565
|
+
body += b'; filename="%s"\r\n' % kbytes
|
|
566
|
+
else:
|
|
567
|
+
body += b"\r\n"
|
|
568
|
+
if isinstance(v, list) or isinstance(v, dict):
|
|
569
|
+
v = json.dumps(v)
|
|
570
|
+
body += b'Content-Type: application/json\r\n'
|
|
571
|
+
if sys.version_info[0] == 3 and isinstance(v, type("")):
|
|
572
|
+
v = v.encode()
|
|
573
|
+
body += b'\r\n%s\r\n' % v
|
|
574
|
+
if body != b'':
|
|
575
|
+
body += b'--%s--\r\n' % boundary
|
|
576
|
+
return body
|
|
577
|
+
|
|
578
|
+
@staticmethod
|
|
579
|
+
def _get_tc3_signature(method: str, path: str, query: str, body: bytes, headers: Dict, date: str, service: str,
|
|
580
|
+
secret_key: str, opts: Dict):
|
|
581
|
+
canonical_uri = path
|
|
582
|
+
canonical_querystring = query
|
|
583
|
+
payload = body
|
|
584
|
+
|
|
585
|
+
if headers.get("X-TC-Content-SHA256") == "UNSIGNED-PAYLOAD":
|
|
586
|
+
payload = b"UNSIGNED-PAYLOAD"
|
|
587
|
+
|
|
588
|
+
payload_hash = hashlib.sha256(payload).hexdigest()
|
|
589
|
+
|
|
590
|
+
canonical_headers = 'content-type:%s\nhost:%s\n' % (
|
|
591
|
+
headers["Content-Type"], headers["Host"])
|
|
592
|
+
signed_headers = 'content-type;host'
|
|
593
|
+
canonical_request = '%s\n%s\n%s\n%s\n%s\n%s' % (method,
|
|
594
|
+
canonical_uri,
|
|
595
|
+
canonical_querystring,
|
|
596
|
+
canonical_headers,
|
|
597
|
+
signed_headers,
|
|
598
|
+
payload_hash)
|
|
599
|
+
|
|
600
|
+
algorithm = 'TC3-HMAC-SHA256'
|
|
601
|
+
credential_scope = date + '/' + service + '/tc3_request'
|
|
602
|
+
if sys.version_info[0] == 3:
|
|
603
|
+
canonical_request = canonical_request.encode("utf8")
|
|
604
|
+
digest = hashlib.sha256(canonical_request).hexdigest()
|
|
605
|
+
string2sign = '%s\n%s\n%s\n%s' % (algorithm,
|
|
606
|
+
headers["X-TC-Timestamp"],
|
|
607
|
+
credential_scope,
|
|
608
|
+
digest)
|
|
609
|
+
return Sign.sign_tc3(secret_key, date, service, string2sign)
|
|
610
|
+
|
|
611
|
+
def set_stream_logger(self, stream=None, level=logging.DEBUG, log_format=None):
|
|
612
|
+
"""Add a stream handler
|
|
613
|
+
|
|
614
|
+
:param stream: e.g. ``sys.stdout`` ``sys.stdin`` ``sys.stderr``
|
|
615
|
+
:type stream: IO[str]
|
|
616
|
+
:param level: Logging level, e.g. ``logging.INFO``
|
|
617
|
+
:type level: int
|
|
618
|
+
:param log_format: Log message format
|
|
619
|
+
:type log_format: str
|
|
620
|
+
"""
|
|
621
|
+
log = logging.getLogger(LOGGER_NAME)
|
|
622
|
+
log.setLevel(level)
|
|
623
|
+
sh = logging.StreamHandler(stream)
|
|
624
|
+
sh.setLevel(level)
|
|
625
|
+
if log_format is None:
|
|
626
|
+
log_format = self.FMT
|
|
627
|
+
formatter = logging.Formatter(log_format)
|
|
628
|
+
sh.setFormatter(formatter)
|
|
629
|
+
log.addHandler(sh)
|
|
630
|
+
|
|
631
|
+
def set_file_logger(self, file_path, level=logging.DEBUG, log_format=None):
|
|
632
|
+
"""Add a file handler
|
|
633
|
+
|
|
634
|
+
:param file_path: path of log file
|
|
635
|
+
:type file_path: str
|
|
636
|
+
:param level: Logging level, e.g. ``logging.INFO``
|
|
637
|
+
:type level: int
|
|
638
|
+
:param log_format: Log message format
|
|
639
|
+
:type log_format: str
|
|
640
|
+
"""
|
|
641
|
+
log = logging.getLogger(LOGGER_NAME)
|
|
642
|
+
log.setLevel(level)
|
|
643
|
+
mb = 1024 * 1024
|
|
644
|
+
fh = logging.handlers.RotatingFileHandler(file_path, maxBytes=512 * mb, backupCount=10)
|
|
645
|
+
fh.setLevel(level)
|
|
646
|
+
if log_format is None:
|
|
647
|
+
log_format = self.FMT
|
|
648
|
+
formatter = logging.Formatter(log_format)
|
|
649
|
+
fh.setFormatter(formatter)
|
|
650
|
+
log.addHandler(fh)
|
|
651
|
+
|
|
652
|
+
def set_default_logger(self):
|
|
653
|
+
"""Set default log handler"""
|
|
654
|
+
pass
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Copyright 1999-2017 Tencent Ltd.
|
|
4
|
+
#
|
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
# you may not use this file except in compliance with the License.
|
|
7
|
+
# You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
# See the License for the specific language governing permissions and
|
|
15
|
+
# limitations under the License.
|
|
16
|
+
|
|
17
|
+
from tencentcloud.common.abstract_client_async import AbstractClient
|
|
18
|
+
from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class CommonClient(AbstractClient):
|
|
22
|
+
"""General client for all products.
|
|
23
|
+
|
|
24
|
+
With CommonClient, you only need to install the tencentcloud-sdk-python-common package to access APIs of all products.
|
|
25
|
+
See GitHub examples for usage details: https://github.com/TencentCloud/tencentcloud-sdk-python/tree/master/examples/common_client
|
|
26
|
+
|
|
27
|
+
:param service: Product name
|
|
28
|
+
:type service: str
|
|
29
|
+
:param version: Version of API
|
|
30
|
+
:type version: str
|
|
31
|
+
:param credential: Request credential
|
|
32
|
+
:type credential: tencentcloud.common.credential.Credential or tencentcloud.common.credential.STSAssumeRoleCredential or None
|
|
33
|
+
:param region: Request region
|
|
34
|
+
:type region: str
|
|
35
|
+
:param profile: Request SDK profile
|
|
36
|
+
:type profile: tencentcloud.common.profile.client_profile.ClientProfile
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
def __init__(self, service, version, credential, region, profile=None):
|
|
40
|
+
if region is None or version is None or service is None:
|
|
41
|
+
raise TencentCloudSDKException("CommonClient Parameter Error, "
|
|
42
|
+
"credential region version service all required.")
|
|
43
|
+
self._apiVersion = version
|
|
44
|
+
self._service = service
|
|
45
|
+
super(CommonClient, self).__init__(credential, region, profile)
|