Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add minimal client implementation for Feeds API #73

Open
wants to merge 44 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
88716eb
feat: add feeds api with examples and wrapper files
Giriharan219 Oct 16, 2024
074f782
feat: separte function for query feeds
Giriharan219 Oct 16, 2024
590d91c
docs: Update doc strings
Giriharan219 Oct 17, 2024
f4f06e0
fix: Update upload mulitple package function
Giriharan219 Oct 17, 2024
5d80d06
fix: errors due to mypy checks
Giriharan219 Oct 21, 2024
7dda9c7
docs: Update rst files for auth and feeds client
Giriharan219 Oct 21, 2024
785eb39
fix: Update file names and client name for feeds client
Giriharan219 Oct 21, 2024
8392e0b
feat: add pytest for feeds and auth apis
Giriharan219 Oct 22, 2024
d90ab93
fix: mypy and black issues
Giriharan219 Oct 23, 2024
facf591
fix: remove hardcoded workspace in pytest for feeds
Giriharan219 Oct 23, 2024
c8aa6eb
docs: update api ref rst file
Giriharan219 Oct 23, 2024
37ebd69
docs: update getting started rst file
Giriharan219 Oct 23, 2024
5d41864
fix: err due to invalid path in getting started.rst file
Giriharan219 Oct 23, 2024
11beed3
fix: remove unwanted helpers
Giriharan219 Oct 24, 2024
0690f73
fix: Address self review comments
Giriharan219 Oct 24, 2024
734429b
docs: alignment in the rst files
Giriharan219 Oct 24, 2024
480e410
fix: address second set of self review comments
Giriharan219 Oct 24, 2024
1c01493
docs: Update doc string of auth models
Giriharan219 Oct 24, 2024
fc06d3a
feat: add delete feed api
Giriharan219 Oct 24, 2024
76bccbc
fix: issues due to linting
Giriharan219 Oct 24, 2024
c046b1a
docs: update rst files
Giriharan219 Oct 24, 2024
c9bd9bb
fix: remove auth implementation
Giriharan219 Oct 25, 2024
77e9f18
fix: address some of the PR comments
Giriharan219 Oct 25, 2024
570843e
fix: address rest of the PR comments
Giriharan219 Oct 30, 2024
7d65312
fix: address self review comments
Giriharan219 Oct 30, 2024
3ea0521
fix: error due to del feed with invalid id
Giriharan219 Oct 30, 2024
99320ba
fix: mypy issues due to incompatible types
Giriharan219 Oct 30, 2024
8efc6de
fix: improvement PR comments
Giriharan219 Nov 2, 2024
cb30e6d
fix: mypy issue due to var type incompatibility
Giriharan219 Nov 2, 2024
8edf916
fix: update self review comments
Giriharan219 Nov 4, 2024
552c39d
fix: issue due to pipeline failure
Giriharan219 Nov 4, 2024
6dfb17e
docs: update the doc with new api for upload feed
Giriharan219 Nov 4, 2024
05e9dcc
fix: address another set of review comments
Giriharan219 Nov 5, 2024
5e0752d
fix: pytest failure due to invalid assertion
Giriharan219 Nov 5, 2024
6b7f2a1
fix: address self review comments
Giriharan219 Nov 5, 2024
26af9a6
fix: issue due to black formatter
Giriharan219 Nov 5, 2024
33c80fb
fix: pipeline failure issue
Giriharan219 Nov 5, 2024
44472b7
fix: address self review comments
Giriharan219 Nov 5, 2024
da58c28
fix: pipeline failure
Giriharan219 Nov 5, 2024
75bef43
fix: address final PR comments
Giriharan219 Nov 7, 2024
14b1401
fix: issue due to black formatter
Giriharan219 Nov 7, 2024
4f683f9
fix: update response models
Giriharan219 Nov 7, 2024
db529c8
fix: update feeds model with some fixes
Giriharan219 Nov 7, 2024
f639d77
docs: update utility doc string
Giriharan219 Nov 7, 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 @@ -13,6 +13,7 @@ API Reference
api_reference/dataframe
api_reference/spec
api_reference/file
api_reference/feeds

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

nisystemlink.clients.feeds
======================

.. autoclass:: nisystemlink.clients.feeds.FeedsClient
:exclude-members: __init__

.. automethod:: __init__
.. automethod:: create_feed
.. automethod:: query_feeds
.. automethod:: upload_package
.. automethod:: delete_feed

