# Devcontainer + vscode + uv + robotcode

**URL:** https://forum.robotframework.org/t/devcontainer-vscode-uv-robotcode/8780
**Category:** Visual Studio Code(ium)
**Created:** [14 April 2025 15:44 UTC](https://forum.robotframework.org/t/devcontainer-vscode-uv-robotcode/8780 "2025-04-14T15:44:17Z")
**Posts on this page:** 10
**Page:** 1

<div class="post-metadata">

### Author: ![fkromer](https://dub1.discourse-cdn.com/flex005/user_avatar/forum.robotframework.org/fkromer/32/3733_2.png) [@fkromer](https://forum.robotframework.org/u/fkromer)
#### Post date: [14 April 2025 15:44 UTC](https://forum.robotframework.org/t/devcontainer-vscode-uv-robotcode/8780/1 "2025-04-14T15:44:17Z")

</div>

I’d like to setup a project for a robotframework library `robotframework-xyz` providing library `XyzLibrary` which is consistent with `uv` (`src/robotframework_xyz`) as well as the naming convention of RF libs (`XyzLibrary`).

The project structure:

```python
robotframework-xyz
  .devcontainer/
    devcontainer.json
  atests/
    xyz.robot
  src/
    robotframework_xyz/
      __init__.py

```

The ` __init__.py` file contains the class `XyzLibrary`.

The content of `devcontainer.json`:

```json
{
  "features": {
    "ghcr.io/jsburckhardt/devcontainer-features/uv:1": {}
  },
  "postCreateCommand": "bash -i -c 'uv sync'",
  "customizations": {
    "vscode": {
      "extensions": [
        "ms-python.python",
        "ms-python.debugpy",
        "d-biehl.robotcode"
      ],
      // https://code.visualstudio.com/docs/python/settings-reference
      "settings": {
        // https://code.visualstudio.com/docs/python/settings-reference#_general-python-settings
        "python.terminal.activateEnvInCurrentTerminal": true,
        "python.defaultInterpreterPath": "/workspaces/robotframework-xyz/.venv/bin/python",
        "python.venvFolders": [
          "/workspaces/robotframework-xyz/.venv"
        ],
        "robotcode.robot.variables": {
          "ROOT": "/workspaces/robotframework-xyz"
        },
        "robotcode.robot.pythonPath": [
          ".",
          "./src/robotframework_xyz"
        ],

```

The content of `pyproject.toml`:

```toml
# https://docs.astral.sh/uv/reference/settings/
[tool.uv.sources]
robotframework-yxz = { workspace = true }

# https://robotcode.io/03_reference/config
[tool.robot]
python-path = [".", "./src/robotframework_xyz"]
paths = ["atests"]
output-dir = "results"

```

The content of ` __init__.py`:

```python
from typing import Protocol
from robot.api.deco import keyword

class SomeProtocol(Protocol):
    def some_method():
        ...

class XyzLibrary(SomeProtocol):
    def some_method(self, ...):
        ...
    @keyword("Keyword '${a}'")
    def some_keyword(self, a):
        ...

```

The content of `xyz.robot`:

```robot
***Settings***

Library XyzLibrary

***Test Cases***
Some test
     Keyword "Something"

```

In general RobotCode is working. But whatever I tried already results in an `Importing test library 'XyzLibrary' failed: ModuleNotFoundError: No module named 'XyzLibrary'` or a

```python
Import definition contains errors.robotcode(ImportContainsErrors)
__init__.py(1, 1): Library 'robotframework_xyz.XyzLibrary' expected at least 1 non-named argument, got 0.

```

Has someone already setup a library with this setup and can help out?

---

<div class="post-metadata">

### Author: ![HelioGuilherme66](https://dub1.discourse-cdn.com/flex005/user_avatar/forum.robotframework.org/helioguilherme66/32/34_2.png) [@HelioGuilherme66](https://forum.robotframework.org/u/HelioGuilherme66)
#### Post date: [14 April 2025 16:46 UTC](https://forum.robotframework.org/t/devcontainer-vscode-uv-robotcode/8780/2 "2025-04-14T16:46:37Z")

</div>

did you installed it with `pip` (`uv pip`)?  
If not you need to add the module dir to `PYTHONPATH`

---

<div class="post-metadata">

### Author: ![fkromer](https://dub1.discourse-cdn.com/flex005/user_avatar/forum.robotframework.org/fkromer/32/3733_2.png) [@fkromer](https://forum.robotframework.org/u/fkromer)
#### Post date: [14 April 2025 18:43 UTC](https://forum.robotframework.org/t/devcontainer-vscode-uv-robotcode/8780/3 "2025-04-14T18:43:24Z")

</div>

No. I’ve installed `uv` into the devcontainer with

```python
  "features": {
    "ghcr.io/jsburckhardt/devcontainer-features/uv:1": {}
  },

```

and declared the pythonPath to RobotCode in the devcontainer

```python
  "customizations": {
    "vscode": {"robotcode.robot.pythonPath": [
          ".",
          "./src/robotframework_xyz"
        ],

```

as well as in the `pyproject.toml` (equivalent to `robot.toml`)

```python
[tool.robot]
python-path = [".", "./src/robotframework_xyz"]
paths = ["atests"]
output-dir = "results"

```

---

<div class="post-metadata">

### Author: ![HelioGuilherme66](https://dub1.discourse-cdn.com/flex005/user_avatar/forum.robotframework.org/helioguilherme66/32/34_2.png) [@HelioGuilherme66](https://forum.robotframework.org/u/HelioGuilherme66)
#### Post date: [14 April 2025 18:55 UTC](https://forum.robotframework.org/t/devcontainer-vscode-uv-robotcode/8780/4 "2025-04-14T18:55:03Z")

</div>

> [@fkromer](#):
>
> The content of ` __init__.py`:

This should be the problem.  
Usually ` __init__.py` are used to declare the code as a module. They can even be empty.

You should (I think), move the code to a file with the name of your library (lowercase), then it can be imported in the ` __init__.py` file.

I don’t know about configuration of vscode, but at least, I would not use relative paths to include in PYTHONPATH.

I assume you test your code first in the command line, and then configure the IDE.

---

<div class="post-metadata">

### Author: ![fkromer](https://dub1.discourse-cdn.com/flex005/user_avatar/forum.robotframework.org/fkromer/32/3733_2.png) [@fkromer](https://forum.robotframework.org/u/fkromer)
#### Post date: [14 April 2025 19:07 UTC](https://forum.robotframework.org/t/devcontainer-vscode-uv-robotcode/8780/5 "2025-04-14T19:07:45Z")

</div>

I’ve recreated the venv. When I installed the lib in [editable mode](https://docs.astral.sh/uv/pip/packages/#editable-packages). I got

```python
$ uv pip install -e .
Resolved 7 packages in 12ms
      Built robotframework-xyz @ file:///workspaces/robotframework-xyz
Prepared 1 package in 771ms
Uninstalled 1 package in 0.63ms
░░░░░░░░░░░░░░░░░░░░ [0/1] Installing wheels... warning: Failed to hardlink files; falling back to full copy. This may lead to degraded performance.
         If the cache and target directories are on different filesystems, hardlinking may not be supported.
         If this is intentional, set `export UV_LINK_MODE=copy` or use `--link-mode=copy` to suppress this warning.
Installed 1 package in 1ms
 ~ robotframework-xyz==0.1.0 (from file:///workspaces/robotframework-xyz)

```

So I ran `$ uv pip install -e --link-mode=copy .` instead.

---

<div class="post-metadata">

### Author: ![robinmackaij](https://dub1.discourse-cdn.com/flex005/user_avatar/forum.robotframework.org/robinmackaij/32/126_2.png) [@robinmackaij](https://forum.robotframework.org/u/robinmackaij)
#### Post date: [14 April 2025 19:30 UTC](https://forum.robotframework.org/t/devcontainer-vscode-uv-robotcode/8780/6 "2025-04-14T19:30:42Z")

</div>

It might not be possible to be consistent with “default Python project layout and naming conventions” and get a library with the RF naming style.

From my understanding, what a `Library` statement does, is (in Python) `import LibraryName from LibraryName` followed by `LibraryName(*args, **kwargs)`.

Now for the import, from a Python naming perspective, you’d actually want to `import LibraryName from library_name` since the top level folder of the package is the import name and folder names for modules / packages are snake\_case according to PEP8.

There might be hacks to work around this, but I’d not be a fan, since then importing the library / module in RF would use a different name then using / testing the import in Python.

What I do for my RF libraries, is have the module name in CamelCase (e.g. OpenApiDriver) with in that folder an ` __init__.py` and, e.g., `openapi_driver.py` (main entry point) containing the class `OpenApiDriver`. In the ` __init__.py` there’s the import statement `from OpenApiDriver.openapi_driver import OpenApiDriver` and an ` __all__ = ["OpenApiDriver"]`. That layout works for RF usage with names as expected and only violates PEP8 for the module name. The Python import for the module is `import OpenApiDriver`, same as the RF “import” name (i.e. the `Library` statement).

---

<div class="post-metadata">

### Author: ![fkromer](https://dub1.discourse-cdn.com/flex005/user_avatar/forum.robotframework.org/fkromer/32/3733_2.png) [@fkromer](https://forum.robotframework.org/u/fkromer)
#### Post date: [14 April 2025 19:49 UTC](https://forum.robotframework.org/t/devcontainer-vscode-uv-robotcode/8780/7 "2025-04-14T19:49:40Z")

</div>

> [@robinmackaij](#):
>
> It might not be possible to be consistent with “default Python project layout and naming conventions” and get a library with the RF naming style.

That’s what I tried to challenge 🙂. I know of two project structure patterns right now:

1. Traditional RF style is [`src/DatabaseLibrary/ __init__.py` \> `class DatabaseLibrary`](https://github.com/MarketSquare/Robotframework-Database-Library/blob/master/src/DatabaseLibrary/ __init__.py#L25) (and what you use in your multi RF lib package `robotframework-openapitools`)
2. `uv` style is [`src/robotframework_construct/ __init__.py` \> `class roborframework_construct`](https://github.com/MarketSquare/robotframework-construct/blob/main/src/robotframework_construct/ __init__.py#L20)

1 is consistent with RF conventions. 2 is consistent with Python package naming conventions.

> [@robinmackaij](#):
>
> From my understanding, what a `Library` statement does, is (in Python) `import LibraryName from LibraryName` followed by `LibraryName(*args, **kwargs)`.
> 
> Now for the import, from a Python naming perspective, you’d actually want to `import LibraryName from library_name` since the top level folder of the package is the import name and folder names for modules / packages are snake\_case according to PEP8.
> 
> There might be hacks to work around this, but I’d not be a fan, since then importing the library / module in RF would use a different name then using / testing the import in Python.

I agree. Actually it is better to stick with 1 and adapt the library package created with [`uv init --lib robotframework-xyz`](https://docs.astral.sh/uv/concepts/projects/init/#libraries).

---

<div class="post-metadata">

### Author: ![daniel](https://dub1.discourse-cdn.com/flex005/user_avatar/forum.robotframework.org/daniel/32/1492_2.png) [@daniel](https://forum.robotframework.org/u/daniel)
#### Post date: [15 April 2025 09:48 UTC](https://forum.robotframework.org/t/devcontainer-vscode-uv-robotcode/8780/8 "2025-04-15T09:48:40Z")

</div>

Some time ago I created a repo where I tried the same thing 😉

> **[GitHub - d-biehl/robot\_uv\_libtest](https://github.com/d-biehl/robot_uv_libtest)**
>
> Trage zur Entwicklung von d-biehl/robot\_uv\_libtest bei, indem du ein Konto bei GitHub erstellst.

The trick to setup a robot framework library with uv is the following:

Create your working folder and in that folder create a normal python library with uv, like this:

```python
mkdir robotframework-dosomething
cd robotframework-dosomething
uv init --name DoSomething --lib # notice here without robotframework-

```

then open the pyproject.toml and prepend `robotframework-` to the `name` setting, like this:

```python
name = "robotframework-dosomething"

```

Now the “complicated” part, that depends on you build-system that your pyproject.toml uses, but if you use uv’s default `hatchling` you should add a new section to your pyproject toml file, like this:

```python
[tool.hatch.build.targets.wheel]
packages = ["src/DoSomething"] # attention this is case sensitive!!!

```

this tells hatchling where it can find the sources for the project when it builds a wheel package, thats what happens if you install the project in editable mode.

You can now add `robotframework` as a dependency with

```python
uv add robotframework

```

and maybe add other dev dependencies like this:

```python
uv add --dev robotframework-tidy

```

and now remove the old `.venv` and create a new one with

```python
uv sync

```

now you can select the python environment in vscode and everything should run and also robot. There is no need to setup what ever python paths or so, because the project is installed per default in editable mode.

---

<div class="post-metadata">

### Author: ![rasjani](https://avatars.discourse-cdn.com/v4/letter/r/858c86/32.png) [@rasjani](https://forum.robotframework.org/u/rasjani)
#### Post date: [15 April 2025 09:57 UTC](https://forum.robotframework.org/t/devcontainer-vscode-uv-robotcode/8780/9 "2025-04-15T09:57:52Z")

</div>

Worth pointing out that that the change Daniel describes above is very similar thing one has to do in “old way of packaging” python code if the library doesn’t reside in the root directory ..

---

<div class="post-metadata">

### Author: ![fkromer](https://dub1.discourse-cdn.com/flex005/user_avatar/forum.robotframework.org/fkromer/32/3733_2.png) [@fkromer](https://forum.robotframework.org/u/fkromer)
#### Post date: [15 April 2025 12:10 UTC](https://forum.robotframework.org/t/devcontainer-vscode-uv-robotcode/8780/10 "2025-04-15T12:10:10Z")

</div>

Thx a lot! So far I used robot in projects only. Not in public libraries. I’ll merge into [Official RF library project template(s)? - #8 by fkromer](https://forum.robotframework.org/t/official-rf-library-project-template-s/8674/8).
