{"id":18637138,"url":"https://github.com/openshift/openshift-restclient-python","last_synced_at":"2025-05-15T06:03:16.672Z","repository":{"id":39706809,"uuid":"82182681","full_name":"openshift/openshift-restclient-python","owner":"openshift","description":"Python client for the OpenShift API","archived":false,"fork":false,"pushed_at":"2023-07-25T22:08:40.000Z","size":3761,"stargazers_count":223,"open_issues_count":1,"forks_count":145,"subscribers_count":27,"default_branch":"master","last_synced_at":"2025-05-15T06:03:03.425Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/openshift.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-02-16T13:19:01.000Z","updated_at":"2025-04-04T22:10:10.000Z","dependencies_parsed_at":"2024-06-18T12:44:01.424Z","dependency_job_id":null,"html_url":"https://github.com/openshift/openshift-restclient-python","commit_stats":{"total_commits":299,"total_committers":43,"mean_commits":6.953488372093023,"dds":0.5986622073578596,"last_synced_commit":"c20fdacf909299ee578dc6e32c2589a9c4f7c7a6"},"previous_names":[],"tags_count":82,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openshift%2Fopenshift-restclient-python","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openshift%2Fopenshift-restclient-python/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openshift%2Fopenshift-restclient-python/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openshift%2Fopenshift-restclient-python/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/openshift","download_url":"https://codeload.github.com/openshift/openshift-restclient-python/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254283336,"owners_count":22045140,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-07T05:33:39.930Z","updated_at":"2025-05-15T06:03:16.652Z","avatar_url":"https://github.com/openshift.png","language":"Python","readme":"OpenShift python client\n======================\n\n[![Build Status](https://travis-ci.com/openshift/openshift-restclient-python.svg?branch=master)](https://travis-ci.com/openshift/openshift-restclient-python)\n[![Coverage Status](https://coveralls.io/repos/github/openshift/openshift-restclient-python/badge.svg?branch=master)](https://coveralls.io/github/openshift/openshift-restclient-python?branch=master)\n\nPython client for the [Kubernetes](https://kubernetes.io/) and [OpenShift](http://openshift.redhat.com/) APIs.\n\nThere are two ways this project interacts with the Kubernetes and OpenShift APIs.\nThe first, **now deprecated**, is to use models and functions generated with\nswagger from the API spec. The second, new approach, is to use a single model\nand client to generically interact with all resources on the server. The\ndynamic client also works with resources that are defined by aggregated\nAPI servers or Custom Resource Definitions.\n\n# Table of Contents\n\n* [Installation](#installation)\n* [Usage](#usage)\n* [Examples](#examples)\n  * [Create a Service](#create-a-service)\n  * [Create a Route](#create-a-route)\n  * [List Projects](#list-projects)\n  * [Custom Resources](#custom-resources)\n  * [OpenShift Login with username and password](#openshift-login-with-username-and-password)\n* [Available Methods for Resources](#available-methods-for-resources)\n  * [Get](#get)\n  * [Create](#create)\n  * [Delete](#delete)\n  * [Patch](#patch)\n  * [Replace](#replace)\n  * [Watch](#watch)\n* [Community, Support, Discussion](#community-support-discussion)\n* [Code of Conduct](#code-of-conduct)\n\n# Installation\n\nFrom source:\n\n```\ngit clone https://github.com/openshift/openshift-restclient-python.git\ncd openshift-restclient-python\npython setup.py install\n```\n\nFrom [PyPi](https://pypi.python.org/pypi/openshift/) directly:\n\n```\npip install openshift\n```\n\nUsing [Dockerfile](Dockerfile):\n\n```\ndocker build -t openshift-restclient-python -f Dockerfile .\n```\n\n# Usage\n\nThe OpenShift client depends on the [Kubernetes Python\nclient](https://github.com/kubernetes-incubator/client-python.git), and as part\nof the installation process, the Kubernetes (K8s) client is automatically\ninstalled.\n\nIn the case you are using Docker, you will likely need to share your\n`.kube/config` with the `openshift-restclient-python` container:\n\n```\ndocker run -it -v $HOME/.kube/config:/root/.kube/config:z openshift-restclient-python python\n```\n\nTo work with the dynamic client, you will need an instantiated Kubernetes\nclient object. The Kubernetes client object requires a Kubernetes Config\nthat can be set in the [Config\nclass](https://github.com/kubernetes-client/python/blob/master/kubernetes/client/configuration.py)\nor using a helper utility.  All of the examples that follow make use of the\n`new_client_from_config()` helper utility provided by the [Kubernetes Client\nConfig](https://github.com/kubernetes-client/python-base/blob/master/config/kube_config.py)\nthat returns an API client to be used with any API object.\nThere are plenty of [Kubernetes Client\nexamples](https://github.com/kubernetes-client/python/tree/master/examples) to\nexamine other ways of accessing Kubernetes Clusters.\n\n# Examples\n\n## Create a Service\n\n```python\nimport yaml\nfrom kubernetes import client, config\nfrom openshift.dynamic import DynamicClient\n\nk8s_client = config.new_client_from_config()\ndyn_client = DynamicClient(k8s_client)\n\nv1_services = dyn_client.resources.get(api_version='v1', kind='Service')\n\nservice = \"\"\"\nkind: Service\napiVersion: v1\nmetadata:\n  name: my-service\nspec:\n  selector:\n    app: MyApp\n  ports:\n  - protocol: TCP\n    port: 8080\n    targetPort: 9376\n\"\"\"\n\nservice_data = yaml.load(service)\nresp = v1_services.create(body=service_data, namespace='default')\n\n# resp is a ResourceInstance object\nprint(resp.metadata)\n```\n\n## Create a Route\n\nNow, we create a Route object, and associate it with the Service from our\nprevious example:\n\n```python\nimport yaml\nfrom kubernetes import client, config\nfrom openshift.dynamic import DynamicClient\n\nk8s_client = config.new_client_from_config()\ndyn_client = DynamicClient(k8s_client)\n\nv1_routes = dyn_client.resources.get(api_version='route.openshift.io/v1', kind='Route')\n\nroute = \"\"\"\napiVersion: route.openshift.io/v1\nkind: Route\nmetadata:\n  name: frontend\nspec:\n  host: www.example.com\n  to:\n    kind: Service\n    name: my-service\n\"\"\"\n\nroute_data = yaml.load(route)\nresp = v1_routes.create(body=route_data, namespace='default')\n\n# resp is a ResourceInstance object\nprint(resp.metadata)\n```\n\n## List Projects\n\nThe following uses the dynamic client to list Projects the user can access:\n\n```python\nfrom kubernetes import client, config\nfrom openshift.dynamic import DynamicClient\n\nk8s_client = config.new_client_from_config()\ndyn_client = DynamicClient(k8s_client)\n\nv1_projects = dyn_client.resources.get(api_version='project.openshift.io/v1', kind='Project')\n\nproject_list = v1_projects.get()\n\nfor project in project_list.items:\n    print(project.metadata.name)\n```\n\n## Custom Resources\n\nIn the following example, we first create a Custom\nResource Definition for `foos.bar.com`, then create an `Foo` resource,\nand finally get a list of `Foo` resources:\n\n```python\nimport yaml\nfrom kubernetes import client, config\nfrom openshift.dynamic import DynamicClient\n\nk8s_client = config.new_client_from_config()\ndyn_client = DynamicClient(k8s_client)\n\ncustom_resources = dyn_client.resources.get(\n  api_version='apiextensions.k8s.io/v1beta1',\n  kind='CustomResourceDefinition'\n)\n\n# Define the Foo Resource\nfoo_crd = \"\"\"\nkind: CustomResourceDefinition\napiVersion: apiextensions.k8s.io/v1beta1\nmetadata:\n  name: foos.bar.com\nspec:\n  group: bar.com\n  names:\n    kind: Foo\n    listKind: FooList\n    plural: foos\n    shortNames:\n    - foo\n    singular: foo\n  scope: Namespaced\n  version: v1beta1\n\"\"\"\ncustom_resources.create(body=yaml.load(foo_crd))\n\nfoo_resources = None\nwhile not foo_resources:\n  try:\n    # Notice the re-instantiation of the dynamic client as a new resource has been created.\n    dyn_client = DynamicClient(k8s_client)\n    foo_resources = dyn_client.resources.get(api_version='bar.com/v1beta1', kind='Foo')\n  except:\n    pass\n\n# Create the Foo Resource\nfoo_resource_cr = \"\"\"\nkind: Foo\napiVersion: bar.com/v1beta1\nmetadata:\n  name: example-foo\n  namespace: default\nspec:\n  version: 1\n\"\"\"\nfoo_resources.create(body=yaml.load(foo_resource_cr))\n\nfor item in foo_resources.get().items:\n  print(item.metadata.name)\n```\n\n## OpenShift Login with username and password\n\n```python\nfrom kubernetes import client\nfrom openshift.dynamic import DynamicClient\nfrom openshift.helper.userpassauth import OCPLoginConfiguration\n \napihost = 'https://api.cluster.example.com:6443'\nusername = 'demo-user'\npassword = 'insecure'\n \nkubeConfig = OCPLoginConfiguration(ocp_username=username, ocp_password=password)\nkubeConfig.host = apihost\nkubeConfig.verify_ssl = True\nkubeConfig.ssl_ca_cert = './ocp.pem' # use a certificate bundle for the TLS validation\n \n# Retrieve the auth token\nkubeConfig.get_token()\n \nprint('Auth token: {0}'.format(kubeConfig.api_key))\nprint('Token expires: {0}'.format(kubeConfig.api_key_expires))\n \nk8s_client = client.ApiClient(kubeConfig)\n \ndyn_client = DynamicClient(k8s_client)\nv1_projects = dyn_client.resources.get(api_version='project.openshift.io/v1', kind='Project')\nproject_list = v1_projects.get()\n \nfor project in project_list.items:\n    print(project.metadata.name)\n \n# Renew the auth token\nkubeConfig.get_token()\n \nprint('Auth token: {0}'.format(kubeConfig.api_key))\nprint('Token expires: {0}'.format(kubeConfig.api_key_expires))\n```\n\n# Available Methods for Resources\n\nThe generic Resource class supports the following methods, though every resource kind does not support every method.\n\n\n## Get\n\n`get(name=None, namespace=None, label_selector=None, field_selector=None, **kwargs)`\n\nQuery for a resource in the cluster. Will return a `ResourceInstance` object or raise a `NotFoundError`\n\n```python\nv1_services = dyn_client.resources.get(api_version='v1', kind='Service')\n\n# Gets the specific Service named 'example' from the 'test' namespace\nv1_services.get(name='example', namespace='test')\n\n# Lists all Services in the 'test' namespace\nv1_services.get(namespace='test')\n\n# Lists all Services in the cluster (requires high permission level)\nv1_services.get()\n\n# Gets all Services in the 'test' namespace with the 'app' label set to 'foo'\nv1_services.get(namespace='test', label_selector='app=foo')\n\n# Gets all Services except for those in the 'default' namespace\nv1_services.get(field_selector='metadata.namespace!=default')\n\n```\n\n`get(body=None, namespace=None, **kwargs)`\n\nQuery for a resource in the cluster. Will return a `ResourceInstance` object or raise a `NotFoundError`\n\nFor List kind resources (ie, the resource name ends in `List`), the `get` implementation is slightly different.\nRather than taking a name, they take a `*List` kind definition and call `get` for each definition in the list.\n\n```python\nv1_service_list = dyn_client.resources.get(api_version='v1', kind='ServiceList')\n\nbody = {\n    'kind': 'ServiceList',\n    'apiVersion': 'v1',\n    'items': [\n        'metadata': {'name': 'my-service'},\n        'spec': {\n            'selector': {'app': 'MyApp'},\n            'ports': [{\n                'protocol': 'TCP',\n                'port': '8080',\n                'targetPort': '9376'\n            }]\n        }\n    ],\n    # More definitions would go here\n}\n# Gets the specified Service(s) from the 'test' namespace\nv1_service_list.get(body=body, namespace='test')\n\n# Lists all Services in the 'test' namespace\nv1_service_list.get(namespace='test')\n\n# Lists all Services in the cluster (requires high permission level)\nv1_service_list.get()\n```\n\n## Create\n\n`create(body=None, namespace=None, **kwargs)`\n\n```python\nv1_services = dyn_client.resources.get(api_version='v1', kind='Service')\n\nbody = {\n    'kind': 'Service',\n    'apiVersion': 'v1',\n    'metadata': {'name': 'my-service'},\n    'spec': {\n        'selector': {'app': 'MyApp'},\n        'ports': [{\n            'protocol': 'TCP',\n            'port': '8080',\n            'targetPort': '9376'\n        }]\n    }\n}\n\n# Creates the above service in the 'test' namespace\nv1_services.create(body=body, namespace='test')\n```\n\nThe `create` implementation is the same for `*List` kinds, except that each definition in the list will be created separately.\n\nIf the resource is namespaced (ie, not cluster-level), then one of `namespace`, `label_selector`, or `field_selector` is required.\n\nIf the resource is cluster-level, then one of `name`, `label_selector`, or `field_selector` is required.\n\n## Delete\n\n`delete(name=None, namespace=None, label_selector=None, field_selector=None, **kwargs)`\n\n```python\nv1_services = dyn_client.resources.get(api_version='v1', kind='Service')\n\n# Deletes the specific Service named 'example' from the 'test' namespace\nv1_services.delete(name='my-service', namespace='test')\n\n# Deletes all Services in the 'test' namespace\nv1_services.delete(namespace='test')\n\n# Deletes all Services in the 'test' namespace with the 'app' label set to 'foo'\nv1_services.delete(namespace='test', label_selector='app=foo')\n\n# Deletes all Services except for those in the 'default' namespace\nv1_services.delete(field_selector='metadata.namespace!=default')\n```\n\n`delete(body=None, namespace=None, **kwargs)`\n\nFor List kind resources (ie, the resource name ends in `List`), the `delete` implementation is slightly different.\nRather than taking a name, they take a `*List` kind definition and call `delete` for each definition in the list.\n\n```python\nv1_service_list = dyn_client.resources.get(api_version='v1', kind='ServiceList')\n\nbody = {\n    'kind': 'ServiceList',\n    'apiVersion': 'v1',\n    'items': [\n        'metadata': {'name': 'my-service'},\n        'spec': {\n            'selector': {'app': 'MyApp'},\n            'ports': [{\n                'protocol': 'TCP',\n                'port': '8080',\n                'tardeletePort': '9376'\n            }]\n        }\n    ],\n    # More definitions would go here\n}\n# deletes the specified Service(s) from the 'test' namespace\nv1_service_list.delete(body=body, namespace='test')\n\n# Deletes all Services in the 'test' namespace\nv1_service_list.delete(namespace='test')\n```\n\n## Patch\n\n`patch(body=None, namespace=None, **kwargs)`\n\n```python\nv1_services = dyn_client.resources.get(api_version='v1', kind='Service')\n\nbody = {\n    'kind': 'Service',\n    'apiVersion': 'v1',\n    'metadata': {'name': 'my-service'},\n    'spec': {\n        'selector': {'app': 'MyApp2'},\n    }\n}\n\n# patchs the above service in the 'test' namespace\nv1_services.patch(body=body, namespace='test')\n```\n\nThe `patch` implementation is the same for `*List` kinds, except that each definition in the list will be patched separately.\n\n## Replace\n\n`replace(body=None, namespace=None, **kwargs)`\n\n```python\nv1_services = dyn_client.resources.get(api_version='v1', kind='Service')\n\nbody = {\n    'kind': 'Service',\n    'apiVersion': 'v1',\n    'metadata': {'name': 'my-service'},\n    'spec': {\n        'selector': {'app': 'MyApp2'},\n        'ports': [{\n            'protocol': 'TCP',\n            'port': '8080',\n            'targetPort': '9376'\n        }]\n    }\n}\n\n# replaces the above service in the 'test' namespace\nv1_services.replace(body=body, namespace='test')\n```\n\nThe `replace` implementation is the same for `*List` kinds, except that each definition in the list will be replaced separately.\n\n## Watch\n\n`watch(namespace=None, name=None, label_selector=None, field_selector=None, resource_version=None, timeout=None)`\n\n```python\nv1_services = dyn_client.resources.get(api_version='v1', kind='Service')\n\n# Prints the resource that triggered each event related to Services in the 'test' namespace\nfor event in v1_services.watch(namespace='test'):\n    print(event['object'])\n```\n\n# Community, Support, Discussion\n\nIf you have any problem with the package or any suggestions, please file an [issue](https://github.com/openshift/openshift-restclient-python/issues).\n\n## Code of Conduct\n\nParticipation in the Kubernetes community is governed by the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md).\n\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenshift%2Fopenshift-restclient-python","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopenshift%2Fopenshift-restclient-python","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenshift%2Fopenshift-restclient-python/lists"}