{ "info": { "author": "Yordy Gelvez", "author_email": "yordy.gelvez@gmail.com", "bugtrack_url": null, "classifiers": [], "description": "# infusionsoft-python\n\nInfusionSoft API wrapper for Infusionsoft written in Python.\n\n## Installing\n```\npip install infusionsoft-python\n```\n\n## Usage\n```python\nfrom infusionsoft.client import Client\nclient = Client('CLIENT_ID', 'CLIENT_SECRET', 'OPTIONAL - access_token')\n```\nFirst time you will have to authorize your app to get the access_token. Follow these steps to do so:\n#### Get authorization url\n```python\nurl = client.oauth_access(\"REDIRECT_URL\")\n```\nFirst, you need to generate a url and direct admin's browser to this url.\nThere she will see an Infusionsoft branded authorisation window.\nWhen she clicks \"Authorize\", the browser will redirect the admin to the REDIRECT_URL that you have passed into this method.\nA GET parameter named 'code' will be passed along side this request. You will need this CODE and the initial REDIRECT_URL to get the token.\n\nCode sample using Flask:\n```python\n@app.route('/infusionsoft-auth', methods=['GET'])\ndef infusionsoft_auth():\n client = Client('CLIENT_ID', 'CLIENT_SECRET')\n\n code = request.args.get('code', None)\n if not code:\n url = client.oauth_access(\"127.0.0.1/infusionsoft-auth\")\n return redirect(url, code=302)\n```\n\n#### Exchange the code for an access token\n```python\ntoken = client.exchange_code('REDIRECT_URL', 'CODE')\n```\nOnce you've got the CODE parameter back, you will need to exchange it for a token, before it expires.\nYou need to use the same REDIRECT_URL that you've use to redirect your admin during the previous step and the CODE\nthat you've received.\n\nThis will get you both REFRESH_TOKEN and ACCESS_TOKEN for your application. **You will need to save both of these.**\n\naccess_token is used to sign every request you make to Infusionsoft. However, it expires every 24 hours.\nrefresh_token is used to get a new access_token and will expire in 90 days. Unless you refresh it within that period.\n\nHere is the modified version of our Flask example:\n```python\n@app.route('/infusionsoft-auth', methods=['GET'])\ndef infusionsoft_auth():\n client = Client('CLIENT_ID', 'CLIENT_SECRET')\n\n code = request.args.get('code', None)\n if not code:\n url = client.oauth_access(\"127.0.0.1/infusionsoft-auth\")\n return redirect(url, code=302)\n else:\n token = client.exchange_code(\"127.0.0.1/infusionsoft-auth\", code)\n refresh_token = token.get('refresh_token')\n access_token = token.get('access_token')\n expiration_datetime = datetime.datetime.now() + datetime.timedelta(seconds=token.get('expires_in')) # This is the time when your access_token will expire exactly.\n```\n\n#### Set access token\nOnce you have an ACCESS_TOKEN you can start making requests. All you need to do is set it bore making a request.\n```python\nclient = Client('CLIENT_ID', 'CLIENT_SECRET')\nclient.set_token('ACCESS_TOKEN')\n\nlist_contacts = client.get_contacts() # Sample request.\n```\nAlternatively, you can set it on initialization.\n```python\nclient = Client('CLIENT_ID', 'CLIENT_SECRET', 'ACCESS_TOKEN')\n\nlist_contacts = client.get_contacts() # Sample request.\n```\n\n#### Refresh token\nBefore your ACCESS_TOKEN expires, it's a good idea to refresh it. You can put this task on cron, for example.\n```python\ntoken = client.refresh_token('REFRESH TOKEN')\n\nrefresh_token = token.get('refresh_token')\naccess_token = token.get('access_token')\nexpiration_datetime = datetime.datetime.now() + datetime.timedelta(seconds=token.get('expires_in')) # This is the time when your access_token will expire exactly.\n```\nPlease note that even if you ACCESS_TOKEN expired, you can still call this method.\nAs long as your REFESH_TOKEN is not expired (usually 90 days).\n\n\n#### Get Contacts\nhere you list the contacts, can receive limit, order, order_direction and offset.\nfor filter specific camps use this sintaxis: get_contacts(field=\"name\", order_direction=\"descending\")\n```python\nlist_contacts = client.get_contacts(order=\"id\", order_direction=\"descending\")\n```\n\n#### Retrieve Contacts\nhere you can retrieve a contact, send the ID and the optional_properties values\n```python\nretrieve_contact = client.retrieve_contact(166, optional_properties=\"custom_fields,preferred_name,opt_in_reason,notes\")\n```\n\n#### Create Contact\nhere you create a contact, you must to give a valid email or a phone number and that is send as a kwarg\ndata = {'email_addresses': [{'email': 'EMAIL@EMAIL.com', 'field': 'EMAIL1'}], 'given_name': 'NAME'}\n```python\ncreate_contact = client.create_contact(**data)\n```\n\n#### Delete Contact\nhere you delete a contact, is obligatory the id of the contact\n```python\ndelete_contact = client.delete_contact('ID')\n```\n\n#### Update Contact\ndata = {'email_addresses': [{'email': 'EMAIL@EMAIL.com', 'field': 'EMAIL1'}], 'given_name': 'NAME'}\n```python\nupdate_contact = client.update_contact('184', **data)\n```\n\n#### Get Campaign\nhere you list the campaigns, can receive limit and offset\n```python\nlist_campaigns = client.get_campaigns()\n```\n\n#### Retrieve Campaign\nhere you can retrieve a specific campaign, obligatory the id of the campaign\n```python\nretrieve_campaign = client.retrieve_campaign('ID')\n```\n\n#### Get Emails\nhere you can get all, can receive limit or offset\n```python\nlist_emails = client.get_emails()\n```\n\n#### Get Opportunities\nhere you can list the opportunities, can receive limit, order, and offset\n```python\nlist_opportunities = client.get_opportunities()\n```\n\n#### Get Opportunities Pipeline\nhere you can list the pipeline opportunities\n```python\nlist_all_opportunities = client.get_opportunities_pipeline()\n```\n\n#### Retrieve Opportunity\nhere you can retrieve a specific opportunity, obligatory send the id\n```python\nretrieve_opportunity = client.retrieve_opportunity('ID')\n```\n\n#### Create Opportunity\nhere you can create an opportunity, obligatory opportunity_title, contact, and stage\ndata = {\n 'contact': {\n 'id': '170'\n },\n 'stage': {\n 'name': 'Stage Test',\n 'id': 10,\n 'details': {\n 'check_list_items': [\n {'description': 'Test Opportunity'}\n ]\n }\n },\n 'opportunity_title': 'OpportunityTitle'\n}\n```python\ncreate_opportunity = client.create_opportunity(**data)\n```\n\n#### Update Opportunity\nhere you can update an opportunity, obligatory send the id of the opportunity and the data to update\ndata = {\n 'contact': {\n 'id': '170'\n },\n 'stage': {\n 'name': 'Stage Test',\n 'id': 10,\n 'details': {\n 'check_list_items': [\n {'description': 'Test Opportunity'}\n ]\n }\n },\n 'opportunity_title': 'OpportunityTitle'\n}\n```python\nupdate_opportunity = client.update_opportunity('ID', **data)\n```\n\n#### Get Products\nhere you can list the products\n```python\nget_products = client.get_products()\n```\n\n#### Retrieve Product\nhere you can retrieve a specific product, just send the id of the product\n```python\nretrieve_product = client.retrieve_product('ID')\n```\n\n#### Get Tasks\nhere you can list the tasks, can receive limit, offset\n```python\nget_tasks = client.get_tasks()\n```\n\n#### Create Task\nhere you can list the tasks, can receive limit, offset\ndata = {'title': 'TASK TITLE', \"contact\": {\"id\": 170}}\n```python\ncreate_task = client.create_task(**data)\n```\n\n#### Delete Task\nhere you can delete a tasks, obligatory send the id of the task\n```python\ndelete_task = client.delete_task('ID')\n```\n\n#### Update Task\nhere you can update a tasks, obligatory send the id of the task to update and the data\ndata = {'title': 'TASK TITLE', \"contact\": {\"id\": 170}}\n```python\nupdate_task = client.update_task('ID', **data)\n```\n\n#### Retrieve Task\nhere you can retrieve a tasks, obligatory send the id of the task\n```python\nretrieve_task = client.retrieve_task('ID')\n```\n\n#### Replace Task\nhere you can replace a task, obligatory send the id of the task\n```python\nreplace_task = client.replace_task('ID')\n```\n\n#### Get Orders\nhere you can get orders, can receive limit, offset\n```python\nget_orders = client.get_orders()\n```\n\n#### Retrieve Order\nhere you can retrieve an order, obligatory send the id of the order\n```python\nretrieve_order = client.retrieve_order('ID')\n```\n\n#### Get Hook Events\nhere you can list the hooks events, just call the method\n```python\nget_hook_events = client.get_hook_events()\n```\n\n#### Get Webhooks\nhere you can get all the hook subscriptions, just call the method\n```python\nget_hook_subscriptions = client.get_hook_subscriptions()\n```\n\n#### Verify Hook Subscription\nhere you can verify a hook subscription, send the id of the webhook to verify it\n```python\nverify_hook = client.verify_hook_subscription('ID')\n```\n\n#### Create Hook Subscription\nhere you can create a hook subscription, send the hook event and the url callback\n```python\ncreate_hook = client.create_hook_subscription(\"opportunity.add\", \"URL\")\n```\n\n#### Update Hook Subscription\nhere you can update a hook, send the hook id, event and url\n```python\nupdate_hook = petition.update_hook_subscription('ID', 'opportunity.delete', 'URL')\n```\n\n#### Delete Hook Subscription\nhere you can delete a hook subscription, is obligatory to send the hook id\n```python\ndelete_hook = petition.delete_hook_subscription('ID')\n```\n\n#### List All Tags\nHere you can get all available tags.\n```python\nall_tags = client.list_tags()\n```\n\n#### Apply Tag\nHere you can apply a tag to a contact.\n```python\nres = client.apply_tag('TAG_ID', 'CONTACT_ID')\n```\nOr to multiple contacts at the same time.\n```python\nres = client.apply_tag('TAG_ID', ['CONTACT1_ID', 'CONTACT2_ID', ...])\n```\nThe result will be a dict with contact IDs as keys and statuses as values.\n```python\n{'1': 'SUCCESS', '3': 'DUPLICATE'}\n```\n\n#### Remove Tag\nHere you can remove previously applied tag from a contact.\n```python\nall_tags = remove_tag.list_tags('TAG_ID', 'CONTACT_ID')\n```\n\n## Error Handling\nAll library errors are inherited from the base **InfusionsoftException**.\nYou can either catch that, or you can catch more specific exceptions. Here is an example:\n```python\nfrom infusionsoft.client import Client\nfrom infusionsoft.errors import InfusionsoftException, AuthError, TokenError, ConnectionError, DataError \n\n\ntry:\n try:\n try:\n try:\n try:\n client = Client('CLIENT_ID', 'CLIENT_SECRET', 'ACCESS_TOKEN')\n list_contacts = client.get_contacts() # Sample request.\n except DataError as e:\n print('Something is wrong with the data.')\n print(e)\n except ConnectionError as e:\n print('Something is wron with Infusionsoft connection.')\n print(e)\n except TokenError as e:\n print('Something is wrong with one of the tokens.')\n print(e)\n except AuthError as e:\n print('Authentication error.')\n print(e)\nexcept InfusionsoftException as e:\n print('Something went wrong with Infusionsoft.')\n print(e)\n```\n\n## Requirements\n- requests\n\n## Tests\n```\ninfusionsoft/test.py\n```\n\n## TODO Endpoints\n- All Appointments Section\n- All File Section\n- All Tag Section\n\n## Contributing\nWe are always grateful for any kind of contribution including but not limited to bug reports, code enhancements, bug fixes, and even functionality suggestions.\n#### You can report any bug you find or suggest new functionality with a new [issue](https://github.com/GearPlug/infusionsoft-python/issues).\n#### If you want to add yourself some functionality to the wrapper:\n1. Fork it ( https://github.com/GearPlug/infusionsoft-python )\n2. Create your feature branch (git checkout -b my-new-feature)\n3. Commit your changes (git commit -am 'Adds my new feature')\n4. Push to the branch (git push origin my-new-feature)\n5. Create a new Pull Request", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/GearPlug/infusionsoft-python", "keywords": "", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "infusionsoft-python", "package_url": "https://pypi.org/project/infusionsoft-python/", "platform": "", "project_url": "https://pypi.org/project/infusionsoft-python/", "project_urls": { "Homepage": "https://github.com/GearPlug/infusionsoft-python" }, "release_url": "https://pypi.org/project/infusionsoft-python/0.1.3/", "requires_dist": null, "requires_python": "", "summary": "API wrapper for Infusionsoft written in Python", "version": "0.1.3" }, "last_serial": 5946835, "releases": { "0.1": [ { "comment_text": "", "digests": { "md5": "de3a296123d3b6d39703ec5473c224fd", "sha256": "86cb03bc3ee1cc457a1b1bd548821540bf6737d8644a0ff380838b72faac213b" }, "downloads": -1, "filename": "infusionsoft-python-0.1.tar.gz", "has_sig": false, "md5_digest": "de3a296123d3b6d39703ec5473c224fd", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6854, "upload_time": "2018-02-20T13:44:23", "url": "https://files.pythonhosted.org/packages/40/3a/4c594d5446a61db6bcbf7cd278d7dca9628f75241a60017f963763b0486c/infusionsoft-python-0.1.tar.gz" } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "baa8d12316baeb6af421808a55a442db", "sha256": "5c0f6e99196139490267c05113b1573477d7e2dce84f3ecc3cc2945697cd76f4" }, "downloads": -1, "filename": "infusionsoft-python-0.1.1.tar.gz", "has_sig": false, "md5_digest": "baa8d12316baeb6af421808a55a442db", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7934, "upload_time": "2018-02-26T14:23:15", "url": "https://files.pythonhosted.org/packages/4d/41/a835bf0fb25218db6f83552d341a40ab5d54a016a870711ca091193236c1/infusionsoft-python-0.1.1.tar.gz" } ], "0.1.2": [ { "comment_text": "", "digests": { "md5": "f9b32f2c73b113b4cceeec222140e4d9", "sha256": "c542745f571582bb03de9e898f6775e732fd83550f548fde36900ecea06d5c06" }, "downloads": -1, "filename": "infusionsoft-python-0.1.2.tar.gz", "has_sig": false, "md5_digest": "f9b32f2c73b113b4cceeec222140e4d9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8625, "upload_time": "2018-09-20T15:57:11", "url": "https://files.pythonhosted.org/packages/81/9f/c594bad7f331fab40530e8b4a54f1b3b34d559558e33493bf2310a804e26/infusionsoft-python-0.1.2.tar.gz" } ], "0.1.3": [ { "comment_text": "", "digests": { "md5": "ea6a499661bbfbccaad2be9fa2d6e579", "sha256": "57d21f3e2c5342fc7563311d288880ca2b38ba10b2ed33b94fb5aace0736ec51" }, "downloads": -1, "filename": "infusionsoft-python-0.1.3.tar.gz", "has_sig": false, "md5_digest": "ea6a499661bbfbccaad2be9fa2d6e579", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13311, "upload_time": "2019-10-08T21:52:04", "url": "https://files.pythonhosted.org/packages/c3/e2/7643b4c16e6b58b6675fa724eccabafd4c307fec35c1fe8e07473f4fea0c/infusionsoft-python-0.1.3.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "ea6a499661bbfbccaad2be9fa2d6e579", "sha256": "57d21f3e2c5342fc7563311d288880ca2b38ba10b2ed33b94fb5aace0736ec51" }, "downloads": -1, "filename": "infusionsoft-python-0.1.3.tar.gz", "has_sig": false, "md5_digest": "ea6a499661bbfbccaad2be9fa2d6e579", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13311, "upload_time": "2019-10-08T21:52:04", "url": "https://files.pythonhosted.org/packages/c3/e2/7643b4c16e6b58b6675fa724eccabafd4c307fec35c1fe8e07473f4fea0c/infusionsoft-python-0.1.3.tar.gz" } ] }