{"id":17478156,"url":"https://github.com/jpetrucciani/hubspot3","last_synced_at":"2025-04-04T07:05:19.544Z","repository":{"id":46611408,"uuid":"88071177","full_name":"jpetrucciani/hubspot3","owner":"jpetrucciani","description":"python3.6+ hubspot client based on hapipy, but modified to use the newer endpoints and non-legacy python","archived":false,"fork":false,"pushed_at":"2023-12-22T17:24:39.000Z","size":459,"stargazers_count":147,"open_issues_count":21,"forks_count":73,"subscribers_count":11,"default_branch":"master","last_synced_at":"2024-10-30T05:56:46.090Z","etag":null,"topics":["hacktoberfest","hubspot","library","python3"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jpetrucciani.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-04-12T16:03:05.000Z","updated_at":"2024-09-04T19:22:54.000Z","dependencies_parsed_at":"2024-06-18T18:44:27.100Z","dependency_job_id":"2f494ea2-0b68-4f1b-b28b-50dc82d20136","html_url":"https://github.com/jpetrucciani/hubspot3","commit_stats":{"total_commits":319,"total_committers":47,"mean_commits":6.787234042553192,"dds":0.8307210031347962,"last_synced_commit":"13cae3d08c8ef3d2521939b1bd006a32bfa95ee5"},"previous_names":[],"tags_count":64,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jpetrucciani%2Fhubspot3","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jpetrucciani%2Fhubspot3/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jpetrucciani%2Fhubspot3/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jpetrucciani%2Fhubspot3/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jpetrucciani","download_url":"https://codeload.github.com/jpetrucciani/hubspot3/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247135141,"owners_count":20889420,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["hacktoberfest","hubspot","library","python3"],"created_at":"2024-10-18T20:11:33.248Z","updated_at":"2025-04-04T07:05:19.525Z","avatar_url":"https://github.com/jpetrucciani.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![PyPI\nversion](https://badge.fury.io/py/hubspot3.svg)](https://badge.fury.io/py/hubspot3)\n[![Code style:\nblack](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black)\n[![Documentation\nStatus](https://readthedocs.org/projects/hubspot3/badge/?version=latest)](https://hubspot3.readthedocs.io/en/latest/?badge=latest)\n[![Python 3.8+\nsupported](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/release/python-380/)\n\nA python wrapper around HubSpot's APIs, _for python 3.8+_.\n\nBuilt initially around hapipy, but heavily modified.\n\nCheck out the [documentation\nhere](https://hubspot3.readthedocs.io/en/latest/)\\! (thanks readthedocs)\n\n# Quick start\n\n## **Note: I'd recommend that you consider using the [official HubSpot Python API](https://github.com/HubSpot/hubspot-api-python). I no longer work at a company that uses HubSpot, and this library is a few versions behind on many of their APIs. I will be open to small PRs and usability fixes, but there will likely not be any further significant work on this library**\n\n## Installation\n\n```bash\n# install hubspot3\npip install hubspot3\n```\n\n## Basic Usage\n\n```python\nfrom hubspot3 import Hubspot3\n\nAPI_KEY = \"your-api-key\"\n\nclient = Hubspot3(api_key=API_KEY)\n\n# all of the clients are accessible as attributes of the main Hubspot3 Client\ncontact = client.contacts.get_contact_by_email('testingapis@hubspot.com')\ncontact_id = contact['vid']\n\nall_companies = client.companies.get_all()\n\n# new usage limit functionality - keep track of your API calls\nclient.usage_limits\n# \u003cHubspot3UsageLimits: 28937/1000000 (0.028937%) [reset in 22157s, cached for 299s]\u003e\n\nclient.usage_limits.calls_remaining\n# 971063\n```\n\n## Individual Clients\n\n```python\nfrom hubspot3.companies import CompaniesClient\n\nAPI_KEY = \"your-api-key\"\n\nclient = CompaniesClient(api_key=API_KEY)\n\nfor company in client.get_all():\n    print(company)\n```\n\n## Passing Params\n\n```python\nimport json\nfrom hubspot3.deals import DealsClient\n\ndeal_id = \"12345\"\nAPI_KEY = \"your_api_key\"\n\ndeals_client = DealsClient(api_key=API_KEY)\n\nparams = {\n    \"includePropertyVersions\": \"true\"\n}  # Note values are camelCase as they appear in the Hubspot Documentation!\n\ndeal_data = deals_client.get(deal_id, params=params)\nprint(json.dumps(deal_data))\n```\n\n## Command-line interface\n\nThere is also a command-line tool available. Install the extra\nrequirement for that tool via:\n\n```bash\npip install hubspot3[cli]\n```\n\nand you can use it as a command:\n\n```bash\nhubspot3 --help\n```\n\nSee the Sphinx documentation for more details and explanations.\n\n# Rate Limiting\n\nBe aware that this uses the HubSpot API directly, so you are subject to\nall of the [guidelines that HubSpot has in\nplace](https://developers.hubspot.com/apps/api_guidelines).\n\nat the time of writing, HubSpot has the following limits in place for\nAPI requests:\n\nFree \u0026 Starter:\n\n- 10 requests per second\n- 250,000 requests per day.\n\nProfessional \u0026 Enterprise:\n\n- 10 requests per second\n- 500,000 requests per day.\n\nThis daily limit resets at midnight based on the time zone setting of\nthe HubSpot account. There is also an additional addon you can purchase\nfor more requests.\n\n# Retrying API Calls\n\nBy default, hubspot3 will attempt to retry all API calls up to 2 times\nupon failure.\n\nIf you'd like to override this behavior, you can add a `number_retries`\nkeyword argument to any Client constructor, or to individual API calls.\n\n# Extending the BaseClient - thanks [@Guysoft](https://github.com/guysoft)\\!\n\nSome of the APIs are not yet complete\\! If you'd like to use an API that\nisn't yet in this repo, you can extend the BaseClient class\\!\n\n```python\nimport json\nfrom hubspot3.base import BaseClient\n\n\nPIPELINES_API_VERSION = \"1\"\n\n\nclass PipelineClient(BaseClient):\n    \"\"\"\n    Lets you extend to non-existing clients, this example extends pipelines\n    \"\"\"\n\n    def __init__(self, *args, **kwargs):\n        super(PipelineClient, self).__init__(*args, **kwargs)\n\n    def get_pipelines(self, **options):\n        params = {}\n\n        return self._call(\"pipelines\", method=\"GET\", params=params)\n\n    def _get_path(self, subpath):\n        return f\"deals/v{self.options.get('version') or PIPELINES_API_VERSION}/{subpath}\"\n\n\nif __name__ == \"__main__\":\n    API_KEY = \"your_api_key\"\n    a = PipelineClient(api_key=API_KEY)\n    print(json.dumps(a.get_pipelines()))\n```\n\n# Advanced oauth2 token storage - thanks [@sangaline](https://github.com/sangaline)\\!\n\nThis is an example of how you can use the `oauth2_token_getter` and `oauth2_token_setter` kwargs on the client to use custom storage (in this case redis) so that multiple clients can share the same access/refresh tokens generated by the oauth2 requests.\n\n```python\nimport aioredis\nfrom hubspot3 import Hubspot3\n\n\nredis_client = await aioredis.create_redis_pool(url, db=db, encoding='utf-8', timeout=10)\n\ndef oauth2_token_getter(token_type: str, client_id: str) -\u003e str:\n    loop = asyncio.get_event_loop()\n    key = f'hubspot-oauth2-tokens:{token_type}:{client_id}'\n    return loop.run_until_complete(redis_client.get(key))\n\ndef oauth2_token_setter(token_type: str, client_id: str, token: str) -\u003e None:\n    loop = asyncio.get_event_loop()\n    key = f'hubspot-oauth2-tokens:{token_type}:{client_id}'\n    # Token expiration is six hours, so match that when we store the tokens.\n    # See: https://developers.hubspot.com/docs/methods/oauth2/refresh-access-token\n    expire_in_seconds = 6 * 60 * 60\n    loop.run_until_complete(redis_client.set(key, token, expire=expire_in_seconds))\n\n# This client will share oauth2 credentials with other clients configured in the same way.\nhubspot3_client = Hubspot3(\n    access_token=access_token,\n    client_id=client_id,\n    client_secret=client_secret,\n    refresh_token=refresh_token,\n    oauth2_token_getter=oauth2_token_getter,\n    oauth2_token_setter=oauth2_token_setter,\n)\n```\n\n# Testing\n\nI'm currently working on rewriting many of the tests with\n[pytest](https://docs.pytest.org/en/latest/) to work against the public\nAPI and ensure that we get the correct type of mock data back. These\ntests are currently in a **very** early state - I'll be working soon to\nget them all built out.\n\n```bash\n# Install required test packages\npip install pytest pytest-cov\n# or\npip install -r requirements-dev.txt\n\n# run tests\nmake\n# or\nmake test_all\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjpetrucciani%2Fhubspot3","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjpetrucciani%2Fhubspot3","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjpetrucciani%2Fhubspot3/lists"}