python3.5+ hubspot client based on hapipy, but modified to use the newer endpoints and non-legacy python

Overview

image PyPI version Code style: black Documentation Status Python 3.5+ supported

A python wrapper around HubSpot's APIs, for python 3.5+.

Built initially around hapipy, but heavily modified.

Check out the documentation here! (thanks readthedocs)

Quick start

Installation

# install hubspot3
pip install hubspot3

Basic Usage

from hubspot3 import Hubspot3

API_KEY = "your-api-key"

client = Hubspot3(api_key=API_KEY)

# all of the clients are accessible as attributes of the main Hubspot3 Client
contact = client.contacts.get_contact_by_email('[email protected]')
contact_id = contact['vid']

all_companies = client.companies.get_all()

# new usage limit functionality - keep track of your API calls
client.usage_limits
# <Hubspot3UsageLimits: 28937/1000000 (0.028937%) [reset in 22157s, cached for 299s]>

client.usage_limits.calls_remaining
# 971063

Individual Clients

from hubspot3.companies import CompaniesClient

API_KEY = "your-api-key"

client = CompaniesClient(api_key=API_KEY)

for company in client.get_all():
    print(company)

Passing Params

import json
from hubspot3.deals import DealsClient

deal_id = "12345"
API_KEY = "your_api_key"

deals_client = DealsClient(api_key=API_KEY)

params = {
    "includePropertyVersions": "true"
}  # Note values are camelCase as they appear in the Hubspot Documentation!

deal_data = deals_client.get(deal_id, params=params)
print(json.dumps(deal_data))

Command-line interface

There is also a command-line tool available. Install the extra requirement for that tool via:

pip install hubspot3[cli]

and you can use it as a command:

hubspot3 --help

See the Sphinx documentation for more details and explanations.

Rate Limiting

Be aware that this uses the HubSpot API directly, so you are subject to all of the guidelines that HubSpot has in place.

at the time of writing, HubSpot has the following limits in place for API requests:

Free & Starter:

  • 10 requests per second
  • 250,000 requests per day.

Professional & Enterprise:

  • 10 requests per second
  • 500,000 requests per day.

This daily limit resets at midnight based on the time zone setting of the HubSpot account. There is also an additional addon you can purchase for more requests.

Retrying API Calls

By default, hubspot3 will attempt to retry all API calls up to 2 times upon failure.

If you'd like to override this behavior, you can add a number_retries keyword argument to any Client constructor, or to individual API calls.

Extending the BaseClient - thanks @Guysoft!

Some of the APIs are not yet complete! If you'd like to use an API that isn't yet in this repo, you can extend the BaseClient class!

import json
from hubspot3.base import BaseClient


PIPELINES_API_VERSION = "1"


class PipelineClient(BaseClient):
    """
    Lets you extend to non-existing clients, this example extends pipelines
    """

    def __init__(self, *args, **kwargs):
        super(PipelineClient, self).__init__(*args, **kwargs)

    def get_pipelines(self, **options):
        params = {}

        return self._call("pipelines", method="GET", params=params)

    def _get_path(self, subpath):
        return "deals/v{}/{}".format(
            self.options.get("version") or PIPELINES_API_VERSION, subpath
        )


if __name__ == "__main__":
    API_KEY = "your_api_key"
    a = PipelineClient(api_key=API_KEY)
    print(json.dumps(a.get_pipelines()))

Advanced oauth2 token storage - thanks @sangaline!

This 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.

import aioredis
from hubspot3 import Hubspot3


redis_client = await aioredis.create_redis_pool(url, db=db, encoding='utf-8', timeout=10)

def oauth2_token_getter(token_type: str, client_id: str) -> str:
    loop = asyncio.get_event_loop()
    key = f'hubspot-oauth2-tokens:{token_type}:{client_id}'
    return loop.run_until_complete(redis_client.get(key))

