This is an automated email from the ASF dual-hosted git repository.

yasithdev pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airavata-portals.git


The following commit(s) were added to refs/heads/main by this push:
     new d2d8f2b0a refactor(portal): fold airavata-django-portal-commons into 
django_airavata.commons (#111)
d2d8f2b0a is described below

commit d2d8f2b0ab03dc40a417059f072651e718d4f233
Author: Yasith Jayawardana <[email protected]>
AuthorDate: Mon Jun 8 01:17:52 2026 -0400

    refactor(portal): fold airavata-django-portal-commons into 
django_airavata.commons (#111)
    
    * refactor(portal): fold airavata-django-portal-commons into 
django_airavata.commons
    
    Move the standalone airavata-django-portal-commons package into the Django 
portal as django_airavata.commons, dropping it as a separate PyPI distribution. 
The dynamic-app loading utilities (load / merge_settings, the 
custom_app_registry context processor, and the dynamic_apps URL include) are 
behavior-unchanged - only the import path moves from 
airavata_django_portal_commons to django_airavata.commons, with settings.py, 
urls.py, the package's internal self-imports, the requirements pi [...]
    
    * fix(portal): use stdlib importlib.metadata in folded-in commons
    
    The standalone airavata-django-portal-commons declared the third-party
    importlib_metadata backport as a dependency, but the portal's requirements
    do not. Now that commons lives in the portal, import entry_points from the
    stdlib importlib.metadata instead - the selectable entry_points(group=...)
    API is available there on the portal's Python 3.10+ baseline - so no 
backport
    dependency is reintroduced. Verified with `manage.py check` on a local dev 
baseline.
---
 CLAUDE.md                                          |   3 +-
 README.md                                          |   3 -
 airavata-django-portal-commons/.gitignore          |   7 --
 airavata-django-portal-commons/MANIFEST.in         |   0
 airavata-django-portal-commons/README.md           | 111 ---------------------
 airavata-django-portal-commons/pyproject.toml      |   6 --
 airavata-django-portal-commons/setup.cfg           |  14 ---
 airavata-django-portal-commons/setup.py            |   3 -
 .../django_airavata/commons}/__init__.py           |   0
 .../commons}/dynamic_apps/__init__.py              |   2 +-
 .../commons}/dynamic_apps/context_processors.py    |   2 +-
 .../django_airavata/commons}/dynamic_apps/urls.py  |   2 +-
 airavata-django-portal/django_airavata/settings.py |   4 +-
 airavata-django-portal/django_airavata/urls.py     |   2 +-
 airavata-django-portal/requirements.txt            |   1 -
 15 files changed, 7 insertions(+), 153 deletions(-)

diff --git a/CLAUDE.md b/CLAUDE.md
index 564e66476..9a5c09a66 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -12,7 +12,6 @@ Monorepo of web portals, SDKs, and tools built on top of 
Apache Airavata. Contai
 |---------|-------|---------|
 | `airavata-django-portal` | Django 3.2 + Vue 2 | Reference science gateway 
(main portal) |
 | `airavata-django-portal-sdk` | Python | Reusable library for custom Django 
app extensions (PyPI) |
-| `airavata-django-portal-commons` | Python | Dynamic app loading and shared 
utilities (PyPI) |
 | `airavata-research-portal` | React 19 + Vite + TypeScript | CyberShuttle 
research platform (newest) |
 | `airavata-custos-portal` | Django + Vue 2 | Identity, group, and permissions 
management UI |
 | `airavata-mft-portal` | Django + Webpack | Managed File Transfer dashboard |
@@ -71,7 +70,7 @@ Each app under `django_airavata/apps/` is self-contained with 
its own frontend:
 
 - **Backend**: Django + DRF, Thrift-based Airavata client, Wagtail CMS for 
page content
 - **Frontend**: Vue 2 per app, webpack/Vue CLI builds, each app has colocated 
