Skip to content
Open
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
c2278f1
feat: add systems client code for get jobs API.
ganesh-nithin Nov 27, 2024
cbba5c7
feat: add systems client code for create job API.
ganesh-nithin Nov 27, 2024
258f373
feat: add systems client code for get jobs summary API.
ganesh-nithin Nov 27, 2024
4e22c28
feat: add systems client code for query jobs API.
ganesh-nithin Nov 27, 2024
6070c71
feat: add systems client code for cancel jobs API.
ganesh-nithin Nov 27, 2024
55684d8
refactor: modify docs strings for systems client.
ganesh-nithin Nov 27, 2024
412c8ef
feat: add unit tests for jobs in systems client/
ganesh-nithin Nov 29, 2024
2f91a6c
refactor: change name systems into system.
ganesh-nithin Nov 29, 2024
63083f5
feat: add example documentation for system client.
ganesh-nithin Nov 29, 2024
5a4f0ae
feat: add api references for system client API.
ganesh-nithin Nov 29, 2024
1e17b89
refactor: format code using black & flake8.
ganesh-nithin Dec 1, 2024
13accda
refactor: address system client PR comments.
ganesh-nithin Dec 3, 2024
5dd2381
refactor: modify system client tests.
ganesh-nithin Dec 3, 2024
4a4b977
refactor: fix lint issues in CI.
ganesh-nithin Dec 3, 2024
814f1fb
refactor: modify model names.
ganesh-nithin Dec 4, 2024
85cc103
refactor: modify test cases for system client.
ganesh-nithin Dec 4, 2024
3ef21ec
refactor: modify field names to be pythonic.
ganesh-nithin Dec 6, 2024
6167da2
refactor: modify tests.
ganesh-nithin Dec 9, 2024
0e33a87
refactor: add wrapping for job client.
ganesh-nithin Dec 10, 2024
5575f20
refactor: modify clients & tests.
ganesh-nithin Dec 11, 2024
ee1d908
refactor: format system client code.
ganesh-nithin Dec 11, 2024
3e727c8
refactor: modify union operator.
ganesh-nithin Dec 11, 2024
6ebb8f1
refactor: format system client code.
ganesh-nithin Dec 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/api_reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ API Reference
api_reference/dataframe
api_reference/spec
api_reference/file
api_reference/system

Indices and tables
------------------
Expand Down
18 changes: 18 additions & 0 deletions docs/api_reference/system.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
.. _api_tag_page:

nisystemlink.clients.system
======================

.. autoclass:: nisystemlink.clients.system.SystemClient
:exclude-members: __init__

.. automethod:: __init__
.. automethod:: list_jobs
.. automethod:: create_job
.. automethod:: get_job_summary
.. automethod:: query_jobs
.. automethod:: cancel_jobs

.. automodule:: nisystemlink.clients.system.models
:members:
:imported-members:
28 changes: 28 additions & 0 deletions docs/getting_started.rst
Original file line number Diff line number Diff line change
Expand Up @@ -210,5 +210,33 @@ Examples
Get the metadata of a File using its Id and download it.

.. literalinclude:: ../examples/file/download_file.py
:language: python
:linenos:


System API
-------

Overview
~~~~~~~~

The :class:`.SystemClient` class is the primary entry point of the System API.

When constructing a :class:`.SystemClient`, you can pass an
:class:`.HttpConfiguration` (like one retrieved from the
:class:`.HttpConfigurationManager`), or let :class:`.SystemClient` use the
default connection. The default connection depends on your environment.

With a :class:`.SystemClient` object, you can:

* Create, get, query, and cancel jobs
* Get the summary of a jobs

Examples
~~~~~~~~

Create, get, query, and cancel jobs

.. literalinclude:: ../examples/system/system.py
:language: python
:linenos:
57 changes: 57 additions & 0 deletions examples/system/system.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
from nisystemlink.clients.core import HttpConfiguration
from nisystemlink.clients.system import SystemClient
from nisystemlink.clients.system.models import (
CancelJobRequest,
CreateJobRequest,
JobState,
QueryJobsRequest,
)

# Setup the server configuration to point to your instance of SystemLink Enterprise
server_configuration = HttpConfiguration(
server_uri="https://yourserver.yourcompany.com",
api_key="YourAPIKeyGeneratedFromSystemLink",
)
client = SystemClient(configuration=server_configuration)

