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

Stacked @card v1.2: Read cli changes for Supporting Multiple@cards #895

Merged
merged 53 commits into from
Jan 25, 2022

Conversation

valayDave
Copy link
Collaborator

Stacked on #894

Supported CLI Variations for card get/card view

# If there are no slashes detected then we assume it to be a stepname for the `latest` runid. Extracts card in the `Step.task` of the lastest run
python myflow.py card view stepname

# If there are slashes detected then we assume it to be of the following form
python myflow.py card view runid/stepname
python myflow.py card view runid/stepname/taskid

# Extracts card with id abc in the `Step.task` of the lastest run
python myflow.py card view stepname --id abc

# filters cards by id. 
python myflow.py card view runid/stepname --id abc
python myflow.py card view runid/stepname/taskid --id abc

Supported for card list

Why is this needed

Because we are now supporting multiple cards we need list functionality in the CLI to ensure that the test suite can work as it should. Since the get /view commands are bound to resolve a single card, we need an unambiguous command that resolves all the metadata about all cards for a taskspec.

Usage

# Command Signature is similar to `get`/`view` commands. Provides the list response from `get`/`view`. 
python myflow.py card list stepname

# Prints the pathspec along with the metadata about the cards as a JSON dictionary
python myflow.py card list stepname --as-json

TODO :

  1. Added the --id option to card view/card get
  2. Allow CLI to have new variations of the get/view supported.
  3. changes in the get_cards function.
  4. card list function

