{ "info": { "author": "Looker Data Sciences, Inc.", "author_email": "support@looker.com", "bugtrack_url": null, "classifiers": [], "description": "===========\nLooker SDK\n===========\n\nThe Looker SDK for Python provides a convenient way to communicate with the\nLooker API available on your Looker server. The library requires python3.7+\nand is annotated using the typing module.\n\n**DISCLAIMER**: This is a *beta* version of the Looker SDK, using a completely\nnew code generator developed by Looker. Implementations are still subject to\nchange, but we expect most SDK method calls to work correctly. If you run into\nproblems with the SDK, please feel free to\n`report an issue `_,\nand please indicate which language SDK you're using in the report.\n\nSample project setup\n====================\n\nInstall python 3.7. We highly recommend using\n`pyenv `_ to install\ndifferent versions of python. Mac users should use\n`homebrew `_ to install pyenv:\n\n.. code-block:: bash\n\n brew install pyenv\n\nFollow the **remaining steps 3 - 5** of\nhttps://github.com/pyenv/pyenv#basic-github-checkout otherwise your python3.7\ninstallation may break.\n\nNow you're ready to install python 3.7:\n\n.. code-block:: bash\n\n pyenv install 3.7.4\n\nNext we'll use `pipenv `_\nas an awesome enhancement to pip to manage project dependencies.\n\n.. code-block:: bash\n\n brew install pipenv\n\nCreate a project directory\n\n.. code-block:: bash\n\n mkdir looker-sdk-example\n\nInstall python3.7 and use it for this directory\n\n.. code-block:: bash\n\n cd looker-sdk-example/\n pyenv local 3.7.4\n\nInstall looker_sdk using pipenv\n\n.. code-block:: bash\n\n pipenv install --python 3.7 --pre looker_sdk\n\n\nConfiguring the SDK\n===================\n\nThe SDK supports configuration through a ``.ini`` file on disk as well\nas setting environment variables (the latter override the former).\n\n**Note**: The ``.ini`` configuration for the Looker SDK is a sample\nimplementation intended to speed up the initial development of python\napplications using the Looker API. See this note on\n`Securing your SDK Credentials `_\nfor warnings about using ``.ini`` files that contain your\nAPI credentials in a source code repository or production environment.\n\nIn order to configure the SDK client, create a \"looker.ini\" file to reference\nduring ``client.setup()``\n\nexample file:\n\n::\n\n [Looker]\n # API version is required\n api_version=3.1\n # Base URL for API. Do not include /api/* in the url\n base_url=https://self-signed.looker.com:19999\n # API 3 client id\n client_id=YourClientID\n # API 3 client secret\n client_secret=YourClientSecret\n # Set to false if testing locally against self-signed certs. Otherwise leave True\n verify_ssl=True\n\n**Note**: If the application using the Looker SDK is going to be committed to a version control system, be sure to\n**ignore** the ``looker.ini`` file so the API credentials aren't unintentionally published.\n\nFor any ``.ini`` setting you can use an environment variable instead. It takes the form of\n``LOOKERSDK_`` e.g. ``LOOKERSDK_CLIENT_SECRET``\n\n\n\nCode example\n============\nCopy the following code block into `example.py`. Note: it's helpful to launch your\ncode editor with your virtual environment loaded so that it can find the looker_sdk\nlibrary and give you a nice code completion experience. Run :code:`pipenv shell` to\nstart load the virtual environment and then run your editor command\n(e.g. for VSCode - :code:`code example.py`)\n\n\n.. code-block:: python\n\n from looker_sdk import client, models, error\n\n # client calls will now automatically authenticate using the\n # api3credentials specified in 'looker.ini'\n sdk = client.setup(\"looker.ini\")\n looker_api_user = sdk.me()\n\n # models can be passed named parameters to the constructor\n new_user = models.WriteUser(first_name=\"John\", last_name=\"Doe\")\n\n # as well as have fields set on the instance\n new_user.is_disabled = True\n new_user.locale = \"fr\"\n\n # create the user with the client\n created_user = sdk.create_user(new_user)\n print(\n f\"Created user({created_user.id}): \"\n f\"{created_user.display_name} \"\n f\"locale({created_user.locale})\"\n )\n\n\n # Updating the user: change first_name and explicitly nullify\n # locale so that it defaults to looker system locale\n update_user = models.WriteUser(\n first_name=\"Jane\", locale=models.EXPLICIT_NULL # do not use None\n )\n\n # update the user with the client\n user_id = created_user.id\n updated_user = sdk.update_user(user_id, body=update_user)\n print(\n f\"Updated user({user_id}): {updated_user.display_name} \"\n f\"locale({updated_user.locale})\"\n )\n\n # perform API calls on behalf of the user: \"sudo\"\n try:\n print(f\"Sudo as {user_id}\")\n sdk.login_user(user_id)\n except error.SDKError:\n print(f\"Oops, we need to enable user({user_id}) first\")\n sdk.update_user(user_id, body=models.WriteUser(is_disabled=False))\n sdk.login_user(user_id)\n\n sudo_user = sdk.me()\n assert sudo_user.id == user_id\n assert sudo_user.id != looker_api_user.id\n\n # logout to switch back to authenticating per 'looker.ini'\n sdk.logout()\n print(f\"Ending sudo({user_id}) session\")\n assert sdk.me().id == looker_api_user.id\n\n # \"sudo\" using a context manager\n with sdk.login_user(user_id):\n assert sdk.me().id == user_id\n\n # exiting context manager is the same as\n # calling sdk.logout()\n assert sdk.me().id == looker_api_user.id\n\n # cleanup\n sdk.delete_user(user_id)\n print(f\"Removed user({user_id})\")\n\nYou can run the example code above but *be aware* it will actually create and\ndelete a user in your looker instance.\n\n.. code-block:: bash\n\n pipenv run python example.py\n\nIf you see a lot of `InsecureRequestWarning` errors because you're running\nagainst an instance with a self-signed cert, this will clean up the output:\n\n.. code-block:: bash\n\n PYTHONWARNINGS=ignore pipenv run python example.py\n\n\nA note on static type checking\n==============================\n\nAll client calls are annotated with with basic types as well as model types.\nMany client calls accept a ``fields`` argument which limits the JSON response\nfrom the API to the specified fields. For this reason, the all properties on the\nmodel are all typed as ``Optional[]``. The effect is that static code analysis\n(`mypy `_ for example) will complain\nif you try to use a field from a model instance in a place that requires\nthe value not be ``Optional``. From the example above\n\n.. code-block:: python\n\n created_user = sdk.create_user(new_user)\n user_id = created_user.id\n\n # mypy error: Argument \"user_id\" to \"update_user\" of \"LookerSDK\"\n # has incompatible type \"Optional[int]\"; expected \"int\"\n sdk.update_user(user_id, ...)\n\nThis is because ``created_user.id`` has type ``Optional[int]`` but we need to use\nit in the ``update_user()`` call which is annotated like this:\n\n.. code-block:: python\n\n def update_user(\n self,\n user_id: int, # note: not Optional[int]\n body: models.WriteUser,\n fields: Optional[str] = None,\n ) -> models.User:\n\n*We* know that ``created_user.id`` is an ``int`` (we didn't pass in a ``fields``\nargument to ``create_user()`` excluding ``id`` from the response). However, mypy\ndoes not so we must guide it in one of the following ways\n\n.. code-block:: python\n\n # assert about the type\n assert isinstance(user_id, int)\n\n # or cast\n from typing import cast\n user_id = cast(created_user.id, int)\n\nNow mypy is happy with ``update_user(user_id, ...)``\n\n\n", "description_content_type": "text/x-rst", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://pypi.python.org/pypi/looker_sdk", "keywords": "looker_sdk,Looker API 3.1", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "looker-sdk", "package_url": "https://pypi.org/project/looker-sdk/", "platform": "", "project_url": "https://pypi.org/project/looker-sdk/", "project_urls": { "Homepage": "https://pypi.python.org/pypi/looker_sdk" }, "release_url": "https://pypi.org/project/looker-sdk/0.1.3b4/", "requires_dist": [ "requests (>=2.22)", "attrs", "cattrs (>=1.0.0rc0)" ], "requires_python": "", "summary": "Looker API 3.1", "version": "0.1.3b4" }, "last_serial": 5945969, "releases": { "0.1.3b1": [ { "comment_text": "", "digests": { "md5": "828f665947f4af0fe452e1aa131c3174", "sha256": "20d44bf245561192e78553181da012a1fe796dcd5fbd660a21548ad74e75b253" }, "downloads": -1, "filename": "looker_sdk-0.1.3b1-py3-none-any.whl", "has_sig": false, "md5_digest": "828f665947f4af0fe452e1aa131c3174", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 96776, "upload_time": "2019-09-24T20:43:12", "url": "https://files.pythonhosted.org/packages/01/99/635fbb6338c327863c75e753bc1d84ef796cbb02de5b6c30576834b606ab/looker_sdk-0.1.3b1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "79274e811ae2188f586557e7eff21f33", "sha256": "5943f92c18ca721dc7a4b543bb8cc5660ef719f1ac856b31f4754c2580c6780d" }, "downloads": -1, "filename": "looker_sdk-0.1.3b1.tar.gz", "has_sig": false, "md5_digest": "79274e811ae2188f586557e7eff21f33", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 85743, "upload_time": "2019-09-24T20:43:15", "url": "https://files.pythonhosted.org/packages/4b/23/a35333be9f668bab60c6fa3d996835cf0330ee16cad6e2e80f3b3aae3cbb/looker_sdk-0.1.3b1.tar.gz" } ], "0.1.3b2": [ { "comment_text": "", "digests": { "md5": "a393363b23ebc5953f9c8b8f0f3762bc", "sha256": "537e3ee5c815694874c0ad74d897848ab7b2ad0ae0ed266adbb020e72a33c099" }, "downloads": -1, "filename": "looker_sdk-0.1.3b2-py3-none-any.whl", "has_sig": false, "md5_digest": "a393363b23ebc5953f9c8b8f0f3762bc", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 97001, "upload_time": "2019-09-30T22:11:51", "url": "https://files.pythonhosted.org/packages/4b/0a/7e3455a391dbbf4ac94ef78f260d48f2ad103dd8b62f6506508df64ac4e8/looker_sdk-0.1.3b2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "663670f49996d1b32eabd0c8e7009739", "sha256": "1a86496a3cde900ed38c63da79e3a9b3dffb3d85bcb67daee318a080ce945a60" }, "downloads": -1, "filename": "looker_sdk-0.1.3b2.tar.gz", "has_sig": false, "md5_digest": "663670f49996d1b32eabd0c8e7009739", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 86241, "upload_time": "2019-09-30T22:11:53", "url": "https://files.pythonhosted.org/packages/82/02/2b292350485848677d5e8ab18285b43a1f99c4af70d3f888fa5c53b1a859/looker_sdk-0.1.3b2.tar.gz" } ], "0.1.3b3": [ { "comment_text": "", "digests": { "md5": "42443c5b6dddd1b888471fdf7ccd1045", "sha256": "d6e28b8ae859c6668d3207be84ce50b50bbb0802e7ee67ec2cf55137eaf57579" }, "downloads": -1, "filename": "looker_sdk-0.1.3b3-py3-none-any.whl", "has_sig": false, "md5_digest": "42443c5b6dddd1b888471fdf7ccd1045", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 97067, "upload_time": "2019-09-30T22:22:45", "url": "https://files.pythonhosted.org/packages/7c/fb/d7abeb98430db4bb42145627548dd47e31ca7bc60138ea1d5b783656547d/looker_sdk-0.1.3b3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "e59f1d669899d238bdb6b6a8f4622aa5", "sha256": "93700e0ef90afcb39ed11c14195dbe651cad9f2e5a6bcbc7a619aacb11bea26d" }, "downloads": -1, "filename": "looker_sdk-0.1.3b3.tar.gz", "has_sig": false, "md5_digest": "e59f1d669899d238bdb6b6a8f4622aa5", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 86385, "upload_time": "2019-09-30T22:22:48", "url": "https://files.pythonhosted.org/packages/66/97/acd5314fb6863824361d6c77761038ee8bd7366b67dfcd6a4a6f3661e3df/looker_sdk-0.1.3b3.tar.gz" } ], "0.1.3b4": [ { "comment_text": "", "digests": { "md5": "841107f5fcd07726f80b4cd506b14472", "sha256": "1c4495f54562468e31af454f81d79949587b13060d7c2cf36ddf6077afb75ddb" }, "downloads": -1, "filename": "looker_sdk-0.1.3b4-py3-none-any.whl", "has_sig": false, "md5_digest": "841107f5fcd07726f80b4cd506b14472", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 100022, "upload_time": "2019-10-08T17:51:38", "url": "https://files.pythonhosted.org/packages/82/32/0c2ef711d3c61a477861ac32141777796f9a80e42710dad0cfab0bf54b34/looker_sdk-0.1.3b4-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "2b6b9589172619d2bdef0c99842d16ec", "sha256": "0e124b304c05ddb4a233210663ca126583d407f52003f5deb9e6fb529f78d7ac" }, "downloads": -1, "filename": "looker_sdk-0.1.3b4.tar.gz", "has_sig": false, "md5_digest": "2b6b9589172619d2bdef0c99842d16ec", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 89455, "upload_time": "2019-10-08T17:51:40", "url": "https://files.pythonhosted.org/packages/9a/7f/4d40eaeb9fbb2e733fff2a04fe4ac39e41986cb0ab58ad31a0dce1cf41ca/looker_sdk-0.1.3b4.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "841107f5fcd07726f80b4cd506b14472", "sha256": "1c4495f54562468e31af454f81d79949587b13060d7c2cf36ddf6077afb75ddb" }, "downloads": -1, "filename": "looker_sdk-0.1.3b4-py3-none-any.whl", "has_sig": false, "md5_digest": "841107f5fcd07726f80b4cd506b14472", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 100022, "upload_time": "2019-10-08T17:51:38", "url": "https://files.pythonhosted.org/packages/82/32/0c2ef711d3c61a477861ac32141777796f9a80e42710dad0cfab0bf54b34/looker_sdk-0.1.3b4-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "2b6b9589172619d2bdef0c99842d16ec", "sha256": "0e124b304c05ddb4a233210663ca126583d407f52003f5deb9e6fb529f78d7ac" }, "downloads": -1, "filename": "looker_sdk-0.1.3b4.tar.gz", "has_sig": false, "md5_digest": "2b6b9589172619d2bdef0c99842d16ec", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 89455, "upload_time": "2019-10-08T17:51:40", "url": "https://files.pythonhosted.org/packages/9a/7f/4d40eaeb9fbb2e733fff2a04fe4ac39e41986cb0ab58ad31a0dce1cf41ca/looker_sdk-0.1.3b4.tar.gz" } ] }