-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
🐙 octavia-cli: add command to list existing sources, destinations and connections #9642
Merged
alafanechere
merged 1 commit into
master
from
augustin/octavia-cli/list-sources-destinations
Jan 25, 2022
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
# | ||
# Copyright (c) 2021 Airbyte, Inc., all rights reserved. | ||
# | ||
|
||
from typing import List | ||
|
||
|
||
def compute_columns_width(data: List[List[str]], padding: int = 2) -> List[int]: | ||
"""Compute columns width for display purposes: | ||
Find size for each columns in the data and add padding. | ||
Args: | ||
data (List[List[str]]): Tabular data containing rows and columns. | ||
padding (int): Number of character to adds to create space between columns. | ||
Returns: | ||
columns_width (List[int]): The computed columns widths for each column according to input data. | ||
""" | ||
columns_width = [0 for _ in data[0]] | ||
for row in data: | ||
for i, col in enumerate(row): | ||
current_col_width = len(col) + padding | ||
if current_col_width > columns_width[i]: | ||
columns_width[i] = current_col_width | ||
return columns_width | ||
|
||
|
||
def camelcased_to_uppercased_spaced(camelcased: str) -> str: | ||
"""Util function to transform a camelCase string to a UPPERCASED SPACED string | ||
e.g: dockerImageName -> DOCKER IMAGE NAME | ||
Args: | ||
camelcased (str): The camel cased string to convert. | ||
|
||
Returns: | ||
(str): The converted UPPERCASED SPACED string | ||
""" | ||
return "".join(map(lambda x: x if x.islower() else " " + x, camelcased)).upper() | ||
|
||
|
||
def display_as_table(data: List[List[str]]) -> str: | ||
"""Formats tabular input data into a displayable table with columns. | ||
Args: | ||
data (List[List[str]]): Tabular data containing rows and columns. | ||
Returns: | ||
table (str): String representation of input tabular data. | ||
""" | ||
columns_width = compute_columns_width(data) | ||
table = "\n".join(["".join(col.ljust(columns_width[i]) for i, col in enumerate(row)) for row in data]) | ||
return table | ||
|
||
|
||
def format_column_names(camelcased_column_names: List[str]) -> List[str]: | ||
"""Format camel cased column names to uppercased spaced column names | ||
|
||
Args: | ||
camelcased_column_names (List[str]): Column names in camel case. | ||
|
||
Returns: | ||
(List[str]): Column names in uppercase with spaces. | ||
""" | ||
return [camelcased_to_uppercased_spaced(column_name) for column_name in camelcased_column_names] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
# | ||
# Copyright (c) 2021 Airbyte, Inc., all rights reserved. | ||
# | ||
|
||
import abc | ||
from typing import List | ||
|
||
import airbyte_api_client | ||
import octavia_cli.list.formatting as formatting | ||
from airbyte_api_client.api import connection_api, destination_api, destination_definition_api, source_api, source_definition_api | ||
from airbyte_api_client.model.workspace_id_request_body import WorkspaceIdRequestBody | ||
|
||
|
||
class BaseListing(abc.ABC): | ||
COMMON_LIST_FUNCTION_KWARGS = {"_check_return_type": False} | ||
|
||
@property | ||
@abc.abstractmethod | ||
def api( | ||
self, | ||
): # pragma: no cover | ||
pass | ||
|
||
@property | ||
@abc.abstractmethod | ||
def fields_to_display( | ||
self, | ||
) -> List[str]: # pragma: no cover | ||
pass | ||
|
||
@property | ||
@abc.abstractmethod | ||
def list_field_in_response( | ||
self, | ||
) -> str: # pragma: no cover | ||
pass | ||
|
||
@property | ||
@abc.abstractmethod | ||
def list_function_name( | ||
self, | ||
) -> str: # pragma: no cover | ||
pass | ||
|
||
@property | ||
def _list_fn(self): | ||
return getattr(self.api, self.list_function_name) | ||
|
||
@property | ||
def list_function_kwargs(self) -> dict: | ||
return {} | ||
|
||
def __init__(self, api_client: airbyte_api_client.ApiClient): | ||
self.api_instance = self.api(api_client) | ||
|
||
def _parse_response(self, api_response) -> List[List[str]]: | ||
items = [[item[field] for field in self.fields_to_display] for item in api_response[self.list_field_in_response]] | ||
return items | ||
|
||
def get_listing(self) -> List[List[str]]: | ||
api_response = self._list_fn(self.api_instance, **self.list_function_kwargs, **self.COMMON_LIST_FUNCTION_KWARGS) | ||
return self._parse_response(api_response) | ||
|
||
def __repr__(self): | ||
items = [formatting.format_column_names(self.fields_to_display)] + self.get_listing() | ||
return formatting.display_as_table(items) | ||
|
||
|
||
class SourceConnectorsDefinitions(BaseListing): | ||
api = source_definition_api.SourceDefinitionApi | ||
fields_to_display = ["name", "dockerRepository", "dockerImageTag", "sourceDefinitionId"] | ||
list_field_in_response = "source_definitions" | ||
list_function_name = "list_latest_source_definitions" | ||
|
||
|
||
class DestinationConnectorsDefinitions(BaseListing): | ||
api = destination_definition_api.DestinationDefinitionApi | ||
fields_to_display = ["name", "dockerRepository", "dockerImageTag", "destinationDefinitionId"] | ||
list_field_in_response = "destination_definitions" | ||
list_function_name = "list_latest_destination_definitions" | ||
|
||
|
||
class WorkspaceListing(BaseListing, abc.ABC): | ||
def __init__(self, api_client: airbyte_api_client.ApiClient, workspace_id: str): | ||
self.workspace_id = workspace_id | ||
super().__init__(api_client) | ||
|
||
@property | ||
def list_function_kwargs(self) -> dict: | ||
return {"workspace_id_request_body": WorkspaceIdRequestBody(workspace_id=self.workspace_id)} | ||
|
||
|
||
class Sources(WorkspaceListing): | ||
api = source_api.SourceApi | ||
fields_to_display = ["name", "sourceName", "sourceId"] | ||
list_field_in_response = "sources" | ||
list_function_name = "list_sources_for_workspace" | ||
|
||
|
||
class Destinations(WorkspaceListing): | ||
api = destination_api.DestinationApi | ||
fields_to_display = ["name", "destinationName", "destinationId"] | ||
list_field_in_response = "destinations" | ||
list_function_name = "list_destinations_for_workspace" | ||
|
||
|
||
class Connections(WorkspaceListing): | ||
api = connection_api.ConnectionApi | ||
fields_to_display = ["name", "connectionId", "status", "sourceId", "destinationId"] | ||
list_field_in_response = "connections" | ||
list_function_name = "list_connections_for_workspace" | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The fact that these inherit from a WorkspaceListing made me think: would it make sense to group these commands under a
workspace
keyword? I.e. the commands would look likeDo you think this would make it more clear what the difference between these commands are to the user? Or would we just end up with a ton of
workspace
commands, making the commands unnecessarily long?I'll leave it up to you to make the final decision here; I don't feel super strongly either way, but just thought I would offer this suggestion in case you liked it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this, looks tidier and will keep the same command "depth" for
list
subcommands.