.. automodule:: nisystemlink.clients.feeds.models
:members:
:imported-members:
41 changes: 39 additions & 2 deletions docs/getting_started.rst
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,6 @@ Update and Delete Specifications
:language: python
:linenos:


File API
-------

Expand All @@ -183,4 +182,42 @@ Get the metadata of a File using its Id and download it.

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

Feeds API
-------

Overview
~~~~~~~~

The :class:`.FeedsClient` class is the primary entry point of the Feeds API.

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

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

* Get the list of feeds, create feed, upload package to feed and delete feed.

Examples
~~~~~~~~

Create a new feed.

.. literalinclude:: ../examples/feeds/create_feed.py
:language: python
:linenos:

Query feeds and upload a package to feed.

.. literalinclude:: ../examples/feeds/query_and_upload_feeds.py
:language: python
:linenos:

Delete a feed.

.. literalinclude:: ../examples/feeds/delete_feed.py
:language: python
:linenos:
38 changes: 38 additions & 0 deletions examples/feeds/create_feed.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
"""Functionality of creating feeds APIs."""

from nisystemlink.clients.core import ApiException, HttpConfiguration
from nisystemlink.clients.feeds._feeds_client import FeedsClient
from nisystemlink.clients.feeds.models import (
CreateFeedRequest,
Platform,
)


FEED_NAME = "EXAMPLE FEED"
FEED_DESCRIPTION = "EXAMPLE DESCRIPTION"
PLATFORM = Platform.WINDOWS

server_url = "" # SystemLink API URL
server_api_key = "" # SystemLink API key
workspace_id = "" # Systemlink workspace id

# Please provide the valid API key and API URL for client intialization.
client = FeedsClient(HttpConfiguration(api_key=server_api_key, server_uri=server_url))

# Creating Feeds.
try:
feed_request = CreateFeedRequest(
name=FEED_NAME,
description=FEED_DESCRIPTION,
platform=PLATFORM,
workspace=workspace_id,
)
created_feed_name = client.create_feed(feed=feed_request).name

print("Feed created Successfully.")
print(f"Created feed name: {created_feed_name}")
Giriharan219 marked this conversation as resolved.
Show resolved Hide resolved

except ApiException as exp:
print(exp)
except Exception as exp:
print(exp)
23 changes: 23 additions & 0 deletions examples/feeds/delete_feed.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
"""Functionality of deleting feed API."""

from nisystemlink.clients.core import ApiException, HttpConfiguration
from nisystemlink.clients.feeds._feeds_client import FeedsClient


FEED_ID = ""
Giriharan219 marked this conversation as resolved.
Show resolved Hide resolved

server_url = "" # SystemLink API URL
server_api_key = "" # SystemLink API key

# Please provide the valid API key and API URL for client intialization.
client = FeedsClient(HttpConfiguration(api_key=server_api_key, server_uri=server_url))

# Deleting Feed.
try:
created_feed_name = client.delete_feed(id=FEED_ID)
print("Feed deleted successfully.")

except ApiException as exp:
print(exp)
except Exception as exp:
print(exp)
44 changes: 44 additions & 0 deletions examples/feeds/query_and_upload_feeds.py
Giriharan219 marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"""Functionality of uploading & querying feeds APIs."""

from nisystemlink.clients.core import ApiException, HttpConfiguration
from nisystemlink.clients.feeds._feeds_client import FeedsClient
from nisystemlink.clients.feeds.models import Platform
from nisystemlink.clients.feeds.utilities import get_feed_id

# Constant
FEED_NAME = "EXAMPLE FEED"
FEED_DESCRIPTION = "EXAMPLE DESCRIPTION"
PLATFORM = Platform.WINDOWS
PACKAGE_NAME = ""
PACKAGE_PATH = ""

server_url = "" # SystemLink API URL
server_api_key = "" # SystemLink API key
workspace_id = "" # Systemlink workspace id
Giriharan219 marked this conversation as resolved.
Show resolved Hide resolved

# Please provide the valid API key and API URL for client intialization.
client = FeedsClient(HttpConfiguration(api_key=server_api_key, server_uri=server_url))

# To upload a package to feed.
try:
# To query available feeds.
query_feeds_response = client.query_feeds(
platform=PLATFORM,
workspace=workspace_id,
)

feed_id = get_feed_id(feeds_details=query_feeds_response.feeds, feed_name=FEED_NAME)