`static/` with its own build config
-- **Dynamic apps**: Plugin-style extensions discovered via Python entry points 
(powered by `airavata-django-portal-commons`)
+- **Dynamic apps**: Plugin-style extensions discovered via Python entry points 
(powered by `django_airavata.commons`)
 - **Web components**: Workspace app builds Vue components as reusable web 
components
 - **No business logic** — the portal is a rendering layer. All logic lives in 
the Airavata server.
 
diff --git a/README.md b/README.md
index 4788074d0..1efb67a88 100644
--- a/README.md
+++ b/README.md
@@ -14,9 +14,6 @@ This repository contains the following sub-projects and 
templates:
 - **airavata-django-portal-sdk**  
   A pluggable SDK enabling custom Django-based science gateways with minimal 
setup.
 
-- **airavata-django-portal-commons**  
-  Shared UI components and utilities used across Django-based portals.
-
 ### Starter Templates
 
 - **airavata-cookiecutter-django-app**  
diff --git a/airavata-django-portal-commons/.gitignore 
b/airavata-django-portal-commons/.gitignore
deleted file mode 100644
index 4f6cd5fa1..000000000
--- a/airavata-django-portal-commons/.gitignore
+++ /dev/null
@@ -1,7 +0,0 @@
-venv
-*.egg-info
-*.pyc
-.vscode
-build
-dist
-*.egg
diff --git a/airavata-django-portal-commons/MANIFEST.in 
b/airavata-django-portal-commons/MANIFEST.in
deleted file mode 100644
index e69de29bb..000000000
diff --git a/airavata-django-portal-commons/README.md 
b/airavata-django-portal-commons/README.md
deleted file mode 100644
index 282c1129a..000000000
--- a/airavata-django-portal-commons/README.md
+++ /dev/null
@@ -1,111 +0,0 @@
-# Airavata Django Portal Commons
-
-Utilities for working with dynamically loaded Django apps.
-
-## Getting Started
-
-Install this package with pip
-
-```
-pip install airavata-django-portal-commons
-```
-
-### Dynamically loaded Django apps
-
-1. At the end of your Django server's settings.py file add
-
-```python
-import sys
-from airavata_django_portal_commons import dynamic_apps
-
-# Add any dynamic apps installed in the virtual environment
-dynamic_apps.load(INSTALLED_APPS)
-
-# (Optional) merge WEBPACK_LOADER settings from custom Django apps
-settings_module = sys.modules[__name__]
-dynamic_apps.merge_settings(settings_module)
-```
-
-- Note: if the dynamic Django app uses WEBPACK_LOADER, keep in mind that it is
-  important that the version of
-  
[django-webpack-loader](https://github.com/django-webpack/django-webpack-loader)
-  and the version of webpack-bundle-tracker be compatible. If you're using
-  django-webpack-loader prior to version 1.0 then a known good pair of versions
-  is django-webpack-loader==0.6.0 and webpack-bundle-tracker==0.4.3.
-
-2. Also add
-   
`'airavata_django_portal_commons.dynamic_apps.context_processors.custom_app_registry'`
-   to the context_processors list:
-
-```python
-TEMPLATES = [
-    {
-        'BACKEND': 'django.template.backends.django.DjangoTemplates',
-        'DIRS': ...
-        'APP_DIRS': True,
-        'OPTIONS': {
-            'context_processors': [
-                ...
-                
'airavata_django_portal_commons.dynamic_apps.context_processors.custom_app_registry',
-            ],
-        },
-    },
-]
-```
-
-3. In your urls.py file add the following to the urlpatterns
-
-```python
-urlpatterns = [
-    # ...
-    path('', include('airavata_django_portal_commons.dynamic_apps.urls')),
-]
-```
-
-## Creating a dynamically loaded Django app
-
-See
-https://apache-airavata-django-portal.readthedocs.io/en/latest/dev/custom_django_app/
-for the latest information.
-
-Note that by default the
-[cookiecutter 
template](https://github.com/machristie/cookiecutter-airavata-django-app)
-registers Django apps under the entry_point group name of `airavata.djangoapp`,
-but you can change this. Just make sure that when you call `dynamic_apps.load`
-that you pass as the second argument the name of the entry_point group.
-
-## Developing
-
-### Making a new release
-
-1. Update the version in setup.cfg.
-2. Commit the update to setup.cfg.
-3. Tag the repo with the same version, with the format `v${version_number}`. 
For
-   example, if the version number in setup.cfg is "1.2" then tag the repo with
-   "v1.2".
-
-   ```
-   VERSION=...
-   git tag -m $VERSION $VERSION
-   git push --follow-tags
-   ```
-
-4. In a clean checkout
-
-   ```
-   cd /tmp/
-   git clone /path/to/airavata-django-portal-commons/ -b $VERSION
-   cd airavata-django-portal-commons
-   python3 -m venv venv
-   source venv/bin/activate
-   python3 -m pip install --upgrade pip build
-   python3 -m build
-   ```
-
-5. Push to pypi.org. Optionally can push to test.pypi.org. See
-   <https://packaging.python.org/tutorials/packaging-projects/> for more info.
-
-   ```
-   python3 -m pip install --upgrade twine
-   python3 -m twine upload dist/*
-   ```
diff --git a/airavata-django-portal-commons/pyproject.toml 
b/airavata-django-portal-commons/pyproject.toml
deleted file mode 100644
index 374b58cbf..000000000
--- a/airavata-django-portal-commons/pyproject.toml
+++ /dev/null
@@ -1,6 +0,0 @@
-[build-system]
-requires = [
-    "setuptools>=42",
-    "wheel"
-]
-build-backend = "setuptools.build_meta"
diff --git a/airavata-django-portal-commons/setup.cfg 
b/airavata-django-portal-commons/setup.cfg
deleted file mode 100644
index 4e82a46e5..000000000
--- a/airavata-django-portal-commons/setup.cfg
+++ /dev/null
@@ -1,14 +0,0 @@
-[metadata]
-name = airavata-django-portal-commons
-version = 1.0.3
-description = Utilities for working with dynamically loaded Django apps.
-long_description = file: README.md
-long_description_content_type = text/markdown
-
-[options]
-packages = find:
-# Include data files as specified in MANIFEST.in
-include_package_data = True
-install_requires =
-    django
-    importlib_metadata
diff --git a/airavata-django-portal-commons/setup.py 
b/airavata-django-portal-commons/setup.py
deleted file mode 100644
index b908cbe55..000000000
--- a/airavata-django-portal-commons/setup.py
+++ /dev/null
@@ -1,3 +0,0 @@
-import setuptools
-
-setuptools.setup()
diff --git 
a/airavata-django-portal-commons/airavata_django_portal_commons/__init__.py 
b/airavata-django-portal/django_airavata/commons/__init__.py
similarity index 100%
rename from 
airavata-django-portal-commons/airavata_django_portal_commons/__init__.py
rename to airavata-django-portal/django_airavata/commons/__init__.py
diff --git 
a/airavata-django-portal-commons/airavata_django_portal_commons/dynamic_apps/__init__.py
 b/airavata-django-portal/django_airavata/commons/dynamic_apps/__init__.py
similarity index 97%
rename from 
airavata-django-portal-commons/airavata_django_portal_commons/dynamic_apps/__init__.py
rename to 
airavata-django-portal/django_airavata/commons/dynamic_apps/__init__.py
index 1ba67e3c8..d0b9a8a1e 100644
--- 
a/airavata-django-portal-commons/airavata_django_portal_commons/dynamic_apps/__init__.py
+++ b/airavata-django-portal/django_airavata/commons/dynamic_apps/__init__.py
@@ -1,6 +1,6 @@
 import logging
 from importlib import import_module
-from importlib_metadata import entry_points
+from importlib.metadata import entry_points
 
 
 # AppConfig instances from custom Django apps
diff --git 
a/airavata-django-portal-commons/airavata_django_portal_commons/dynamic_apps/context_processors.py
 
b/airavata-django-portal/django_airavata/commons/dynamic_apps/context_processors.py
similarity index 98%
rename from 
airavata-django-portal-commons/airavata_django_portal_commons/dynamic_apps/context_processors.py
rename to 
airavata-django-portal/django_airavata/commons/dynamic_apps/context_processors.py
index 438016553..f43cfe9f7 100644
--- 
a/airavata-django-portal-commons/airavata_django_portal_commons/dynamic_apps/context_processors.py
+++ 
b/airavata-django-portal/django_airavata/commons/dynamic_apps/context_processors.py
@@ -3,7 +3,7 @@ from importlib import import_module
 import logging
 import re
 
-from airavata_django_portal_commons import dynamic_apps
+from django_airavata.commons import dynamic_apps
 
 logger = logging.getLogger(__name__)
 
diff --git 
a/airavata-django-portal-commons/airavata_django_portal_commons/dynamic_apps/urls.py
 b/airavata-django-portal/django_airavata/commons/dynamic_apps/urls.py
similarity index 88%
rename from 
airavata-django-portal-commons/airavata_django_portal_commons/dynamic_apps/urls.py
rename to airavata-django-portal/django_airavata/commons/dynamic_apps/urls.py
index 256a6f88c..6ce60020f 100644
--- 
a/airavata-django-portal-commons/airavata_django_portal_commons/dynamic_apps/urls.py
+++ b/airavata-django-portal/django_airavata/commons/dynamic_apps/urls.py
@@ -1,4 +1,4 @@
-from airavata_django_portal_commons import dynamic_apps
+from django_airavata.commons import dynamic_apps
 from django.conf.urls import include
 from django.urls import path
 
diff --git a/airavata-django-portal/django_airavata/settings.py 
b/airavata-django-portal/django_airavata/settings.py
index df495996a..81de01b9b 100644
--- a/airavata-django-portal/django_airavata/settings.py
+++ b/airavata-django-portal/django_airavata/settings.py
@@ -13,7 +13,7 @@ https://docs.djangoproject.com/en/1.10/ref/settings/
 import os
 import sys
 
-from airavata_django_portal_commons import dynamic_apps
+from django_airavata.commons import dynamic_apps
 
 # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
@@ -118,7 +118,7 @@ TEMPLATES = [
                 'django.contrib.auth.context_processors.auth',
                 'django.contrib.messages.context_processors.messages',
                 'django_airavata.context_processors.airavata_app_registry',
-                
'airavata_django_portal_commons.dynamic_apps.context_processors.custom_app_registry',
+                
'django_airavata.commons.dynamic_apps.context_processors.custom_app_registry',
                 'django_airavata.context_processors.get_notifications',
                 'django_airavata.context_processors.user_session_data',
                 
'django_airavata.context_processors.google_analytics_tracking_id',
diff --git a/airavata-django-portal/django_airavata/urls.py 
b/airavata-django-portal/django_airavata/urls.py
index 5c0dcf78d..5f6a043b8 100644
--- a/airavata-django-portal/django_airavata/urls.py
+++ b/airavata-django-portal/django_airavata/urls.py
@@ -41,7 +41,7 @@ urlpatterns = [
     re_path(r'^403/', views.error403),
     re_path(r'^404/', views.error404),
     re_path(r'^500/', views.error500),
-    path('', include('airavata_django_portal_commons.dynamic_apps.urls')),
+    path('', include('django_airavata.commons.dynamic_apps.urls')),
     path('', include(wagtail_urls)),
 ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
 
diff --git a/airavata-django-portal/requirements.txt 
b/airavata-django-portal/requirements.txt
index 2ef07015d..35109faeb 100644
--- a/airavata-django-portal/requirements.txt
+++ b/airavata-django-portal/requirements.txt
@@ -26,6 +26,5 @@ grpcio==1.53.2 ; python_version >= "3.7"
 
 airavata-django-portal-sdk==1.8.4
 airavata-python-sdk==2.2.7
-airavata-django-portal-commons==1.0.0
 
 -e "."

Reply via email to