main 75a6989512f2 cached
9 files
11.5 KB
3.3k tokens
3 symbols
1 requests
Download .txt
Repository: mpeteuil/poetry-dotenv-plugin
Branch: main
Commit: 75a6989512f2
Files: 9
Total size: 11.5 KB

Directory structure:
gitextract_xbolhul7/

├── .github/
│   └── workflows/
│       ├── build.yml
│       └── release.yml
├── LICENSE
├── README.md
├── poetry_dotenv_plugin/
│   ├── __init__.py
│   └── dotenv_plugin.py
├── pyproject.toml
└── tests/
    ├── __init__.py
    └── test_system.sh

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/workflows/build.yml
================================================
# Heavily based on the Poetry main Github Actions workflow
# https://github.com/python-poetry/poetry/blob/1.2.0a1/.github/workflows/main.yml

name: "CI"
on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - '**'

jobs:
  tests:
    name: ${{ matrix.os }} / ${{ matrix.python-version }}
    runs-on: ${{ matrix.os }}-latest
    strategy:
      matrix:
        os: [Ubuntu, MacOS]
        python-version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"]
    defaults:
      run:
        shell: bash
    steps:
      - uses: actions/checkout@v4

      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v4
        id: setup-python
        with:
          python-version: ${{ matrix.python-version }}

      - name: Install poetry
        run: |
          if [[ "${{ matrix.python-version }}" == "3.7" ]]; then
            curl -sSL https://install.python-poetry.org | python - --version 1.5.1 -y
          else
            curl -sSL https://install.python-poetry.org | python - -y
          fi

      - name: Update PATH
        run: echo "$HOME/.local/bin" >> $GITHUB_PATH

      - name: Configure poetry
        run: poetry config virtualenvs.in-project true

      - name: Set up cache
        uses: actions/cache@v3
        id: cache
        with:
          path: .venv
          key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/poetry.lock') }}

      - name: Ensure cache is healthy
        if: steps.cache.outputs.cache-hit == 'true'
        run: timeout 10s poetry run pip --version || rm -rf .venv

      - name: Install dependencies
        run: poetry install --no-root

      - name: Install poetry-dotenv-plugin
        run: poetry self add "$GITHUB_WORKSPACE"

      - name: Run system tests
        run: tests/test_system.sh


================================================
FILE: .github/workflows/release.yml
================================================
# Based on
# https://github.com/python-poetry/poetry/blob/a0cc7d6b9ea9b59203ac01e4ac641643dc7c9c7a/.github/workflows/release.yml

name: Release

on:
  push:
    tags:
      - '*.*.*'

