This repository serves as a minimal example of a local Python package. It illustrates the basic structure and setup needed to quickly create and install a simple Python module.
mytoolbox/
│
├── mytoolbox/
│ ├── __init__.py
│ └── kurucz_atomic_symbols.py
├── tests/
│ └── test_kurucz_atomic_symbols.py
├── pyproject.toml
└── README.txt
-
mytoolbox/__init__.py
:
Tells Python thatmytoolbox
is a package, allowing you to import its modules. Additionally, it serves as a convenient place to control how submodules are exposed to users. By importing specific functions into__init__.py
, you simplify the API so users can directly access key functionalities without needing to know your module's internal structure. Alternatively, you could keep submodules separate, leaving it up to users to import each submodule explicitly. Both approaches have their merits: explicit submodules maintain clear boundaries, while convenience imports offer a simpler user experience. -
mytoolbox/kurucz_atomic_symbols.py
:
Contains Python functions to convert between atomic symbols and Kurucz atomic codes. -
tests/test_kurucz_atomic_symbols.py
:
Contains unit tests to verify the correctness of functions implemented inkurucz_atomic_symbols.py
. Tests are optional but highly recommended, as they help you spot problems early and confidently modify your code without fear of unintentionally breaking existing functionality. While there's no need to put form over function, good tests ensure your module stays reliable and maintainable. -
pyproject.toml
:
Tells Python how to install your module, including metadata and dependencies. -
README.txt
:
Provides instructions and usage examples for your module. (You're reading this file right now!)
Install locally in editable (-e
) mode. You want to use this mode if you need to make changes to your code and immediately test them without reinstalling the package each time.
pip install -e .
Tests are provided for convenience to ensure the package functions correctly, but they are entirely optional when creating your package. To run all tests for this project:
Ensure you have pytest installed (if not already):
pip install pytest
Navigate to the project’s root directory (the same directory containing pyproject.toml). Run pytest:
pytest
For more detailed output, you can use:
pytest -v
Pytest will automatically discover and execute any test files (like test_kurucz_atomic_symbols.py) located in the tests/ directory. If all is configured correctly, you should see a report indicating whether the tests passed or failed.
After installation, the package can be imported and used as follows:
import mytoolbox as mt
# Check the actual location of the imported module (helpful to understand effect of pip install -e)
print(mt.__file__)
# Print the docstring for the kurucz_code_to_symbol function
# help(mt.kurucz_code_to_symbol)
# Convert Kurucz code to atomic symbol and ion stage
print(mt.kurucz_code_to_symbol('26.01')) # Output: Fe II
# Convert atomic symbol and ion stage to Kurucz code
print(mt.symbol_to_kurucz_code('Fe II')) # Output: 26.01
# Explicitly print a variable from a submodule
# (see description in __init__.py for further details)
print(mt.kurucz_atomic_symbols.ION_STAGES)
To automatically reload your module after editing the code:
# Load IPython's autoreload extension and configure automatic reloading
%load_ext autoreload
%autoreload 2
# Import your module
import mytoolbox as mt
# Now, edits to 'kurucz_atomic_symbols.py' will automatically reload
print(mt.kurucz_code_to_symbol('26.01')) # Immediate feedback from edits
You can manually recreate this minimal module structure by following the directory structure provided above and creating each file yourself. However, if you prefer, you can quickly start by cloning the existing example using git:
git clone https://github.com/RozanskiT/mytoolbox_tutorial.git
cd mytoolbox_tutorial
Then proceed with installation steps above.
If you don't understand something or need coding help, ask AI—they're very good at it!
Here are some concise recommendations and principles useful for scientists developing Python packages:
- Think "Test First" (TDD): Consider writing tests before writing your code — it ensures reliability from the start.
- Respect Boundaries: Clearly define interfaces; minimize dependencies between modules.
- Avoid Globals: Global variables complicate debugging and maintenance. Keep variables local and explicit.
- Simplicity Wins: Write straightforward code — complexity is harder to test, debug, and maintain.
- Minimal Dependencies: Avoid adding unnecessary dependencies — this pays off when running your code on clusters.
Essential Documentation:
- Python Packaging Guide: Official resources for Python packaging.
- pytest Documentation: Powerful yet simple testing framework.
Continuous Integration (CI):
- Automate your testing workflow to detect issues early: