django-nova 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. django_nova-0.2.0/.github/workflows/python-publish.yml +70 -0
  2. django_nova-0.2.0/.gitignore +0 -0
  3. django_nova-0.2.0/.idea/.gitignore +5 -0
  4. django_nova-0.2.0/.idea/django-nova.iml +11 -0
  5. django_nova-0.2.0/.idea/inspectionProfiles/Project_Default.xml +24 -0
  6. django_nova-0.2.0/.idea/inspectionProfiles/profiles_settings.xml +6 -0
  7. django_nova-0.2.0/.idea/markdown.xml +8 -0
  8. django_nova-0.2.0/.idea/misc.xml +7 -0
  9. django_nova-0.2.0/.idea/modules.xml +8 -0
  10. django_nova-0.2.0/.idea/shelf/Uncommitted_changes_before_Update_at_12_06_2026,_08_36_[Changes]/shelved.patch +31 -0
  11. django_nova-0.2.0/.idea/shelf/Uncommitted_changes_before_Update_at_12_06_2026__08_36__Changes_.xml +4 -0
  12. django_nova-0.2.0/.idea/vcs.xml +6 -0
  13. django_nova-0.2.0/.idea/workspace.xml +147 -0
  14. django_nova-0.2.0/CHANGELOG.md +14 -0
  15. django_nova-0.2.0/PKG-INFO +214 -0
  16. django_nova-0.2.0/README.RU.md +161 -0
  17. django_nova-0.2.0/README.md +161 -0
  18. django_nova-0.2.0/docs/architecture.md +34 -0
  19. django_nova-0.2.0/docs/index.md +60 -0
  20. django_nova-0.2.0/docs/index.svg +1 -0
  21. django_nova-0.2.0/docs/installation.md +15 -0
  22. django_nova-0.2.0/docs/installation.svg +1 -0
  23. django_nova-0.2.0/example_project/models.py +81 -0
  24. django_nova-0.2.0/pyproject.toml +89 -0
  25. django_nova-0.2.0/release.txt +134 -0
  26. django_nova-0.2.0/schemas.txt +49 -0
  27. django_nova-0.2.0/src/__init__.py +0 -0
  28. django_nova-0.2.0/src/nova/__init__.py +42 -0
  29. django_nova-0.2.0/src/nova/admin/__init__.py +0 -0
  30. django_nova-0.2.0/src/nova/admin/api.py +50 -0
  31. django_nova-0.2.0/src/nova/admin/components.py +37 -0
  32. django_nova-0.2.0/src/nova/async_orm/__init__.py +0 -0
  33. django_nova-0.2.0/src/nova/async_orm/manager.py +30 -0
  34. django_nova-0.2.0/src/nova/async_orm/queryset.py +42 -0
  35. django_nova-0.2.0/src/nova/cache/__init__.py +0 -0
  36. django_nova-0.2.0/src/nova/cache/invalidation.py +45 -0
  37. django_nova-0.2.0/src/nova/cache/queryset_cache.py +167 -0
  38. django_nova-0.2.0/src/nova/core/__init__.py +0 -0
  39. django_nova-0.2.0/src/nova/core/config.py +58 -0
  40. django_nova-0.2.0/src/nova/core/exceptions.py +69 -0
  41. django_nova-0.2.0/src/nova/core/observability.py +40 -0
  42. django_nova-0.2.0/src/nova/core/tracing.py +53 -0
  43. django_nova-0.2.0/src/nova/db/__init__.py +0 -0
  44. django_nova-0.2.0/src/nova/db/splitter.py +43 -0
  45. django_nova-0.2.0/src/nova/db/zero_downtime.py +58 -0
  46. django_nova-0.2.0/src/nova/ecosystem/__init__.py +0 -0
  47. django_nova-0.2.0/src/nova/ecosystem/drf.py +91 -0
  48. django_nova-0.2.0/src/nova/ecosystem/fastapi.py +151 -0
  49. django_nova-0.2.0/src/nova/tasks/__init__.py +0 -0
  50. django_nova-0.2.0/src/nova/tasks/decorators.py +31 -0
  51. django_nova-0.2.0/src/nova/tasks/engine.py +89 -0
  52. django_nova-0.2.0/src/nova/typing/__init__.py +0 -0
  53. django_nova-0.2.0/src/nova/typing/fields.py +33 -0
  54. django_nova-0.2.0/src/nova/typing/models.py +192 -0
  55. django_nova-0.2.0/src/nova/typing/querysets.py +33 -0
  56. django_nova-0.2.0/src/nova/validation/__init__.py +0 -0
  57. django_nova-0.2.0/src/nova/validation/pydantic_bridge.py +84 -0
  58. django_nova-0.2.0/src/nova/validation/unified.py +51 -0
  59. django_nova-0.2.0/tests/__init__.py +0 -0
  60. django_nova-0.2.0/tests/apps.py +5 -0
  61. django_nova-0.2.0/tests/cache/test_queryset_cache.py +94 -0
  62. django_nova-0.2.0/tests/conftest.py +24 -0
  63. django_nova-0.2.0/tests/core/__init__.py +0 -0
  64. django_nova-0.2.0/tests/core/test_observability.py +46 -0
  65. django_nova-0.2.0/tests/core/test_tracing.py +64 -0
  66. django_nova-0.2.0/tests/db/test_migrations.py +71 -0
  67. django_nova-0.2.0/tests/ecosystem/__init__.py +0 -0
  68. django_nova-0.2.0/tests/ecosystem/test_drf_integration.py +85 -0
  69. django_nova-0.2.0/tests/ecosystem/test_fastapi_bridge.py +68 -0
  70. django_nova-0.2.0/tests/models.py +57 -0
  71. django_nova-0.2.0/tests/test_full_integration.py +54 -0
  72. django_nova-0.2.0/tests/typing/test_typed_models.py +79 -0
