{ "info": { "author": "Adam Jaso", "author_email": "ajaso@hsdp.io", "bugtrack_url": null, "classifiers": [], "description": "# Python Cloud Foundry API Client\n\nThis module provides a pure Python interface to the Cloud Foundry APIs.\n\n## Installation\n\nYou can install from PIP\n\n`pip install cf-api`\n\nor view it on [PyPI](https://pypi.python.org/pypi/cf_api).\n\n## Documentation\n\nSee the docs at [https://cf-api.readthedocs.io/en/latest/](https://cf-api.readthedocs.io/en/latest/) or in the [./docs](docs) directory and the [./examples](examples) directory.\n\n## Getting Started\n\nThe following examples should be enough to get you started using this library.\n\n```python\n# Initializing the Cloud Controller client\n\nfrom getpass import getpass\nimport cf_api\nimport json\n\ncloud_controller = 'https://api.yourcloudfoundry.com'\ndeploy_client_id = 'cf'\ndeploy_client_secret = ''\nverify_ssl = True\nusername = 'youser'\npassword = getpass('Password: ').strip()\n\ncc = cf_api.new_cloud_controller(\n cloud_controller,\n client_id=deploy_client_id,\n client_secret=deploy_client_secret,\n username=username,\n password=password,\n).set_verify_ssl(verify_ssl)\n \n \n# List all organizations\nreq = cc.organizations()\nres = req.get()\norgs = res.resources\nfor r in orgs:\n print('org', r.guid, r.name)\n \n \n# List all spaces\nres = cc.spaces().get()\nspaces = res.resources\nfor r in spaces:\n print('space', r.guid, r.name)\n\n\n# List all applications\n\nres = cc.apps().get()\napps = res.resources\nfor r in apps:\n print('app', r.guid, r.name)\n\n\n# Find an app by it's org/space/name\n\norg_name = 'your_org'\nspace_name = 'your_space'\napp_name = 'your_app'\n\n# find your org by name\nres = cc.organizations().get_by_name(org_name)\n# you can access the first array resource using the `resource` attribute\nyour_org = res.resource\n\n# find your space by name within your org\nres = cc.request(your_org.spaces_url).get_by_name(space_name)\nyour_space = res.resource\n\n# find your app by name within your space\nres = cc.request(your_space.apps_url).get_by_name(app_name)\nyour_app = res.resource\nprint('your_app', your_app)\n\n\n# Find an app by it's GUID\n# \n# Note that this same pattern applies to all Cloud Controller resources\n#\n\nres = cc.apps(your_app.guid).get()\n# you can also use the `resource` attribute to access a response with a \n# non-array result\nyour_same_app = res.resource\nprint('your_same_app', your_same_app)\n\n\n# Find a stack by name\nyour_stack = 'some_stack'\nres = cc.stacks().get_by_name(your_stack)\nstack = res.resource\n\n\n# Create an app\nyour_buildpack = 'some_buildpack'\ncommand = 'python server.py'\nres = cc.apps().set_params(\n name=app_name,\n space_guid=your_space.guid,\n stack_guid=stack.guid,\n buildpack=your_buildpack,\n command=command,\n health_check_type='port',\n health_check_timeout=60,\n instances=2,\n memory=512,\n disk_quota=512\n).post()\nprint('new app', res.data)\n\n\n# Upload the bits for an app\nmy_zipfile = '/tmp/app.zip'\nwith open(my_zipfile, 'r') as f:\n res = cc.apps(your_app.guid, 'bits')\\\n .set_query(async='true')\\\n .add_field('resources', json.dumps([]))\\\n .add_file('application', 'application.zip', f, 'application/zip')\\\n .put()\n print(res.data)\n```\n\n## Environment Variables\n\nThe library is also configurable via environment variables.\n\n| Variable | Description |\n| --- | --- |\n| `PYTHON_CF_URL` | This is the cloud controller base URL. **Do not include a trailing slash on the URL.**\n| `PYTHON_CF_CLIENT_ID` | This is the UAA client ID the library should use.\n| `PYTHON_CF_CLIENT_SECRET` | This is the UAA client secret the library should use.\n| `PYTHON_CF_IGNORE_SSL` | This indicates whether to verify SSL certs. Default is false. Set to `true` to ignore SSL verification.\n| `CF_DOCKER_PASSWORD` | This variable optionally provides the Docker user's password if a docker image is being used. This variable is not necessarily required to use a docker image.\n\nAn example library usage with these variables set would look like this:\n\n```python\n# env vars might be set as follows\n# PYTHON_CF_URL=https://api.cloudfoundry.com\n# PYTHON_CF_CLIENT_ID=my_client_id\n# PYTHON_CF_CLIENT_SECRET=my_client_secret\n\nimport cf_api\n\n# no args are required when the above env vars are detected\ncc = cf_api.new_cloud_controller()\nres = cc.apps().get()\n# ...\n\n# the same principle applies to new_uaa()\nuaa = cf_api.new_uaa()\n# ...\n```\n\n## Log in with Cloud Foundry Authorization Code\n\nThe following functions may be used to implement login with Cloud Foundry via Authorization Codes.\n\nThe function `get_openid_connect_url()` shows how to build UAA URL to which the user can be \nredirected in order to log in.\n \nThe function `verify_code()` can be used when the user successfully logs in and UAA redirects back\nto redirect_uri with the `code` attached. Pass the code and original redirect_uri into this function\nin order to get the OAuth2 Token and to also verify the signature of the JWT.\n\nThis particular example applies to OpenID Connect.\n\n```python\nimport cf_api\n\ncc = 'https://api.yourcloudfoundry.com'\nclient_id = 'yourclient'\nclient_secret = 'yoursecret'\nresponse_type = 'code'\n\ndef get_openid_connect_url(redirect_uri):\n return cf_api\\\n .new_uaa(cc=cc, client_id=client_id, client_secret=client_secret, no_auth=True)\\\n .authorization_code_url(response_type, scope='openid', redirect_uri=redirect_uri)\n\n\ndef verify_code(code, redirect_uri):\n uaa = cf_api.new_uaa(cc=cc, client_id=client_id, client_secret=client_secret, no_auth=True)\n res = uaa.authorization_code(code, response_type, redirect_uri)\n data = res.data\n uaa.verify_token(data['id_token'], audience=uaa.client_id)\n return data\n```\n\n## Deploy an Application\n\nThe `cf_api.deploy_manifest` module may be used to deploy a Cloud Foundry app. The \nfollowing snippet demonstrates the usage for deploying an app.\n\n```bash\ncd path/to/your/project\npython -m cf_api.deploy_manifest \\\n --cloud-controller https://api.yourcloudfoundry.com \\\n -u youser -o yourg -s yourspace \\\n -m manifest.yml -v -w\n# For the CLI usage of deploy_manifest, you may also set\n# the CF_REFRESH_TOKEN environment variable as a substitute\n# for collecting username and password\n```\n\nThis module may also be used programmatically.\n \n```python\nfrom __future__ import print_function\nimport cf_api\nfrom getpass import getpass\nfrom cf_api.deploy_manifest import Deploy\n\ncc = cf_api.new_cloud_controller(\n 'https://api.yourcloudfoundry.com',\n username='youruser',\n password=getpass().strip(),\n client_id='cf',\n client_secret='',\n verify_ssl=True\n)\n\nmanifest_filename = 'path/to/manifest.yml'\n\napps = Deploy.parse_manifest(manifest_filename, cc)\n\nfor app in apps:\n app.set_debug(True)\n app.set_org_and_space('yourorg', 'yourspace')\n print (app.push()) \n # print (app.destroy(destroy_routes=True))\n```\n\n## Deploy a Service\n\nThe `cf_api.deploy_service` module may be used to deploy a Cloud Foundry service to a space. The \nfollowing snippet demonstrates the usage for deploying a service.\n\n```bash\ncd path/to/your/project\npython -m cf_api.deploy_service \\\n --cloud-controller https://api.yourcloudfoundry.com \\\n -u youser -o yourg -s yourspace \\\n --name your-custom-service-name --service-name cf-service-type \\\n --service-plan cf-service-type-plan -v -w\n```\n\nThis module may also be used programmatically.\n\n```python\nfrom __future__ import print_function\nimport cf_api\nfrom getpass import getpass\nfrom cf_api.deploy_service import DeployService\n\ncc = cf_api.new_cloud_controller(\n 'https://api.yourcloudfoundry.com',\n username='youruser',\n password=getpass().strip(),\n client_id='cf',\n client_secret='',\n verify_ssl=True\n)\n\nservice = DeployService(cc)\\\n .set_debug(True)\\\n .set_org_and_space('yourorg', 'yourspace')\n \nresult = service.create('my-custom-db', 'database-service', 'small-database-plan')\nprint(result)\n```\n\n## Query a Space\n\nThe `cf_api.deploy_space` module provides a convenience interface for working with Cloud Foundry\nspaces. The module provides read-only (i.e. GET requests only) support for the Cloud Controller API\nendpoints scoped to a specific space i.e. /v2/spaces//(routes|service_instances|apps).\nThe following snippet demonstrates the usage for listing apps for in a space.\n\n```bash\ncd path/to/your/project\npython -m cf_api.deploy_space \\\n --cloud-controller https://api.yourcloudfoundry.com \\\n -u youser -o yourg -s yourspace apps\n```\n\nThis module may also be used programmatically.\n\n```python\nfrom __future__ import print_function\nimport cf_api\nfrom getpass import getpass\nfrom cf_api.deploy_space import Space\n\ncc = cf_api.new_cloud_controller(\n 'https://api.yourcloudfoundry.com',\n username='youruser',\n password=getpass().strip(),\n client_id='cf',\n client_secret='',\n verify_ssl=True\n)\n\nspace = Space(cc, org_name='yourorg', space_name='yourspace')\n\n# create the space\nspace.create()\n\n# destroy the space\nspace.destroy()\n\n# make a Cloud Controller request within the space\napps_in_the_space = space.request('apps').get()\n\n# deploys an application to this space\nspace.deploy_manifest('/path/to/manifest.yml') # push the app\nspace.wait_manifest('/path/to/manifest.yml') # wait for the app to start\nspace.destroy_manifest('/path/to/manifest.yml') # destroy the app\n\napp = space.get_app_by_name('yourappname') # find an application by its name within the space\n\n# deploy a service in this space\nspace.get_deploy_service().create('my-custom-db', 'database-service', 'small-database-plan')\nservice = space.get_service_instance_by_name('my-custom-db') # find a service by its name within the space\n```\n\n## Tail Application Logs\n\nThe `cf_api.logs_util` module may be used to tail Cloud Foundry application logs. Both\n`recentlogs` and `stream` modes are supported. The following snippet demonstrates the usage for\nlisting recent logs and tailing app logs simultaneously.\n\n```bash\ncd path/to/your/project\npython -m cf_api.logs_util \\\n --cloud-controller https://api.yourcloudfoundry.com \\\n -u youser -o yourg -s yourspace -a yourapp \\\n -r -t\n```\n\nThis module may also be used programmatically.\n\n```python\nfrom __future__ import print_function\nimport cf_api\nfrom getpass import getpass\nfrom cf_api import dropsonde_util\n\ncc = cf_api.new_cloud_controller(\n 'https://api.yourcloudfoundry.com',\n username='youruser',\n password=getpass().strip(),\n client_id='cf',\n client_secret='',\n verify_ssl=True,\n init_doppler=True\n)\n\napp_guid = 'your-app-guid'\napp = cc.apps(app_guid).get().resource\n\n# get recent logs\nlogs = cc.doppler.apps(app.guid, 'recentlogs').get().multipart\n\n# convert log envelopes from protobuf to dict\nlogs = [dropsonde_util.parse_envelope_protobuf(log) for log in logs]\n\nprint(logs)\n\n# stream logs\nws = cc.doppler.ws_request('apps', app.guid, 'stream')\ntry:\n ws.connect()\n ws.watch(lambda m: print(dropsonde_util.parse_envelope_protobuf(m)))\nexcept Exception as e:\n print(e)\nfinally:\n ws.close()\n```\n\n## TODO\n\n### v1.x plans\n\n- Move core logic out of `__init__.py` and into a `core.py` module so that we can import `cf_api` without triggering `ImportError` due to requirements not being installed yet.\n- Make `deploy_manifest`, `deploy_service` use `deploy_space` to initialize\n- Rename `deploy_manifest` to `manifest` and `deploy_manifest.Deploy` to `manifest.Manifest`\n- Rename `deploy_service` to `service` and `deploy_service.DeployService` to `service.Service`\n- Rename `deploy_space` to `space`\n- Simplify `cf_api.new_uaa()` by removing functionality to initialize from Cloud Controller URL as well as UAA URL; consider always requiring a `cc` instance to initialize\n- Remove dependency on `PyJWT` if possible, to remove the sub-dependency on `cryptography` which slows down the package install.\n- Full support for Python 3\n- Consider moving helper modules like `deploy_manifest`, `deploy_service`, and `deploy_blue_green` into a separate package.\n", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/hsdp/python-cf-api", "keywords": "", "license": "Apache License Version 2.0", "maintainer": "", "maintainer_email": "", "name": "cf_api", "package_url": "https://pypi.org/project/cf_api/", "platform": "", "project_url": "https://pypi.org/project/cf_api/", "project_urls": { "Homepage": "https://github.com/hsdp/python-cf-api" }, "release_url": "https://pypi.org/project/cf_api/0.1.12/", "requires_dist": null, "requires_python": "", "summary": "Python Interface for Cloud Foundry APIs", "version": "0.1.12" }, "last_serial": 3933624, "releases": { "0.1.10": [ { "comment_text": "", "digests": { "md5": "b1d82724bd86c8952280a7429ce0be6c", "sha256": "be13c395c0ced4637fda8db9254b9cfe9666c208939022904f0eaf9681252176" }, "downloads": -1, "filename": "cf_api-0.1.10.tar.gz", "has_sig": false, "md5_digest": "b1d82724bd86c8952280a7429ce0be6c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 59576, "upload_time": "2018-01-20T19:15:54", "url": "https://files.pythonhosted.org/packages/9f/52/d7d03cacdbfbd91c1895a0e2b71cf0ed02ce72544261584821e6b028329e/cf_api-0.1.10.tar.gz" } ], "0.1.11": [ { "comment_text": "", "digests": { "md5": "f6283fc80100f9c1136aa1cf7de0d566", "sha256": "109ada178942bc6473c7ae07f0ba9c0ae222890ace62083da03738d62fad036c" }, "downloads": -1, "filename": "cf_api-0.1.11.tar.gz", "has_sig": false, "md5_digest": "f6283fc80100f9c1136aa1cf7de0d566", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 55140, "upload_time": "2018-03-23T18:10:59", "url": "https://files.pythonhosted.org/packages/f8/0b/e3eda27a96d5bcefd723efc5feae21cfa80a90013e093b89f126cbf15ad2/cf_api-0.1.11.tar.gz" } ], "0.1.11a1": [ { "comment_text": "", "digests": { "md5": "feff6e3fad63b5e500b1efb50711c4d3", "sha256": "a0680f0990f341fbb2ec44c8599c097249015f18d4fe6a701c1e46a7d5fc51e2" }, "downloads": -1, "filename": "cf_api-0.1.11a1.tar.gz", "has_sig": false, "md5_digest": "feff6e3fad63b5e500b1efb50711c4d3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 50870, "upload_time": "2018-02-08T01:07:00", "url": "https://files.pythonhosted.org/packages/2b/c1/21e36cfd202127fe3ca79483b88e309a1ae7f46a97a91045220aab47bca1/cf_api-0.1.11a1.tar.gz" } ], "0.1.11a2": [ { "comment_text": "", "digests": { "md5": "750fbde804bf79727eecd93f413d3863", "sha256": "18c787ce91803b582880d98bdffa09ef306ea88f831384e13018a33085ef1643" }, "downloads": -1, "filename": "cf_api-0.1.11a2.tar.gz", "has_sig": false, "md5_digest": "750fbde804bf79727eecd93f413d3863", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 55101, "upload_time": "2018-02-23T21:15:10", "url": "https://files.pythonhosted.org/packages/16/be/cb96c11903a1fba984adf93c610d8f2dd517e336a925091cacda2ea5d27b/cf_api-0.1.11a2.tar.gz" } ], "0.1.12": [ { "comment_text": "", "digests": { "md5": "7f6d5d5e78fad4511572fb8f59f0f201", "sha256": "5b5718c712084a25d18fe0058d00d84fb99303863853c40bbd0c342a2c24df84" }, "downloads": -1, "filename": "cf_api-0.1.12.tar.gz", "has_sig": false, "md5_digest": "7f6d5d5e78fad4511572fb8f59f0f201", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 55178, "upload_time": "2018-05-03T23:18:25", "url": "https://files.pythonhosted.org/packages/d3/e8/b7c773a981a151de97ceb888f43b82403c95f7eea708fcf8b721056a9023/cf_api-0.1.12.tar.gz" } ], "0.1.8": [ { "comment_text": "", "digests": { "md5": "02eea80f38f50bdbdabaeedba9e24afe", "sha256": "0bb82a88a5a7b2b41864680f676353544d161fc1944fa7f33a94438392dc3386" }, "downloads": -1, "filename": "cf_api-0.1.8.tar.gz", "has_sig": false, "md5_digest": "02eea80f38f50bdbdabaeedba9e24afe", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 45270, "upload_time": "2018-01-19T01:03:23", "url": "https://files.pythonhosted.org/packages/fd/0d/ec2c45df32526d8afaec2684a07fdd355bc51287f9976222232095259c9a/cf_api-0.1.8.tar.gz" } ], "0.1.9": [ { "comment_text": "", "digests": { "md5": "0a35ae12464526ddb2f49e792b418db6", "sha256": "a1f511c46b0b47b2c39365a84e11db54d58ea3d71d8421816f35d835c04bf2e2" }, "downloads": -1, "filename": "cf_api-0.1.9.tar.gz", "has_sig": false, "md5_digest": "0a35ae12464526ddb2f49e792b418db6", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 58235, "upload_time": "2018-01-19T22:32:39", "url": "https://files.pythonhosted.org/packages/55/e1/bc359b09b9fb2a62e2069506e5f9cf113a8a9adb1cc1ad0da28f4496d3da/cf_api-0.1.9.tar.gz" } ], "1.0.0a1": [ { "comment_text": "", "digests": { "md5": "7c69f2555c7614c8ad3cf893831022f7", "sha256": "944dd2499ebd717f758f694161102de194c28a2c55dd26643c81bac418a6ae37" }, "downloads": -1, "filename": "cf_api-1.0.0a1.tar.gz", "has_sig": false, "md5_digest": "7c69f2555c7614c8ad3cf893831022f7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 50273, "upload_time": "2018-05-15T01:03:55", "url": "https://files.pythonhosted.org/packages/26/76/31ae4ee8a702247ec854a875ea68b29f5f3234785bd2cf3601d00b5e19a0/cf_api-1.0.0a1.tar.gz" } ], "1.0.0a2": [ { "comment_text": "", "digests": { "md5": "0dde24f184baa089185021afe66a0e3c", "sha256": "dcaa8978ae0d7f8ff1f6129e2aca4ad2f21380d4c7c6c282211ac4b98e189279" }, "downloads": -1, "filename": "cf_api-1.0.0a2.tar.gz", "has_sig": false, "md5_digest": "0dde24f184baa089185021afe66a0e3c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 50719, "upload_time": "2018-05-15T16:07:38", "url": "https://files.pythonhosted.org/packages/20/56/2180b7caeb3beaa08f93a429930389363cb1587da6fdc05de30e5f86789e/cf_api-1.0.0a2.tar.gz" } ], "1.0.0a3": [ { "comment_text": "", "digests": { "md5": "f1a3c8f0a897575e3bdf1156974a4c2f", "sha256": "2cad7060e979d6ad31f436b94766c44b39f62c929cc5c9305330f1678da0f53b" }, "downloads": -1, "filename": "cf_api-1.0.0a3.tar.gz", "has_sig": false, "md5_digest": "f1a3c8f0a897575e3bdf1156974a4c2f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 50678, "upload_time": "2018-05-16T23:28:58", "url": "https://files.pythonhosted.org/packages/8a/d6/bb65597dcaa44b5f01435dbfbf0b752ec214b845745af1f1a1876ee5f35a/cf_api-1.0.0a3.tar.gz" } ], "1.0.0a4": [ { "comment_text": "", "digests": { "md5": "f540c2a31f4bd0b0b91309eb6bc288bd", "sha256": "eaa72a39e0fee1251569fde7bf7c9679159a1a8e274ce3105f0cd9c94f5605ad" }, "downloads": -1, "filename": "cf_api-1.0.0a4.tar.gz", "has_sig": false, "md5_digest": "f540c2a31f4bd0b0b91309eb6bc288bd", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 50677, "upload_time": "2018-05-16T23:55:19", "url": "https://files.pythonhosted.org/packages/64/2c/718f7cce4bdb9a96c1957bbeaa7ecf8f854582c77af8f98314d81de403ad/cf_api-1.0.0a4.tar.gz" } ], "1.0.0a5": [ { "comment_text": "", "digests": { "md5": "edd6d9b459f18f7d8bdf4ce7f18811db", "sha256": "97bd584d261113dd6442d694a1214c5c4229d78e88e1a21c1db7eadf55c26901" }, "downloads": -1, "filename": "cf_api-1.0.0a5.tar.gz", "has_sig": false, "md5_digest": "edd6d9b459f18f7d8bdf4ce7f18811db", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 50698, "upload_time": "2018-06-05T18:35:37", "url": "https://files.pythonhosted.org/packages/ee/8b/419253a849cd4a23324a0a2fe068850d856d1bc4049331956d66d3a8f4c8/cf_api-1.0.0a5.tar.gz" } ], "1.0.0a6": [ { "comment_text": "", "digests": { "md5": "427d02100faa4a6b8ec0c85dcffd7932", "sha256": "04db361c2bb366d853ff6158966392c2f87571c7563f5a690032ee628204a323" }, "downloads": -1, "filename": "cf_api-1.0.0a6.tar.gz", "has_sig": false, "md5_digest": "427d02100faa4a6b8ec0c85dcffd7932", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 50709, "upload_time": "2018-06-05T19:50:57", "url": "https://files.pythonhosted.org/packages/e5/44/5a465db1938dab36b5f8a3916de7c7f0075e8cdc360862c09cecbb94c25e/cf_api-1.0.0a6.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "7f6d5d5e78fad4511572fb8f59f0f201", "sha256": "5b5718c712084a25d18fe0058d00d84fb99303863853c40bbd0c342a2c24df84" }, "downloads": -1, "filename": "cf_api-0.1.12.tar.gz", "has_sig": false, "md5_digest": "7f6d5d5e78fad4511572fb8f59f0f201", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 55178, "upload_time": "2018-05-03T23:18:25", "url": "https://files.pythonhosted.org/packages/d3/e8/b7c773a981a151de97ceb888f43b82403c95f7eea708fcf8b721056a9023/cf_api-0.1.12.tar.gz" } ] }