def oauth2_token_setter(token_type: str, client_id: str, token: str) -> None:
    loop = asyncio.get_event_loop()
    key = f'hubspot-oauth2-tokens:{token_type}:{client_id}'
    # Token expiration is six hours, so match that when we store the tokens.
    # See: https://developers.hubspot.com/docs/methods/oauth2/refresh-access-token
    expire_in_seconds = 6 * 60 * 60
    loop.run_until_complete(redis_client.set(key, token, expire=expire_in_seconds))

# This client will share oauth2 credentials with other clients configured in the same way.
hubspot3_client = Hubspot3(
    access_token=access_token,
    client_id=client_id,
    client_secret=client_secret,
    refresh_token=refresh_token,
    oauth2_token_getter=oauth2_token_getter,
    oauth2_token_setter=oauth2_token_setter,
)

Testing

I'm currently working on rewriting many of the tests with pytest to work against the public API and ensure that we get the correct type of mock data back. These tests are currently in a very early state - I'll be working soon to get them all built out.

# Install required test packages
pip install pytest pytest-cov
# or
pip install -r requirements-dev.txt

# run tests
make
# or
make test_all
Comments
  • This package is having an issue loading for me. Hubspot3UsageLimits

    This package is having an issue loading for me. Hubspot3UsageLimits

    File "send_docs.py", line 22, in

    from hubspot3 import Hubspot3
    

    File "C:\Users\Ty Cooper\AppData\Local\Programs\Python\Python37\lib\site-packages\hubspot3_init_.py", line 9, in

    class Hubspot3UsageLimits:
    

    File "C:\Users\Ty Cooper\AppData\Local\Programs\Python\Python37\lib\site-packages\hubspot3_init_.py", line 21, in Hubspot3UsageLimits

    collected_at: datetime = datetime.fromtimestamp(0),
    

    OSError: [Errno 22] Invalid argument

    opened by tycooperaow 19
  • Trouble using the command line

    Trouble using the command line "AttributeError: 'int' object has no attribute 'value'"

    I am trying to use hubspot3 with this command:

    hubspot3 --config config.json crm_associations create --from_object 7307801 --to_object 1181162112 --definition 4

    and receive the following error. AttributeError: 'int' object has no attribute 'value'

    I cannot figure it out. Any ideas?

    My apologies if this question is super basic and obvious. I'm new to this and after 12 hours I think I need some help.

    opened by myperfectcolor 16
  • added support for custom ticket properties

    added support for custom ticket properties

    While developing a ticketing system using this API, I found that support for custom ticket properties was missing. I modified the necessary files to allow for the following:

    tickets = client.tickets.get_all(properties=["subject", "content", "hs_pipeline", "hs_pipeline_stage", "created_by", "hs_ticket_category", "hubspot_owner_id"])

    as well as:

    ticket = client.tickets.get(10239456, properties=["subject", "content", "hs_pipeline", "hs_pipeline_stage", "created_by", "hs_ticket_category", "hubspot_owner_id"])

    I found it extremely valuable being able to specify custom properties. The implementation of this feature may or may not be the proper approach, as I am new to Python. Nonetheless, I find myself having to keep merging my changes locally every time I update my hubspot3 API code.

    opened by huntdesignco 10
  • Add HubSpot's error message on top of HubspotError string representation

    Add HubSpot's error message on top of HubspotError string representation

    HubspotError currently uses the following template for generating its string representation, which contains a lot of useful debugging info:

    ---- request ----
    {method} {host}{url}, [timeout={timeout}]
    
    ---- body ----
    {body}
    
    ---- headers ----
    {headers}
    
    ---- result ----
    {result_status}
    
    ---- body -----
    {result_body}
    
    ---- headers -----
    {result_headers}
    
    ---- reason ----
    {result_reason}
    
    ---- trigger error ----
    {error}
    

    However I've noticed that when using error-tracking services like Sentry, the first line of the error message is usually used as the issue title, which in this case is ---- request ---- . This leads to all of HubSpot errors being merged into one issue, making them pretty hard to track and work with.

    I suggest adding an error message returned from HubSpot as the first line of __str__/__unicode__, which would solve this problem.

    My implementation expects HubSpot's error responses to be returned in the following format (which seems to be the one they're using):

    {
      "status": "error",
      "message": "Property values were not valid",
      ...
    }
    

    Haven't added any tests yet, just want to make sure it makes sense to you first.

    opened by ArtemGordinsky 8
  • Is there OAuth 2 support?

    Is there OAuth 2 support?

    Hey, it's me again :)

    Does the library support running an API that requires OAuth 2 authentication?

    EDIT: I also mean if for example I took care of the authentication myself, can I use the access token instead of API key to run the commands using this library?

    Thanks!

    opened by Nusnus 7
  • Pulling custom properties for Contacts

    Pulling custom properties for Contacts

    Hello,

    I believe this is closely related to ticket #14. I'm trying to pull a number of fields across all contacts: vid, email, and a custom field.

    Is there a way to select this within .get_all()? Or is there another way to solve for this?

    opened by NickBrecht 5
  • Missing API endpoints (bridge, deals, line items)

    Missing API endpoints (bridge, deals, line items)

    Hi there,

    this PR adds some missing endpoints for different API clients:

    • Check the sync status of an object (https://developers.hubspot.com/docs/methods/ecommerce/v2/check-sync-status)
    • Delete a line item (https://developers.hubspot.com/docs/methods/line-items/delete-line-item)
    • Delete a Deal (https://developers.hubspot.com/docs/methods/deals/delete_deal)

    A small note: due to the fact that all deal tests currently use your development Hubspot account I added a test for the deal deletion that actually creates and deletes a deal (to not differ from the other test implementations). That can cause CI errors if the maximum request limit was reached. It would be the best to refactor those test and to mock out the Hubspot calls, but I guess you already discussed that topic with some of my colleagues.

    opened by hkage 4
  • CLI interface issue

    CLI interface issue

    Jacobi,

    Firstly, thank you (and other contributors) for this library.

    I'm a bit new to python (despite many years as a developer - I'm old ;-) and thought this was a great opportunity to develop my python skills while working on a Hubspot integration project.

    My first few attempts to query Hubspot have worked fine. As we are at the design state, I would be expecting to be trialing many different queries and updates, to clarify the approach we'll take to integrations.

    I was particularly interested in the CLI approach for this.. Sadly, I haven't had a lot of success so far... and this could easily be a case of my inexperience and environment (I'm working in a WSL environment.. have access to many flavours of linux, but this is by far the most convenient in the workplace).

    I believe I've followed the setup instructions correctly (but who isn't blind to a few mistakes)

    I think it's the elegance of python-fire that's defeating me at the moment... or maybe understanding the implementation.

    The very simple initial call via CLI is as follows: % hubspot3 --api-key="blahblah" contacts get-all

    The innermost exception appears in main.py in _replace_stdin_token, which is executing a return with an uninitialized variable, new_args.

    I believe this is because the following 'if' will only initialise new_args if stdin_indices or stdin_keys contain a value based on the value of STDIN_TOKEN

     if stdin_indices or stdin_keys:
            value = json.load(sys.stdin)
            new_args = list(args)
            for index in stdin_indices:
                new_args[index] = value
            for key in stdin_keys:
                kwargs[key] = value
    

    --> return new_args, kwargs No matter what I've tried in terms of cli calls, I get an exception at the above line (here's the run time exception, I will add debug session below)

    File "/home/ben/fishscaler/hubspot3/main.py", line 189, in _replace_stdin_token return new_args, kwargs UnboundLocalError: local variable 'new_args' referenced before assignment

    Below is a debug session, where I think the only explanation is, both stdin_indices and stdin_keys aren't initialised with a value... and working back from there has defeated me so far.

    Any light you can shed on this would be appreciated.

    Here's my debug session, including a print(str(sys.argv)) ahead of the call to main()

    /home/ben/fishscaler/cli.py(9)() -> if name == 'main': (Pdb) n /home/ben/fishscaler/cli.py(10)() -> sys.argv[0] = re.sub(r'(-script.pyw?|.exe)?$', '', sys.argv[0]) (Pdb) n /home/ben/fishscaler/cli.py(11)() -> print(str(sys.argv)) (Pdb) n ['cli.py', '--api-key=blahblah', 'contacts', 'get-all'] /home/ben/fishscaler/cli.py(12)() -> sys.exit(main()) (Pdb) s --Call-- /home/ben/fishscaler/hubspot3/main.py(231)main() -> def main(): (Pdb) c /home/ben/fishscaler/hubspot3/main.py(179)_replace_stdin_token() -> index for index, value in enumerate(args) if value == self.STDIN_TOKEN (Pdb) n /home/ben/fishscaler/hubspot3/main.py(181)_replace_stdin_token() -> stdin_keys = [key for key, value in kwargs.items() if value == self.STDIN_TOKEN] (Pdb) n /home/ben/fishscaler/hubspot3/main.py(182)_replace_stdin_token() -> if stdin_indices or stdin_keys: (Pdb) p str(stdin_indices) '[]' (Pdb) p stdin_indices '[]' .... my read on this is - these two empty lists will result in a return of uninitialised new_args

    I'm afraid I'm getting lost in the ClientCLIWrapper and HubspotCLIWrapper calls..

    Please excuse my lack of experience here... I'd really like to use hubspot3, and contribute if I can.

    Thanks, Ben

    opened by BernardBurke 4
  • Naming Conventions and Deprecation Policy

    Naming Conventions and Deprecation Policy

    My colleagues and I are currently in the process of extending existing clients by adding more endpoints (mainly contacts) and adding new clients (e.g. Ecommerce Bridge) - PRs will follow. ;-)

    When it comes to the Contacts API, one of the endpoints we want to add is the Update a contact by email endpoint (currently, hubspot3 only offers the corresponding endpoint that works with IDs). To implement this as a new method, we will have to choose a name for it - which is why we found that the methods of the ContactsClient use multiple different naming conventions:

    • containing the by_id/by_email suffix, e.g. get_contact_by_id
    • containing the a_contact suffix, e.g. update_a_contact
    • short names, e.g. update

    The first two conventions seem to follow the names from the endpoint overview on the left side of the HubSpot API docs, although the a_contact suffix is not necessarily nice.

    The update_a_contact and update methods also seem to contain the same logic and are therefore duplicates, which means that one of them should probably be removed in the long run.

    My questions are:

    • What is the preferred naming scheme for these methods? Should the new method be called update_a_contact_by_email to follow the names in the HubSpot API overview or should it be called update_contact_by_email to follow the convention of the get_...-methods (while renaming the current update method to update_contact_by_id)? Or even something shorter like update_by_email?
    • How to deal with the duplicate update method and other deprecations? I would generally suggest to change one of the duplicate methods to give a deprecation warning and then simply call the other method (that way, the duplicate code is removed, but both methods remain for implementations that already use them; the method containing the deprecation warning can then be removed in the future after developers had the time to react to the warning). The same could be applied to methods that would potentially need renaming after choosing a naming scheme in the first question. Is there a deprecation policy so we can already include the version number in which such methods would finally be removed in such warnings (we could also just say "will be removed in the future")?

    We would implement all of this when extending the ContactsClient and throw a PR your way - we just need to know what the preferred naming convention/deprecation policy would be.

    question 
    opened by W1ldPo1nter 4
  • Add a CLI

    Add a CLI

    This PR will extend the hubspot3 package by a command line interface, which would make it possible to use all of the package's API-interacting functionality outside of a Python project. This would be useful for things like:

    • embedding it in applications not written in Python
    • using it to simply test API calls or to perform some quick one-time actions using the command-line

    Usage

    Using a checkout of the source, it could be called like this: python -m hubspot3 ...

    Due to the added entrypoint in the setup.py, the usage becomes even easier after the package was actually installed via setuptools/pip: hubspot3 ...

    The actual arguments passed to the CLI would always have the following format: python -m hubspot3 <client args> <api name> <method name> <method args> where

    • <client args> are named arguments to pass to the Hubspot3 initializer, e.g. --api_key demo
    • <api name> is the name of the "sub-client" to call, whereby the name is derived from the names are the ones of the properties on the Hubspot3 object, e.g. contacts
    • <method name> name is the name of the python method to invoke on the "sub-client", e.g. get_contact_by_id for the contacts client
    • <method args> are arguments passed as to the called python method als parameters, e.g. simply 51 for positional arguments or --contact_id 51 for named arguments

    An example call would therefore look like this: python -m hubspot3 --api_key demo contacts get_contact_by_id --contact_id 51 Assuming a contact with this ID exists, the CLI will then output the JSON-encoded results from the API on stdout.

    Further descriptions and options can be found in the added sphinx documentation.

    Special options

    The CLI also offers two special options:

    • Using a JSON config file for the <client args>, so the client parameters don't have to be specified over and over again. This will also help security as credentials like the API key do not have to appear on the command line.
    • Reading JSON-encoded data for a method argument from stdin, which is intended for the data that is sent to API endpoints that create/update records. This will also help with security as the data will also not appear on the command line and it helps to not exceed maximum command lengths.

    More info on how to use these options can also be found in the added sphinx documentation.

    Maintenance

    The CLI is designed to be low-maintenance and to not require any changes to the existing code of the API clients. It is built on Google's Fire library, which allows to transform objects of all kinds into CLIs. We introduced some wrapper classes for the Hubspot3 main client and the "sub-clients" that make sure that only the right things are exposed via the Fire-generated CLI:

    • The public client properties on the Hubspot3 main client are automatically detected and transformed into CLI options.
    • On these clients, all public methods are automatically detected and offered as CLI operations.

    New clients should therefore automatically work as long as they are added as a property to the Hubspot3 main class, so there will be no need to touch the CLI code when adding new clients/methods. The only time the CLI code will require some love is when properties on the Hubspot3 main client or methods on "sub-clients" should be explicitly excluded from the CLI (the code for this is already in place).

    Requirements

    The CLI requires one new python package: Google's Fire. This requirement was added to the setup.py as an extra_requirement, so it won't be installed for people who don't want to use the CLI. The package could therefore still be installed as hubspot3 if CLI usage is not intended or as hubspot3[cli] if someone wants to use the CLI as well. You could also move the fire requirement to the regular install_requires if you don't think this separation of requirements is useful.

    I hope this was enough of an explanation. Thank you for maintaining this library and we hope the addition of this CLI is something you consider useful, so it can become a part of hubspot3.

    opened by W1ldPo1nter 4
  • CRM Associations

    CRM Associations

    Hi Jacobi,

    Our team has requested support for CRM Associations (child company to parent companies). I'm going test a local prototype this week and aim to propose a PR here to roll it in.

    I had thought it would just involve updating a company property, but it has its own endpoint: https://developers.hubspot.com/docs/methods/crm-associations/associate-objects

    Adding this issue in case someone wants to team up on this :)

    Cheers,

    Siobhán

    new api 
    opened by SioKCronin 4
  • Disabling auto-retry spams out warnings

    Disabling auto-retry spams out warnings

    According to the documentation:

    # Retrying API Calls
    
    By default, hubspot3 will attempt to retry all API calls up to 2 times
    upon failure.
    
    If you'd like to override this behavior, you can add a `number_retries`
    keyword argument to any Client constructor, or to individual API calls.
    

    However, setting number_retries=0 causes the library to spam out warnings on the first failure, e.g.

    Too many retries for /deals/v1/deal/110248399499?
    Too many retries for /deals/v1/deal/102249436582?
    Too many retries for /deals/v1/deal/102351008917?
    

    When disabling the auto-retry mechanism it is expected that the library will not auto-retry, and will not output anything in regards to retrying.

    Can we disable this warning in case of number_retries==0?

    opened by advance512 1
  • ACCESS TOKEN example

    ACCESS TOKEN example

    Now that the use of API KEYS have been depreciated by HS, would you kindly add an example of authenticating using an ACCESS TOKEN to your readme.

    Thanks for the recent updates.

    opened by kgb105 1
  • Add a Webhooks client

    Add a Webhooks client

    This adds a new Webhooks client that can be used to manage webhook settings and subscriptions using the Hubspot Webhooks API. This API has different requirements from the other API clients, namely it requires the use of an API key for the developer account where the webhook subscriptions live; oauth authentication won't work, nor will the legacy API key or private app access token from a non-developer account. Conversely, the developer account API key cannot be used to access anything from a non-developer account (e.g. contacts, deals, companies). The API also requires that an app_id be specified when initializing the client, for example:

    client = Hubspot3(api_key='<my-developer-key>', app_id=1234)
    client.webhooks.get_all_subscriptions()
    

    As a side note, the API keys for non-developer accounts are being officially sunset tomorrow and will stop working for anybody who didn't specifically get an extension. This might suggest that the api_key parameter should be phased out, but it's worth noting that it's deprecation is only for non-developer accounts and this PR is an example of how the parameter continues to be useful moving forward.

    opened by sangaline 2
  • Error on calling client.usage_limits

    Error on calling client.usage_limits

    I am getting this error when calling client.usage_limits

    ---------------------------------------------------------------------------
    TypeError                                 Traceback (most recent call last)
    <ipython-input-4-99b56d0c4e75> in <module>
    ----> 1 client.usage_limits
    
    ~/projects_backup/env/lib/python3.7/site-packages/hubspot3/__init__.py in usage_limits(self)
        369                 current_usage=int(limits["currentUsage"]),
        370                 fetch_status=limits["fetchStatus"],
    --> 371                 resets_at=datetime.fromtimestamp(int(limits["resetsAt"]) / 1000),
        372                 usage_limit=limits["usageLimit"],
        373             )
    
    TypeError: int() argument must be a string, a bytes-like object or a number, not 'NoneType'
    
    opened by bninopaul 0
  • Help needed - Is there any way to load all the events using Web Analytics API

    Help needed - Is there any way to load all the events using Web Analytics API

    The Web Analytics endpoint allows developers to find and filter events associated with a CRM object of any type. Do we have any way to get all the events exported?

    URL: https://developers.hubspot.com/docs/api/events/web-analytics

    opened by maheshsonavane 0
