Repository: iterative/dvc

Issue:
dvc.api.params_show: Relative stages paths required when run from a different directory than dvc.yaml
# Bug Report

<!--
## Issue name

Issue names must follow the pattern `command: description` where the command is the dvc command that you are trying to run. The description should describe the consequence of the bug. 

Example: `repro: doesn't detect input changes`
-->

## Description

<!--
A clear and concise description of what the bug is.
-->
When run from a different directory than one where `dvc.yaml` is, `dvc.api.params_show` fails with `DvcException: No params found
` unless the `stages` parameter is provided as "relative/path/to/dvc.yaml:stage_name" (or a list of such stage names). 

I.e. for example when run with a working directory one level below where `dvc.yaml` is, then this works:
```
dvc.api.params_show(stages="../dvc.yaml:prepare", deps=True)
```
and this does not:
```
dvc.api.params_show(stages="prepare", deps=True)
```

I am pretty sure this is because in `dvc.repo.Repo` the `addressing` attribute of  `index.stages` is initialized in such a path-relative fashion and it is then checked that the string in `addressing` corresponds to the strings from `stages` parameter of `dvc.api.params_show`. This is checked by [_read_params ](https://github.com/iterative/dvc/blob/78dd045d29f274960bcaf48fd2d055366abaf2c1/dvc/repo/params/show.py#L81) and [_collect_vars](https://github.com/iterative/dvc/blob/78dd045d29f274960bcaf48fd2d055366abaf2c1/dvc/repo/params/show.py#L108).



### Expected

I am not completely sure if this second issue can be considered a bug it works if I specify the stages strings in the specific way above and it is not quite clear how this could be dealt with when there are multiple `dvc.yaml` files. Still, even if this is not considered a bug, I think it should at least be mentioned in documentation that the stages should be given as paths relative to the working directory (plus the `dvc.yaml:<stage_name>` syntax) in this case, since this is not completely obvious to the user.

<!--
A clear and concise description of what you expect to happen.
-->

### Environment information

<!--
This is required to ensure that we can reproduce the bug.
-->

**Output of `dvc doctor`:**

```console
$ dvc doctor
DVC version: 2.19.0 (pip)
---------------------------------
Platform: Python 3.10.5 on Linux-5.19.1-3-MANJARO-x86_64-with-glibc2.36
Supports:
        http (aiohttp = 3.8.1, aiohttp-retry = 2.8.3),
        https (aiohttp = 3.8.1, aiohttp-retry = 2.8.3)
Cache types: <https://error.dvc.org/no-dvc-cache>
Caches: local
Remotes: https
Workspace directory: ext4 on /dev/nvme0n1p2
Repo: dvc, git
```

**Additional Information (if any):**

<!--
Please check https://github.com/iterative/dvc/wiki/Debugging-DVC on ways to gather more information regarding the issue.

If applicable, please also provide a `--verbose` output of the command, eg: `dvc add --verbose`.
If the issue is regarding the performance, please attach the profiling information and the benchmark comparisons.
-->



Discussion:
> I am not completely sure if this second issue can be considered a bug it works if I specify the stages strings in the specific way above and it is not quite clear how this could be dealt with when there are multiple dvc.yaml files. 

The use of `addressing` was deliberately introduced for dealing with conflicts in multiple dvc.yaml files.

> Still, even if this is not considered a bug, I think it should at least be mentioned in documentation that the stages should be given as paths relative to the working directory (plus the dvc.yaml:<stage_name> syntax) in this case, since this is not completely obvious to the user.

Agree, I will update the docs accordingly and add an example

Resolving patch:
diff --git a/dvc/api/params.py b/dvc/api/params.py
--- a/dvc/api/params.py
+++ b/dvc/api/params.py
@@ -37,6 +37,10 @@ def params_show(
             stages to retrieve parameters from.
             Defaults to `None`.
             If `None`, all parameters from all stages will be retrieved.
+            If this method is called from a different location to the one where
+            the `dvc.yaml` is found, the relative path to the `dvc.yaml` must
+            be provided as a prefix with the syntax `{relpath}:{stage}`.
+            For example: `subdir/dvc.yaml:stage-0` or `../dvc.yaml:stage-1`.
         rev (str, optional): Name of the `Git revision`_ to retrieve parameters
             from.
             Defaults to `None`.


Test patch:
diff --git a/tests/func/api/test_params.py b/tests/func/api/test_params.py
--- a/tests/func/api/test_params.py
+++ b/tests/func/api/test_params.py
@@ -1,3 +1,4 @@
+import os
 from textwrap import dedent
 
 import pytest
@@ -92,6 +93,27 @@ def test_params_show_stages(params_repo):
         api.params_show(stages="stage-0")
 
 
+def test_params_show_stage_addressing(tmp_dir, dvc):
+    for subdir in {"subdir1", "subdir2"}:
+        subdir = tmp_dir / subdir
+        subdir.mkdir()
+        with subdir.chdir():
+            subdir.gen("params.yaml", "foo: 1")
+
+            dvc.run(name="stage-0", cmd="echo stage-0", params=["foo"])
+
+    for s in {"subdir1", "subdir2"}:
+        dvcyaml = os.path.join(s, "dvc.yaml")
+        assert api.params_show(stages=f"{dvcyaml}:stage-0") == {"foo": 1}
+
+    with subdir.chdir():
+        nested = subdir / "nested"
+        nested.mkdir()
+        with nested.chdir():
+            dvcyaml = os.path.join("..", "dvc.yaml")
+            assert api.params_show(stages=f"{dvcyaml}:stage-0") == {"foo": 1}
+
+
 def test_params_show_revs(params_repo):
     assert api.params_show(rev="HEAD~1") == {
         "params.yaml:foo": 1,