- modified datastore and fixed the exception class.
- Added changes to cli
- Allowing some ambiguity in what pathspec argument.
- `python myflow.py card view stepname` works now.
- `python nonameflow.py card view runid/stepname/taskid` also works
-
- added functionality to list cards about a task and even list it as JSON.
- instead of equating we check `startswith`
- listing all cards from the latest run when card list is called with no argument
- `--as-json` works for many cards and single cards
@valayDave valayDave changed the title Read cli changes for Supporting Multiple@cards Stacked @card v1.2: PR Read cli changes for Supporting Multiple@cards Jan 13, 2022
def resolve_card(
ctx,
pathspec,
follow_resumed=True,
hash=None,
type=None,
card_id=None,
no_echo=False,
):
"""Resolves the card path based on the arguments provided. We allow identifier to be a pathspec or a id of card.
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

TODO : Need to remove the comment : We allow identifier to be a pathspec or a id of card.

ctx.obj.echo(print_str, fg="green")
else:
card_pathspec = origin_taskpathspec
print_str = ("Resolving card resumed from: %s" % origin_taskpathspec,)
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

TODO : remove ,) in print_str

if len(pthsplits) == 1:
# This means stepname
resolving_from = "stepname"
latest_run = Flow(flow_name).latest_run
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we want the latest run or latest_successful_run?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

latest because we want to access cards during the execution of a flow. Because flows can have a long running time, it's much more convenient when accessing latest_run. Based on your comment I feel that adding namespace(None) at the start of the block was not the best idea as I should use namespace(None) when users add runid/stepname or runid/stepname/taskid

if latest_run is not None:
run_id = latest_run.pathspec
try:
task = latest_run[pathspec].task
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we want to warn if there are multiple tasks?

task,
run_id,
resolved_from,
) = resolve_task_from_pathspec(flow_name, pathspec)
Copy link
Contributor

Choose a reason for hiding this comment

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

run_id and resolved_from do not seem to be used except to raise an exception. The logic in resolve_task_from_pathspec is fairly long and could probably be simplified if the exception could be simplified a bit. Further, based on the logic in that function, there are cases where when task is none, run_id is also none and doesn't contain a lot of useful information. Perhaps we can simplify and just say that the string given as pathspec does not allow us to resolve to a task. You could, if you wanted to, also give a warning about resolving to multiple tasks.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I can refactor the function by raising the error from inside resolve_task_from_pathspecand also returning only a pathspec.

metaflow/plugins/cards/card_cli.py Outdated Show resolved Hide resolved
help="Print all available cards as a JSON object",
)
@click.pass_context
def list(
Copy link
Contributor

Choose a reason for hiding this comment

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

It may make sense in these commands to respect the "--quiet" flag which should only print things that are easily machine parseable (at least that's the intent IIRC). This would impact the listing functions above to have a quiet mode in essence and maybe list things simply as opposed to prettily.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Currently, we respect --quiet in list unless it is called with --as-json; the same goes for get. If I call card get stepname then it will print the card in the stdout. But calling card get stepname filename.html will save that card to the file. The test uses --quiet so I need this functionality to print/pass information when calling CLI commands in CliCheck.


if task_card_path.is_file:
cards_found.append(card_path)

return cards_found

def create_full_path(self, card_path):
Copy link
Contributor

Choose a reason for hiding this comment

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

This may be a stupid comment so ignore it if it is but I thought we had a separate value for card root (METAFLOW_CARD_S3ROOT). Granted, it defaults to the one for the datastore but shouldn't we use the actual value in case it isn't like the one for the datastore?

Copy link
Contributor

Choose a reason for hiding this comment

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

Given your reliance on the flow_datastore, it may be better to not leave this as an option to users (and maybe only allow them to configure the card sub-directory -- with restrictions that it should probably not be a valid python name to avoid conflicts with a flow).

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I actually set the storage root here. That's why the path generally lands up correct even when METAFLOW_CARD_S3ROOT is set.

valayDave and others added 21 commits January 21, 2022 05:38
- small refactor to cli + card ds.
* user-facing `MetaflowCardComponent`s
- import via `from metaflow.cards import Artifact,..`

* 7 Major Changes:
- Removed `Section` component from `metaflow.cards`
- Making user-facing component inherent to `UserComponent` which in turn inherits `MetaflowCardComponent`
- Wrap all `UserComponents` inside a section after rendering everything per card
- created a `render_safely` decorator to ensure fail-safe render of `UserComponent`s
- removed code from component serializer which used internal components
- Refactored some components that return render
- Added docstrings to all components.

* JS + CSS + Cards UI Build

* Stacked @card v1.2 : Graph Related Changes to card cli (#911)

* accomodating changes from #833
- Minor tweaks to `graph.py`

* Stacked @card v1.2 : Namespace Packages with `@card` (#897)

* setup import of cards from `metaflow_extensions` using `metaflow.extension_support`
- Added import modules in `card_modules`
- Added hook in card decorators to add custom packages

* Added some debug statements for external imports.

* Stacked @card v1.2 : Test cases for Multiple `@card`s (#898)

* Multiple Cards Test Suite Mods (#27)

- Added `list_cards` to `CliCheck` and `MetadataCheck`
- Bringing #875 into the code
- Added a card that prints taskspec with random number

* Added test case for multiple cards

* Added tests card, summary :
- `current.cards['myid']` should be accessible when cards have an `id` argument in decorator
- `current.cards.append` should not work when there are no single default editable card.
- if a card has `ALLOW_USER_COMPONENTS=False` then it can still be edited via accessing it with `id` property.
- adding arbitrary information to `current.cards.append` should not break user code.
- Only cards with `ALLOW_USER_COMPONENTS=True` are considered default editable.
- If a single @card decorator is present with `id` then it `current.cards.append` should still work
- Access of `current.cards` with non existant id should not fail.
- `current.cards.append` should be accessible to the card with `customize=True`.
-

* fixed `DefaultEditableCardTest` test case
- Fixed comment
- Fixed the `customize=True` test case.

* ensure `test_pathspec_card` has no duplicates
- ensure entropy of rendered information is high enough to not overwrite a file.

* test case fix : `current.cards` to `current.card`

* Added Test case to support import of cards.
- Test case validates that broken card modules don't break metaflow
- test case validates that we are able to import cards from metaflow_extensions
- Test case validate that cards can be editable if they are importable.

* Added Env var to tests to avoid warnings added to cards.

* Added Test for card resume.

* Stacked @card v1.2: Card Dev Docs (#899)

Co-authored-by: Romain Cledat <rcledat@netflix.com>

Co-authored-by: Brendan Gibson <brendan@outerbounds.co>
Co-authored-by: Brendan Gibson <93726128+obgibson@users.noreply.github.com>
Co-authored-by: adam <203779+seethroughdev@users.noreply.github.com>
Co-authored-by: Romain Cledat <rcledat@netflix.com>
@valayDave valayDave merged commit 8694045 into mfcards-s1-current-card Jan 25, 2022
@valayDave valayDave deleted the mfcards-s2-read-cli branch January 25, 2022 04:40
valayDave added a commit that referenced this pull request Jan 25, 2022
* allow passing userland `MetaflowCardComponents`
-  Added api for `current.cards` that handles multiple decorators

* `current.cards` with `id` support.
- Introduced `ALLOW_USER_COMPONENTS` attribute to `MetaflowCard` class
- setting `ALLOW_USER_COMPONENTS=True` allow editable cards
- Modified logic of `CardComponentCollector`
- `CardComponentCollector.append` only accessible to default editble card

* Added `customize=True` in `@card`
- `customize=True` only allowed for one @card deco per @step
- `customize=True` sets the card to be default editable
- `current.card.append` appends to @card with `customize=True`


* Stacked @card v1.2: Read cli changes for Supporting Multiple`@card`s (#895)

* Added the `--id` option to `card view`/`card get`
- modified datastore and fixed the exception class.
- Allowing some ambiguity in pathspec argument for `get/view` command.

* Added `id` argument to `get_cards`

* Bringing `card list` cli functionality from test-suite branch
- added functionality to list cards about a task and even list it as JSON.

* changed hash checking logic.
- instead of equating we check `startswith`

* Added list many feature for `card list`
- listing all cards from the latest run when card list is called with no argument

* Added `card list` print formatting changes
- `--as-json` works for many cards and single cards


* Stacked @card v1.2 : New `MetaflowCardComponent`s  (#896)

* user-facing `MetaflowCardComponent`s
- import via `from metaflow.cards import Artifact,..`

* 7 Major Changes:
- Removed `Section` component from `metaflow.cards`
- Making user-facing component inherent to `UserComponent` which in turn inherits `MetaflowCardComponent`
- Wrap all `UserComponents` inside a section after rendering everything per card
- created a `render_safely` decorator to ensure fail-safe render of `UserComponent`s
- removed code from component serializer which used internal components
- Refactored some components that return render
- Added docstrings to all components.

* JS + CSS + Cards UI Build

* Stacked @card v1.2 : Graph Related Changes to card cli (#911)

* accomodating changes from #833
- Minor tweaks to `graph.py`

* Stacked @card v1.2 : Namespace Packages with `@card` (#897)

* setup import of cards from `metaflow_extensions` using `metaflow.extension_support`
- Added import modules in `card_modules`
- Added hook in card decorators to add custom packages

* Added some debug statements for external imports.

* Stacked @card v1.2 : Test cases for Multiple `@card`s (#898)

* Multiple Cards Test Suite Mods (#27)

- Added `list_cards` to `CliCheck` and `MetadataCheck`
- Bringing #875 into the code
- Added a card that prints taskspec with random number

* Added test case for multiple cards

* Added tests card, summary :
- `current.cards['myid']` should be accessible when cards have an `id` argument in decorator
- `current.cards.append` should not work when there are no single default editable card.
- if a card has `ALLOW_USER_COMPONENTS=False` then it can still be edited via accessing it with `id` property.
- adding arbitrary information to `current.cards.append` should not break user code.
- Only cards with `ALLOW_USER_COMPONENTS=True` are considered default editable.
- If a single @card decorator is present with `id` then it `current.cards.append` should still work
- Access of `current.cards` with non existant id should not fail.
- `current.cards.append` should be accessible to the card with `customize=True`.
-

* fixed `DefaultEditableCardTest` test case
- Fixed comment
- Fixed the `customize=True` test case.

* ensure `test_pathspec_card` has no duplicates
- ensure entropy of rendered information is high enough to not overwrite a file.

* test case fix : `current.cards` to `current.card`

* Added Test case to support import of cards.
- Test case validates that broken card modules don't break metaflow
- test case validates that we are able to import cards from metaflow_extensions
- Test case validate that cards can be editable if they are importable.

* Added Env var to tests to avoid warnings added to cards.

* Added Test for card resume.

* Stacked @card v1.2: Card Dev Docs (#899)

Co-authored-by: Brendan Gibson <brendan@outerbounds.co>
Co-authored-by: Brendan Gibson <93726128+obgibson@users.noreply.github.com>
Co-authored-by: adam <203779+seethroughdev@users.noreply.github.com>
Co-authored-by: Romain Cledat <rcledat@netflix.com>
oavdeev pushed a commit that referenced this pull request Jan 25, 2022
* multiple decorator support

* Fixing comments

* comment fix.

* commet fix

* allow multiple decorators of same type from cli

* Stacked @card v1.2 : Customizing `@card` with `current.card` (#894)

* allow passing userland `MetaflowCardComponents`
-  Added api for `current.cards` that handles multiple decorators

* `current.cards` with `id` support.
- Introduced `ALLOW_USER_COMPONENTS` attribute to `MetaflowCard` class
- setting `ALLOW_USER_COMPONENTS=True` allow editable cards
- Modified logic of `CardComponentCollector`
- `CardComponentCollector.append` only accessible to default editble card

* Added `customize=True` in `@card`
- `customize=True` only allowed for one @card deco per @step
- `customize=True` sets the card to be default editable
- `current.card.append` appends to @card with `customize=True`


* Stacked @card v1.2: Read cli changes for Supporting Multiple`@card`s (#895)

* Added the `--id` option to `card view`/`card get`
- modified datastore and fixed the exception class.
- Allowing some ambiguity in pathspec argument for `get/view` command.

* Added `id` argument to `get_cards`

* Bringing `card list` cli functionality from test-suite branch
- added functionality to list cards about a task and even list it as JSON.

* changed hash checking logic.
- instead of equating we check `startswith`

* Added list many feature for `card list`
- listing all cards from the latest run when card list is called with no argument

* Added `card list` print formatting changes
- `--as-json` works for many cards and single cards


* Stacked @card v1.2 : New `MetaflowCardComponent`s  (#896)

* user-facing `MetaflowCardComponent`s
- import via `from metaflow.cards import Artifact,..`

* 7 Major Changes:
- Removed `Section` component from `metaflow.cards`
- Making user-facing component inherent to `UserComponent` which in turn inherits `MetaflowCardComponent`
- Wrap all `UserComponents` inside a section after rendering everything per card
- created a `render_safely` decorator to ensure fail-safe render of `UserComponent`s
- removed code from component serializer which used internal components
- Refactored some components that return render
- Added docstrings to all components.

* JS + CSS + Cards UI Build

* Stacked @card v1.2 : Graph Related Changes to card cli (#911)

* accomodating changes from #833
- Minor tweaks to `graph.py`

* Stacked @card v1.2 : Namespace Packages with `@card` (#897)

* setup import of cards from `metaflow_extensions` using `metaflow.extension_support`
- Added import modules in `card_modules`
- Added hook in card decorators to add custom packages

* Added some debug statements for external imports.

* Stacked @card v1.2 : Test cases for Multiple `@card`s (#898)

* Multiple Cards Test Suite Mods (#27)

- Added `list_cards` to `CliCheck` and `MetadataCheck`
- Bringing #875 into the code
- Added a card that prints taskspec with random number

* Added test case for multiple cards

* Added tests card, summary :
- `current.cards['myid']` should be accessible when cards have an `id` argument in decorator
- `current.cards.append` should not work when there are no single default editable card.
- if a card has `ALLOW_USER_COMPONENTS=False` then it can still be edited via accessing it with `id` property.
- adding arbitrary information to `current.cards.append` should not break user code.
- Only cards with `ALLOW_USER_COMPONENTS=True` are considered default editable.
- If a single @card decorator is present with `id` then it `current.cards.append` should still work
- Access of `current.cards` with non existant id should not fail.
- `current.cards.append` should be accessible to the card with `customize=True`.
-

* fixed `DefaultEditableCardTest` test case
- Fixed comment
- Fixed the `customize=True` test case.

* ensure `test_pathspec_card` has no duplicates
- ensure entropy of rendered information is high enough to not overwrite a file.

* test case fix : `current.cards` to `current.card`

* Added Test case to support import of cards.
- Test case validates that broken card modules don't break metaflow
- test case validates that we are able to import cards from metaflow_extensions
- Test case validate that cards can be editable if they are importable.

* Added Env var to tests to avoid warnings added to cards.

* Added Test for card resume.

* Stacked @card v1.2: Card Dev Docs (#899)

Co-authored-by: Brendan Gibson <brendan@outerbounds.co>
Co-authored-by: Brendan Gibson <93726128+obgibson@users.noreply.github.com>
Co-authored-by: adam <203779+seethroughdev@users.noreply.github.com>
Co-authored-by: Romain Cledat <rcledat@netflix.com>

* Nit fix in error.

* Fixing bug in decorator

* whitespace.

* Changing import scheme of warning variable.

* fixing warning suppression env var setting

Co-authored-by: Brendan Gibson <brendan@outerbounds.co>
Co-authored-by: Brendan Gibson <93726128+obgibson@users.noreply.github.com>
Co-authored-by: adam <203779+seethroughdev@users.noreply.github.com>
Co-authored-by: Romain Cledat <rcledat@netflix.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants