0

Problem Description:

I am working on a Python project with the following structure:

Scriptus
 ├── frontend
 │   ├── hf_call.py
 │   ├── slide_deck.py
 │   ├── slide_gen.py
 │   └── ui.py
 ├── hf_service
 │   ├── consts.py
 │   └── hf_model.py
 ├── generated/
 ├── .env
 ├── .gitignore
 ├── .gitattributes
 ├── README.md
 └── requirements.txt

Issue 1: When running frontend/hf_call.py directly, I encounter:

ModuleNotFoundError: No module named 'hf_service'

Issue 2: When running the script as a module with python -m frontend.hf_call, I get:

SyntaxError: source code string cannot contain null bytes

Code Details:

hf_service/consts.py:

HF_API_URL = "https://api-inference.huggingface.co/models/"
MODEL_NAME = "meta-llama/Meta-Llama-3.1-8B-Instruct"

hf_service/hf_model.py:

import os
import requests
from dotenv import load_dotenv
from consts import HF_API_URL, MODEL_NAME

load_dotenv()
HF_API_KEY = os.getenv('HF_API_KEY')

def generate_text(input_text: str) -> str:
    api_url = f"{HF_API_URL}/{MODEL_NAME}"
    headers = {"Authorization": f"Bearer {HF_API_KEY}"}
    payload = {"inputs": input_text}
    response = requests.post(api_url, headers=headers, json=payload)
    response.raise_for_status()
    return response.json().get('generated_text', '')

if __name__ == "__main__":
    input_text = "Hello, world!"
    print(generate_text(input_text))

frontend/hf_call.py:

import requests
import os
from dotenv import load_dotenv
from hf_service.consts import HF_API_URL, MODEL_NAME

load_dotenv()
HF_API_KEY = os.getenv('HF_API_KEY')

def generate_text(input_text: str) -> str:
    api_url = f"{HF_API_URL}/{MODEL_NAME}"
    headers = {"Authorization": f"Bearer {HF_API_KEY}"}
    payload = {"inputs": input_text}
    response = requests.post(api_url, headers=headers, json=payload)
    response.raise_for_status()
    return response.json().get('generated_text', '')

if __name__ == "__main__":
    input_text = "Hello, world!"
    print(generate_text(input_text))

.env:

HF_API_KEY=your_huggingface_api_key_here

What I Tried:

Running frontend/hf_call.py Directly:

  • Command: python frontend/hf_call.py
  • Issue Encountered: ModuleNotFoundError: No module named 'hf_service'

Running the Script as a Module:

  • Command: python -m frontend.hf_call
  • Issue Encountered: SyntaxError: source code string cannot contain null bytes

Checked and Updated Code Files:

Verified and updated code in hf_service/consts.py, hf_service/hf_model.py, and frontend/hf_call.py.

Confirmed Presence of .env File:

Ensured .env file exists with the correct API key.

What I Expected:

For Issue 1: I expected to be able to run frontend/hf_call.py without encountering import errors by correctly configuring the module imports.

For Issue 2: I expected the script to run without syntax errors when using python -m frontend.hf_call, following the correct module execution process.

Summary: Help resolving the ModuleNotFoundError and SyntaxError issues to ensure proper execution of the scripts and functionality of the project.

3
  • I'm not sure about the syntax error, but the module error is due to the common misunderstanding about where Python will look for modules. You need Scriptus to be on the module search path, and it's not when you execute python frontend/hf_call.py (because Scriptus/frontend, not Scriptus itself, is automatically added to the path). As a general rule, do not put scripts in directories intended to define packages. Commented Aug 8, 2024 at 14:20
  • I don't understand why you did not get the syntax error the first time. Commented Aug 8, 2024 at 14:21
  • If I inject a null byte into consts.py, for example, I can get the syntax error with the second call. The first call fails to import the module in the first place, so never sees the syntax error. Commented Aug 8, 2024 at 14:35

1 Answer 1

0

Short Answer

Python's import statement only looks in the directory of which listed in sys.path, typically the directory of the .py file, and python's site-packages folder.

You can see all these by doing:

import sys
print(sys.path)

And also, if you try to import above your executing directory, you get an error:

ValueError: attempted relative import beyond top-level package

Work around - 1

Add your working directory into sys.path

in frontend/hf_call.py:
# --- added code ---
import sys
import os
sys.path.append(os.path.join(os.path.dirname(__file__), ".."))
# -- end of edit ---

import requests
import os
from dotenv import load_dotenv
from hf_service.consts import HF_API_URL, MODEL_NAME

load_dotenv()
HF_API_KEY = os.getenv('HF_API_KEY')

def generate_text(input_text: str) -> str:
    api_url = f"{HF_API_URL}/{MODEL_NAME}"
    headers = {"Authorization": f"Bearer {HF_API_KEY}"}
    payload = {"inputs": input_text}
    response = requests.post(api_url, headers=headers, json=payload)
    response.raise_for_status()
    return response.json().get('generated_text', '')

if __name__ == "__main__":
    input_text = "Hello, world!"
    print(generate_text(input_text))

Work around - 2

Create a main script right under your working directory:

Scriptus
 ├── frontend
 │   └── hf_call.py
 ├── hf_service
 │   └── consts.py
 └── main.py // create a main script

And import your generate_text function:

from frontend.hf_call import generate_text

if __name__ == "__main__":
    input_text = "Hello, world!"
    print(generate_text(input_text))

And execute the main script:

python3 main.py
Sign up to request clarification or add additional context in comments.

2 Comments

This doesn't address the purported syntax error at all.
I didn't encounter the syntax error on my end, it might be caused of wrong line ending or else encoding issues, see if this helps you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.