Package: import-embargo
Import embargo - check your cross app importsWARNING: This is stil a WIP project. Contributors welcome.Import embargo is a tool for python applications which can check the imports across your local
packages/modules.Why would I need this?In python there is no enforced encapsulation with public/private by the python interpreter. Anyone can import anything.
This can lead to a mess in medium/large scale applications.If you strive forDomain Driven Development, this package can mark your packages public/private and check for imports which violate the encapsulation.Features:Define which packages/modules can be imported from your module/package.Define which packages/modules can be exported from your module/package.Supports Python 3.10+LimitsOnly imports with absolute paths can be checked.Usage:Output of --helpusage: main.py [-h] [--app-root APP_ROOT] [filenames ...]

positional arguments:
  filenames            List of files or directories. Example: src/module_a src/module_b

options:
  -h, --help           show this help message and exit
  --app-root APP_ROOT  Defines the root directory where your python application lives. Must be relative to the cwd path of execution of this script. Default value is current working directory. Example: --app-root=src_folderConfig fileCreate a config file called__embargo__.jsonin any module in your python app.
Example config:{"allowed_export_modules":["your_module_x.submodule"],"allowed_import_modules":["your_submodule_y"],"bypass_export_check_for_modules":[]}allowed_export_modulesModule definitions in the keyallowed_export_modulesmean which modules can be exported and imported from other modules in you app.allowed_import_modulesModule definitions in the keyallowed_import_modulesmean which modules can be imported from the checked module.bypass_export_check_for_modulesModule definition in the keybypass_export_check_for_modulesmean which modules can bypass the export check.If any key is an empty list, nothing is allowed. If the key is missing, check for import/export will be skipped.Example directorypython_app_root/
├─ payments/
│  ├─ __init__.py
│  ├─ payment_service.py
│  ├─ private_utils.py
│  ├─ __embargo__.json
│  ├─ bank/
│  │  ├─ __init__.py
│  │  ├─ private_banking_services.py/
│  ├─ credit_cards/
│  │  ├─ __init__.py
│  │  ├─ private_credit_card_services.py/
├─ users/
│  ├─ __init__.py
│  ├─ users_service.py
│  ├─ private_service.py
├─ orders/
│  ├─ __init__.py
│  ├─ orders_service.py
│  ├─ __embargo__.json
├─ __init__.pyTeam who is working on payments doesn't want other teams to accessprivate_utilsorprivate_banking_services.pydirectly.
They must go through payment_service. Withpayment-embargo, payments team can create the configpython_app_root/payments/__embargo__.jsonwith the following contents:{"allowed_export_modules":["payments.payment_service.py"]}This will allowpayments.payment_service.pyto be imported in any module, but it will fail for anything else inpaymentsmodule.Example error when someone fromorders/orders_service.pywould try to import something frompayments/private_utils.py:❌ Export violations detected

/home/user/python_app_root/orders/orders_service.py: payments.private_utils
Allowed exports: [payments.payment_service]
Config file: /home/user/python_app_root/orders/__embargo__.jsonImporting inside of a moduleWith the example config above, you would limit the exporting topayments.payment_service.py. But in the case wherepayments.payment_service.pywould import and call some function or method frompayments.bank.private_banking_services, the export check would fail, becausepayments.bank.private_banking_servicesis not exported.To bypass inter module importing, you can use the config keybypass_export_check_for_modules.{"allowed_export_modules":["payments.payment_service.py"],"bypass_export_check_for_modules":["payments"]}With this config, any inter imports (payments.payment_serviceimportingpayments.bank.private_banking_services) are allowed.Config hierarchyIf something is being imported,import-embargois going to check for__embargo__.jsonon the level of imported module. If config does not exist, it will be searched for in upper directory levels all until the specified python application root.This feature allows you to create an__embargo__.jsonfile on one level and all subdirectories will automatically be protected.In other words. When searching for config file, the first found config file will be used for checking.Will all of my imports fail if I start usingimport-embargotool?No. You can add__embargo__.jsonfiles incrementaly. If config file does not exist, all of the checks will be skipped.