# Get all jobs that have succeeded
jobs = client.list_jobs(
system_id="system_id",
jid="jid",
state=JobState.SUCCEEDED,
function="function",
skip=0,
take=10,
)

# Create a job
arg = [["A description"]]
tgt = ["HVM_domU--SN-ec200972-eeca-062e-5bf5-017a25451b39--MAC-0A-E1-20-D6-96-2B"]
fun = ["system.set_computer_desc"]
metadata = {"queued": True, "refresh_minion_cache": {"grains": True}}
job = CreateJobRequest(
arg=arg,
tgt=tgt,
fun=fun,
metadata=metadata,
)

create_job_response = client.create_job(job)

# Get job summary
job_summary = client.get_job_summary()

# Query jobs
query_job = QueryJobsRequest(
skip=0,
take=1000,
filter="result.success.Contains(false)",
projection="new(id,jid,state,lastUpdatedTimestamp,metadata.queued as queued)",
orderBy="createdTimestamp descending",
)
query_jobs_response = client.query_jobs(query_job)


# Cancel a job
cancel_job_request = CancelJobRequest(jid=create_job_response.jid, tgt=tgt[0])
cancel_job_response = client.cancel_jobs([cancel_job_request])
3 changes: 3 additions & 0 deletions nisystemlink/clients/system/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from ._system_client import SystemClient

# flake8: noqa
132 changes: 132 additions & 0 deletions nisystemlink/clients/system/_system_client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
from typing import List, Optional

from nisystemlink.clients import core
from nisystemlink.clients.core._uplink._base_client import BaseClient
from nisystemlink.clients.core._uplink._methods import (
get,
post,
)
from uplink import Query

from . import models


class SystemClient(BaseClient):
def __init__(self, configuration: Optional[core.HttpConfiguration] = None):
"""Initialize an instance.

Args:
configuration: Defines the web server to connect to and information about
how to connect. If not provided, the
:class:`HttpConfigurationManager <nisystemlink.clients.core.HttpConfigurationManager>`
is used to obtain the configuration.

Raises:
ApiException: if unable to communicate with the System Service.
"""
if configuration is None:
configuration = core.HttpConfigurationManager.get_configuration()

super().__init__(configuration, "/nisysmgmt/v1/")

