|travis build| |Coverage Status|

|pillow\_talk\_icon| # **Pillowtalk**

Creates intuitive python wrappers for APIs. **Pillowtalk** talks to APIs
and handles all of the model relationships behind the scenes, providing
a clean and easy-to-use wrapper for your models.

Why another package?
====================

While there are plenty of excellent libraries for creating APIs, but
creating intuitive wrappers for these APIs isn't entirely
straightforward. **Pillowtalk** cleanly captures the underlying database
relationships APIs may be providing making it easy to write python
models. It provides a wrapper for making intuitive live API calls using
your python models and the underlying relationships you specified.

In future versions, **pillowtalk** will be able to create and update
your code based on a list of JSON files and *guess* at the underlying
relationships between models. From there, **pillowtalk** will
automatically generate or update python models. This means changes to
some API can trigger an automatic update to your python wrapper to that
API!

Features and Examples
=====================

Minimalistic models with relationships
--------------------------------------

e.g. Person with ONE Address; Address has MANY people

.. code:: python

    class MyBase(PillowtalkBase):
        @classmethod
        def find(cls, id):
             ...
             
        def where(cls, data):
             ...

    @add_schema
    class Person(MyBase):
        FIELDS = ["id", "name"]
        RELATIONSHIPS = [
          One("address", "find Person.address_id <> Address.id")
        ]
          
    @add_schema
    class Address(MyBase):
        FIELDS = ["id", "str"]
        RELATIONSHIPS = [
          Many("people", "where Address.id <> Person.address_id")
        ]

Intuitive calls uses live API connection to deserialize data to your
models

.. code:: python

    # address.people doesn't exist yet
    address = Address.find(3)

    # calling .people causes a api call using "where" and deserialization of data
    people = address.people # returns a list of People objects found through "where"

    # returned is a list of Person objects!
    assert type(people[0]) is Person 

Handling impartial data

.. code:: python

    person = {
      "id": 5,
      "name": "Joe",
      "address": {"id": 4}
    }

    p = Person.load(person_data)

    # a.address will magically return Address object even though data is enveloped in a json.
    # we do not specifically have to handle deserialization of impartial data since the
    # relationship between Person.address_id <> Address.id was already defined.
    a = p.address
    assert type(a) is Address
    assert person.address_id == 4 # this wasn't defined explicitly but it is inferred from "address": {"id": 4}

More examples and magic to come!
--------------------------------

::

    Other things include:
        * Magic chaining in relationships
        * Session managing suggestions
        * automatically creating model skeletons from list of JSON
        * model relationships through associations
        * examples of connecting to MySQL or SQLlite
        * examples of using CLI through hug
        

.. |travis build| image:: https://img.shields.io/travis/jvrana/**Pillowtalk**.svg
   :target: https://travis-ci.org/jvrana/**Pillowtalk**
.. |Coverage Status| image:: https://coveralls.io/repos/github/jvrana/**Pillowtalk**/badge.svg?branch=master
   :target: https://coveralls.io/github/jvrana/**Pillowtalk**?branch=master
.. |pillow\_talk\_icon| image:: images/pillowtalk_icon_medium.png?raw=true