if feed_id:
upload_package = client.upload_package(
feed_id=feed_id,
overwrite=True,
package=open(PACKAGE_PATH, "rb"),
)
print("Package uploaded sucessfully.")

except ApiException as exp:
print(exp)

except Exception as exp:
print(exp)
3 changes: 3 additions & 0 deletions nisystemlink/clients/feeds/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from ._feeds_client import FeedsClient

# flake8: noqa
146 changes: 146 additions & 0 deletions nisystemlink/clients/feeds/_feeds_client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
"""Implementation of SystemLink Feeds Client."""

from typing import BinaryIO, Optional

from nisystemlink.clients import core
from nisystemlink.clients.core._uplink._base_client import BaseClient
from nisystemlink.clients.core._uplink._methods import delete, get, post
from uplink import Part, Path, Query

from . import models


class FeedsClient(BaseClient):
"""A set of methods to access the APIs of SystemLink Feeds Client."""
Giriharan219 marked this conversation as resolved.
Show resolved Hide resolved

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 Feeds Service.
"""
if configuration is None:
configuration = core.JupyterHttpConfiguration()
Giriharan219 marked this conversation as resolved.
Show resolved Hide resolved

super().__init__(configuration, base_path="/nifeed/v1/")

@post("feeds")
def create_feed(self, feed: models.CreateFeedRequest) -> models.Feed:
"""Create a new feed with the provided feed details.

Args:
feeds (models.CreateFeedsRequest): Request model to create the feed.
Giriharan219 marked this conversation as resolved.
Show resolved Hide resolved

Returns:
models.Feed: Details of the created feed.
"""
...

@get("feeds", args=[Query, Query])
def __query_feeds(
self,
platform: Optional[str] = None,
Giriharan219 marked this conversation as resolved.
Show resolved Hide resolved
workspace: Optional[str] = None,
) -> models.QueryFeedsResponse:
"""Get a set of feeds based on the provided `platform` and `workspace`.

Args:
platform (Optional[str]): Information about system platform. Defaults to None.
workspace (Optional[str]): Workspace id. Defaults to None.

Returns:
models.QueryFeedsResponse: List of feeds.
"""
...

def query_feeds(
self,
platform: Optional[models.Platform] = None,
workspace: Optional[str] = None,
) -> models.QueryFeedsResponse:
Giriharan219 marked this conversation as resolved.
Show resolved Hide resolved
"""Get a set of feeds based on the provided `platform` and `workspace`.
Giriharan219 marked this conversation as resolved.
Show resolved Hide resolved

Args:
platform (Optional[models.Platform]): Information about system platform. \
Defaults to None.
workspace (Optional[str]): Workspace id. Defaults to None.

Returns:
models.QueryFeedsResponse: List of feeds.
"""
platform_by_str = platform.value if platform is not None else None
response = self.__query_feeds(
platform=platform_by_str,
workspace=workspace,
)

return response

@post(
"feeds/{feedId}/packages",
args=[Path(name="feedId"), Query(name="ShouldOverwrite")],
)
def __upload_package(
self,
feed_id: str,
package: Part,
overwrite: Query = False,
) -> models.Package:
"""Upload package to SystemLink feed.

Args:
feed_id (str): ID of the feed.
package (Part): Package file as a form data.
overwrite (Query): Set to True, to overwrite the package if it already exists.\
Defaults to False.

Returns:
models.Package: Uploaded package response information.
"""
...

def upload_package(
Giriharan219 marked this conversation as resolved.
Show resolved Hide resolved
self,
feed_id: str,
package: BinaryIO,
overwrite: bool = False,
) -> models.Package:
"""Upload package to SystemLink feed.

Args:
feed_id (str): ID of the feed.
package (BinaryIO): Package file to be uploaded.
overwrite (bool): Set to True, to overwrite the package if it already exists.\
Defaults to False.

Returns:
models.Package: Uploaded package response information.
"""
response = self.__upload_package(
feed_id=feed_id,
overwrite=overwrite,
package=package,
)

return response

@delete(
"feeds/{feedId}",
args=[Path(name="feedId")],
)
def delete_feed(self, id: str) -> None:
"""Delete feed and its packages.

Args:
id (str): ID of the feed to be deleted.

Returns:
None.
"""
...
9 changes: 9 additions & 0 deletions nisystemlink/clients/feeds/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from ._feeds_models import (
CreateFeedRequest,
Feed,
Package,
Platform,
QueryFeedsResponse,
)

# flake8: noqa
Loading