oscar-python


Nameoscar-python JSON
Version 1.3.3 PyPI version JSON
download
home_pageNone
SummaryPython client for OSCAR clusters
upload_time2025-10-24 09:48:59
maintainerNone
docs_urlNone
authorGRyCAP - I3M - UPV
requires_python>=3.8
licenseApache-2.0
keywords oscar faas serverless
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            ## Python OSCAR client

[![Tests](https://github.com/grycap/oscar_python/actions/workflows/tests.yaml/badge.svg?branch=main)](https://github.com/grycap/oscar_python/actions/workflows/tests.yaml)
[![PyPI](https://img.shields.io/pypi/v/oscar-python)](https://pypi.org/project/oscar-python/)

This package provides a client to interact with OSCAR (https://oscar.grycap.net) clusters and services. It is available on Pypi with the name [oscar-python](https://pypi.org/project/oscar-python/).

### Contents
- [Python OSCAR client](#python-oscar-client)
  - [Contents](#contents)
  - [Client](#client)
    - [Initialize a client with basic authentication](#initialize-a-client-with-basic-authentication)
    - [Initialize a client OIDC authentication](#initialize-a-client-oidc-authentication)
  - [Sample usage](#sample-usage)
  - [Client methods](#client-methods)
    - [Cluster methods](#cluster-methods)
    - [Service methods](#service-methods)
    - [Logs methods](#logs-methods)
    - [Storage usage](#storage-usage)

### Client

#### Initialize a client with basic authentication
``` python
  options_basic_auth = {'cluster_id':'cluster-id',
                'endpoint':'https://cluster-endpoint',
                'user':'username',
                'password':'password',
                'ssl':'True'}

  client = Client(options = options_basic_auth)
```
#### Initialize a client OIDC authentication

If you want to use OIDC tokens to authenticate with EGI Check-In, you can use the [OIDC Agent](https://indigo-dc.gitbook.io/oidc-agent/) to create an account configuration for the EGI issuer (https://aai.egi.eu/auth/realms/egi/) and then initialize the client specifying the `shortname` of your account like follows.

``` python
  options_oidc_auth = {'cluster_id':'cluster-id',
                'endpoint':'https://cluster-endpoint',
                'shortname':'oidc-agent-shortname',
                'ssl':'True'}
                
  client = Client(options = options_oidc_auth)
```

If you already have a valid token, you can use the parameter `oidc_token` instead.

``` python
  options_oidc_auth = {'cluster_id':'cluster-id',
                'endpoint':'https://cluster-endpoint',
                'oidc_token':'token',
                'ssl':'True'}
                
  client = Client(options = options_oidc_auth)
```
An example of using a generated token is if you want to use EGI Notebooks. Since you can't use oidc-agent on the Notebook, you can make use of the generated token that EGI provides on path `/var/run/secrets/egi.eu/access_token`.

If you have a valid refresh token (long live token), you can use the parameter `refresh_token` instead.

``` python
  options_oidc_auth = {'cluster_id':'cluster-id',
                'endpoint':'https://cluster-endpoint',
                'refresh_token':'token',
                'ssl':'True'}
                
  client = Client(options = options_oidc_auth)
```

You can get a refresh token from EGI Check-In using the [Token Portal](https://aai.egi.eu/token).

In case of using other OIDC provider you must provide two additional parameters `token_endpoint`
and `scopes`:

``` python
  options_oidc_auth = {'cluster_id':'cluster-id',
                'endpoint':'https://cluster-endpoint',
                'refresh_token':'token',
                'scopes': ["openid", "profile", "email"],
                'token_endpoint': "http://issuer.com/token",
                'client_id': "your_client_id"
                'ssl':'True'}
                
  client = Client(options = options_oidc_auth)
```

### Sample usage

- Sample code that creates a client and gets information about the cluster

``` python
from oscar_python.client import Client

options_basic_auth = {'cluster_id':'cluster-id',
              'endpoint':'https://cluster-endpoint',
              'user':'username',
              'password':'password',
              'ssl':'True'}

client = Client(options = options)

# get the cluster information
try:
  info = client.get_cluster_info()
  print(info.text)
except Exception as err:
  print("Failed with: ", err)
```

- Sample code to create a simple service with the [cowsay example](https://github.com/grycap/oscar/tree/master/examples/cowsay) and make a synchronous invocation.

``` python
from oscar_python.client import Client

options_basic_auth = {'cluster_id':'cluster-id',
              'endpoint':'https://cluster-endpoint',
              'user':'username',
              'password':'password',
              'ssl':'True'}

client = Client(options = options)

try:
  client.create_service("/absolute_path/cowsay.yaml")
  response = client.run_service("cowsay", input = '{"message": "Hi there"}')   
  if response.status_code == 200:
      print(response.text)
except Exception as err:
  print("Failed with: ", err)
```

### Client methods

#### Cluster methods

**get_cluster_info**
``` python
# get the cluster information
info = client.get_cluster_info() # returns an HTTP response or an HTTPError
```

**get_cluster_config**
``` python
# get the cluster config
config = client.get_cluster_config() # returns an http response or an HTTPError
```

#### Service methods

**get_service**
``` python
# get the definition of a service 
service = client.get_service("service_name") # returns an http response or an HTTPError
```

**list_services**
``` python
# get a list of all the services deployed 
services = client.list_services() # returns an http response or an HTTPError
```

> _Note_ : Both `path_to_fdl` and the script path inside the fdl must be absolute.

**create_service**
``` python
# create a service 
err = client.create_service("path_to_fdl" | "JSON_definition") # returns nothing if the service is created or an error if something goes wrong
```

**update_service**
``` python
# update a service 
err = client.update_service("service_name","path_to_fdl" | "JSON_definition") # returns nothing if the service is created or an error if something goes wrong
```

**remove_service**
``` python
# remove a service 
response = client.remove_service("service_name") # returns an http response
```

**run_service**

 *`input`, `output` and `timeout` are optional parameters.*

``` python
# make a synchronous execution 
response = client.run_service("service_name", input="input", output="out.png", timeout=100) # returns an http response

# make an asynchronous execution
response = client.run_service("service_name", input="input", async_call=True) # returns an http response
```

#### Logs methods

**get_job_logs**
``` python
# get logs of a job
logs = client.get_job_logs("service_name", "job_id") # returns an http response
```

**list_jobs**
``` python
# get a list of jobs in a service
log_list = client.list_jobs("service_name") # returns an http response
# to get more jobs use the page parameter
log_list = client.list_jobs("service_name",page="token_to_next_page") # returns an http response
```

**remove_job**
``` python
# remove a job of a service
response = client.remove_job("service_name", "job_id") # returns an http response
```

**remove_all_jobs**
``` python
# remove all jobs in a service
response = client.remove_all_jobs("service_name") # returns an http response
```

#### Storage usage

You can create a storage object to operate over the different storage providers defined on a service with the method `create_storage_client`. This constructor returns a storage object with methos to interact with the storage providers.

The default constructor, seen as follows, will create a provider to interact with the default MinIO instance through the user's credentials. 

``` python
storage_service = client.create_storage_client() # returns a storage object
```
Additionally, if you need to interact with specific storage providers defined on a service, the constructor accepts a `svc` parameter where you can state the service name from which to search for additional credentials.

``` python
storage_service = client.create_storage_client("service_name") # returns a storage object
```

> _Note_ : The `storage_provider` parameter on the storage methods follows the format: `["storage_provider_type"].["storage_provider_name"]` where `storage_provider_type` is one of the suported storage providers (minIO, S3, Onedata or webdav) and `storage_provider_name` is the identifier _(ex: minio.default)_

**list_files_from_path**

This method returns a JSON with the info except for OneData, which returns an HTTP response.

``` python
# get a list of the files of one of the service storage provider 
files = storage_service.list_files_from_path("storage_provider", "remote_path") # returns json
```

**upload_file**
``` python
# upload a file from a local path to a remote path 
response = storage_service.upload_file("storage_provider", "local_path", "remote_path")
```

**download_file**
``` python
# download a file from a remote path to a local path 
response = storage_service.download_file("storage_provider", "local_path", "remote_path")
```

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "oscar-python",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": null,
    "keywords": "oscar, faas, serverless",
    "author": "GRyCAP - I3M - UPV",
    "author_email": null,
    "download_url": "https://files.pythonhosted.org/packages/57/9a/0c6f637b94c88804e75b3f2ba38f3c81e555ed76c3a1b33bac9490d5b824/oscar_python-1.3.3.tar.gz",
    "platform": null,
    "description": "## Python OSCAR client\n\n[![Tests](https://github.com/grycap/oscar_python/actions/workflows/tests.yaml/badge.svg?branch=main)](https://github.com/grycap/oscar_python/actions/workflows/tests.yaml)\n[![PyPI](https://img.shields.io/pypi/v/oscar-python)](https://pypi.org/project/oscar-python/)\n\nThis package provides a client to interact with OSCAR (https://oscar.grycap.net) clusters and services. It is available on Pypi with the name [oscar-python](https://pypi.org/project/oscar-python/).\n\n### Contents\n- [Python OSCAR client](#python-oscar-client)\n  - [Contents](#contents)\n  - [Client](#client)\n    - [Initialize a client with basic authentication](#initialize-a-client-with-basic-authentication)\n    - [Initialize a client OIDC authentication](#initialize-a-client-oidc-authentication)\n  - [Sample usage](#sample-usage)\n  - [Client methods](#client-methods)\n    - [Cluster methods](#cluster-methods)\n    - [Service methods](#service-methods)\n    - [Logs methods](#logs-methods)\n    - [Storage usage](#storage-usage)\n\n### Client\n\n#### Initialize a client with basic authentication\n``` python\n  options_basic_auth = {'cluster_id':'cluster-id',\n                'endpoint':'https://cluster-endpoint',\n                'user':'username',\n                'password':'password',\n                'ssl':'True'}\n\n  client = Client(options = options_basic_auth)\n```\n#### Initialize a client OIDC authentication\n\nIf you want to use OIDC tokens to authenticate with EGI Check-In, you can use the [OIDC Agent](https://indigo-dc.gitbook.io/oidc-agent/) to create an account configuration for the EGI issuer (https://aai.egi.eu/auth/realms/egi/) and then initialize the client specifying the `shortname` of your account like follows.\n\n``` python\n  options_oidc_auth = {'cluster_id':'cluster-id',\n                'endpoint':'https://cluster-endpoint',\n                'shortname':'oidc-agent-shortname',\n                'ssl':'True'}\n                \n  client = Client(options = options_oidc_auth)\n```\n\nIf you already have a valid token, you can use the parameter `oidc_token` instead.\n\n``` python\n  options_oidc_auth = {'cluster_id':'cluster-id',\n                'endpoint':'https://cluster-endpoint',\n                'oidc_token':'token',\n                'ssl':'True'}\n                \n  client = Client(options = options_oidc_auth)\n```\nAn example of using a generated token is if you want to use EGI Notebooks. Since you can't use oidc-agent on the Notebook, you can make use of the generated token that EGI provides on path `/var/run/secrets/egi.eu/access_token`.\n\nIf you have a valid refresh token (long live token), you can use the parameter `refresh_token` instead.\n\n``` python\n  options_oidc_auth = {'cluster_id':'cluster-id',\n                'endpoint':'https://cluster-endpoint',\n                'refresh_token':'token',\n                'ssl':'True'}\n                \n  client = Client(options = options_oidc_auth)\n```\n\nYou can get a refresh token from EGI Check-In using the [Token Portal](https://aai.egi.eu/token).\n\nIn case of using other OIDC provider you must provide two additional parameters `token_endpoint`\nand `scopes`:\n\n``` python\n  options_oidc_auth = {'cluster_id':'cluster-id',\n                'endpoint':'https://cluster-endpoint',\n                'refresh_token':'token',\n                'scopes': [\"openid\", \"profile\", \"email\"],\n                'token_endpoint': \"http://issuer.com/token\",\n                'client_id': \"your_client_id\"\n                'ssl':'True'}\n                \n  client = Client(options = options_oidc_auth)\n```\n\n### Sample usage\n\n- Sample code that creates a client and gets information about the cluster\n\n``` python\nfrom oscar_python.client import Client\n\noptions_basic_auth = {'cluster_id':'cluster-id',\n              'endpoint':'https://cluster-endpoint',\n              'user':'username',\n              'password':'password',\n              'ssl':'True'}\n\nclient = Client(options = options)\n\n# get the cluster information\ntry:\n  info = client.get_cluster_info()\n  print(info.text)\nexcept Exception as err:\n  print(\"Failed with: \", err)\n```\n\n- Sample code to create a simple service with the [cowsay example](https://github.com/grycap/oscar/tree/master/examples/cowsay) and make a synchronous invocation.\n\n``` python\nfrom oscar_python.client import Client\n\noptions_basic_auth = {'cluster_id':'cluster-id',\n              'endpoint':'https://cluster-endpoint',\n              'user':'username',\n              'password':'password',\n              'ssl':'True'}\n\nclient = Client(options = options)\n\ntry:\n  client.create_service(\"/absolute_path/cowsay.yaml\")\n  response = client.run_service(\"cowsay\", input = '{\"message\": \"Hi there\"}')   \n  if response.status_code == 200:\n      print(response.text)\nexcept Exception as err:\n  print(\"Failed with: \", err)\n```\n\n### Client methods\n\n#### Cluster methods\n\n**get_cluster_info**\n``` python\n# get the cluster information\ninfo = client.get_cluster_info() # returns an HTTP response or an HTTPError\n```\n\n**get_cluster_config**\n``` python\n# get the cluster config\nconfig = client.get_cluster_config() # returns an http response or an HTTPError\n```\n\n#### Service methods\n\n**get_service**\n``` python\n# get the definition of a service \nservice = client.get_service(\"service_name\") # returns an http response or an HTTPError\n```\n\n**list_services**\n``` python\n# get a list of all the services deployed \nservices = client.list_services() # returns an http response or an HTTPError\n```\n\n> _Note_ : Both `path_to_fdl` and the script path inside the fdl must be absolute.\n\n**create_service**\n``` python\n# create a service \nerr = client.create_service(\"path_to_fdl\" | \"JSON_definition\") # returns nothing if the service is created or an error if something goes wrong\n```\n\n**update_service**\n``` python\n# update a service \nerr = client.update_service(\"service_name\",\"path_to_fdl\" | \"JSON_definition\") # returns nothing if the service is created or an error if something goes wrong\n```\n\n**remove_service**\n``` python\n# remove a service \nresponse = client.remove_service(\"service_name\") # returns an http response\n```\n\n**run_service**\n\n *`input`, `output` and `timeout` are optional parameters.*\n\n``` python\n# make a synchronous execution \nresponse = client.run_service(\"service_name\", input=\"input\", output=\"out.png\", timeout=100) # returns an http response\n\n# make an asynchronous execution\nresponse = client.run_service(\"service_name\", input=\"input\", async_call=True) # returns an http response\n```\n\n#### Logs methods\n\n**get_job_logs**\n``` python\n# get logs of a job\nlogs = client.get_job_logs(\"service_name\", \"job_id\") # returns an http response\n```\n\n**list_jobs**\n``` python\n# get a list of jobs in a service\nlog_list = client.list_jobs(\"service_name\") # returns an http response\n# to get more jobs use the page parameter\nlog_list = client.list_jobs(\"service_name\",page=\"token_to_next_page\") # returns an http response\n```\n\n**remove_job**\n``` python\n# remove a job of a service\nresponse = client.remove_job(\"service_name\", \"job_id\") # returns an http response\n```\n\n**remove_all_jobs**\n``` python\n# remove all jobs in a service\nresponse = client.remove_all_jobs(\"service_name\") # returns an http response\n```\n\n#### Storage usage\n\nYou can create a storage object to operate over the different storage providers defined on a service with the method `create_storage_client`. This constructor returns a storage object with methos to interact with the storage providers.\n\nThe default constructor, seen as follows, will create a provider to interact with the default MinIO instance through the user's credentials. \n\n``` python\nstorage_service = client.create_storage_client() # returns a storage object\n```\nAdditionally, if you need to interact with specific storage providers defined on a service, the constructor accepts a `svc` parameter where you can state the service name from which to search for additional credentials.\n\n``` python\nstorage_service = client.create_storage_client(\"service_name\") # returns a storage object\n```\n\n> _Note_ : The `storage_provider` parameter on the storage methods follows the format: `[\"storage_provider_type\"].[\"storage_provider_name\"]` where `storage_provider_type` is one of the suported storage providers (minIO, S3, Onedata or webdav) and `storage_provider_name` is the identifier _(ex: minio.default)_\n\n**list_files_from_path**\n\nThis method returns a JSON with the info except for OneData, which returns an HTTP response.\n\n``` python\n# get a list of the files of one of the service storage provider \nfiles = storage_service.list_files_from_path(\"storage_provider\", \"remote_path\") # returns json\n```\n\n**upload_file**\n``` python\n# upload a file from a local path to a remote path \nresponse = storage_service.upload_file(\"storage_provider\", \"local_path\", \"remote_path\")\n```\n\n**download_file**\n``` python\n# download a file from a remote path to a local path \nresponse = storage_service.download_file(\"storage_provider\", \"local_path\", \"remote_path\")\n```\n",
    "bugtrack_url": null,
    "license": "Apache-2.0",
    "summary": "Python client for OSCAR clusters",
    "version": "1.3.3",
    "project_urls": {
        "Homepage": "https://github.com/grycap/oscar-python",
        "Repository": "https://github.com/grycap/oscar-python"
    },
    "split_keywords": [
        "oscar",
        " faas",
        " serverless"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "ec18850054b29d7a8d6764c0415aae85b6be75cddd85608ba776a409e14aa6de",
                "md5": "bc4b1270df91af157dbf814729f4e31c",
                "sha256": "bcf25af20cff7a20667bd53d3ee15868be9e2e5cf37a32e8529c5796480a2199"
            },
            "downloads": -1,
            "filename": "oscar_python-1.3.3-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "bc4b1270df91af157dbf814729f4e31c",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 21773,
            "upload_time": "2025-10-24T09:48:57",
            "upload_time_iso_8601": "2025-10-24T09:48:57.900860Z",
            "url": "https://files.pythonhosted.org/packages/ec/18/850054b29d7a8d6764c0415aae85b6be75cddd85608ba776a409e14aa6de/oscar_python-1.3.3-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "579a0c6f637b94c88804e75b3f2ba38f3c81e555ed76c3a1b33bac9490d5b824",
                "md5": "c65416a6e6492139365b5fe6afbf2dd5",
                "sha256": "7ab670fce193b6b7352ef8e27c56975c5d8abbd61802018cd60611cb0ebb20f7"
            },
            "downloads": -1,
            "filename": "oscar_python-1.3.3.tar.gz",
            "has_sig": false,
            "md5_digest": "c65416a6e6492139365b5fe6afbf2dd5",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 26212,
            "upload_time": "2025-10-24T09:48:59",
            "upload_time_iso_8601": "2025-10-24T09:48:59.237720Z",
            "url": "https://files.pythonhosted.org/packages/57/9a/0c6f637b94c88804e75b3f2ba38f3c81e555ed76c3a1b33bac9490d5b824/oscar_python-1.3.3.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-10-24 09:48:59",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "grycap",
    "github_project": "oscar-python",
    "github_not_found": true,
    "lcname": "oscar-python"
}
        
Elapsed time: 2.04691s