Releases(3.2.51)
  • 3.2.51(Oct 4, 2021)

    This release includes quite a few PRs that were opened while I had been away from open source for a while - Thanks everyone for your contributions and patience as I get back in the groove of maintaining my open source repos!

    This release adds:

    • UsersClient to access user provisioning via @sangaline (#114)
    • ability to PATCH an engagement in the EngagementsClient via @FredrikWendt (#119)

    This release fixes:

    • type hints of companies.search_domain via @jeking3 (#102)
    • pickling HubspotError by adding a __reduce__() via @jeking3 (#103)
    • excessive log output and potential token exposure via @robinpercy (#113)
    • sensitive data appearing in the logs via @dpgaspar (#117)
    • typing_extensions no longer required as of python 3.8 via @singingwolfboy (#118)
    Source code(tar.gz)
    Source code(zip)
  • 3.2.50(May 13, 2020)

  • 3.2.49(Apr 12, 2020)

  • 3.2.48(Mar 31, 2020)

    This release adds the following new methods to OAuth2Client via @jsancho-gpl (#95 ):

    • get_access_token_data
    • get_refresh_token_data
    • delete_refresh_token
    Source code(tar.gz)
    Source code(zip)
  • 3.2.47(Mar 20, 2020)

  • 3.2.46(Mar 11, 2020)

  • 3.2.45(Mar 2, 2020)

  • 3.2.44(Feb 25, 2020)

  • 3.2.43(Feb 23, 2020)

  • 3.2.42(Jan 5, 2020)

    This release adds:

    • Fix to the TicketsClient update method thanks to @selinfildis (#81)
    • Fix to PipelinesClient update and create methods (fixes #83)
    • More setup info in the readme thanks to @vivithemage (#82)
    Source code(tar.gz)
    Source code(zip)
  • 3.2.41(Dec 16, 2019)

    This release adds a Union[Definitions, int] type for definitions to the methods on CRMAssociationsClient to allow them to work via the CLI (since the code used to only accept a Definitions enum value)

    Source code(tar.gz)
    Source code(zip)
  • 3.2.40(Dec 7, 2019)

    This release merges in @sangaline's addition of custom storage for oauth2 tokens so that multiple clients can share oauth2 tokens for their lifetime, instead of requesting multiple tokens from different instances (#78)

    Source code(tar.gz)
    Source code(zip)
  • 3.2.39(Nov 21, 2019)

    This release adds:

    • limit/offset/since kwargs to the CompaniesClient.get_recently_modified() via @himynameistimli (#76)
    • limit/offset/since kwargs to the CompaniesClient.get_recently_created() via @himynameistimli (#76)
    Source code(tar.gz)
    Source code(zip)
  • 3.2.38(Nov 20, 2019)

  • 3.2.37(Nov 15, 2019)

    This release adds:

    • TicketsClient.update() via @huntdesignco (#74)
    • custom properties kwargs for TicketsClient.get() and TicketsClient.get_all() via @huntdesignco (#74)
    Source code(tar.gz)
    Source code(zip)
  • 3.2.36(Oct 21, 2019)

  • 3.2.35(Oct 15, 2019)

  • 3.2.34(Oct 14, 2019)

    This release adds:

    • LinesClient.get_all() via @jisson (#67)
    • Fixes to ProductsClient: create, update, and delete via @jisson (#66)

    And removes:

    • API Preview warning message for LinesClient, TicketsClient, and ProductsClient

    Potentially breaking change to ProductsClient.create; The data passed in will no longer automatically translate to the data dict passed in into name: value pairs. This didn't align with a lot of the other Client create methods - we'll be trying to standardize this across the board soon

    Source code(tar.gz)
    Source code(zip)
  • 3.2.33(Oct 10, 2019)

    This release adds:

    • prospector config updates
    • various code cleanup via prospector, fixing some small issues
    • GitHub actions for static analysis of changes and Pull Requests
    • @antonioIrizar's change (#65) to add a date data type for VALID_PROPERTY_DATA_TYPES
    Source code(tar.gz)
    Source code(zip)
  • 3.2.32(Oct 9, 2019)

  • 3.2.31(Sep 17, 2019)

  • 3.2.30(Sep 13, 2019)

    This release includes @BuddhaOhneHals's addition (#61) to add a starting_page keyword arg while getting sync errors instead of always starting at page one!

    Source code(tar.gz)
    Source code(zip)
  • 3.2.29(Sep 3, 2019)

  • 3.2.28(Aug 27, 2019)

    This release adds @rheinwerk-mp's changes to the PropertiesClient (#59), adding in an update method, as well as reworking how it validates its fields.

    Source code(tar.gz)
    Source code(zip)
  • 3.2.27(Aug 15, 2019)

  • 3.2.26(Aug 14, 2019)

  • 3.2.25(Aug 8, 2019)

  • 3.2.24(Aug 7, 2019)

    This release merges in @W1ldPo1nter's updates to the EcommerceBridgeClient (#53), fixing some auth issues, as well as adding a new method: get_sync_errors_for_app_and_account.

    Source code(tar.gz)
    Source code(zip)
  • 3.2.23(Aug 6, 2019)

  • 3.2.22(Aug 5, 2019)

Owner
Jacobi Petrucciani
python, bash, docker, k8s, nix, and AWS 🐍 🐳
Jacobi Petrucciani
Drover is a command-line utility for deploying Python packages to Lambda functions.

drover drover: a command-line utility for deploying Python packages to Lambda functions. Background This utility aims to provide a simple, repeatable,

Jeffrey Wilges 4 May 19, 2021
A Telegram bot for Download songs in mp3 format from YouTube and Extract lyrics from Genius.com ❤️

MeudsaMusic A Telegram bot for Download songs in mp3 format from YouTube and Extract lyrics from Genius.com ❤️ Commands Reach @MedusaMusic on Telegram

Bibee 14 Oct 06, 2022
API generated by OpenAPI for nhentai.net

nhentai-api No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) This Python package is automati

Shikanime Deva 1 Nov 01, 2021
A pre-attack hacker tool which aims to find out sensitives comments in HTML comment tag and to help on reconnaissance process

Find Out in Comment Find sensetive comment out in HTML ⚈ About This is a pre-attack hacker tool that searches for sensitives words in HTML comments ta

Pablo Emídio S.S 8 Dec 31, 2022
A Python Tumblr API v2 Client

PyTumblr Installation Install via pip: $ pip install pytumblr Install from source: $ git clone https://github.com/tumblr/pytumblr.git $ cd pytumblr $

Tumblr 677 Dec 21, 2022
A Python wrapper around the Pushbullet API to send different types of push notifications to your phone or/and computer.

pushbullet-python A Python wrapper around the Pushbullet API to send different types of push notifications to your phone or/and computer. Installation

Janu Lingeswaran 1 Jan 14, 2022
Discord bot that manages expiration of roles with subscriptions!

Discord bot that manages expiration of roles with subscriptions!

Chakeaw__ 3 Apr 28, 2022
A simple Python API wrapper for Cloudflare Stream's API.

python-cloudflare-stream A basic Python API wrapper for working with Cloudflare Stream. Arbington.com started off using Cloudflare Stream. We used the

Arbington 3 Sep 08, 2022
A collection of discord tools I've made.

Discord A collection of discord tools i've made. What's in here? Basically every discord related project i've worked on can be found here, i'll try an

?? ?? ?? 6 Nov 13, 2021
A Telegram Bot to display Codeforces Contest Ranklist

CFRankListBot A bot that displays the top ranks for a Codeforces contest. Participants' Details All the details of a participant is in the utils/__ini

Code IIEST 5 Dec 25, 2021
Chronocalc - Calculates the dates and times when the sun or moon is in a given position in the sky

Chronocalc I wrote this script after I was busy updating my article on chronoloc

16 Dec 13, 2022
Códigos pela Força Bruta e Algoritmo Genético para o Problema da Mochila

O problema da mochila é um problema de optimização combinatória. O nome dá-se devido ao modelo de uma situação em que é necessário preencher uma mochi

Hemili Beatriz 1 Jan 08, 2022
Cleiton Leonel 4 Apr 22, 2022
Unofficial calendar integration with Gradescope

Gradescope-Calendar This script scrapes your Gradescope account for courses and assignment details. Assignment details currently can be transferred to

6 May 06, 2022
A telegram bot that can upload telegram media files to anonfiles.com and give you direct download link

✯ AnonFilesBot ✯ Telegram Files to AnonFiles Upload Bot It will Also Give Direct Download Link Process : Fork This Repositry And Simply Cick On Heroku

Avishkar Patil 38 Dec 30, 2022
Python SCript to scrape members from a selected Telegram group.

A python script to scrape all the members in a telegram group anad save in a CSV file. REGESTRING Go to this link https://core.telegram.org/api/obtain

Gurjeet Singh 7 Dec 01, 2022
Simple Instagram Login Link Generator

instagram-account-login Simple Instagram Login Link Generator Info Program generates instagram login links and you may get into someone´s thought the

Kevin 5 Dec 03, 2022
Multi-purpose bot made with discord.py

PizzaHat Discord Bot A multi-purpose bot for your server! ℹ️ • Info PizzaHat is a multi-purpose bot, made to satisfy your needs, as well as your serve

DTS 28 Dec 16, 2022
um simples script para localizar IP

um simples script para localizar IP pkg install git (apt-get install git) pkg install python (apt-get install python) git clone https://github.com/byd

bydeathlxncer 4 Nov 29, 2021
Create Fast and easy image datasets using reddit

Reddit-Image-Scraper Reddit Reddit is an American Social news aggregation, web content rating, and discussion website. Reddit has been devided by topi

Wasin Silakong 4 Apr 27, 2022