Skip to content

A Python demonstration of modular architecture featuring two independent sub-projects that communicate via cross-project imports. Includes shared utilities, menu-driven interface, and showcases practical patterns for organizing complex Python applications with interdependent modules.

License

Notifications You must be signed in to change notification settings

esaesa/python-modular-architecture-demo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Python Multi-Project Architecture with Cross-Module Communication

Description

This Python project demonstrates a modular architecture with cross-project communication capabilities. The project consists of a main controller and two independent sub-projects that can run separately but also share common utilities and import functionality from each other.

The implementation showcases how to structure a Python application where multiple sub-projects coexist, each with their own functionality, while maintaining the ability to share code and communicate between them. This is achieved through dynamic path manipulation using sys.path.append() to enable cross-module imports.

This educational example illustrates practical approaches to modular Python development, demonstrating both the benefits and limitations of this architecture pattern.

Features

  • Modular Architecture: Two distinct sub-projects that can function independently
  • Cross-Project Communication: Sub-projects can import and utilize functionality from each other
  • Shared Utilities: Common functions accessible to all sub-projects through a shared module
  • Menu Interface: Main entry point provides a user-friendly menu to select which sub-project to run
  • Dynamic Path Manipulation: Uses sys.path.append() to enable cross-module imports
  • Error Handling: Graceful handling of import failures when sub-projects are run independently

Installation

  1. Clone or download this repository to your local machine
  2. Ensure you have Python 3.x installed on your system
  3. No additional dependencies are required - this project uses only Python standard library modules
git clone https://github.com/your-username/python-multi-project-architecture.git
cd python-multi-project-architecture

Usage

Running the Main Controller

Execute the main script to access the menu-driven interface:

python main.py

This will display a menu allowing you to choose which sub-project to run:

  1. Sub-project 1
  2. Sub-project 2
  3. Exit

Running Sub-Projects Independently

Each sub-project can be run independently:

# Run Sub-project 1
python sub-project-1/main.py

# Run Sub-project 2
python sub-project-2/main.py

When run independently, each sub-project will attempt to import shared utilities and functionality from the other sub-project. If successful, it will demonstrate the cross-project communication capabilities.

Project Structure

python-multi-project-architecture/
├── main.py                 # Main controller with menu interface
├── sub-project-1/          # First independent sub-project
│   ├── main.py             # Entry point for sub-project 1
│   └── project1_utils.py   # Project-specific utilities
├── sub-project-2/          # Second independent sub-project
│   ├── main.py             # Entry point for sub-project 2
│   └── project2_utils.py   # Project-specific utilities
└── shared/                 # Shared utilities accessible to all projects
    ├── __init__.py         # Python package initializer
    └── common_utils.py     # Common functions used by all projects

Component Details

  • main.py: The main entry point that presents a menu to the user and executes the selected sub-project
  • sub-project-1/: Contains all files related to the first sub-project
    • main.py: Implements sub-project 1 functionality and demonstrates importing from sub-project 2
    • project1_utils.py: Utility functions specific to sub-project 1
  • sub-project-2/: Contains all files related to the second sub-project
    • main.py: Implements sub-project 2 functionality and demonstrates importing from sub-project 1
    • project2_utils.py: Utility functions specific to sub-project 2
  • shared/: Directory containing utilities shared between all projects
    • common_utils.py: Functions that can be used by the main controller and both sub-projects

Implementation Notes

Cross-Project Imports

Cross-project imports are implemented using dynamic path manipulation:

# In sub-project main files
sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'shared'))
sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'sub-project-2'))  # or sub-project-1

This approach allows each sub-project to import functions from:

  1. The shared utilities module
  2. The other sub-project

Error Handling

Each sub-project includes error handling for import operations:

try:
    from common_utils import greet_user
    shared_utils_available = True
except ImportError:
    shared_utils_available = False
    print("Warning: Could not import shared utilities")

This ensures that sub-projects can run even if some imports fail, making them more robust.

