Wout van der Hoef
Wout van der Hoef

Reputation: 23

When using brownie I can't use external modules, pip install doesn't work brownie

PROBLEM: Can't import PIL module when using python 3 and brownie

When I run 'brownie run scripts/create_metadata.py --network rinkeby' I get the following error: ModuleNotFoundError: No module named 'PIL'.

The simple solution would be to pip install pillow. The problem is that I do have it installed. Pillow shows up when I run 'pip list' in my cmd. The error only occures when using brownie, I CAN use the PIL module when running the script regularly in python. But when I run the script using 'brownie run...' I do get the error. Below is the full output and the code.

Any tips would be greatly appreciated.

This is the code for scripts/create_metadata.py:

from brownie import StreamCollectible, network
from metadata.sample_metadata import metadata_template
from pathlib import Path
import requests
import json
import os
import math
import PIL

# from PIL import Image, ImageFont, ImageDraw

PINATA_BASE_URL = "https://api.pinata.cloud/"
endpoint = "pinning/pinFileToIPFS"
headers = {
    "pinata_api_key": str(os.getenv("PINATA_API_KEY")),
    "pinata_secret_api_key": str(os.getenv("PINATA_API_SECRET")),
}


def main():
    stream_collectible = StreamCollectible[-1]
    number_of_collectibles = stream_collectible.tokenCounter()
    print(f"There are {number_of_collectibles} stream collectibles")
    for token_id in range(number_of_collectibles):
        metadata_file_name = f"./metadata/{network.show_active()}/{token_id}"
        metadata = metadata_template
        if Path(metadata_file_name).exists():
            print(f"{metadata_file_name} already exists! Delete it to overwrite it")
        else:
            print(f"Creating Metadata file: {metadata_file_name}")
            metadata["name"] = f"Stream Token #{token_id}"
            metadata["description"] = ""

            img_path = f"./images/{token_id}.jpg"
            create_img(token_id)

            img_uri = None
            if os.getenv("UPLOAD_IPFS") == "true":
                img_uri = upload_pinata_IPFS(token_id)

            metadata["image"] = img_uri
            with open(metadata_file_name, "w") as file:
                json.dump(metadata, file)


def upload_pinata_IPFS(file_name):
    file_path = f"./images/{file_name}.jpg"
    with Path(file_path).open("rb") as fp:

        image_binary = fp.read()

        response = requests.post(
            str(PINATA_BASE_URL + endpoint),
            files={"file": (str(file_name), str(image_binary))},
            headers=headers,
        )
        JSON_response = response.json()

        URI = f"https://ipfs.io/ipfs/{JSON_response['IpfsHash']}?filename={file_name}.json"

        print("JSON RESPONSE")
        print(JSON_response)
        print("")
        print("URI")
        print(URI)
        return URI


def create_img(n):
    width = 17
    nList = list(str(n))
    bImage = Image.new("L", (width, width), 255)

    for i in range(len(nList)):
        xAxis = (7 - 2 * (len(nList) - 1)) + 4 * i
        nImage = Image.open(f"template/{nList[i]}.png")
        bImage.paste(nImage, (xAxis, 6))

    if not os.path.exists("./images"):
        os.makedirs("./images")
    bImage.save(f"./images/{n}.png")
    n -= 1

This is the full output:

INFO: Could not find files for the given pattern(s).
Brownie v1.17.2 - Python development framework for Ethereum

Erc721StreamtokenProject is the active project.
  File "C:\Users\user\.local\pipx\venvs\eth-brownie\lib\site-packages\brownie\_cli\run.py", line 50, in main
    return_value, frame = run(
  File "C:\Users\user\.local\pipx\venvs\eth-brownie\lib\site-packages\brownie\project\scripts.py", line 53, in run       
    module = _import_from_path(script)
  File "C:\Users\user\.local\pipx\venvs\eth-brownie\lib\site-packages\brownie\project\scripts.py", line 149, in _import_from_path
    _import_cache[import_str] = importlib.import_module(import_str)
  File "C:\Program, line line, in in
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen, line line, in in
  File "<frozen, line line, in in
  File "<frozen, line line, in in
  File "<frozen, line line, in in
  File "<frozen, line line, in in
  File "<frozen, line line, in in
  File ".\scripts\create_metadata.py", line 8, in <module>
    import PIL
ModuleNotFoundError: No module named 'PIL'

Upvotes: 1

Views: 886

Answers (1)

Patrick Collins
Patrick Collins

Reputation: 6131

When using brownie installed via pipx, you actually install brownie in it's own virtual environment. When you run brownie, it doesn't look into your locally installed packages. You have to inject your modules into the brownie virtual environment, like so:

pipx inject eth-brownie Pillow

Or whatever your module is

Upvotes: 4

Related Questions