Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何改进此脚本以使其更具Python风格?_Python_Python 2.7_Csv_Hubspot - Fatal编程技术网

如何改进此脚本以使其更具Python风格?

如何改进此脚本以使其更具Python风格?,python,python-2.7,csv,hubspot,Python,Python 2.7,Csv,Hubspot,我对Python编程相当陌生,迄今为止一直是以前的开发人员编写的反向工程代码,或者是我自己拼凑的一些函数 剧本本身是有效的;长话短说,其目的是解析CSV,并(a)创建和/或更新CSV中的联系人,以及(b)将联系人正确分配给其关联公司。所有这些都在使用。为了实现这一点,我还引入了和 我有以下问题: 如何改进此脚本以使其更具Python风格 使此脚本在远程服务器上运行的最佳方法是什么, 请记住,请求和CSVMapper可能不是 安装在那个服务器上,而我很可能不会安装 安装它们的权限-最好的“打包”方

我对Python编程相当陌生,迄今为止一直是以前的开发人员编写的反向工程代码,或者是我自己拼凑的一些函数

剧本本身是有效的;长话短说,其目的是解析CSV,并(a)创建和/或更新CSV中的联系人,以及(b)将联系人正确分配给其关联公司。所有这些都在使用。为了实现这一点,我还引入了和