@@ -0,0 +1,70 @@
1
+ # This workflow will upload a Python Package to PyPI when a release is created
2
+ # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python#publishing-to-package-registries
3
+
4
+ # This workflow uses actions that are not certified by GitHub.
5
+ # They are provided by a third-party and are governed by
6
+ # separate terms of service, privacy policy, and support
7
+ # documentation.
8
+
9
+ name: Upload Python Package
10
+
11
+ on:
12
+ release:
13
+ types: [published]
14
+
15
+ permissions:
16
+ contents: read
17
+
18
+ jobs:
19
+ release-build:
20
+ runs-on: ubuntu-latest
21
+
22
+ steps:
23
+ - uses: actions/checkout@v4
24
+
25
+ - uses: actions/setup-python@v5
26
+ with:
27
+ python-version: "3.x"
28
+
29
+ - name: Build release distributions
30
+ run: |
31
+ # NOTE: put your own distribution build steps here.
32
+ python -m pip install build
33
+ python -m build
34
+
35
+ - name: Upload distributions
36
+ uses: actions/upload-artifact@v4
37
+ with:
38
+ name: release-dists
39
+ path: dist/
40
+
41
+ pypi-publish:
42
+ runs-on: ubuntu-latest
43
+ needs:
44
+ - release-build
45
+ permissions:
46
+ # IMPORTANT: this permission is mandatory for trusted publishing
47
+ id-token: write
48
+
49
+ # Dedicated environments with protections for publishing are strongly recommended.
50
+ # For more information, see: https://docs.github.com/en/actions/deployment/targeting-different-environments/using-environments-for-deployment#deployment-protection-rules
51
+ environment:
52
+ name: pypi
53
+ # OPTIONAL: uncomment and update to include your PyPI project URL in the deployment status:
54
+ # url: https://pypi.org/p/YOURPROJECT
55
+ #
56
+ # ALTERNATIVE: if your GitHub Release name is the PyPI project version string
57
+ # ALTERNATIVE: exactly, uncomment the following line instead:
58
+ url: https://test.pypi.org/project/django-nova/0.1.0/${{ Artem Alimpiev }}
59
+
60
+ steps:
61
+ - name: Retrieve release distributions
62
+ uses: actions/download-artifact@v4
63
+ with:
64
+ name: release-dists
65
+ path: dist/
66
+
67
+ - name: Publish release distributions to PyPI
68
+ uses: pypa/gh-action-pypi-publish@release/v1
69
+ with:
70
+ packages-dir: dist/
File without changes
@@ -0,0 +1,5 @@
1
+ # Default ignored files
2
+ /shelf/
3
+ /workspace.xml
4
+ # Editor-based HTTP Client requests
5
+ /httpRequests/
@@ -0,0 +1,11 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <module type="PYTHON_MODULE" version="4">
3
+ <component name="NewModuleRootManager">
4
+ <content url="file://$MODULE_DIR$">
5
+ <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
6
+ <excludeFolder url="file://$MODULE_DIR$/.venv" />
7
+ </content>
8
+ <orderEntry type="jdk" jdkName="Python 3.12 (django-nova) (2)" jdkType="Python SDK" />
9
+ <orderEntry type="sourceFolder" forTests="false" />
10
+ </component>
11
+ </module>
@@ -0,0 +1,24 @@
1
+ <component name="InspectionProjectProfileManager">
2
+ <profile version="1.0">
3
+ <option name="myName" value="Project Default" />
4
+ <inspection_tool class="PyCompatibilityInspection" enabled="true" level="WARNING" enabled_by_default="true">
5
+ <option name="ourVersions">
6
+ <value>
7
+ <list size="2">
8
+ <item index="0" class="java.lang.String" itemvalue="2.7" />
9
+ <item index="1" class="java.lang.String" itemvalue="3.14" />
10
+ </list>
11
+ </value>
12
+ </option>
13
+ </inspection_tool>
14
+ <inspection_tool class="PyPackageRequirementsInspection" enabled="true" level="WARNING" enabled_by_default="true">
15
+ <option name="ignoredPackages">
16
+ <list>
17
+ <option value="pytest-asyn" />
18
+ <option value="cio" />
19
+ <option value="langchain-openai" />
20
+ </list>
21
+ </option>
22
+ </inspection_tool>
23
+ </profile>
24
+ </component>
@@ -0,0 +1,6 @@
1
+ <component name="InspectionProjectProfileManager">
2
+ <settings>
3
+ <option name="USE_PROJECT_PROFILE" value="false" />
4
+ <version value="1.0" />
5
+ </settings>
6
+ </component>
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="MarkdownSettings">
4
+ <option name="previewPanelProviderInfo">
5
+ <ProviderInfo name="Mermaid Studio (Chromium browser)" className="MermaidStudio_z.MermaidStudio_R.MermaidStudio_n.MermaidStudio_Q.MermaidStudio_U.MermaidStudio__.JCEFHtmlPanelProvider" />
6
+ </option>
7
+ </component>
8
+ </project>
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="Black">
4
+ <option name="sdkName" value="Python 3.12 (django-nova) (2)" />
5
+ </component>
6
+ <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.12 (django-nova) (2)" project-jdk-type="Python SDK" />
7
+ </project>
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ProjectModuleManager">
4
+ <modules>
5
+ <module fileurl="file://$PROJECT_DIR$/.idea/django-nova.iml" filepath="$PROJECT_DIR$/.idea/django-nova.iml" />
6
+ </modules>
7
+ </component>
8
+ </project>
@@ -0,0 +1,31 @@
1
+ Index: run_fastapi.py
2
+ IDEA additional info:
3
+ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
4
+ <+>UTF-8
5
+ ===================================================================
6
+ diff --git a/run_fastapi.py b/run_fastapi.py
7
+ new file mode 100644
8
+ --- /dev/null (date 1781207527557)
9
+ +++ b/run_fastapi.py (date 1781207527557)
10
+ @@ -0,0 +1,20 @@
11
+ +import django
12
+ +from django.conf import settings
13
+ +
14
+ +if not settings.configured:
15
+ + settings.configure(
16
+ + DEBUG=True,
17
+ + DATABASES={'default': {'ENGINE': 'django.db.backends.sqlite3', 'NAME': ':memory:'}},
18
+ + INSTALLED_APPS=['django.contrib.contenttypes', 'django.contrib.auth', 'nova', 'tests.apps.TestsConfig'],
19
+ + SECRET_KEY='test', USE_TZ=True,
20
+ + )
21
+ +django.setup()
22
+ +
23
+ +from fastapi import FastAPI
24
+ +from nova.ecosystem.fastapi import to_fastapi_router
25
+ +from tests.models import Lab
26
+ +
27
+ +app = FastAPI(title="Django Nova OpenAPI Demo", version="0.1.0")
28
+ +app.include_router(to_fastapi_router(Lab, prefix="/api/labs"))
29
+ +
30
+ +# ะ—ะฐะฟัƒัะบ: uvicorn run_fastapi:app --reload
31
+
@@ -0,0 +1,4 @@
1
+ <changelist name="Uncommitted_changes_before_Update_at_12_06_2026,_08_36_[Changes]" date="1781242616719" recycled="false" toDelete="true">
2
+ <option name="PATH" value="$PROJECT_DIR$/.idea/shelf/Uncommitted_changes_before_Update_at_12_06_2026,_08_36_[Changes]/shelved.patch" />
3
+ <option name="DESCRIPTION" value="Uncommitted changes before Update at 12.06.2026, 08:36 [Changes]" />
4
+ </changelist>
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="VcsDirectoryMappings">
4
+ <mapping directory="$PROJECT_DIR$" vcs="Git" />
5
+ </component>
6
+ </project>
@@ -0,0 +1,147 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="AutoImportSettings">
4
+ <option name="autoReloadType" value="SELECTIVE" />
5
+ </component>
6
+ <component name="ChangeListManager">
7
+ <list default="true" id="2040f54d-711a-4dfd-88d1-7c5051d4a070" name="Changes" comment="Release v0.2.0: Enterprise Observability, DRF &amp; FastAPI Ecosystem">
8
+ <change beforePath="$PROJECT_DIR$/dist/django_nova-0.2.0-py3-none-any.whl" beforeDir="false" />
9
+ <change beforePath="$PROJECT_DIR$/dist/django_nova-0.2.0.tar.gz" beforeDir="false" />
10
+ </list>
11
+ <option name="SHOW_DIALOG" value="false" />
12
+ <option name="HIGHLIGHT_CONFLICTS" value="true" />
13
+ <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
14
+ <option name="LAST_RESOLUTION" value="IGNORE" />
15
+ </component>
16
+ <component name="FileTemplateManagerImpl">
17
+ <option name="RECENT_TEMPLATES">
18
+ <list>
19
+ <option value="Python Script" />
20
+ </list>
21
+ </option>
22
+ </component>
23
+ <component name="Git.Settings">
24
+ <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
25
+ </component>
26
+ <component name="GitHubPullRequestSearchHistory">{
27
+ &quot;lastFilter&quot;: {
28
+ &quot;state&quot;: &quot;OPEN&quot;,
29
+ &quot;assignee&quot;: &quot;Artem7898&quot;
30
+ }
31
+ }</component>
32
+ <component name="GithubPullRequestsUISettings">{
33
+ &quot;selectedUrlAndAccountId&quot;: {
34
+ &quot;url&quot;: &quot;https://github.com/Artem7898/django-nova.git&quot;,
35
+ &quot;accountId&quot;: &quot;c08155fe-f126-45fc-acbd-91240ab8f3c1&quot;
36
+ }
37
+ }</component>
38
+ <component name="McpProjectServerCommands">
39
+ <commands />
40
+ <urls />
41
+ </component>
42
+ <component name="ProjectColorInfo">{
43
+ &quot;customColor&quot;: &quot;&quot;,
44
+ &quot;associatedIndex&quot;: 2
45
+ }</component>
46
+ <component name="ProjectId" id="3CCEcBOjDYLt0mtxULic5GNBsHq" />
47
+ <component name="ProjectViewState">
48
+ <option name="hideEmptyMiddlePackages" value="true" />
49
+ <option name="showLibraryContents" value="true" />
50
+ </component>
51
+ <component name="PropertiesComponent">{
52
+ &quot;keyToString&quot;: {
53
+ &quot;ModuleVcsDetector.initialDetectionPerformed&quot;: &quot;true&quot;,
54
+ &quot;RunOnceActivity.MCP Project settings loaded&quot;: &quot;true&quot;,
55
+ &quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;,
56
+ &quot;RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252&quot;: &quot;true&quot;,
57
+ &quot;RunOnceActivity.git.unshallow&quot;: &quot;true&quot;,
58
+ &quot;RunOnceActivity.typescript.service.memoryLimit.init&quot;: &quot;true&quot;,
59
+ &quot;codeWithMe.voiceChat.enabledByDefault&quot;: &quot;false&quot;,
60
+ &quot;git-widget-placeholder&quot;: &quot;main&quot;,
61
+ &quot;last_opened_file_path&quot;: &quot;/home/atrem/PycharmProjects/django-nova&quot;,
62
+ &quot;node.js.detected.package.eslint&quot;: &quot;true&quot;,
63
+ &quot;node.js.detected.package.tslint&quot;: &quot;true&quot;,
64
+ &quot;node.js.selected.package.eslint&quot;: &quot;(autodetect)&quot;,
65
+ &quot;node.js.selected.package.tslint&quot;: &quot;(autodetect)&quot;,
66
+ &quot;nodejs_package_manager_path&quot;: &quot;npm&quot;,
67
+ &quot;settings.editor.selected.configurable&quot;: &quot;com.jetbrains.python.configuration.PyActiveSdkModuleConfigurable&quot;
68
+ }
69
+ }</component>
70
+ <component name="SharedIndexes">
71
+ <attachedChunks>
72
+ <set>
73
+ <option value="bundled-python-sdk-024ed6589d45-c2ffad84badb-com.jetbrains.pycharm.pro.sharedIndexes.bundled-PY-261.23567.174" />
74
+ </set>
75
+ </attachedChunks>
76
+ </component>
77
+ <component name="TaskManager">
78
+ <task active="true" id="Default" summary="Default task">
79
+ <changelist id="2040f54d-711a-4dfd-88d1-7c5051d4a070" name="Changes" comment="" />
80
+ <created>1775881230494</created>
81
+ <option name="number" value="Default" />
82
+ <option name="presentableId" value="Default" />
83
+ <updated>1775881230494</updated>
84
+ </task>
85
+ <task id="LOCAL-00001" summary="Migration Safety Hardening">
86
+ <option name="closed" value="true" />
87
+ <created>1781242256699</created>
88
+ <option name="number" value="00001" />
89
+ <option name="presentableId" value="LOCAL-00001" />
90
+ <option name="project" value="LOCAL" />
91
+ <updated>1781242256699</updated>
92
+ </task>
93
+ <task id="LOCAL-00002" summary="Migration Safety Hardening">
94
+ <option name="closed" value="true" />
95
+ <created>1781243330688</created>
96
+ <option name="number" value="00002" />
97
+ <option name="presentableId" value="LOCAL-00002" />
98
+ <option name="project" value="LOCAL" />
99
+ <updated>1781243330688</updated>
100
+ </task>
101
+ <task id="LOCAL-00003" summary="Release v0.2.0: Enterprise Observability, DRF &amp; FastAPI Ecosystem">
102
+ <option name="closed" value="true" />
103
+ <created>1781246810674</created>
104
+ <option name="number" value="00003" />
105
+ <option name="presentableId" value="LOCAL-00003" />
106
+ <option name="project" value="LOCAL" />
107
+ <updated>1781246810674</updated>
108
+ </task>
109
+ <task id="LOCAL-00004" summary="Release v0.2.0: Enterprise Observability, DRF &amp; FastAPI Ecosystem">
110
+ <option name="closed" value="true" />
111
+ <created>1781255936367</created>
112
+ <option name="number" value="00004" />
113
+ <option name="presentableId" value="LOCAL-00004" />
114
+ <option name="project" value="LOCAL" />
115
+ <updated>1781255936367</updated>
116
+ </task>
117
+ <task id="LOCAL-00005" summary="Release v0.2.0: Enterprise Observability, DRF &amp; FastAPI Ecosystem">
118
+ <option name="closed" value="true" />
119
+ <created>1781256186897</created>
120
+ <option name="number" value="00005" />
121
+ <option name="presentableId" value="LOCAL-00005" />
122
+ <option name="project" value="LOCAL" />
123
+ <updated>1781256186897</updated>
124
+ </task>
125
+ <option name="localTasksCounter" value="6" />
126
+ <servers />
127
+ </component>
128
+ <component name="TypeScriptGeneratedFilesManager">
129
+ <option name="version" value="3" />
130
+ </component>
131
+ <component name="Vcs.Log.Tabs.Properties">
132
+ <option name="TAB_STATES">
133
+ <map>
134
+ <entry key="MAIN">
135
+ <value>
136
+ <State />
137
+ </value>
138
+ </entry>
139
+ </map>
140
+ </option>
141
+ </component>
142
+ <component name="VcsManagerConfiguration">
143
+ <MESSAGE value="Migration Safety Hardening" />
144
+ <MESSAGE value="Release v0.2.0: Enterprise Observability, DRF &amp; FastAPI Ecosystem" />
145
+ <option name="LAST_COMMIT_MESSAGE" value="Release v0.2.0: Enterprise Observability, DRF &amp; FastAPI Ecosystem" />
146
+ </component>
147
+ </project>
@@ -0,0 +1,14 @@
1
+ ## [0.2.0] - 2025-05-06 - "Enterprise & Ecosystem"
2
+
3
+ ### Added
4
+ - **Structured Observability:** Integrated `structlog` for machine-readable JSON logging. Cache miss/hit events now include ISO-timestamps and execution timings.
5
+ - **Distributed Tracing:** Added OpenTelemetry integration (`nova.core.tracing`). Automatic spans for `Model.save()` and `QuerySetCache` operations. Uses "Safe Import" pattern (0 overhead if OTEL is not installed).
6
+ - **Migration Safety:** Implemented `AddFieldConcurrently` and `CreateIndexConcurrently` for true zero-downtime schema changes on PostgreSQL.
7
+ - **DRF Auto-Serializer:** Added `to_drf_serializer()`. Dynamically generates Django Rest Framework `ModelSerializer` that delegates business logic validation strictly to Pydantic schemas.
8
+ - **FastAPI Auto-Router:** Added `to_fastapi_router()`. Dynamically generates FastAPI endpoints (`GET/POST`) bound to Django ORM.
9
+ - **Native OpenAPI:** FastAPI routers automatically generate perfect Swagger/OpenAPI schemas using runtime signature injection (`inspect.Signature`), bypassing PEP 563 limitations.
10
+
11
+ ### Changed
12
+ - `QuerySetCache` now uses SQL Compiler for deterministic cache key hashing (safe across all Django 5.x versions).
13
+ - `QuerySetCache` invalidation moved from hash-search to O(1) reverse index mapping.
14
+
@@ -0,0 +1,214 @@
1
+ Metadata-Version: 2.4
2
+ Name: django-nova
3
+ Version: 0.2.0
4
+ Summary: Next-generation Django toolkit: typed ORM, unified validation, async-first, smart caching
5
+ Author-email: Artem Alimpiev <alimpievne@gmail.com>
6
+ License-Expression: MIT
7
+ Classifier: Development Status :: 3 - Alpha
8
+ Classifier: Framework :: Django :: 5.0
9
+ Classifier: Framework :: Django :: 5.1
10
+ Classifier: Programming Language :: Python :: 3.12
11
+ Classifier: Programming Language :: Python :: 3.13
12
+ Classifier: Topic :: Scientific/Engineering
13
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
14
+ Requires-Python: >=3.12
15
+ Requires-Dist: asyncpg>=0.30; extra == 'async'
16
+ Requires-Dist: cachetools>=5.4
17
+ Requires-Dist: django<6.0,>=5.0
18
+ Requires-Dist: pydantic-settings<3.0,>=2.5
19
+ Requires-Dist: pydantic<3.0,>=2.8
20
+ Requires-Dist: redis>=5.0; extra == 'cache'
21
+ Requires-Dist: typing-extensions>=4.12
22
+ Provides-Extra: async
23
+ Requires-Dist: asyncpg>=0.30; extra == 'async'
24
+ Requires-Dist: databases[asyncpg]>=0.9; extra == 'async'
25
+ Provides-Extra: cache
26
+ Requires-Dist: hiredis>=3.0; extra == 'cache'
27
+ Requires-Dist: redis>=5.0; extra == 'cache'
28
+ Provides-Extra: dev
29
+ Requires-Dist: coverage>=7.6; extra == 'dev'
30
+ Requires-Dist: djangorestframework>=3.15; extra == 'dev'
31
+ Requires-Dist: fastapi>=0.115; extra == 'dev'
32
+ Requires-Dist: hatch>=1.12; extra == 'dev'
33
+ Requires-Dist: httpx>=0.27; extra == 'dev'
34
+ Requires-Dist: opentelemetry-api>=1.20; extra == 'dev'
35
+ Requires-Dist: pyright>=1.1; extra == 'dev'
36
+ Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
37
+ Requires-Dist: pytest-django>=4.9; extra == 'dev'
38
+ Requires-Dist: pytest>=8.3; extra == 'dev'
39
+ Requires-Dist: ruff>=0.6; extra == 'dev'
40
+ Requires-Dist: structlog>=24.0; extra == 'dev'
41
+ Provides-Extra: drf
42
+ Requires-Dist: djangorestframework>=3.15; extra == 'drf'
43
+ Provides-Extra: fastapi
44
+ Requires-Dist: fastapi>=0.115; extra == 'fastapi'
45
+ Requires-Dist: uvicorn>=0.30; extra == 'fastapi'
46
+ Provides-Extra: observability
47
+ Requires-Dist: structlog>=24.0; extra == 'observability'
48
+ Provides-Extra: tasks
49
+ Requires-Dist: asyncio-throttle>=1.0; extra == 'tasks'
50
+ Provides-Extra: tracing
51
+ Requires-Dist: opentelemetry-api>=1.20; extra == 'tracing'
52
+ Description-Content-Type: text/markdown
53
+
54
+ <div align="center">
55
+
56
+ # ๐Ÿš€ Django Nova
57
+
58
+ **Typed, unified, and async-first toolkit for Django 5+**
59
+
60
+ [![Python 3.12+](https://img.shields.io/badge/python-3.12%2B-blue.svg)](https://www.python.org/downloads/)
61
+ [![Django 5.0+](https://img.shields.io/badge/django-5.0%2B-green.svg)](https://www.djangoproject.com/)
62
+ [![PyPI version](https://img.shields.io/pypi/v/django-nova.svg)](https://pypi.org/project/django-nova/)
63
+ [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
64
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
65
+
66
+ *Django Nova eliminates fundamental architectural flaws in Django that lead to data corruption, runtime errors, and maintainability issues in scientific and enterprise software.*
67
+
68
+ </div>
69
+
70
+ ---
71
+
72
+ ## ๐Ÿ”‘ Key Innovations
73
+
74
+ - โœ… **Single Source of Truth:** Define validation once in Pydantic. Django Models, Forms, and APIs automatically read from it. No more duplication.
75
+ - ๐Ÿ”’ **Strict Type Safety:** Full `pyright --strict` compatibility for ORM, QuerySets, and Models using modern PEP 695 syntax.
76
+ - โšก **Smart QuerySet Cache:** Automatic O(1) cache invalidation on write via Django signals. Zero percent stale data in research pipelines.
77
+ - ๐Ÿ”„ **Zero-Downtime Migrations:** Native PostgreSQL `CONCURRENTLY` operations for locked tables containing millions of rows.
78
+ - ๐Ÿ“Š **Structured Observability:** Built-in `structlog` integration emitting machine-readable JSON logs with ISO-timestamps for Datadog/ELK.
79
+ - ๐Ÿ” **Distributed Tracing:** OpenTelemetry spans for `Model.save()` and Cache operations. Zero overhead if OTEL is not installed.
80
+ - ๐Ÿ”Œ **DRF Auto-Serializer:** Generate Django Rest Framework Serializers dynamically from Pydantic schemas. Pydantic validation overrides DRF.
81
+ - ๐Ÿš€ **FastAPI Auto-Router:** Generate fully documented FastAPI routers with native OpenAPI/Swagger from Django models.
82
+
83
+ ---
84
+
85
+ ## ๐Ÿš€ Quick Start
86
+
87
+ ### Installation
88
+
89
+ ```bash
90
+ # Core library
91
+ pip install django-nova
92
+
93
+ # With DRF support
94
+ pip install django-nova[drf]
95
+
96
+ # With FastAPI support
97
+ pip install django-nova[fastapi]
98
+
99
+ # With full enterprise stack (tracing, logging)
100
+ pip install django-nova[tracing,observability]
101
+ ```
102
+
103
+ ---
104
+
105
+ ## ๐Ÿ’ก Usage Example
106
+
107
+ ### Define your rules once, use them everywhere:
108
+
109
+ ```python
110
+ # models.py
111
+ from pydantic import BaseModel, field_validator
112
+ from django.db import models
113
+ from nova import NovaModel, NovaConfig
114
+
115
+ # 1. Define validation rules (ONCE)
116
+ class ResearcherSchema(BaseModel):
117
+ name: str
118
+ h_index: int = 0
119
+
120
+ @field_validator("h_index")
121
+ @classmethod
122
+ def validate_h_index(cls, v: int) -> int:
123
+ if v < 0:
124
+ raise ValueError("h-index cannot be negative")
125
+ return v
126
+
127
+ # 2. Link to Django
128
+ class Researcher(NovaModel):
129
+ name = models.CharField(max_length=300)
130
+ h_index = models.IntegerField(default=0)
131
+
132
+ _nova_config = NovaConfig(
133
+ pydantic_schema=ResearcherSchema,
134
+ cache_enabled=True,
135
+ strict_validation=True
136
+ )
137
+ ```
138
+
139
+ **Now, any attempt to save invalid data is blocked at the ORM level, and the schema is automatically reused in DRF and FastAPI!**
140
+
141
+ ---
142
+
143
+ ## ๐Ÿ”— Ecosystem Integration
144
+
145
+ Django Nova acts as a universal hub between Python frameworks.
146
+
147
+ ### Django Rest Framework
148
+
149
+ ```python
150
+ from nova.ecosystem.drf import to_drf_serializer
151
+
152
+ # Dynamically generates a ModelSerializer that delegates business logic to Pydantic
153
+ ResearcherSerializer = to_drf_serializer(Researcher)
154
+ ```
155
+
156
+ ### FastAPI
157
+
158
+ ```python
159
+ from fastapi import FastAPI
160
+ from nova.ecosystem.fastapi import to_fastapi_router
161
+
162
+ app = FastAPI()
163
+ # Generates GET/POST endpoints with native OpenAPI/Swagger documentation
164
+ app.include_router(to_fastapi_router(Researcher, prefix="/api/researchers"))
165
+ ```
166
+
167
+ ---
168
+
169
+ ## ๐Ÿ—๏ธ Architecture
170
+
171
+ Django Nova intercepts standard processes at the core level:
172
+
173
+ ```text
174
+ Request -> View -> Model.save() -> [Pydantic Validation -> Django Fields -> Business Logic] -> DB
175
+ |
176
+ +-> Cache Invalidation Signal -> Evict stale QuerySets
177
+ |
178
+ +-> OpenTelemetry Span -> Metrics & Traces
179
+ |
180
+ +-> Structlog -> JSON Logs to Datadog/ELK
181
+ ```
182
+
183
+ ### Core Tech Stack:
184
+
185
+ - **PEP 562:** Lazy imports bypassing AppRegistryNotReady.
186
+ - **PEP 695:** Modern generic syntax (`class Cache[T]:`).
187
+ - **SQL Compiler:** Deterministic cache hash key generation (safe across any Django version).
188
+
189
+ ---
190
+
191
+ ## ๐Ÿงช Testing
192
+
193
+ The project is tested on the bleeding-edge stack (Python 3.14 + Django 5.2).
194
+
195
+ ```bash
196
+ pip install -e ".[dev]"
197
+ pytest tests/ -v # 39 passed
198
+ ```
199
+
200
+ ---
201
+
202
+ ## ๐Ÿ‘ค Author
203
+
204
+ **Artem Alimpiev**
205
+
206
+ - ORCID: [0009-0007-6740-7242](https://orcid.org/0009-0007-6740-7242)
207
+ - DOI: [10.5281/zenodo.20057443](https://doi.org/10.5281/zenodo.20057443)
208
+ - DOI: [10.5281/zenodo.20659647](https://doi.org/10.5281/zenodo.20659647)
209
+
210
+ ---
211
+
212
+ ## ๐Ÿ“„ License
213
+
214
+ This project is licensed under the terms of the MIT License. See the [LICENSE](LICENSE) file for details.