importing python file as a package in .qmd file fails

Hi all, I went through numerous number of articles on how to import python file, but it seem to be working wobbly sometimes in .qmd file. (as is, I made it work a few times, but once the RStudio session was restarted, it didnt work again.)

My file Structure:

SourceReports:
|_ main.py
|_ FunctionSet.py
|_ ReportSourceCodes
.....| init.py
.....| Report 1
..........| init.py
..........| Report1.qmd
......| Report 2
...........| init.py
...........| Report 2.qmd

FunctionSet is where I want to have all of my functions that I would call in each of the Report.qmd file.

According to this tutorial (No known parent package - How relative imports works in python) I need to create a main.py in the root directory so python interpreter knows the location of the file from the root file.

"import FunctionSet" OR "from A_SourceReports import FunctionSet" brings an error of "ModuleNotFoundError: No module named 'FunctionSet'"

Does anyone know where the issue lies here and how to finally import this custom library?

Thanks

Hello @Justinas365,

Thanks for the question.

My suggestion is for you to create a Python package to host main.py and install the Python package.

From a fresh Conda environment:

$ conda create -y -n example python=3.10
$ conda activate example

And the file structure:

.
├── _quarto.yml
├── rep
│   ├── __init__.py
│   └── main.py
├── setup.py
├── SourceReports.qmd
└── SourceReports.Rproj

You can install the package using

$ python -m pip install -e .

Note the -e. It will install the package in "edit" mode. This means that changes to main.py will take effect immediately when you load the package again.

Now, you can run quarto to render your SourceReports.qmd that uses functions from main.py. If you are rendering from RStudio, you need to change the path of the Python interpreter: Tools > Project Options > Python.

Content of the files:

setup.py:

from setuptools import setup

setup(
   name='rep',
   version='0.1.0',
   author='An Awesome Coder',
   author_email='aac@example.com',
   packages=['rep'],
   scripts=[],
   url='http://pypi.python.org/pypi/PackageName/',
   license='',
   description='An awesome package that does something',
   long_description='',
   install_requires=[
   ],
)

rep/main.py:

def hello():
  return "hello"

_quarto.yml:

project:
  title: "SourceReports"

editor: visual

cat SourceReports.qmd:

---
title: "SourceReports"
---

## Quarto

Quarto enables you to weave together content and executable code into a finished document. To learn more about Quarto see <https://quarto.org>.

```{r}
1 + 1
```

## Python

```{python}
import rep.main

rep.main.hello()
```

SourceReports.Rproj:

Version: 1.0

RestoreWorkspace: Default
SaveWorkspace: Default
AlwaysSaveHistory: Default

EnableCodeIndexing: Yes
UseSpacesForTab: Yes
NumSpacesForTab: 2
Encoding: UTF-8

RnwWeave: Sweave
LaTeX: pdfLaTeX

PythonType: conda
PythonVersion: 3.10.5
PythonPath: ~/mambaforge/envs/example/bin/python

Thank you for your reply.

I wonder, why this solution is not being easily found on stackoverflow and other comprehensive tutorials? I would still be leaning towards using approaches described in the following tutorials:
Absolute vs Relative Imports in Python – Real Python
No known parent package - How relative imports works in python (napuzba.com)

Im still willing to give your approach a go, as im loosing my faith in any other tutorial.

Where would you run the "$ python -m pip install -e ." command? I tried running it in R console, terminal, conda cmd.exe with the current env activated and a cmd.

This is a message that I get:

I wonder, why this solution is not being easily found on stackoverflow and other comprehensive tutorials?

It is a question of the question that you do: "how to import" vs "how to install".

Where would you run the python -m pip install -e . command?

Did you include the dot (.) at the end of your command? From the error message that you provided, you forgot the dot at the end of the command. It is

python -m pip install -e .

instead of

python -m pip install -e

The dot means the current directory. In this case, you need to run the command from SourceReports folder.