Repository: conan-io/conan

Issue:
[bug] ProfilesAPI: wrong path to profile plugin
### Describe the bug

Conan Version: 2.12
OS: Windows 11
Python: 3.13

Consuming the ConanAPI, specifically the ProfilesAPI I ran into a fatal bug, that leads to a FileNotFound error.
When calling _load_profile_plugin of the API's profile.py (e.g. by calling get_profile), the call to load_python_file throws an exception (resulting in a FileNotFound) due to an erroneous ModuleSpec returned by imp_util.spec_from_file_location. The ModuleSpec's origin is wrong. It contains a path which has a subpath occuring twice.
Let's say the plugin file that should be loaded in the process is at /subpath1/subpath2/plugin_file.py. The returned path however is /subpath1/subpath2/subpath2/plugin_file.py, that doesn't exist, of course. 


### How to reproduce it

I used a minimal python script that did nothing more than instanciate a ConanAPI object and try to request a Profile object like this:
```python
cn_api = ConanAPI(cache_folder = "test")
profile_api = cn_api.profiles
print(profile_api.get_profile(["default"]))
```
So, at my project root I have this script (say, `script.py`) and the `test/` folder that is used as CONAN_HOME for the API calls. So, `/project_root/test/extensions/plugins/profile.py` is what should be loaded when _load_profile_plugin is called. However, the ModuleSpec's origin points to `/project_root/test/extensions/plugins/test/extensions/plugins/profile.py`.
Of course this path is bogus and leads to a FileNotFound error.

I tried to find out what is going on by checking what reference the ProfileAPI object has stored:
```python
print(profile_api._home_paths.profile_plugin_path)
```
which prints `test/extensions/plugins/profile.py`, which is correct. This is what is given to spec_from_file_location as the location.

It seems to me that the [parameters to the call of spec_from_file_location](https://github.com/conan-io/conan/blob/9eb72c8242f683978255a04f198a4765ec5809d7/conans/client/loader.py#L337C24-L337C56) may be erroneous or there is something else interfering.


Discussion:
Hi @AlexTUM 

Thanks for your report.
This doesn't look like a bug, the ``cache_folder`` must be an absolute path, it cannot be a relative one like ``ConanAPI(cache_folder = "test")``, please try using an absolute path instead of ``test``.

I'll try to add a check or something to avoid this input.
Doing https://github.com/conan-io/conan/pull/17851 to close this ticket.

I'd also like to suggest using the custom commands framework instead the row ``ConanAPI()``. It is way more convenient and it has lots of advantages, like automatic management and sharing with ``conan config install/install-pkg``, with versioning, reproducibility with lockfiles etc. with the second ``conan config install-pkg``.
Thanks for your replies, I'll look into the custom commands framework (although I'm not sure it meets my needs since the issue I reported here was just me playing around. I have a bunch of requirements and complexity for actual use)



Patch:
diff --git a/conan/api/conan_api.py b/conan/api/conan_api.py
index 30fe82cc217..8a518b21dc6 100644
--- a/conan/api/conan_api.py
+++ b/conan/api/conan_api.py
@@ -1,3 +1,4 @@
+import os
 import sys
 
 from conan.api.output import init_colorama
@@ -35,6 +36,8 @@ def __init__(self, cache_folder=None):
         version = sys.version_info
         if version.major == 2 or version.minor < 6:
             raise ConanException("Conan needs Python >= 3.6")
+        if cache_folder is not None and not os.path.isabs(cache_folder):
+            raise ConanException("cache_folder has to be an absolute path")
 
         init_colorama(sys.stderr)
         self.workspace = WorkspaceAPI(self)


Test patch:
diff --git a/test/integration/conan_api/test_profile_api.py b/test/integration/conan_api/test_profile_api.py
new file mode 100644
index 00000000000..4f06d9d105a
--- /dev/null
+++ b/test/integration/conan_api/test_profile_api.py
@@ -0,0 +1,11 @@
+import pytest
+
+from conan.api.conan_api import ConanAPI
+from conan.errors import ConanException
+
+
+def test_profile_api():
+    # It must be an absolute path
+    with pytest.raises(ConanException) as e:
+        ConanAPI(cache_folder="test")
+    assert "cache_folder has to be an absolute path" in str(e.value)