Repository: kubeflow/pipelines

Issue:
[bug] Containerized Python Components
`kfp.__version__ = 1.8.14`

Trying the instructions at [2. Containerized Python components](https://www.kubeflow.org/docs/components/pipelines/v2/author-a-pipeline/components/#2-containerized-python-components):
- command `kfp component build ...` results in error: "Error: No such command 'component'."
     - KFP API SDK Reference for [kfp compontent build](https://kubeflow-pipelines.readthedocs.io/en/master/source/cli.html#kfp-component-build)
     - changing `kfp component` to `kfp components` seem to get pass the command issue
- using `kfp components build` throw errors for `*.py` files that do not contain components: `ERROR: No KFP components found in file ...`
     - the other `*.py` file are modules imported by the file.py with component definitions using relative imports.  This seems to be 
 exactly how the example is laid out [doc example](https://www.kubeflow.org/docs/components/pipelines/v2/author-a-pipeline/components/#2-containerized-python-components)





Discussion:
**Update**

I upgraded to `kfp.__version__ = 2.0.0b5` and it fixe the error of "ERROR: No such command 'component'." and it matches the KFP API SDK.

I still see the behavior of `ERROR: No KFP components found in file ...` for any module in the folder that does not contain a component definition.  I tried using `--component-filepattern my_component.py` but then it fails to find my other python modules and returns errors like `No module named ...` for each module being imported in the `my_component.py`.

To check that my non component python modules work I:
- used import statements in an interactive Python environment and tested the included functions
- ran the entrypoint python module from a command line and observed its successful completion


Hi, @statmike. Can you please provide the file tree that contains `my_component.py` and the accompanying source code files? Can you also provide what `my_component.py` looks like (feel free to omit the component body -- it's probably not necessary)?
Having the same issue.  Here are mine for a second look:

# my_component.py
from kfp import dsl

@dsl.component(
    base_image='python:3.9'
    , target_image='gcr.io/my-project/my-containerized_python_component:v1'
    , output_component_file="component_containerized_python_component.yaml"
)
def train_model(
):
    # component functionality
    print("hello")


# my_helper_module.py
def adding_stuff(x, y):
    return x + y
Hello @connor-mccarthy ,
This is the full example I have been setting up:

**tree**
- ./src
     - __init__.py
     - my_component.py
     - my_helper.py
     - train.py

**__init__.py**
is empty

**my_component.py**
```python
# my_component.py
from kfp.v2 import dsl
import train

@dsl.component(
    base_image = 'python:3.7',
    target_image = 'us-central1-docker.pkg.dev/statmike-mlops-349915/statmike-mlops-349915/tips_kfp_kfp_component',
    packages_to_install = ['numpy', 'scikit-learn']
)
def train_model(
    size: int,
    metrics: dsl.Output[dsl.Metrics],
    class_metrics: dsl.Output[dsl.ClassificationMetrics]
):
    # run
    cm, auPRC = train.runner(size)
    
    # output
    metrics.log_metric('auPRC', auPRC)
    class_metrics.log_confusion_matrix(['Not Fraud', 'Fraud'], cm)
```

**train.py**
```python
# train.py
from sklearn import metrics
import my_helper

def runner(size):
    # make data
    x, y, p = my_helper.make_dataset(size)

    # fit logistic regression
    y_pred = my_helper.fit_logistic(x, y)

    # gather metrics
    cm = metrics.confusion_matrix(y, y_pred)
    auPRC = metrics.accuracy_score(y, y_pred)
    
    return cm, auPRC

cm, auPRC = runner(100)
```

**my_helper.py**
```python
# my_helper.py
import numpy as np
from sklearn import linear_model

# Make some data where y = 0, 1 for a range of x's - let y=1 be more likely as x increases
def make_dataset(size):
    x = np.random.randn(size)
    p = 1 / (1 + np.exp(-1 * (5 * x)))
    y = np.random.binomial(1, p, size)   
    return x, y, p

# fit logistic regression
def fit_logistic(x, y):
    logisticReg = linear_model.LogisticRegression()
    x2 = x.reshape(-1,1)
    fit = logisticReg.fit(x2, y)
    return fit.predict(x2)
```


Resolving patch:
diff --git a/sdk/python/kfp/cli/component.py b/sdk/python/kfp/cli/component.py
--- a/sdk/python/kfp/cli/component.py
+++ b/sdk/python/kfp/cli/component.py
@@ -171,10 +171,6 @@ def _load_components(self):
                     module_name=module_name, module_directory=module_directory)
 
                 python_file = str(python_file)
-                if not component_modules:
-                    logging.error(
-                        f'No KFP components found in file {python_file}')
-                    raise sys.exit(1)
 
                 logging.info(
                     f'Found {len(component_modules)} component(s) in file {python_file}:'


Test patch: