Package: basecrm
basecrm-pythonBaseCRM Official API V2 library client for PythonInstallationBaseCRM package can be installed either via pip or easy_install:.. code:: bash$ pip install --upgrade basecrmor.. code:: bash$ easy_install --upgrade basecrmYou can install from the source code as well. First clone the repo and
then execute:.. code:: bash$ python setup.py installAfter installing, importbasecrmpackage:.. code:: pythonimport basecrmUsage.. code:: pythonimport basecrm

# Then we instantiate a client (as shown below)Build a client**Using this api without authentication gives an error**

.. code:: python

    client = basecrm.Client(access_token='<YOUR_PERSONAL_ACCESS_TOKEN>')

Client OptionsThe following options are available while instantiating a client:access_token: Personal access tokenbase_url: Base url for the apiuser_agent: Default user-agent for all requeststimeout: Request timeoutverbose: Verbose/debug modeArchitectureThe library follows few architectural principles you should understand
before digging deeper. 1. Interactions with resources are done via
service objects. 2. Service objects are exposed as properties on client
instances. 3. Service objects expose resource-oriented actions. 4.
Actions return dictionaries that support attribute-style access, a la
JavaScript (thanks to Bunch and it's form Munch).

For example, to interact with deals API you will use
``basecrm.DealsService``, which you can get if you call:

.. code:: python

    client = basecrm.Client(access_token='<YOUR_PERSONAL_ACCESS_TOKEN>')
    client.deals # basecrm.DealsService

To retrieve list of resources and use filtering you will call ``#list``
method:

.. code:: python

    client = basecrm.Client(access_token='<YOUR_PERSONAL_ACCESS_TOKEN>')
    client.deals.list(organization_id=google.id, hot=True) # list(dict|Munch)

To find custom field by name and its value pass kwargs as an argument:

.. code:: python

    client = basecrm.Client(access_token='<YOUR_PERSONAL_ACCESS_TOKEN>')
    client.deals.list(**{'custom_fields[name]': 1})

To find a resource by its unique identifier use ``#retrieve`` method:

.. code:: python

    client = basecrm.Client(access_token='<YOUR_PERSONAL_ACCESS_TOKEN>')
    client.deals.retrieve(id=google.id)

When you'd like to create a resource, or update it's attributes you want
to use either ``#create`` or ``#update`` methods. For example if you
want to create a new deal you will call:

.. code:: python

    client = basecrm.Client(access_token='<YOUR_PERSONAL_ACCESS_TOKEN>')
    deal = client.deals.create(name='Website redesign', contact_id=coffeeshop.id)

    deal.value = Decimal("1000.99")
    deal.currency = 'USD'

    client.deals.update(deal.id, deal)

To destroy a resource use ``#destroy`` method:

.. code:: python

    client = basecrm.Client(access_token='<YOUR_PERSONAL_ACCESS_TOKEN>')
    client.deals.destroy(coffeshopdeal.id)

There other non-CRUD operations supported as well. Please contact
corresponding service files for in-depth documentation.

Full exampleCreate a new organization and after that change it's attributes
(website)... code:: pythonclient = basecrm.Client(access_token='<YOUR_PERSONAL_ACCESS_TOKEN>')
lead = client.leads.create(organization_name='Design service company')

lead.website = 'http://www.designservices.com'
client.leads.update(lead.id, lead)PaginationYou can control the maximum number of records that are returned using the standard per_page query parameter.
To choose a page, use the standard page query parameter.
The default page is always the first one. The default limit is 25 and maximum number that can be returned is 100.

.. code:: python

    client = basecrm.Client(access_token='<YOUR_PERSONAL_ACCESS_TOKEN>')
    leads = client.leads.list(per_page=50, page=2)

Error handlingWhen you instantiate a client or make any request via service objects,
exceptions can be raised for multiple of reasons e.g. a network error,
an authentication error, an invalid param error etc.Sample below shows how to properly handle exceptions:.. code:: pythontry:
    # Instantiate a client.
    client = basecrm.Client(access_token='<YOUR_PERSONAL_ACCESS_TOKEN>')
    lead = client.leads.create(organization_name='Design service company')
    print lead
except basecrm.ConfigurationError as e:
    #  Invalid client configuration option
    pass
except basecrm.ResourceError as e:
    # Resource related error
    print 'Http status = ' + e.http_status
    print 'Request ID = ' + e.logref
    for error in e.errors:
        print 'field = ' + error.field
        print 'code = ' + error.code
        print 'message = ' + error.message
        print 'details = ' + error.details
except basecrm.RequestError as e:
    # Invalid query parameters, authentication error etc.
    pass
except Exception as e:
    # Other kind of exceptioni, probably connectivity related
    passSync APIThe following sample code shows how to perform a full synchronization flow using high-level wrapper.First of all you need an instance ofbasecrm.Client. High-levelbasecrm.Syncwrapper usesbasecrm.SyncServiceto interact with the Sync API.
In addition to the client instance, you must provide a device’s UUID withindevice_uuidparameter. The device’s UUID must not change between synchronization sessions, otherwise the sync service will not recognize the device and will send all the data again... code:: pythonclient = basecrmClient(access_token='<YOUR_PERSONAL_ACCESS_TOKEN>')
sync = basecrm.Sync(client=client, device_uuid='<YOUR_DEVICES_UUID')Now all you have to do is to callfetchmethod and pass a lambda or function that you might use to store fetched data to a database... code:: pythondef synchronize(meta, data):
  result =  DAO.execute(table=meta.type,
                        statement=meta.sync.event_type,
                        properties=data)
  return basecrm.Sync.ACK if result else basecrm.sync.NACK

sync.fetch(synchronize)Notice that you must return eitherbasecrm.Sync.ACKorbasecrm.Sync.NACK.Resources and actionsDocumentation for every action can be found inbasecrm/services.pyfile.Account.. code:: python

    client = basecrm.Client(access_token='<YOUR_PERSONAL_ACCESS_TOKEN>')
    client.accounts # => basecrm.AccountsService

Actions:

* Retrieve account details - ``client.accounts.self``

AssociatedContact.. code:: pythonclient = basecrm.Client(access_token='<YOUR_PERSONAL_ACCESS_TOKEN>')
client.associated_contacts # => basecrm.AssociatedContactsServiceActions:Retrieve deal's associated contacts -client.associated_contacts.listCreate an associated contact -client.associated_contacts.createRemove an associated contact -client.associated_contacts.destroyContact.. code:: python

    client = basecrm.Client(access_token='<YOUR_PERSONAL_ACCESS_TOKEN>')
    client.contacts # => basecrm.ContactsService

Actions:

* Retrieve all contacts - ``client.contacts.list``
* Create a contact - ``client.contacts.create``
* Retrieve a single contact - ``client.contacts.retrieve``
* Update a contact - ``client.contacts.update``
* Delete a contact - ``client.contacts.destroy``

Deal
~~~~

.. code:: python

    client = basecrm.Client(access_token='<YOUR_PERSONAL_ACCESS_TOKEN>')
    client.deals # => basecrm.DealsService

Actions:

* Retrieve all deals - ``client.deals.list``
* Create a deal - ``client.deals.create``
* Retrieve a single deal - ``client.deals.retrieve``
* Update a deal - ``client.deals.update``
* Delete a deal - ``client.deals.destroy``

**A note about deal value**

It is prefered to use decimal from string or directly string for deal values when creating or modifying a deal. This guarantees correct precision

.. code:: python

    deal.value = Decimal("1000.99")
    deal.value = "1000.00"

You should not be using floats or decimal constructed from floats as it may result in precision loss.

.. code:: python

    deal.value = 1000.99
    deal.value = decimal(1000.99)

DealSource.. code:: pythonclient = basecrm.Client(access_token='<YOUR_PERSONAL_ACCESS_TOKEN>')
client.deal_sources # => basecrm.DealSourcesServiceActions:Retrieve all sources -client.deal_sources.listCreate a new source -client.deal_sources.createRetrieve a single source -client.deal_sources.retrieveUpdate a source -client.deal_sources.updateDelete a source -client.deal_sources.destroyDealUnqualifiedReason.. code:: python

    client = basecrm.Client(access_token='<YOUR_PERSONAL_ACCESS_TOKEN>')
    client.deal_unqualified_reasons # => basecrm.DealUnqualifiedReasonsService

Actions:

* Retrieve all deal unqualified reasons - ``client.deal_unqualified_reasons.list``
* Create a deal unqualified reason - ``client.deal_unqualified_reasons.create``
* Retrieve a single deal unqualified reason - ``client.deal_unqualified_reasons.retrieve``
* Update a deal unqualified reason - ``client.deal_unqualified_reasons.update``
* Delete a deal unqualified reason - ``client.deal_unqualified_reasons.destroy``

Lead
~~~~

.. code:: python

    client = basecrm.Client(access_token='<YOUR_PERSONAL_ACCESS_TOKEN>')
    client.leads # => basecrm.LeadsService

Actions:

* Retrieve all leads - ``client.leads.list``
* Create a lead - ``client.leads.create``
* Retrieve a single lead - ``client.leads.retrieve``
* Update a lead - ``client.leads.update``
* Delete a lead - ``client.leads.destroy``

LeadSource
~~~~~~~~~~

.. code:: python

    client = basecrm.Client(access_token='<YOUR_PERSONAL_ACCESS_TOKEN>')
    client.lead_sources # => basecrm.LeadSourcesService

Actions:

* Retrieve all sources - ``client.lead_sources.list``
* Create a new source - ``client.lead_sources.create``
* Retrieve a single source - ``client.lead_sources.retrieve``
* Update a source - ``client.lead_sources.update``
* Delete a source - ``client.lead_sources.destroy``

LeadUnqualifiedReason.. code:: pythonclient = basecrm.Client(access_token='<YOUR_PERSONAL_ACCESS_TOKEN>')
client.lead_unqualified_reasons # => basecrm.LeadUnqualifiedReasonsServiceActions:Retrieve all lead unqualified reasons -client.lead_unqualified_reasons.listLineItem.. code:: python

    client = basecrm.Client(access_token='<YOUR_PERSONAL_ACCESS_TOKEN>')
    client.line_items # => basecrm.LineItemsService

Actions:

* Retrieve order's line items - ``client.line_items.list``
* Create a line item - ``client.line_items.create``
* Retrieve a single line item - ``client.line_items.retrieve``
* Delete a line item - ``client.line_items.destroy``

LossReason.. code:: pythonclient = basecrm.Client(access_token='<YOUR_PERSONAL_ACCESS_TOKEN>')
client.loss_reasons # => basecrm.LossReasonsServiceActions:Retrieve all reasons -client.loss_reasons.listCreate a loss reason -client.loss_reasons.createRetrieve a single reason -client.loss_reasons.retrieveUpdate a loss reason -client.loss_reasons.updateDelete a reason -client.loss_reasons.destroyNote.. code:: python

    client = basecrm.Client(access_token='<YOUR_PERSONAL_ACCESS_TOKEN>')
    client.notes # => basecrm.NotesService

Actions:

* Retrieve all notes - ``client.notes.list``
* Create a note - ``client.notes.create``
* Retrieve a single note - ``client.notes.retrieve``
* Update a note - ``client.notes.update``
* Delete a note - ``client.notes.destroy``

Order.. code:: pythonclient = basecrm.Client(access_token='<YOUR_PERSONAL_ACCESS_TOKEN>')
client.orders # => basecrm.OrdersServiceActions:Retrieve all orders -client.orders.listCreate an order -client.orders.createRetrieve a single order -client.orders.retrieveUpdate an order -client.orders.updateDelete an order -client.orders.destroyPipeline.. code:: python

    client = basecrm.Client(access_token='<YOUR_PERSONAL_ACCESS_TOKEN>')
    client.pipelines # => basecrm.PipelinesService

Actions:

* Retrieve all pipelines - ``client.pipelines.list``

Product
~~~~~~~

.. code:: python

    client = basecrm.Client(access_token='<YOUR_PERSONAL_ACCESS_TOKEN>')
    client.products # => basecrm.ProductsService

Actions:

* Retrieve all products - ``client.products.list``
* Create a product - ``client.products.create``
* Retrieve a single product - ``client.products.retrieve``
* Update a product - ``client.products.update``
* Delete a product - ``client.products.destroy``

Source (deprecated, use DealSource, LeadSource instead)
~~~~~~

.. code:: python

    client = basecrm.Client(access_token='<YOUR_PERSONAL_ACCESS_TOKEN>')
    client.sources # => basecrm.SourcesService

Actions:

* Retrieve all sources - ``client.sources.list``
* Create a source - ``client.sources.create``
* Retrieve a single source - ``client.sources.retrieve``
* Update a source - ``client.sources.update``
* Delete a source - ``client.sources.destroy``

Stage
~~~~~

.. code:: python

    client = basecrm.Client(access_token='<YOUR_PERSONAL_ACCESS_TOKEN>')
    client.stages # => basecrm.StagesService

Actions:

* Retrieve all stages - ``client.stages.list``

Tag
~~~

.. code:: python

    client = basecrm.Client(access_token='<YOUR_PERSONAL_ACCESS_TOKEN>')
    client.tags # => basecrm.TagsService

Actions:

* Retrieve all tags - ``client.tags.list``
* Create a tag - ``client.tags.create``
* Retrieve a single tag - ``client.tags.retrieve``
* Update a tag - ``client.tags.update``
* Delete a tag - ``client.tags.destroy``

Task
~~~~

.. code:: python

    client = basecrm.Client(access_token='<YOUR_PERSONAL_ACCESS_TOKEN>')
    client.tasks # => basecrm.TasksService

Actions:

* Retrieve all tasks - ``client.tasks.list``
* Create a task - ``client.tasks.create``
* Retrieve a single task - ``client.tasks.retrieve``
* Update a task - ``client.tasks.update``
* Delete a task - ``client.tasks.destroy``

TextMessage.. code:: pythonclient = basecrm.Client(access_token='<YOUR_PERSONAL_ACCESS_TOKEN>')
client.text_messages # => basecrm.TextMessagesServiceActions:Retrieve text messages -client.text_messages.listRetrieve a single text message -client.text_messages.retrieveUser.. code:: python

    client = basecrm.Client(access_token='<YOUR_PERSONAL_ACCESS_TOKEN>')
    client.users # => basecrm.UsersService

Actions:

* Retrieve all users - ``client.users.list``
* Retrieve a single user - ``client.users.retrieve``
* Retrieve an authenticating user - ``client.users.self``

Visit.. code:: pythonclient = basecrm.Client(access_token='<YOUR_PERSONAL_ACCESS_TOKEN>')
client.visits # => basecrm.VisitsServiceActions:Retrieve visits -client.visits.listVisitOutcome.. code:: python

    client = basecrm.Client(access_token='<YOUR_PERSONAL_ACCESS_TOKEN>')
    client.visit_outcomes # => basecrm.VisitOutcomesService

Actions:

* Retrieve visit outcomes - ``client.visit_outcomes.list``


Tests
-----

To run all test suites:

.. code:: bash

    $ python setup.py test

And to run a single suite:

.. code:: bash

    $ python setup.py test -s basecrm.test.test_associated_contacts_service.AssociatedContactsServiceTests

Thanks
------

We would like to give huge thanks to
`YunoJuno <https://www.yunojuno.com>`__. They reqlinquished the package
name so we were able to publish official wrapper under **basecrm** name.

Thank You!

License
-------

MIT

Bug Reports
-----------

Report `here <https://github.com/basecrm/basecrm-python/issues>`__.

Contact
-------

BaseCRM developers (developers@getbase.com)