'KeyError with os.environ[] accessing variable from .env file

I'm trying to build a slackbot and retrieve the slack token from a separate .env file. When I run it, I get thrown an error that looks like this:

raise KeyError(key) from None
KeyError: 'SLACK_TOKEN'

The code for the bot (ShoppingListBot.py) is here:

import slack
import os
from pathlib import Path
from dotenv import load_dotenv

env_path = Path('.') / '.env'
load_dotenv(dotenv_path=env_path)

client = slack.WebClient(token=os.environ["SLACK_TOKEN"])

The code for the .env file (.env) is here:

SLACK_TOKEN="xoxb-1691324762768-1693412284260-RdP0ZQUaQxD9j9mtLlwfNMbD"


Solution 1:[1]

Instead of os.environ["SLACK_TOKEN"] you should use os.getenv("SLACK_TOKEN").

From the docs (emphasis mine):

This mapping is captured the first time the os module is imported, typically during Python startup as part of processing site.py. Changes to the environment made after this time are not reflected in os.environ, except for changes made by modifying os.environ directly.

Or use override=True in load_dotenv()

Solution 2:[2]

I usally use YAML files but it would appear you should use os.getenv("SLACK_TOKEN") not os.environ["SLACK_TOKEN"] according to pip python-dotenv

Solution 3:[3]

Not sure if you're still having this problem, but anyone else with this problem - this is how I solved it. note: I am still learning

I created a .env file in the same directory with the proper values, then wrote the following to 'app.py'

from http import client
from slack_bolt import App
from slack_bolt.adapter.socket_mode import SocketModeHandler
import os
from dotenv import load_dotenv
from pathlib import Path

load_dotenv()
#loading from .env file that was made
SLACK_BOT_TOKEN = os.environ['SLACK_BOT_TOKEN']
SLACK_APP_TOKEN = os.environ['SLACK_APP_TOKEN']

app = App(token=SLACK_BOT_TOKEN)

if __name__ == '__main__':
    SocketModeHandler(app, os.environ['SLACK_APP_TOKEN']).start()

Before running, make sure that you go into your python install folder and run the install certificates command as well. Must be installed in order to successfully communicate with servers.

This was returned with a confirmation that the bolt app was running.

Hope this helps!

-----Source----

Solution 4:[4]

In simple terms for the option one - think about reference as a separate pointer object by itself - this object points to an actual instance of something that you are passing to your method.
So, inside your method, you are assigning an object "root.left" to this reference "object", therefore this reference object now points to the ’root.left’ instance. then again, another assignment - again, root reference points to the ’newNode’ instance. But the actual thing, the original root object, to which the reference was passed inside the method has not been modified.
Only the reference has been modified and it is now pointing to something else.

Option 2 actually changes something inside the object, which the passed reference is pointing to - therefore the original actual root object is modified.

This is a bit of a simplification, but at least should point you in the right direction.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Mike Scotty
Solution 2 Jxck
Solution 3
Solution 4 Despacito 2