When to Use This Approach

When to Use

This modular architecture with sys.path.append() is particularly well-suited for:

  1. Educational Projects: This approach is excellent for teaching and learning purposes, as it demonstrates fundamental concepts of modular programming and cross-module communication in a straightforward manner.

  2. Prototypes and Proof-of-Concept: When quickly building prototypes or proof-of-concept applications, this architecture allows for rapid development and easy experimentation with different module interactions.

  3. Small to Medium-Sized Projects: For projects that don't require complex dependency management, this approach provides a simple way to organize code into logical modules while maintaining flexibility.

  4. Projects with Shared Utilities: When you have common functionality that multiple independent modules need to access, this pattern allows for easy sharing without complex packaging.

  5. Exploratory Programming: For data science, scripting, or other exploratory programming tasks where you're frequently modifying and reorganizing code, this approach offers flexibility without the overhead of formal packaging.

When to Avoid

While this approach has its benefits, there are several scenarios where it should be avoided:

  1. Production Applications: For production systems where reliability and maintainability are critical, this approach is not recommended due to its runtime nature of import resolution.

  2. Large-Scale Projects: As projects grow in complexity, the lack of explicit dependency management can lead to maintenance challenges and difficulty in tracking module relationships.

  3. Projects Requiring Strict Version Control: When you need precise control over module versions and dependencies, this dynamic approach doesn't provide the necessary guarantees.

  4. Applications with Complex Packaging Requirements: For applications that will be distributed or installed by others, proper packaging with tools like setuptools is more appropriate.

  5. Team Projects with Multiple Developers: In collaborative environments, this approach can lead to confusion about module dependencies and make code reviews more challenging.

Pros and Cons

Pros

  1. Simplicity: Extremely simple to implement and understand, making it ideal for educational purposes.

  2. Flexibility: Allows for dynamic module loading and easy experimentation with different module combinations.

  3. No Complex Dependency Management: Avoids the overhead of managing complex dependency trees or virtual environments.

  4. Good for Learning: Clearly demonstrates how Python's import system works and how paths are resolved.

  5. Quick Prototyping: Enables rapid development without the need for formal package structure.

Cons

  1. Runtime Errors: Import issues are only discovered at runtime rather than at import time, which can lead to unexpected failures.

  2. Less Robust: More prone to breaking when file structures change compared to proper packaging solutions.

  3. Not Suitable for Production: Lacks the reliability and maintainability required for production systems.

  4. Can Become Difficult to Manage: In larger projects, tracking all the sys.path modifications can become challenging.

  5. IDE Support: Some IDEs may not properly recognize the dynamically added paths, leading to reduced code completion and navigation support.

Contributing

Contributions to improve this demonstration are welcome! Please follow these steps:

  1. Fork the repository
  2. Create a new branch for your feature or bug fix
  3. Make your changes and ensure they follow the existing code style
  4. Add comments explaining any complex functionality
  5. Test your changes thoroughly
  6. Submit a pull request with a clear description of your changes

Since this is an educational project, please focus on:

  • Improving clarity of the examples
  • Adding more practical use cases
  • Enhancing documentation
  • Fixing any bugs or issues

License

This project is licensed under the Apache License, Version 2.0 - see the LICENSE file for details.

The Apache License 2.0 is a permissive open-source license that allows for free use, modification, and distribution of the code, both for personal and commercial purposes. It provides additional protections compared to the MIT License, including an express grant of patent rights from contributors to users and a defense clause against patent litigation. The license requires preservation of the copyright notice and disclaimer, but does not require reproduction of the license text in distributions of the software.


This project is designed as an educational example to demonstrate modular Python architecture concepts. It is not intended for production use without significant modifications.

About

A Python demonstration of modular architecture featuring two independent sub-projects that communicate via cross-project imports. Includes shared utilities, menu-driven interface, and showcases practical patterns for organizing complex Python applications with interdependent modules.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages