zoukankan      html  css  js  c++  java
  • 调用App Store Connect Api

    对iOS的证书、描述文件、账号、设备等管理,之前都去苹果开发者中心操作,官网上操作也比较繁杂,想搞一些自动化之类的,更是麻烦,有时候官网都打不开……

    其实苹果还提供里一套API接口,创建证书、创建账号、增加devices等等,这些都可以调用命令操作,可以按需来完成自动化操作或批量操作。

    API接口地址:https://api.appstoreconnect.apple.com

    文档地址:https://developer.apple.com/documentation/appstoreconnectapi

    有人可能看完文档还是不知道怎么下手,简述一下步骤:

    1. 生成token

    (1)key 和iss以及.p8文件生成就不累述

    (2) 构造header

    algorithm = 'ES256'
    base_api_url = "https://api.appstoreconnect.apple.com"
    header = {
            "alg": algorithm,
            "kid": key,
            "typ": "JWT"
        }

    (3)构造payload

    # 
        payload = {
            "iss": iss,
            "exp": int(time.mktime((datetime.now() + timedelta(minutes=20)).timetuple())),
            "aud": "appstoreconnect-v1"
        }

    (4)生成token

    token = jwt.encode(payload=payload, key=private_key, algorithm=algorithm, headers=header).decode('ascii')
        return token

    (5)封装请求处理

    def base_call(url, token, method="get", data=None):
        """
        :param url:
        :param token:
        :param method:
        :param data:
        :return:
        """
    
        re_header = {"Authorization": "Bearer %s" % token}
        r = {}
        url = base_api_url + url
    
        requests.adapters.DEFAULT_RETRIES = 1
        req = requests.session()
        req.keep_alive = False
    
        if method.lower() == "get":
            r = req.get(url, params=data, headers=re_header)
    
        elif method.lower() == "post":
            re_header["Content-Type"] = "application/json"
            r = req.post(url=url, headers=re_header, data=json.dumps(data))
    
        elif method.lower() == "patch":
            re_header["Content-Type"] = "application/json"
            r = req.patch(url=url, headers=re_header, data=json.dumps(data))
        return r

    比如我们以增加设备id为例:

    def set_devices(api_token, data):
        """
        增加devices信息
        :param api_token:
        :param data:
        :return:
        """
        set_device_url = '/v1/devices'
        res = base_call(set_device_url, api_token, 'post', data)
        return res
    post_data = {
        "data": {
            "attributes": {
            "name": i.split(',')[0],
            "platform": "IOS",
            "udid": i.split(',')[1]
              },
        "type": "devices"
        }
    }
    res = api.set_devices(api_token, post_data)
    if res.status_code != 201:
        print(res.json()['errors'][0]['detail'])
    else:
        print("add time:", res.json()['data']['attributes']['addedDate'])                

    这里的参数组装需要注意,需要参考文档一层层组装参数,data包含自子参数,子参数再包含子参数

    完整的代码示例:

    # -*- coding:utf-8 -*-
    # Author: drew
    # create time: 2020-07030
    # update time:
    # app store connect api
    
    
    import jwt
    import time
    import json
    import requests
    from datetime import datetime, timedelta
    
    
    algorithm = 'ES256'
    base_api_url = "https://api.appstoreconnect.apple.com"
    
    
    def get_token(key, iss, key_file):
        """
        :param key:
        :param iss:
        :param key_file:
        :return:
        """
        # 读取私钥
        private_key = open(key_file, 'r').read()
        # 构造header
        header = {
            "alg": algorithm,
            "kid": key,
            "typ": "JWT"
        }
        # 构造payload
        payload = {
            "iss": iss,
            "exp": int(time.mktime((datetime.now() + timedelta(minutes=20)).timetuple())),
            "aud": "appstoreconnect-v1"
        }
    
        token = jwt.encode(payload=payload, key=private_key, algorithm=algorithm, headers=header).decode('ascii')
        return token
    
    
    def base_call(url, token, method="get", data=None):
        """
        :param url:
        :param token:
        :param method:
        :param data:
        :return:
        """
    
        re_header = {"Authorization": "Bearer %s" % token}
        r = {}
        url = base_api_url + url
    
        requests.adapters.DEFAULT_RETRIES = 1
        req = requests.session()
        req.keep_alive = False
    
        if method.lower() == "get":
            r = req.get(url, params=data, headers=re_header)
    
        elif method.lower() == "post":
            re_header["Content-Type"] = "application/json"
            r = req.post(url=url, headers=re_header, data=json.dumps(data))
    
        elif method.lower() == "patch":
            re_header["Content-Type"] = "application/json"
            r = req.patch(url=url, headers=re_header, data=json.dumps(data))
        return r
    
    # ------------------ 获取具体接口的方法 ------------------
    
    
    def get_devices(api_token, data=None):
        """
        获取devices信息
        :param api_token:
        :param data:
        :return:
        """
        get_devices_url = '/v1/devices'
        if data is None:
            data = {
                "filter[platform]": "IOS",
                # "filter[status]": "ENABLED",
                "limit": 100
            }
        res = base_call(get_devices_url, api_token, 'get', data)
        return res
    
    
    def set_devices(api_token, data):
        """
        增加devices信息
        :param api_token:
        :param data:
        :return:
        """
        set_device_url = '/v1/devices'
        res = base_call(set_device_url, api_token, 'post', data)
        return res
    
    
    def update_devices(api_token, id, data,):
        """
        增加devices信息
        :param id:
        :param api_token:
        :param data:
        :return:
        """
        set_device_url = '/v1/devices/{%s}' % id
        res = base_call(set_device_url, api_token, 'patch', data)
        return res
    
    
    
    """
    if __name__ == "__main__":
    
        ios_api_key = 'T8****8AD8'
        ios_api_issuer = '69a**9-b79b-4**3-e053-5b**1a4d1'
        file_key = "/Users/drew/.private_keys/AuthKey_T85LR***8.p8"
        token_api = get_token(ios_api_key, ios_api_issuer, file_key)
        # get_udid()
        post_data = {
            "data": {
                "attributes": {
                    "name": "zb",
                    "platform": "IOS",
                    "udid": "80b677c2c****e476caf61ba0d34274000"
                },
                "type": "devices"
            }
        }
    
        res = set_udid(token_api, post_data)
        print(res)
    """
     
    
    



  • 相关阅读:
    FilterLog代码分析
    Session
    关于XML的技术详情----XML定义 用途 工作原理及未来
    javaee思维导图
    互联网应用与企业级应用的区别
    javaee课程目标
    Recycle -- 项目总结
    python3.6学习笔记2基础语法
    python3.6学习笔记1认识python
    CentOS6.5下Virtualenv搭建Python3开发环境
  • 原文地址:https://www.cnblogs.com/drewgg/p/13452033.html
Copyright © 2011-2022 走看看