jobs:
  release:
    name: Release
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up Python 3.11
        uses: actions/setup-python@v4
        with:
          python-version: "3.11"

      - name: Install Poetry
        run: curl -sSL https://install.python-poetry.org | python - -y

      - name: Update PATH
        run: echo "$HOME/.local/bin" >> $GITHUB_PATH

      - name: Build project for distribution
        run: poetry build

      - name: Check Version
        id: check-version
        run: |
          [[ "$(poetry version --short)" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] \
            || echo "prerelease=true" >> "$GITHUB_OUTPUT"

      - name: Create Release
        uses: ncipollo/release-action@v1
        with:
          artifacts: "dist/*"
          token: ${{ secrets.GITHUB_TOKEN }}
          draft: false
          prerelease: steps.check-version.outputs.prerelease == 'true'

      - name: Publish to PyPI
        env:
          POETRY_PYPI_TOKEN_PYPI: ${{ secrets.PYPI_TOKEN }}
        run: poetry publish


================================================
FILE: LICENSE
================================================
Copyright (c) 2021 Michael Peteuil

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.md
================================================
# Poetry Dotenv Plugin

[![CI](https://github.com/mpeteuil/poetry-dotenv-plugin/actions/workflows/build.yml/badge.svg)](https://github.com/mpeteuil/poetry-dotenv-plugin/actions/workflows/build.yml)

A [Poetry](https://python-poetry.org/) plugin that automatically loads environment variables from `.env` files into the environment before poetry commands are run.

Supports Python 3.7+[^1]

```sh
$ cat .env
MY_ENV_VAR='Hello World'

$ poetry run python -c 'import os; print(os.environ.get("MY_ENV_VAR"))'
Hello World
```

This plugin depends on the [`python-dotenv` package](https://github.com/theskumar/python-dotenv) for its functionality and therefore also supports features that `python-dotenv` supports. Interpolating variables using POSIX variable expansion for example.

### Origins

Initial implementation based on the event handler application plugin example in the [Poetry docs](https://python-poetry.org/docs/plugins/#event-handler).

## Install

```sh
poetry self add poetry-dotenv-plugin
```

### Coming from Pipenv

If you are transitioning from `pipenv` there shouldn't be much to change with regard to the `.env` loading. If you were a user of [`pipenv`'s environment variables](https://pipenv.pypa.io/en/latest/advanced/#automatic-loading-of-env) to control `.env` loading then you can use the analogous environment variables listed below.

Pipenv env var | Poetry env var
-------------- | ----------------------
PIPENV_DOTENV_LOCATION | POETRY_DOTENV_LOCATION
PIPENV_DONT_LOAD_ENV | POETRY_DONT_LOAD_ENV

### Overriding existing environment variables

By default, this plugin will override existing environment variables. This is because this plugin was built to make onboarding for users coming from `pipenv` as seamless as possible. If you want to prevent existing environment variables from being overridden, you can set the `POETRY_DOTENV_DONT_OVERRIDE` environment variable to `true`.[^2]

[^1]: Python 3.7 is supported only when using Poetry < [1.6.0](https://python-poetry.org/history/#160---2023-08-20), which [dropped support for Python 3.7](https://github.com/python-poetry/poetry/pull/7674).
[^2]: See [#16](https://github.com/mpeteuil/poetry-dotenv-plugin/pull/16) for background.


================================================
FILE: poetry_dotenv_plugin/__init__.py
================================================


================================================
FILE: poetry_dotenv_plugin/dotenv_plugin.py
================================================
import os

from cleo.events.console_events import COMMAND
import dotenv
from poetry.console.application import Application
from poetry.console.commands.env_command import EnvCommand
from poetry.plugins.application_plugin import ApplicationPlugin

class DotenvPlugin(ApplicationPlugin):
    def activate(self, application):
        application.event_dispatcher.add_listener(COMMAND, self.load_dotenv)

    def load_dotenv(
        self,
        event,
        event_name,
        dispatcher
    ):
        POETRY_DONT_LOAD_ENV = bool(os.environ.get("POETRY_DONT_LOAD_ENV"))
        command = event.command

        if not isinstance(command, EnvCommand) or POETRY_DONT_LOAD_ENV:
            return

        POETRY_DOTENV_LOCATION = os.environ.get("POETRY_DOTENV_LOCATION")
        io = event.io

        if io.is_debug():
            io.write_line("<debug>Loading environment variables.</debug>")

        path = POETRY_DOTENV_LOCATION or dotenv.find_dotenv(usecwd=True)
        POETRY_DOTENV_DONT_OVERRIDE = os.environ.get("POETRY_DOTENV_DONT_OVERRIDE", "")
        DOTENV_OVERRIDE = not POETRY_DOTENV_DONT_OVERRIDE.lower() in (
            "true",
            "1",
        )
        dotenv.load_dotenv(dotenv_path=path, override=DOTENV_OVERRIDE)


================================================
FILE: pyproject.toml
================================================
[tool.poetry]
name = "poetry-dotenv-plugin"
version = "0.2.0"
description = "A Poetry plugin to automatically load environment variables from .env files"
authors = ["Michael Peteuil <michael.peteuil@gmail.com>"]
license = "MIT"
readme = "README.md"
packages = [{include = "poetry_dotenv_plugin"}]
homepage = "https://github.com/mpeteuil/poetry-dotenv-plugin"
repository = "https://github.com/mpeteuil/poetry-dotenv-plugin"
keywords = ["poetry", "poetry-plugin", "plugin", "dotenv"]
classifiers = [
    "Topic :: Software Development",
    "Topic :: System :: Systems Administration",
    "Topic :: Utilities",
]

[tool.poetry.dependencies]
python = ">=3.7,<4"
poetry = ">=1.2.0a1"
python-dotenv = ">=0.10.0"

[tool.poetry.group.dev.dependencies]
pytest = "^6.2.3"

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

[tool.poetry.plugins."poetry.application.plugin"]
poetry-dotenv-plugin = "poetry_dotenv_plugin.dotenv_plugin:DotenvPlugin"


================================================
FILE: tests/__init__.py
================================================


================================================
FILE: tests/test_system.sh
================================================
#!/usr/bin/env bash

function create_dotenv_file() {
  # Setup .env file so the plugin can do its job
  echo "export MY_ENV_VAR='foo'" > .env
}

function delete_dotenv_file() {
  # Tear down .env file since we no longer need it
  rm -f .env
}

function test_end_to_end_system_with_default_dotenv_file() {
  # Setup
  local expected
  expected='foo'
  create_dotenv_file

  local output
  output=$(poetry run python -c "import os; print(os.environ['MY_ENV_VAR'])")

  # Cleanup
  delete_dotenv_file

  if [ "$expected" = "$output" ]; then
    printf "test_end_to_end_system_with_default_dotenv_file: PASSED\n"
  else
    printf "Expected '$expected', but got '%s'.\n" "$output"
    exit 1
  fi
}

function test_end_to_end_system_with_dotenv_location_override() {
  # Setup
  local expected
  expected='bar'
  local new_dotenv_path
  new_dotenv_path="$PWD/tests/tmp"
  create_dotenv_file

  # Override the file that was just created
  mkdir -p "$new_dotenv_path" && echo "export MY_ENV_VAR='bar'" > "$new_dotenv_path/.env"

  local output
  output=$(export POETRY_DOTENV_LOCATION="$new_dotenv_path/.env" && poetry run python -c "import os; print(os.environ['MY_ENV_VAR'])")

  # Cleanup
  rm -rf "$new_dotenv_path"
  delete_dotenv_file

  if [ "$expected" = "$output" ]; then
    printf "test_end_to_end_system_with_dotenv_location_override: PASSED\n"
  else
    printf "Expected '$expected', but got '%s'.\n" "$output"
    exit 1
  fi
}

function test_end_to_end_system_with_default_env_overrides() {
  # Setup
  local expected
  expected='foo'
  create_dotenv_file

  local output
  output=$(export MY_ENV_VAR='bar' && poetry run python -c "import os; print(os.environ['MY_ENV_VAR'])")

  # Cleanup
  delete_dotenv_file

  if [ "$expected" = "$output" ]; then
    printf "test_end_to_end_system_with_default_env_overrides: PASSED\n"
  else
    printf "Expected '$expected', but got '%s'.\n" "$output"
    exit 1
  fi
}

function test_end_to_end_system_without_env_overrides() {
  # Setup
  local expected
  expected='bar'
  create_dotenv_file

  local output
  output=$(export MY_ENV_VAR='bar' POETRY_DOTENV_DONT_OVERRIDE=true && poetry run python -c "import os; print(os.environ['MY_ENV_VAR'])")

  # Cleanup
  delete_dotenv_file

  if [ "$expected" = "$output" ]; then
    printf "test_end_to_end_system_without_env_overrides: PASSED\n"
  else
    printf "Expected '$expected', but got '%s'.\n" "$output"
    exit 1
  fi
}

function test_end_to_end_system_without_loading_dotenv_file() {
  # Setup
  local expected
  expected='Nonexistent Variable'
  create_dotenv_file

  local output
  output=$(export POETRY_DONT_LOAD_ENV=true && poetry run python -c "import os; print(os.environ.get('MY_ENV_VAR', '$expected'))")

  # Cleanup
  delete_dotenv_file

  if [ "$expected" = "$output" ]; then
    printf "test_end_to_end_system_without_loading_dotenv_file: PASSED\n"
  else
    printf "Expected '$expected', but got '%s'.\n" "$output"
    exit 1
  fi
}

test_end_to_end_system_with_default_dotenv_file
test_end_to_end_system_with_dotenv_location_override
test_end_to_end_system_with_default_env_overrides
test_end_to_end_system_without_env_overrides
test_end_to_end_system_without_loading_dotenv_file
Download .txt
gitextract_xbolhul7/

├── .github/
│   └── workflows/
│       ├── build.yml
│       └── release.yml
├── LICENSE
├── README.md
├── poetry_dotenv_plugin/
│   ├── __init__.py
│   └── dotenv_plugin.py
├── pyproject.toml
└── tests/
    ├── __init__.py
    └── test_system.sh
Download .txt
SYMBOL INDEX (3 symbols across 1 files)

FILE: poetry_dotenv_plugin/dotenv_plugin.py
  class DotenvPlugin (line 9) | class DotenvPlugin(ApplicationPlugin):
    method activate (line 10) | def activate(self, application):
    method load_dotenv (line 13) | def load_dotenv(
Condensed preview — 9 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (13K chars).
[
  {
    "path": ".github/workflows/build.yml",
    "chars": 1837,
    "preview": "# Heavily based on the Poetry main Github Actions workflow\n# https://github.com/python-poetry/poetry/blob/1.2.0a1/.githu"
  },
  {
    "path": ".github/workflows/release.yml",
    "chars": 1279,
    "preview": "# Based on\n# https://github.com/python-poetry/poetry/blob/a0cc7d6b9ea9b59203ac01e4ac641643dc7c9c7a/.github/workflows/rel"
  },
  {
    "path": "LICENSE",
    "chars": 1059,
    "preview": "Copyright (c) 2021 Michael Peteuil\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this"
  },
  {
    "path": "README.md",
    "chars": 2211,
    "preview": "# Poetry Dotenv Plugin\n\n[![CI](https://github.com/mpeteuil/poetry-dotenv-plugin/actions/workflows/build.yml/badge.svg)]("
  },
  {
    "path": "poetry_dotenv_plugin/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "poetry_dotenv_plugin/dotenv_plugin.py",
    "chars": 1247,
    "preview": "import os\n\nfrom cleo.events.console_events import COMMAND\nimport dotenv\nfrom poetry.console.application import Applicati"
  },
  {
    "path": "pyproject.toml",
    "chars": 973,
    "preview": "[tool.poetry]\nname = \"poetry-dotenv-plugin\"\nversion = \"0.2.0\"\ndescription = \"A Poetry plugin to automatically load envir"
  },
  {
    "path": "tests/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "tests/test_system.sh",
    "chars": 3201,
    "preview": "#!/usr/bin/env bash\n\nfunction create_dotenv_file() {\n  # Setup .env file so the plugin can do its job\n  echo \"export MY_"
  }
]

About this extraction

This page contains the full source code of the mpeteuil/poetry-dotenv-plugin GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 9 files (11.5 KB), approximately 3.3k tokens, and a symbol index with 3 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!