@get(
"jobs",
args=[
Query("systemId"),
Query("jid"),
Query("state"),
Query("function"),
Query("skip"),
Query("take"),
],
)
def list_jobs(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def list_jobs(
def list_jobs_paged(

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skipping the suggestion as list jobs are not paged as it don't have continuation token property.

self,
system_id: Optional[str] = None,
jid: Optional[str] = None,
state: Optional[models.JobState] = None,
function: Optional[str] = None,
skip: Optional[int] = None,
take: Optional[int] = None,
) -> List[models.Job]:
"""List the jobs that matched the criteria.

Args:
system_id: The ID of the system to that the jobs belong.
jid: The ID of the job.
state: The state of the jobs.
function: The salt function to run on the client.
skip: The number of jobs to skip.
take: The number of jobs to return.

Returns:
The list of jobs that matched the criteria.

Raises:
ApiException: if unable to communicate with the System Service
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
ApiException: if unable to communicate with the System Service
ApiException: if unable to communicate with the ``/nisysmgmt`` Service

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update in all other places

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have updated it, & reflected the same in other places.

or provided an invalid argument.
"""
...

@post("jobs")
def create_job(self, job: models.CreateJobRequest) -> models.CreateJobResponse:
"""Create a job.

Args:
job: The request to create the job.

Returns:
The job that was created.

Raises:
ApiException: if unable to communicate with the System Service
or provided an invalid argument.
"""
...

@get("get-jobs-summary")
def get_job_summary(self) -> models.JobSummaryResponse:
"""Get a summary of the jobs.

Returns:
An instance of a JobsSummaryResponse.

Raises:
ApiException: if unable to communicate with the System Service
or provided an invalid argument.
"""
...

@post("query-jobs")
def query_jobs(self, query: models.QueryJobsRequest) -> models.QueryJobsResponse:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def query_jobs(self, query: models.QueryJobsRequest) -> models.QueryJobsResponse:
def query_jobs_paged(self, query: models.QueryJobsRequest) -> models.QueryJobsResponse:

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skipping the suggestion as query jobs are not paged as it don't have continuation token property.

"""Query the jobs.

Args:
query: The request to query the jobs.

Returns:
An instance of QueryJobsRequest.

Raises:
ApiException: if unable to communicate with the System Service
or provided an invalid argument.
"""
...

@post("cancel-jobs")
def cancel_jobs(
self, job_ids: List[models.CancelJobRequest]
) -> models.CancelJobResponse:
"""Cancel the jobs.

Args:
job_ids: List of CancelJobRequest.

Returns:
The errors that appear while attempting the operation.

Raises:
ApiException: if unable to communicate with the System Service
or provided an invalid argument.
"""
...
11 changes: 11 additions & 0 deletions nisystemlink/clients/system/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from ._job_state import JobState
from ._job import Job
from ._create_job_request import CreateJobRequest
from ._create_job_response import CreateJobResponse
from ._job_summary_response import JobSummaryResponse
from ._query_jobs_request import QueryJobsRequest
from ._query_jobs_response import QueryJobsResponse
from ._cancel_job_request import CancelJobRequest
from ._cancel_job_response import CancelJobResponse

# flake8: noqa
13 changes: 13 additions & 0 deletions nisystemlink/clients/system/models/_cancel_job_request.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from typing import Optional

from nisystemlink.clients.core._uplink._json_model import JsonModel


class CancelJobRequest(JsonModel):
"""Model for cancel job request."""

jid: Optional[str] = None
"""The ID of the job to cancel."""

system_id: Optional[str] = None
"""The system ID that the job to cancel targets."""
12 changes: 12 additions & 0 deletions nisystemlink/clients/system/models/_cancel_job_response.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from typing import Optional

from nisystemlink.clients.core._uplink._json_model import JsonModel

from ._http_error import HttpError


class CancelJobResponse(JsonModel):
"""Model for response of a cancel job request."""

error: Optional[HttpError] = None
"""Represents the standard error structure."""
10 changes: 10 additions & 0 deletions nisystemlink/clients/system/models/_create_job_request.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from typing import Any, Dict, Optional

from ._job_config import JobConfig


class CreateJobRequest(JobConfig):
"""Model for create job request."""

metadata: Optional[Dict[str, Any]] = None
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please update it with actual properties..

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have updated it. As CreateJobResponse is extended from CreateJobRequest, properties will be updated in it.

"""The metadata associated with the job."""
14 changes: 14 additions & 0 deletions nisystemlink/clients/system/models/_create_job_response.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from typing import Optional

from ._create_job_request import CreateJobRequest
from ._http_error import HttpError


class CreateJobResponse(CreateJobRequest):
"""Model for response of create job request."""

error: Optional[HttpError] = None
"""Represents the standard error structure."""

jid: Optional[str] = None
"""The job ID."""
35 changes: 35 additions & 0 deletions nisystemlink/clients/system/models/_http_error.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from typing import List, Optional

from nisystemlink.clients.core._uplink._json_model import JsonModel


class HttpError(JsonModel):
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use ApiError class from uplink core module instead of creating new one.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have updated it, & reflected the same in other places.

"""Represents the standard error structure."""

name: Optional[str] = None
"""Gets the fully-qualified name that identifies the error code, such as the output of
M:NationalInstruments.SystemLink.ServiceBase.ErrorHandling.ErrorCode.ToString."""

code: Optional[int] = None
"""Gets the optional NationalInstruments.SystemLink.ServiceBase.ErrorHandling.ErrorCode.NumericCode
(not HTTP status code) that identifies the error code."""

message: Optional[str] = None
"""Gets the formatted error message, which is the NationalInstruments.SystemLink.ServiceBase.ErrorHandling
.ErrorCode.Message with NationalInstruments.SystemLink.ServiceBase.HttpError.Args inserted into
any placeholders."""

resourceType: Optional[str] = None
"""Gets the type of resource associated with the error, if any. Typically only used for instances within
NationalInstruments.SystemLink.ServiceBase.HttpError.InnerErrors."""

resourceId: Optional[str] = None
"""Gets the ID of the resource associated with the error, if any. Typically only used for instances within
NationalInstruments.SystemLink.ServiceBase.HttpError.InnerErrors."""

args: Optional[List[str]] = None
"""Gets the arguments that produced NationalInstruments.SystemLink.ServiceBase.HttpError.Message."""

innerErrors: Optional[List["HttpError"]] = None
"""Gets any nested errors if this instance represents more than one error. Typically only set for instances
related to NationalInstruments.SystemLink.ServiceBase.ErrorHandling.SkylineErrorCodes.OneOrMoreErrorsOccurred."""
Loading