我有以下问题:

  • 如何改进此脚本以使其更具Python风格
  • 使此脚本在远程服务器上运行的最佳方法是什么, 请记住,请求和CSVMapper可能不是 安装在那个服务器上,而我很可能不会安装 安装它们的权限-最好的“打包”方式是什么 脚本,还是将请求和CSVMapper上载到服务器
  • 非常感谢您的建议

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    from __future__ import print_function
    import sys, os.path, requests, json, csv, csvmapper, glob, shutil
    from time import sleep
    major, minor, micro, release_level, serial =  sys.version_info
    
    # Client Portal ID
    portal = "XXXXXX"
    
    # Client API Key
    
    hapikey = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
    
    # This attempts to find any file in the directory that starts with "note" and ends with ".CSV"
    # Server Version
    # findCSV = glob.glob('/home/accountName/public_html/clientFolder/contact*.CSV')
    
    # Local Testing Version
    findCSV = glob.glob('contact*.CSV')
    
    for i in findCSV:
    
        theCSV = i
    
        csvfileexists = os.path.isfile(theCSV)
    
        # Prints a confirmation if file exists, prints instructions if it doesn't.
    
        if csvfileexists:
            print ("\nThe \"{csvPath}\" file was found ({csvSize} bytes); proceeding with sync ...\n".format(csvSize=os.path.getsize(theCSV), csvPath=os.path.basename(theCSV)))
        else:
            print ("File not found; check the file name to make sure it is in the same directory as this script. Exiting ...")
            sys.exit()
    
        # Begin the CSVmapper mapping... This creates a virtual "header" row - the CSV therefore does not need a header row.
    
        mapper = csvmapper.DictMapper([
          [
            {'name':'account'}, #"Org. Code"
            {'name':'id'}, #"Hubspot Ref"
            {'name':'company'}, #"Company Name"
            {'name':'firstname'}, #"Contact First Name"
            {'name':'lastname'}, #"Contact Last Name"
            {'name':'job_title'}, #"Job Title"
            {'name':'address'}, #"Address"
            {'name':'city'}, #"City"
            {'name':'phone'}, #"Phone"
            {'name':'email'}, #"Email"
            {'name':'date_added'} #"Last Update"
          ]
        ])
    
        # Parse the CSV using the mapper
        parser = csvmapper.CSVParser(os.path.basename(theCSV), mapper)
    
        # Build the parsed object
        obj = parser.buildObject()
    
        def contactCompanyUpdate():
    
            # Open the CSV, use commas as delimiters, store it in a list called "data", then find the length of that list.
            with open(os.path.basename(theCSV),"r") as f:
                reader = csv.reader(f, delimiter = ",", quotechar="\"")
                data = list(reader)
    
                # For every row in the CSV ...
                for row in range(0, len(data)):
                    # Set up the JSON payload ...
    
                    payload = {
                                "properties": [
                                    {
                                        "name": "account",
                                        "value": obj[row].account
                                    },
                                    {
                                        "name": "id",
                                        "value": obj[row].id
                                    },
                                    {
                                        "name": "company",
                                        "value": obj[row].company
                                    },
                                    {
                                        "property": "firstname",
                                        "value": obj[row].firstname
                                    },
                                    {
                                        "property": "lastname",
                                        "value": obj[row].lastname
                                    },
                                    {
                                        "property": "job_title",
                                        "value": obj[row].job_title
                                    },
                                    {
                                        "property": "address",
                                        "value": obj[row].address
                                    },
                                    {
                                        "property": "city",
                                        "value": obj[row].city
                                    },
                                    {
                                        "property": "phone",
                                        "value": obj[row].phone
                                    },
                                    {
                                        "property": "email",
                                        "value": obj[row].email
                                    },
                                    {
                                        "property": "date_added",
                                        "value": obj[row].date_added
                                    }
                                ]
                            }
    
                    nameQuery = "{first} {last}".format(first=obj[row].firstname, last=obj[row].lastname)
    
                    # Get a list of all contacts for a certain company.
                    contactCheck = "https://api.hubapi.com/contacts/v1/search/query?q={query}&hapikey={hapikey}".format(hapikey=hapikey, query=nameQuery)
    
                    # Convert the payload to JSON and assign it to a variable called "data"
                    data = json.dumps(payload)
    
                    # Defined the headers content-type as 'application/json'
                    headers = {'content-type': 'application/json'}
    
                    contactExistCheck = requests.get(contactCheck, headers=headers)
    
                    for i in contactExistCheck.json()[u'contacts']:
    
                        # ... Get the canonical VIDs
                        canonicalVid = i[u'canonical-vid']
    
                        if canonicalVid:
                            print ("{theContact} exists! Their VID is \"{vid}\"".format(theContact=obj[row].firstname, vid=canonicalVid))
                            print ("Attempting to update their company...")
                            contactCompanyUpdate = "https://api.hubapi.com/companies/v2/companies/{companyID}/contacts/{vid}?hapikey={hapikey}".format(hapikey=hapikey, vid=canonicalVid, companyID=obj[row].id)
                            doTheUpdate = requests.put(contactCompanyUpdate, headers=headers)
                            if doTheUpdate.status_code == 200:
                                print ("Attempt Successful! {theContact}'s has an updated company.\n".format(theContact=obj[row].firstname))
                                break
                            else:
                                print ("Attempt Failed. Status Code: {status}. Company or Contact not found.\n".format(status=doTheUpdate.status_code))
    
        def createOrUpdateClient():
    
            # Open the CSV, use commas as delimiters, store it in a list called "data", then find the length of that list.
            with open(os.path.basename(theCSV),"r") as f:
                reader = csv.reader(f, delimiter = ",", quotechar="\"")
                data = list(reader)
    
                # For every row in the CSV ...
                for row in range(0, len(data)):
                    # Set up the JSON payload ...
    
                    payloadTest = {
                                "properties": [
                                    {
                                        "property": "email",
                                        "value": obj[row].email
                                    },
                                    {
                                        "property": "firstname",
                                        "value": obj[row].firstname
                                    },
                                    {
                                        "property": "lastname",
                                        "value": obj[row].lastname
                                    },
                                    {
                                        "property": "website",
                                        "value": None
                                    },
                                    {
                                        "property": "company",
                                        "value": obj[row].company
                                    },
                                    {
                                        "property": "phone",
                                        "value": obj[row].phone
                                    },
                                    {
                                        "property": "address",
                                        "value": obj[row].address
                                    },
                                    {
                                        "property": "city",
                                        "value": obj[row].city
                                    },
                                    {
                                        "property": "state",
                                        "value": None
                                    },
                                    {
                                        "property": "zip",
                                        "value": None
                                    }
                                ]
                            }
    
                    # Convert the payload to JSON and assign it to a variable called "data"
                    dataTest = json.dumps(payloadTest)
    
                    # Defined the headers content-type as 'application/json'
                    headers = {'content-type': 'application/json'}
    
                    #print ("{theContact} does not exist!".format(theContact=obj[row].firstname))
                    print ("Attempting to add {theContact} as a contact...".format(theContact=obj[row].firstname))
                    createOrUpdateURL = 'http://api.hubapi.com/contacts/v1/contact/createOrUpdate/email/{email}/?hapikey={hapikey}'.format(email=obj[row].email,hapikey=hapikey)
    
                    r = requests.post(createOrUpdateURL, data=dataTest, headers=headers)
    
                    if r.status_code == 409:
                        print ("This contact already exists.\n")
                    elif (r.status_code == 200) or (r.status_code == 202):
                        print ("Success! {firstName} {lastName} has been added.\n".format(firstName=obj[row].firstname,lastName=obj[row].lastname, response=r.status_code))
                    elif r.status_code == 204:
                        print ("Success! {firstName} {lastName} has been updated.\n".format(firstName=obj[row].firstname,lastName=obj[row].lastname, response=r.status_code))
                    elif r.status_code == 400:
                        print ("Bad request. You might get this response if you pass an invalid email address, if a property in your request doesn't exist, or if you pass an invalid property value.\n")
                    else:
                        print ("Contact Marko for assistance.\n")
    
        if __name__ == "__main__":
            # Run the Create or Update function
            createOrUpdateClient()
    
            # Give the previous function 5 seconds to take effect.
            sleep(5.0)
    
            # Run the Company Update function
            contactCompanyUpdate()
            print("Sync complete.")
    
            print("Moving \"{something}\" to the archive folder...".format(something=theCSV))
    
            # Cron version
            #shutil.move( i, "/home/accountName/public_html/clientFolder/archive/" + os.path.basename(i))
    
            # Local version
            movePath = "archive/{thefile}".format(thefile=theCSV)
            shutil.move( i, movePath )
    
            print("Move successful! Exiting...\n")
    
    sys.exit()
    

    我会从上到下。第一条规则是,做其中的事,这不是最终的风格指南,但它肯定是Python程序员的参考基准,这更重要,尤其是当您刚开始的时候。第二条规则是,使其可维护。几年后,当其他新来的孩子出现时,她应该很容易明白你在做什么。有时候,这意味着要做很多事情,以减少错误。有时,这意味着要缩短时间,减少错误。:-)

    两件事:根据政治公众人物8,编码正确。及

    编写好的文档字符串(也称为“docstrings”)的约定在

    你有一个可以做点什么的程序。但你没有记录什么

    from __future__ import print_function
    import sys, os.path, requests, json, csv, csvmapper, glob, shutil
    from time import sleep
    major, minor, micro, release_level, serial =  sys.version_info
    
    按照PEP 8:将您的
    导入模块
    语句每行一条

    根据奥斯汀:使你的段落有单独的主题。在一些版本信息的旁边有一些导入。插入一个空行。另外,对数据做点什么!或者你不需要它就在这里,是吗

    # Client Portal ID
    portal = "XXXXXX"
    
    # Client API Key
    
    hapikey = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
    
    你用不止一种方式掩盖了这些。WTF是一个hapikey?我想你的意思是
    Hubspot\u API\u key
    portal
    做什么

    一条建议:事物越“全球化”,它就应该越“正式”。如果有for循环,可以调用其中一个变量
    i
    。如果在函数中使用了一段数据,请将其称为
    obj
    portal
    。但是,如果您有一段数据是全局使用的,或者是一个类变量,请将其放在领带和外套上,以便每个人都能识别它:将其设置为
    Hubspot\u api\u key
    ,而不是
    client\u api\u key
    。如果存在多个api,甚至可能
    Hubspot\u client\u api\u key
    。对
    portal
    执行相同的操作

    # This attempts to find any file in the directory that starts with "note" and ends with ".CSV"
    # Server Version
    # findCSV = glob.glob('/home/accountName/public_html/clientFolder/contact*.CSV')
    
    没过多久,这些评论就变成了谎言。如果它们不是真的,就删除它们

    # Local Testing Version
    findCSV = glob.glob('contact*.CSV')
    
    这是您应该为其创建函数的类型。只需创建一个名为“get_csv_files”的简单函数,让它返回一个文件名列表。这使您与glob分离,这意味着您可以使测试代码数据驱动(将文件名列表传递到函数中,或将单个文件传递到函数中,而不是要求它搜索它们)。此外,这些glob模式正是配置文件、全局变量或作为命令行参数传递的类型

    for i in findCSV:
    
    我敢打赌一直用大写字母输入CSV是件痛苦的事。那么
    findCSV
    是什么意思?读这一行,找出应该调用的变量。可能是
    csv\u文件
    ?或
    新建联系人文件
    ?证明事物是一个集合的东西

        theCSV = i
        csvfileexists = os.path.isfile(theCSV)
    
    现在我做什么?你有一个很好的小变量名,在一个biiig循环中。这是一个错误,因为如果不能在一个页面上看到一个变量的整个作用域,它可能需要一个更长的名称。但是你为它创建了一个别名。
    i
    csv
    都指同一事物。而且。。。我没有看到您再次使用
    I
    。因此,您的循环变量可能应该是
    theCSV
    。或者它应该是的_csv,以便更容易输入。或者只是
    csvname

        # Prints a confirmation if file exists, prints instructions if it doesn't.
    
    这似乎有点不必要。如果您使用
    glob
    获取文件名,那么它们基本上是存在的。(如果没有,那是因为它们是在您调用
    glob
    和尝试打开它们之间被删除的。这是可能的,但很少见。只需
    继续
    或引发异常,具体取决于。)

    在这段代码中,您使用
    csvfileexists
    的值。但那是你唯一使用它的地方。在这种情况下,您可能可以将对
    os.path.isfile()
    的调用移动到if语句中,并去掉该变量

        else:
            print ("File not found; check the file name to make sure it is in the same directory as this script. Exiting ...")
            sys.exit()
    
    请注意,在本例中,当出现实际问题时,您没有打印文件名吗?这有多大帮助

    另外,还记得你在远程服务器上的那部分吗?您应该考虑使用Python来以有用的方式记录这些消息。

    # Begin the CSVmapper mapping... This creates a virtual "header" row - the CSV therefore does not need a header row.
    
    mapper = csvmapper.DictMapper([
      [
        {'name':'account'}, #"Org. Code"
        {'name':'id'}, #"Hubspot Ref"
        {'name':'company'}, #"Company Name"
        {'name':'firstname'}, #"Contact First Name"
        {'name':'lastname'}, #"Contact Last Name"
        {'name':'job_title'}, #"Job Title"
        {'name':'address'}, #"Address"
        {'name':'city'}, #"City"
        {'name':'phone'}, #"Phone"
        {'name':'email'}, #"Email"
        {'name':'date_added'} #"Last Update"
      ]
    ])
    
    您正在创建一个包含大量数据的对象。这将是一个举行活动的好地方。定义一个
    make_csvmapper()
    函数来为您执行所有这些操作,并将其移出行外

    另外,请注意,该标准具有您正在使用的大部分功能。我认为您实际上不需要
    csvmapper

    # Parse the CSV using the mapper
    parser = csvmapper.CSVParser(os.path.basename(theCSV), mapper)
    
    # Build the parsed object
    obj = parser.buildObject()
    
    这是另一个功能的机会。也许您可以返回
    obj
    ,而不是制作csv映射器

    def contactCompanyUpdate():
    
    在这一点上,事情变得可疑。您已经缩进了这些函数定义,但我认为您不需要它们。这是stackoverflow问题,还是您的代码看起来像这样

        # Open the CSV, use commas as delimiters, store it in a list called "data", then find the length of that list.
    
        with open(os.path.basename(theCSV),"r") as f:
    
    不,显然是这样的。因为您在这个函数中使用了
    csv
    ,而实际上您并不需要这样做。请考虑使用
    def contactCompanyUpdate():
    
        # Open the CSV, use commas as delimiters, store it in a list called "data", then find the length of that list.
    
        with open(os.path.basename(theCSV),"r") as f:
    
            reader = csv.reader(f, delimiter = ",", quotechar="\"")
            data = list(reader)
    
            # For every row in the CSV ...
            for row in range(0, len(data)):
    
                # Set up the JSON payload ...
                payload = {
                            "properties": [
                                {
                                    "name": "account",
                                    "value": obj[row].account
                                },
                                {
                                    "name": "id",
                                    "value": obj[row].id
                                },
                                {
                                    "name": "company",
                                    "value": obj[row].company
                                },
                                {
                                    "property": "firstname",
                                    "value": obj[row].firstname
                                },
                                {
                                    "property": "lastname",
                                    "value": obj[row].lastname
                                },
                                {
                                    "property": "job_title",
                                    "value": obj[row].job_title
                                },
                                {
                                    "property": "address",
                                    "value": obj[row].address
                                },
                                {
                                    "property": "city",
                                    "value": obj[row].city
                                },
                                {
                                    "property": "phone",
                                    "value": obj[row].phone
                                },
                                {
                                    "property": "email",
                                    "value": obj[row].email
                                },
                                {
                                    "property": "date_added",
                                    "value": obj[row].date_added
                                }
                            ]
                        }
    
                nameQuery = "{first} {last}".format(first=obj[row].firstname, last=obj[row].lastname)
    
                # Get a list of all contacts for a certain company.
                contactCheck = "https://api.hubapi.com/contacts/v1/search/query?q={query}&hapikey={hapikey}".format(hapikey=hapikey, query=nameQuery)
                # Convert the payload to JSON and assign it to a variable called "data"
                data = json.dumps(payload)
    
                # Defined the headers content-type as 'application/json'
                headers = {'content-type': 'application/json'}
    
                contactExistCheck = requests.get(contactCheck, headers=headers)
    
                for i in contactExistCheck.json()[u'contacts']:
    
                    # ... Get the canonical VIDs
                    canonicalVid = i[u'canonical-vid']
    
                    if canonicalVid:
                        print ("{theContact} exists! Their VID is \"{vid}\"".format(theContact=obj[row].firstname, vid=canonicalVid))
                        print ("Attempting to update their company...")
                        contactCompanyUpdate = "https://api.hubapi.com/companies/v2/companies/{companyID}/contacts/{vid}?hapikey={hapikey}".format(hapikey=hapikey, vid=canonicalVid, companyID=obj[row].id)
                        doTheUpdate = requests.put(contactCompanyUpdate, headers=headers)
                        if doTheUpdate.status_code == 200:
                            print ("Attempt Successful! {theContact}'s has an updated company.\n".format(theContact=obj[row].firstname))
                            break
                        else:
                            print ("Attempt Failed. Status Code: {status}. Company or Contact not found.\n".format(status=doTheUpdate.status_code))
    
    def createOrUpdateClient():
    
                else:
                    print ("Contact Marko for assistance.\n")
    
    if __name__ == "__main__":
        # Run the Create or Update function
        createOrUpdateClient()
    
        # Give the previous function 5 seconds to take effect.
        sleep(5.0)
    
        # Run the Company Update function
        contactCompanyUpdate()
        print("Sync complete.")
    
        print("Moving \"{something}\" to the archive folder...".format(something=theCSV))
    
        # Cron version
        #shutil.move( i, "/home/accountName/public_html/clientFolder/archive/" + os.path.basename(i))
    
        # Local version
        movePath = "archive/{thefile}".format(thefile=theCSV)
        shutil.move( i, movePath )
    
        print("Move successful! Exiting...\n")
    
    sys.exit()