GeneralManager 0.15.1__tar.gz → 0.16.1__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.
Potentially problematic release.
This version of GeneralManager might be problematic. Click here for more details.
- {generalmanager-0.15.1/src/GeneralManager.egg-info → generalmanager-0.16.1}/PKG-INFO +50 -84
- generalmanager-0.16.1/README.md +108 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/pyproject.toml +26 -4
- {generalmanager-0.15.1 → generalmanager-0.16.1/src/GeneralManager.egg-info}/PKG-INFO +50 -84
- {generalmanager-0.15.1 → generalmanager-0.16.1}/src/GeneralManager.egg-info/SOURCES.txt +14 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/src/GeneralManager.egg-info/requires.txt +0 -1
- generalmanager-0.16.1/src/general_manager/__init__.py +27 -0
- generalmanager-0.16.1/src/general_manager/_types/__init__.py +3 -0
- generalmanager-0.16.1/src/general_manager/_types/api.py +18 -0
- generalmanager-0.16.1/src/general_manager/_types/bucket.py +16 -0
- generalmanager-0.16.1/src/general_manager/_types/cache.py +20 -0
- generalmanager-0.16.1/src/general_manager/_types/factory.py +44 -0
- generalmanager-0.16.1/src/general_manager/_types/general_manager.py +28 -0
- generalmanager-0.16.1/src/general_manager/_types/interface.py +18 -0
- generalmanager-0.16.1/src/general_manager/_types/manager.py +18 -0
- generalmanager-0.16.1/src/general_manager/_types/measurement.py +16 -0
- generalmanager-0.16.1/src/general_manager/_types/permission.py +14 -0
- generalmanager-0.16.1/src/general_manager/_types/rule.py +12 -0
- generalmanager-0.16.1/src/general_manager/_types/utils.py +30 -0
- generalmanager-0.16.1/src/general_manager/api/__init__.py +28 -0
- generalmanager-0.16.1/src/general_manager/bucket/__init__.py +28 -0
- generalmanager-0.16.1/src/general_manager/cache/__init__.py +28 -0
- generalmanager-0.16.1/src/general_manager/factory/__init__.py +28 -0
- generalmanager-0.16.1/src/general_manager/interface/__init__.py +28 -0
- generalmanager-0.16.1/src/general_manager/manager/__init__.py +28 -0
- generalmanager-0.16.1/src/general_manager/measurement/__init__.py +28 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/src/general_manager/permission/__init__.py +8 -12
- generalmanager-0.16.1/src/general_manager/public_api_registry.py +160 -0
- generalmanager-0.16.1/src/general_manager/py.typed +0 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/src/general_manager/rule/__init__.py +7 -6
- generalmanager-0.16.1/src/general_manager/utils/__init__.py +28 -0
- generalmanager-0.15.1/README.md +0 -148
- generalmanager-0.15.1/src/general_manager/__init__.py +0 -49
- generalmanager-0.15.1/src/general_manager/api/__init__.py +0 -36
- generalmanager-0.15.1/src/general_manager/bucket/__init__.py +0 -32
- generalmanager-0.15.1/src/general_manager/cache/__init__.py +0 -38
- generalmanager-0.15.1/src/general_manager/factory/__init__.py +0 -34
- generalmanager-0.15.1/src/general_manager/interface/__init__.py +0 -36
- generalmanager-0.15.1/src/general_manager/manager/__init__.py +0 -36
- generalmanager-0.15.1/src/general_manager/measurement/__init__.py +0 -37
- generalmanager-0.15.1/src/general_manager/utils/__init__.py +0 -44
- {generalmanager-0.15.1 → generalmanager-0.16.1}/LICENSE +0 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/setup.cfg +0 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/src/GeneralManager.egg-info/dependency_links.txt +0 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/src/GeneralManager.egg-info/top_level.txt +0 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/src/general_manager/api/graphql.py +0 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/src/general_manager/api/mutation.py +0 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/src/general_manager/api/property.py +0 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/src/general_manager/apps.py +0 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/src/general_manager/bucket/baseBucket.py +0 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/src/general_manager/bucket/calculationBucket.py +0 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/src/general_manager/bucket/databaseBucket.py +0 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/src/general_manager/bucket/groupBucket.py +0 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/src/general_manager/cache/cacheDecorator.py +0 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/src/general_manager/cache/cacheTracker.py +0 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/src/general_manager/cache/dependencyIndex.py +0 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/src/general_manager/cache/modelDependencyCollector.py +0 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/src/general_manager/cache/signals.py +0 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/src/general_manager/factory/autoFactory.py +0 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/src/general_manager/factory/factories.py +0 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/src/general_manager/factory/factoryMethods.py +0 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/src/general_manager/interface/baseInterface.py +0 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/src/general_manager/interface/calculationInterface.py +0 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/src/general_manager/interface/databaseBasedInterface.py +0 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/src/general_manager/interface/databaseInterface.py +0 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/src/general_manager/interface/models.py +0 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/src/general_manager/interface/readOnlyInterface.py +0 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/src/general_manager/manager/generalManager.py +0 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/src/general_manager/manager/groupManager.py +0 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/src/general_manager/manager/input.py +0 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/src/general_manager/manager/meta.py +0 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/src/general_manager/measurement/measurement.py +0 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/src/general_manager/measurement/measurementField.py +0 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/src/general_manager/permission/basePermission.py +0 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/src/general_manager/permission/fileBasedPermission.py +0 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/src/general_manager/permission/managerBasedPermission.py +0 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/src/general_manager/permission/mutationPermission.py +0 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/src/general_manager/permission/permissionChecks.py +0 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/src/general_manager/permission/permissionDataManager.py +0 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/src/general_manager/permission/utils.py +0 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/src/general_manager/rule/handler.py +0 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/src/general_manager/rule/rule.py +0 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/src/general_manager/utils/argsToKwargs.py +0 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/src/general_manager/utils/filterParser.py +0 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/src/general_manager/utils/formatString.py +0 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/src/general_manager/utils/jsonEncoder.py +0 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/src/general_manager/utils/makeCacheKey.py +0 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/src/general_manager/utils/noneToZero.py +0 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/src/general_manager/utils/pathMapping.py +0 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/src/general_manager/utils/public_api.py +0 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/src/general_manager/utils/testing.py +0 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/tests/test_settings.py +0 -0
- {generalmanager-0.15.1 → generalmanager-0.16.1}/tests/test_urls.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: GeneralManager
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.16.1
|
|
4
4
|
Summary: Modular Django-based data management framework with ORM, GraphQL, fine-grained permissions, rule validation, calculations and caching.
|
|
5
5
|
Author-email: Tim Kleindick <tkleindick@yahoo.de>
|
|
6
6
|
License: MIT License
|
|
@@ -24,6 +24,12 @@ License: MIT License
|
|
|
24
24
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
25
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
26
|
SOFTWARE.
|
|
27
|
+
Project-URL: Homepage, https://github.com/TimKleindick/general_manager
|
|
28
|
+
Project-URL: Documentation, https://timkleindick.github.io/general_manager/
|
|
29
|
+
Project-URL: Repository, https://github.com/TimKleindick/general_manager
|
|
30
|
+
Project-URL: Issues, https://github.com/TimKleindick/general_manager/issues
|
|
31
|
+
Project-URL: Changelog, https://github.com/TimKleindick/general_manager/releases
|
|
32
|
+
Keywords: django,orm,graphql,permissions,validation,caching,framework
|
|
27
33
|
Classifier: License :: OSI Approved :: MIT License
|
|
28
34
|
Classifier: Programming Language :: Python :: 3
|
|
29
35
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
@@ -32,6 +38,7 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
32
38
|
Classifier: Framework :: Django
|
|
33
39
|
Classifier: Intended Audience :: Developers
|
|
34
40
|
Classifier: Operating System :: OS Independent
|
|
41
|
+
Classifier: Typing :: Typed
|
|
35
42
|
Requires-Python: >=3.12
|
|
36
43
|
Description-Content-Type: text/markdown
|
|
37
44
|
License-File: LICENSE
|
|
@@ -54,7 +61,6 @@ Requires-Dist: Pint>=0.24.4
|
|
|
54
61
|
Requires-Dist: platformdirs>=4.3.7
|
|
55
62
|
Requires-Dist: promise>=2.3
|
|
56
63
|
Requires-Dist: python-dateutil>=2.9.0.post0
|
|
57
|
-
Requires-Dist: setuptools==80.0.0
|
|
58
64
|
Requires-Dist: six>=1.17.0
|
|
59
65
|
Requires-Dist: smmap>=5.0.2
|
|
60
66
|
Requires-Dist: sqlparse>=0.5.3
|
|
@@ -73,135 +79,95 @@ Dynamic: license-file
|
|
|
73
79
|
|
|
74
80
|
## Overview
|
|
75
81
|
|
|
76
|
-
GeneralManager
|
|
82
|
+
GeneralManager helps teams ship complex, data-driven products on top of Django without rewriting the same plumbing for every project. It combines domain modelling, GraphQL APIs, calculations, and permission logic in one toolkit so that you can focus on business rules instead of infrastructure.
|
|
77
83
|
|
|
78
|
-
##
|
|
79
|
-
|
|
80
|
-
### 1. **Data Management**
|
|
81
|
-
- **Flexibility**: Supports managing all kinds of data, not just projects and derivatives.
|
|
82
|
-
- **Database Integration**: Seamless integration with the Django ORM for database operations.
|
|
83
|
-
- **External Interfaces**: Support for interfaces to other programs, such as Excel.
|
|
84
|
-
|
|
85
|
-
### 2. **Data Modeling**
|
|
86
|
-
- **Django Models**: The data structure is based on Django models, extended by custom fields like `MeasurementField`.
|
|
87
|
-
- **Rules and Validations**: Define rules for data validation, e.g., ensuring that a project's start date is before its end date.
|
|
84
|
+
## Documentation
|
|
88
85
|
|
|
89
|
-
|
|
90
|
-
- Automatic generation of GraphQL interfaces for all models.
|
|
91
|
-
- Support for custom queries and mutations.
|
|
86
|
+
The full documentation is published on GitHub Pages: [GeneralManager Documentation](https://timkleindick.github.io/general_manager/). It covers tutorials, concept guides, API reference, and examples.
|
|
92
87
|
|
|
93
|
-
|
|
94
|
-
- **ManagerBasedPermission**: A flexible permission system based on user roles and attributes.
|
|
95
|
-
- Attribute-level CRUD permissions.
|
|
96
|
-
|
|
97
|
-
### 5. **Interfaces**
|
|
98
|
-
- **CalculationInterface**: Allows the implementation of calculation logic.
|
|
99
|
-
- **DatabaseInterface**: Provides a standardized interface for database operations.
|
|
100
|
-
- **ReadOnlyInterface**: For read-only data access.
|
|
88
|
+
## Key Features
|
|
101
89
|
|
|
102
|
-
|
|
103
|
-
- **
|
|
104
|
-
- **
|
|
90
|
+
- **Domain-first modelling**: Describe rich business entities in plain Python and let GeneralManager project them onto the Django ORM.
|
|
91
|
+
- **GraphQL without boilerplate**: Generate a complete API, then extend it with custom queries and mutations when needed.
|
|
92
|
+
- **Attribute-based access control**: Enforce permissions with `ManagerBasedPermission` down to single fields and operations.
|
|
93
|
+
- **Deterministic calculations**: Ship reusable interfaces e.g. for volume distributions, KPI calculations, and derived data.
|
|
94
|
+
- **Factory-powered testing**: Create large, realistic datasets quickly for demos, QA, and load tests.
|
|
95
|
+
- **Composable interfaces**: Connect to databases, spreadsheets, or computed sources with the same consistent abstractions.
|
|
105
96
|
|
|
106
|
-
##
|
|
97
|
+
## Quick Start
|
|
107
98
|
|
|
108
99
|
### Installation
|
|
109
100
|
|
|
110
|
-
Install the
|
|
101
|
+
Install the package from PyPI:
|
|
111
102
|
|
|
112
103
|
```bash
|
|
113
104
|
pip install GeneralManager
|
|
114
105
|
```
|
|
115
106
|
|
|
116
|
-
###
|
|
117
|
-
|
|
118
|
-
The following example demonstrates how to create a GeneralManager and generate sample data (in this case 10 projects):
|
|
107
|
+
### Minimal example
|
|
119
108
|
|
|
120
109
|
```python
|
|
110
|
+
from datetime import date
|
|
111
|
+
from typing import Optional
|
|
112
|
+
|
|
113
|
+
from django.db.models import CharField, DateField
|
|
114
|
+
|
|
121
115
|
from general_manager import GeneralManager
|
|
122
116
|
from general_manager.interface.database import DatabaseInterface
|
|
123
|
-
from general_manager.measurement import
|
|
117
|
+
from general_manager.measurement import Measurement, MeasurementField
|
|
124
118
|
from general_manager.permission import ManagerBasedPermission
|
|
125
119
|
|
|
120
|
+
|
|
126
121
|
class Project(GeneralManager):
|
|
127
122
|
name: str
|
|
128
123
|
start_date: Optional[date]
|
|
129
124
|
end_date: Optional[date]
|
|
130
125
|
total_capex: Optional[Measurement]
|
|
131
|
-
derivative_list: DatabaseBucket[Derivative]
|
|
132
126
|
|
|
133
127
|
class Interface(DatabaseInterface):
|
|
134
128
|
name = CharField(max_length=50)
|
|
135
|
-
number = CharField(max_length=7, validators=[RegexValidator(r"^AP\d{4,5}$")])
|
|
136
|
-
description = TextField(null=True, blank=True)
|
|
137
129
|
start_date = DateField(null=True, blank=True)
|
|
138
130
|
end_date = DateField(null=True, blank=True)
|
|
139
131
|
total_capex = MeasurementField(base_unit="EUR", null=True, blank=True)
|
|
140
132
|
|
|
141
|
-
class Meta:
|
|
142
|
-
constraints = [
|
|
143
|
-
constraints.UniqueConstraint(
|
|
144
|
-
fields=["name", "number"], name="unique_booking"
|
|
145
|
-
)
|
|
146
|
-
]
|
|
147
|
-
|
|
148
|
-
rules = [
|
|
149
|
-
Rule["Project"](
|
|
150
|
-
lambda x: cast(date, x.start_date) < cast(date, x.end_date)
|
|
151
|
-
),
|
|
152
|
-
Rule["Project"](lambda x: cast(Measurement, x.total_capex) >= "0 EUR"),
|
|
153
|
-
]
|
|
154
|
-
|
|
155
|
-
class Factory:
|
|
156
|
-
name = LazyProjectName()
|
|
157
|
-
end_date = LazyDeltaDate(365 * 6, "start_date")
|
|
158
|
-
total_capex = LazyMeasurement(75_000, 1_000_000, "EUR")
|
|
159
|
-
|
|
160
133
|
class Permission(ManagerBasedPermission):
|
|
161
|
-
__read__ = ["
|
|
162
|
-
__create__ = ["
|
|
163
|
-
__update__ = ["
|
|
164
|
-
__delete__ = ["admin", "isMatchingKeyAccount", "isProjectTeamMember"]
|
|
134
|
+
__read__ = ["public"]
|
|
135
|
+
__create__ = ["isAdmin"]
|
|
136
|
+
__update__ = ["isAdmin"]
|
|
165
137
|
|
|
166
|
-
total_capex = {"update": ["isSalesResponsible", "isProjectManager"]}
|
|
167
138
|
|
|
168
139
|
Project.Factory.createBatch(10)
|
|
169
140
|
```
|
|
170
141
|
|
|
171
|
-
|
|
142
|
+
The example above defines a project model, exposes it through the auto-generated GraphQL schema, and produces ten sample records with a single call. The full documentation walks through extending this setup with custom rules, interfaces, and queries.
|
|
172
143
|
|
|
173
|
-
|
|
144
|
+
## Core Building Blocks
|
|
174
145
|
|
|
175
|
-
|
|
146
|
+
- **Entities & interfaces**: Compose domain entities with database-backed or computed interfaces to control persistence and data flows.
|
|
147
|
+
- **Rules & validation**: Protect your data with declarative constraints and business rules that run automatically.
|
|
148
|
+
- **Permissions**: Implement attribute-based access control with reusable policies that match your organisation’s roles.
|
|
149
|
+
- **GraphQL layer**: Serve a typed schema that mirrors your models and stays in sync as you iterate.
|
|
150
|
+
- **Caching & calculations**: Use the built-in caching decorator and calculation helpers to keep derived data fast and reliable.
|
|
176
151
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
totalCapex {
|
|
184
|
-
value
|
|
185
|
-
unit
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
```
|
|
152
|
+
## Production-Ready Extras
|
|
153
|
+
|
|
154
|
+
- Works with Postgres, SQLite, and any database supported by Django.
|
|
155
|
+
- Plays nicely with CI thanks to deterministic factories, typing, and code coverage.
|
|
156
|
+
- Ships with MkDocs documentation, auto-generated API reference, and a growing cookbook of recipes.
|
|
157
|
+
- Designed for teams: opinionated defaults without blocking custom extensions or overrides.
|
|
190
158
|
|
|
191
|
-
##
|
|
159
|
+
## Use Cases
|
|
192
160
|
|
|
193
|
-
-
|
|
194
|
-
-
|
|
195
|
-
-
|
|
196
|
-
-
|
|
197
|
-
- **Data Validation**: Automatic validation of data through rules and constraints.
|
|
198
|
-
- **Caching**: Automatic cache generation with the `@cached` decorator to improve performance.
|
|
161
|
+
- Internal tooling that mirrors real-world workflows, pricing models, or asset hierarchies.
|
|
162
|
+
- Customer-facing platforms that combine transactional data with live calculations.
|
|
163
|
+
- Analytics products that need controlled data sharing between teams or clients.
|
|
164
|
+
- Proof-of-concept projects that must scale into production without a rewrite.
|
|
199
165
|
|
|
200
166
|
## Requirements
|
|
201
167
|
|
|
202
168
|
- Python >= 3.12
|
|
203
169
|
- Django >= 5.2
|
|
204
|
-
- Additional dependencies (see `requirements.txt`):
|
|
170
|
+
- Additional dependencies (see `requirements/base.txt`):
|
|
205
171
|
- `graphene`
|
|
206
172
|
- `numpy`
|
|
207
173
|
- `Pint`
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# GeneralManager
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/GeneralManager/)
|
|
4
|
+
[](https://pypi.org/project/GeneralManager/)
|
|
5
|
+
[](https://github.com/TimKleindick/general_manager/actions/workflows/test.yml)
|
|
6
|
+
[](https://app.codecov.io/gh/TimKleindick/general_manager)
|
|
7
|
+
[](LICENSE)
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
GeneralManager helps teams ship complex, data-driven products on top of Django without rewriting the same plumbing for every project. It combines domain modelling, GraphQL APIs, calculations, and permission logic in one toolkit so that you can focus on business rules instead of infrastructure.
|
|
12
|
+
|
|
13
|
+
## Documentation
|
|
14
|
+
|
|
15
|
+
The full documentation is published on GitHub Pages: [GeneralManager Documentation](https://timkleindick.github.io/general_manager/). It covers tutorials, concept guides, API reference, and examples.
|
|
16
|
+
|
|
17
|
+
## Key Features
|
|
18
|
+
|
|
19
|
+
- **Domain-first modelling**: Describe rich business entities in plain Python and let GeneralManager project them onto the Django ORM.
|
|
20
|
+
- **GraphQL without boilerplate**: Generate a complete API, then extend it with custom queries and mutations when needed.
|
|
21
|
+
- **Attribute-based access control**: Enforce permissions with `ManagerBasedPermission` down to single fields and operations.
|
|
22
|
+
- **Deterministic calculations**: Ship reusable interfaces e.g. for volume distributions, KPI calculations, and derived data.
|
|
23
|
+
- **Factory-powered testing**: Create large, realistic datasets quickly for demos, QA, and load tests.
|
|
24
|
+
- **Composable interfaces**: Connect to databases, spreadsheets, or computed sources with the same consistent abstractions.
|
|
25
|
+
|
|
26
|
+
## Quick Start
|
|
27
|
+
|
|
28
|
+
### Installation
|
|
29
|
+
|
|
30
|
+
Install the package from PyPI:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
pip install GeneralManager
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Minimal example
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
from datetime import date
|
|
40
|
+
from typing import Optional
|
|
41
|
+
|
|
42
|
+
from django.db.models import CharField, DateField
|
|
43
|
+
|
|
44
|
+
from general_manager import GeneralManager
|
|
45
|
+
from general_manager.interface.database import DatabaseInterface
|
|
46
|
+
from general_manager.measurement import Measurement, MeasurementField
|
|
47
|
+
from general_manager.permission import ManagerBasedPermission
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class Project(GeneralManager):
|
|
51
|
+
name: str
|
|
52
|
+
start_date: Optional[date]
|
|
53
|
+
end_date: Optional[date]
|
|
54
|
+
total_capex: Optional[Measurement]
|
|
55
|
+
|
|
56
|
+
class Interface(DatabaseInterface):
|
|
57
|
+
name = CharField(max_length=50)
|
|
58
|
+
start_date = DateField(null=True, blank=True)
|
|
59
|
+
end_date = DateField(null=True, blank=True)
|
|
60
|
+
total_capex = MeasurementField(base_unit="EUR", null=True, blank=True)
|
|
61
|
+
|
|
62
|
+
class Permission(ManagerBasedPermission):
|
|
63
|
+
__read__ = ["public"]
|
|
64
|
+
__create__ = ["isAdmin"]
|
|
65
|
+
__update__ = ["isAdmin"]
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
Project.Factory.createBatch(10)
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
The example above defines a project model, exposes it through the auto-generated GraphQL schema, and produces ten sample records with a single call. The full documentation walks through extending this setup with custom rules, interfaces, and queries.
|
|
72
|
+
|
|
73
|
+
## Core Building Blocks
|
|
74
|
+
|
|
75
|
+
- **Entities & interfaces**: Compose domain entities with database-backed or computed interfaces to control persistence and data flows.
|
|
76
|
+
- **Rules & validation**: Protect your data with declarative constraints and business rules that run automatically.
|
|
77
|
+
- **Permissions**: Implement attribute-based access control with reusable policies that match your organisation’s roles.
|
|
78
|
+
- **GraphQL layer**: Serve a typed schema that mirrors your models and stays in sync as you iterate.
|
|
79
|
+
- **Caching & calculations**: Use the built-in caching decorator and calculation helpers to keep derived data fast and reliable.
|
|
80
|
+
|
|
81
|
+
## Production-Ready Extras
|
|
82
|
+
|
|
83
|
+
- Works with Postgres, SQLite, and any database supported by Django.
|
|
84
|
+
- Plays nicely with CI thanks to deterministic factories, typing, and code coverage.
|
|
85
|
+
- Ships with MkDocs documentation, auto-generated API reference, and a growing cookbook of recipes.
|
|
86
|
+
- Designed for teams: opinionated defaults without blocking custom extensions or overrides.
|
|
87
|
+
|
|
88
|
+
## Use Cases
|
|
89
|
+
|
|
90
|
+
- Internal tooling that mirrors real-world workflows, pricing models, or asset hierarchies.
|
|
91
|
+
- Customer-facing platforms that combine transactional data with live calculations.
|
|
92
|
+
- Analytics products that need controlled data sharing between teams or clients.
|
|
93
|
+
- Proof-of-concept projects that must scale into production without a rewrite.
|
|
94
|
+
|
|
95
|
+
## Requirements
|
|
96
|
+
|
|
97
|
+
- Python >= 3.12
|
|
98
|
+
- Django >= 5.2
|
|
99
|
+
- Additional dependencies (see `requirements/base.txt`):
|
|
100
|
+
- `graphene`
|
|
101
|
+
- `numpy`
|
|
102
|
+
- `Pint`
|
|
103
|
+
- `factory_boy`
|
|
104
|
+
- and more.
|
|
105
|
+
|
|
106
|
+
## License
|
|
107
|
+
|
|
108
|
+
This project is distributed under the **MIT License**. For further details see the [LICENSE](./LICENSE) file.
|
|
@@ -1,14 +1,24 @@
|
|
|
1
1
|
[build-system]
|
|
2
|
-
requires = ["setuptools>=
|
|
2
|
+
requires = ["setuptools>=68", "wheel"]
|
|
3
3
|
build-backend = "setuptools.build_meta"
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "GeneralManager"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.16.1"
|
|
8
8
|
description = "Modular Django-based data management framework with ORM, GraphQL, fine-grained permissions, rule validation, calculations and caching."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
authors = [{ name = "Tim Kleindick", email = "tkleindick@yahoo.de" }]
|
|
11
11
|
license = { file = "LICENSE" }
|
|
12
|
+
requires-python = ">=3.12"
|
|
13
|
+
keywords = [
|
|
14
|
+
"django",
|
|
15
|
+
"orm",
|
|
16
|
+
"graphql",
|
|
17
|
+
"permissions",
|
|
18
|
+
"validation",
|
|
19
|
+
"caching",
|
|
20
|
+
"framework",
|
|
21
|
+
]
|
|
12
22
|
classifiers = [
|
|
13
23
|
"License :: OSI Approved :: MIT License",
|
|
14
24
|
"Programming Language :: Python :: 3",
|
|
@@ -18,8 +28,8 @@ classifiers = [
|
|
|
18
28
|
"Framework :: Django",
|
|
19
29
|
"Intended Audience :: Developers",
|
|
20
30
|
"Operating System :: OS Independent",
|
|
31
|
+
"Typing :: Typed",
|
|
21
32
|
]
|
|
22
|
-
requires-python = ">=3.12"
|
|
23
33
|
dependencies = [
|
|
24
34
|
"asgiref>=3.8.1",
|
|
25
35
|
"Django>=5.2.7",
|
|
@@ -40,7 +50,6 @@ dependencies = [
|
|
|
40
50
|
"platformdirs>=4.3.7",
|
|
41
51
|
"promise>=2.3",
|
|
42
52
|
"python-dateutil>=2.9.0.post0",
|
|
43
|
-
"setuptools==80.0.0",
|
|
44
53
|
"six>=1.17.0",
|
|
45
54
|
"smmap>=5.0.2",
|
|
46
55
|
"sqlparse>=0.5.3",
|
|
@@ -49,9 +58,22 @@ dependencies = [
|
|
|
49
58
|
"tzdata>=2025.2",
|
|
50
59
|
]
|
|
51
60
|
|
|
61
|
+
[project.urls]
|
|
62
|
+
Homepage = "https://github.com/TimKleindick/general_manager"
|
|
63
|
+
Documentation = "https://timkleindick.github.io/general_manager/"
|
|
64
|
+
Repository = "https://github.com/TimKleindick/general_manager"
|
|
65
|
+
Issues = "https://github.com/TimKleindick/general_manager/issues"
|
|
66
|
+
Changelog = "https://github.com/TimKleindick/general_manager/releases"
|
|
67
|
+
|
|
68
|
+
[tool.setuptools]
|
|
69
|
+
include-package-data = true
|
|
70
|
+
|
|
52
71
|
[tool.setuptools.packages.find]
|
|
53
72
|
where = ["src"]
|
|
54
73
|
|
|
74
|
+
[tool.setuptools.package-data]
|
|
75
|
+
"general_manager" = ["py.typed"]
|
|
76
|
+
|
|
55
77
|
[tool.semantic_release]
|
|
56
78
|
allow_zero_version = true
|
|
57
79
|
major_on_zero = false
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: GeneralManager
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.16.1
|
|
4
4
|
Summary: Modular Django-based data management framework with ORM, GraphQL, fine-grained permissions, rule validation, calculations and caching.
|
|
5
5
|
Author-email: Tim Kleindick <tkleindick@yahoo.de>
|
|
6
6
|
License: MIT License
|
|
@@ -24,6 +24,12 @@ License: MIT License
|
|
|
24
24
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
25
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
26
|
SOFTWARE.
|
|
27
|
+
Project-URL: Homepage, https://github.com/TimKleindick/general_manager
|
|
28
|
+
Project-URL: Documentation, https://timkleindick.github.io/general_manager/
|
|
29
|
+
Project-URL: Repository, https://github.com/TimKleindick/general_manager
|
|
30
|
+
Project-URL: Issues, https://github.com/TimKleindick/general_manager/issues
|
|
31
|
+
Project-URL: Changelog, https://github.com/TimKleindick/general_manager/releases
|
|
32
|
+
Keywords: django,orm,graphql,permissions,validation,caching,framework
|
|
27
33
|
Classifier: License :: OSI Approved :: MIT License
|
|
28
34
|
Classifier: Programming Language :: Python :: 3
|
|
29
35
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
@@ -32,6 +38,7 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
32
38
|
Classifier: Framework :: Django
|
|
33
39
|
Classifier: Intended Audience :: Developers
|
|
34
40
|
Classifier: Operating System :: OS Independent
|
|
41
|
+
Classifier: Typing :: Typed
|
|
35
42
|
Requires-Python: >=3.12
|
|
36
43
|
Description-Content-Type: text/markdown
|
|
37
44
|
License-File: LICENSE
|
|
@@ -54,7 +61,6 @@ Requires-Dist: Pint>=0.24.4
|
|
|
54
61
|
Requires-Dist: platformdirs>=4.3.7
|
|
55
62
|
Requires-Dist: promise>=2.3
|
|
56
63
|
Requires-Dist: python-dateutil>=2.9.0.post0
|
|
57
|
-
Requires-Dist: setuptools==80.0.0
|
|
58
64
|
Requires-Dist: six>=1.17.0
|
|
59
65
|
Requires-Dist: smmap>=5.0.2
|
|
60
66
|
Requires-Dist: sqlparse>=0.5.3
|
|
@@ -73,135 +79,95 @@ Dynamic: license-file
|
|
|
73
79
|
|
|
74
80
|
## Overview
|
|
75
81
|
|
|
76
|
-
GeneralManager
|
|
82
|
+
GeneralManager helps teams ship complex, data-driven products on top of Django without rewriting the same plumbing for every project. It combines domain modelling, GraphQL APIs, calculations, and permission logic in one toolkit so that you can focus on business rules instead of infrastructure.
|
|
77
83
|
|
|
78
|
-
##
|
|
79
|
-
|
|
80
|
-
### 1. **Data Management**
|
|
81
|
-
- **Flexibility**: Supports managing all kinds of data, not just projects and derivatives.
|
|
82
|
-
- **Database Integration**: Seamless integration with the Django ORM for database operations.
|
|
83
|
-
- **External Interfaces**: Support for interfaces to other programs, such as Excel.
|
|
84
|
-
|
|
85
|
-
### 2. **Data Modeling**
|
|
86
|
-
- **Django Models**: The data structure is based on Django models, extended by custom fields like `MeasurementField`.
|
|
87
|
-
- **Rules and Validations**: Define rules for data validation, e.g., ensuring that a project's start date is before its end date.
|
|
84
|
+
## Documentation
|
|
88
85
|
|
|
89
|
-
|
|
90
|
-
- Automatic generation of GraphQL interfaces for all models.
|
|
91
|
-
- Support for custom queries and mutations.
|
|
86
|
+
The full documentation is published on GitHub Pages: [GeneralManager Documentation](https://timkleindick.github.io/general_manager/). It covers tutorials, concept guides, API reference, and examples.
|
|
92
87
|
|
|
93
|
-
|
|
94
|
-
- **ManagerBasedPermission**: A flexible permission system based on user roles and attributes.
|
|
95
|
-
- Attribute-level CRUD permissions.
|
|
96
|
-
|
|
97
|
-
### 5. **Interfaces**
|
|
98
|
-
- **CalculationInterface**: Allows the implementation of calculation logic.
|
|
99
|
-
- **DatabaseInterface**: Provides a standardized interface for database operations.
|
|
100
|
-
- **ReadOnlyInterface**: For read-only data access.
|
|
88
|
+
## Key Features
|
|
101
89
|
|
|
102
|
-
|
|
103
|
-
- **
|
|
104
|
-
- **
|
|
90
|
+
- **Domain-first modelling**: Describe rich business entities in plain Python and let GeneralManager project them onto the Django ORM.
|
|
91
|
+
- **GraphQL without boilerplate**: Generate a complete API, then extend it with custom queries and mutations when needed.
|
|
92
|
+
- **Attribute-based access control**: Enforce permissions with `ManagerBasedPermission` down to single fields and operations.
|
|
93
|
+
- **Deterministic calculations**: Ship reusable interfaces e.g. for volume distributions, KPI calculations, and derived data.
|
|
94
|
+
- **Factory-powered testing**: Create large, realistic datasets quickly for demos, QA, and load tests.
|
|
95
|
+
- **Composable interfaces**: Connect to databases, spreadsheets, or computed sources with the same consistent abstractions.
|
|
105
96
|
|
|
106
|
-
##
|
|
97
|
+
## Quick Start
|
|
107
98
|
|
|
108
99
|
### Installation
|
|
109
100
|
|
|
110
|
-
Install the
|
|
101
|
+
Install the package from PyPI:
|
|
111
102
|
|
|
112
103
|
```bash
|
|
113
104
|
pip install GeneralManager
|
|
114
105
|
```
|
|
115
106
|
|
|
116
|
-
###
|
|
117
|
-
|
|
118
|
-
The following example demonstrates how to create a GeneralManager and generate sample data (in this case 10 projects):
|
|
107
|
+
### Minimal example
|
|
119
108
|
|
|
120
109
|
```python
|
|
110
|
+
from datetime import date
|
|
111
|
+
from typing import Optional
|
|
112
|
+
|
|
113
|
+
from django.db.models import CharField, DateField
|
|
114
|
+
|
|
121
115
|
from general_manager import GeneralManager
|
|
122
116
|
from general_manager.interface.database import DatabaseInterface
|
|
123
|
-
from general_manager.measurement import
|
|
117
|
+
from general_manager.measurement import Measurement, MeasurementField
|
|
124
118
|
from general_manager.permission import ManagerBasedPermission
|
|
125
119
|
|
|
120
|
+
|
|
126
121
|
class Project(GeneralManager):
|
|
127
122
|
name: str
|
|
128
123
|
start_date: Optional[date]
|
|
129
124
|
end_date: Optional[date]
|
|
130
125
|
total_capex: Optional[Measurement]
|
|
131
|
-
derivative_list: DatabaseBucket[Derivative]
|
|
132
126
|
|
|
133
127
|
class Interface(DatabaseInterface):
|
|
134
128
|
name = CharField(max_length=50)
|
|
135
|
-
number = CharField(max_length=7, validators=[RegexValidator(r"^AP\d{4,5}$")])
|
|
136
|
-
description = TextField(null=True, blank=True)
|
|
137
129
|
start_date = DateField(null=True, blank=True)
|
|
138
130
|
end_date = DateField(null=True, blank=True)
|
|
139
131
|
total_capex = MeasurementField(base_unit="EUR", null=True, blank=True)
|
|
140
132
|
|
|
141
|
-
class Meta:
|
|
142
|
-
constraints = [
|
|
143
|
-
constraints.UniqueConstraint(
|
|
144
|
-
fields=["name", "number"], name="unique_booking"
|
|
145
|
-
)
|
|
146
|
-
]
|
|
147
|
-
|
|
148
|
-
rules = [
|
|
149
|
-
Rule["Project"](
|
|
150
|
-
lambda x: cast(date, x.start_date) < cast(date, x.end_date)
|
|
151
|
-
),
|
|
152
|
-
Rule["Project"](lambda x: cast(Measurement, x.total_capex) >= "0 EUR"),
|
|
153
|
-
]
|
|
154
|
-
|
|
155
|
-
class Factory:
|
|
156
|
-
name = LazyProjectName()
|
|
157
|
-
end_date = LazyDeltaDate(365 * 6, "start_date")
|
|
158
|
-
total_capex = LazyMeasurement(75_000, 1_000_000, "EUR")
|
|
159
|
-
|
|
160
133
|
class Permission(ManagerBasedPermission):
|
|
161
|
-
__read__ = ["
|
|
162
|
-
__create__ = ["
|
|
163
|
-
__update__ = ["
|
|
164
|
-
__delete__ = ["admin", "isMatchingKeyAccount", "isProjectTeamMember"]
|
|
134
|
+
__read__ = ["public"]
|
|
135
|
+
__create__ = ["isAdmin"]
|
|
136
|
+
__update__ = ["isAdmin"]
|
|
165
137
|
|
|
166
|
-
total_capex = {"update": ["isSalesResponsible", "isProjectManager"]}
|
|
167
138
|
|
|
168
139
|
Project.Factory.createBatch(10)
|
|
169
140
|
```
|
|
170
141
|
|
|
171
|
-
|
|
142
|
+
The example above defines a project model, exposes it through the auto-generated GraphQL schema, and produces ten sample records with a single call. The full documentation walks through extending this setup with custom rules, interfaces, and queries.
|
|
172
143
|
|
|
173
|
-
|
|
144
|
+
## Core Building Blocks
|
|
174
145
|
|
|
175
|
-
|
|
146
|
+
- **Entities & interfaces**: Compose domain entities with database-backed or computed interfaces to control persistence and data flows.
|
|
147
|
+
- **Rules & validation**: Protect your data with declarative constraints and business rules that run automatically.
|
|
148
|
+
- **Permissions**: Implement attribute-based access control with reusable policies that match your organisation’s roles.
|
|
149
|
+
- **GraphQL layer**: Serve a typed schema that mirrors your models and stays in sync as you iterate.
|
|
150
|
+
- **Caching & calculations**: Use the built-in caching decorator and calculation helpers to keep derived data fast and reliable.
|
|
176
151
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
totalCapex {
|
|
184
|
-
value
|
|
185
|
-
unit
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
```
|
|
152
|
+
## Production-Ready Extras
|
|
153
|
+
|
|
154
|
+
- Works with Postgres, SQLite, and any database supported by Django.
|
|
155
|
+
- Plays nicely with CI thanks to deterministic factories, typing, and code coverage.
|
|
156
|
+
- Ships with MkDocs documentation, auto-generated API reference, and a growing cookbook of recipes.
|
|
157
|
+
- Designed for teams: opinionated defaults without blocking custom extensions or overrides.
|
|
190
158
|
|
|
191
|
-
##
|
|
159
|
+
## Use Cases
|
|
192
160
|
|
|
193
|
-
-
|
|
194
|
-
-
|
|
195
|
-
-
|
|
196
|
-
-
|
|
197
|
-
- **Data Validation**: Automatic validation of data through rules and constraints.
|
|
198
|
-
- **Caching**: Automatic cache generation with the `@cached` decorator to improve performance.
|
|
161
|
+
- Internal tooling that mirrors real-world workflows, pricing models, or asset hierarchies.
|
|
162
|
+
- Customer-facing platforms that combine transactional data with live calculations.
|
|
163
|
+
- Analytics products that need controlled data sharing between teams or clients.
|
|
164
|
+
- Proof-of-concept projects that must scale into production without a rewrite.
|
|
199
165
|
|
|
200
166
|
## Requirements
|
|
201
167
|
|
|
202
168
|
- Python >= 3.12
|
|
203
169
|
- Django >= 5.2
|
|
204
|
-
- Additional dependencies (see `requirements.txt`):
|
|
170
|
+
- Additional dependencies (see `requirements/base.txt`):
|
|
205
171
|
- `graphene`
|
|
206
172
|
- `numpy`
|
|
207
173
|
- `Pint`
|
|
@@ -8,6 +8,20 @@ src/GeneralManager.egg-info/requires.txt
|
|
|
8
8
|
src/GeneralManager.egg-info/top_level.txt
|
|
9
9
|
src/general_manager/__init__.py
|
|
10
10
|
src/general_manager/apps.py
|
|
11
|
+
src/general_manager/public_api_registry.py
|
|
12
|
+
src/general_manager/py.typed
|
|
13
|
+
src/general_manager/_types/__init__.py
|
|
14
|
+
src/general_manager/_types/api.py
|
|
15
|
+
src/general_manager/_types/bucket.py
|
|
16
|
+
src/general_manager/_types/cache.py
|
|
17
|
+
src/general_manager/_types/factory.py
|
|
18
|
+
src/general_manager/_types/general_manager.py
|
|
19
|
+
src/general_manager/_types/interface.py
|
|
20
|
+
src/general_manager/_types/manager.py
|
|
21
|
+
src/general_manager/_types/measurement.py
|
|
22
|
+
src/general_manager/_types/permission.py
|
|
23
|
+
src/general_manager/_types/rule.py
|
|
24
|
+
src/general_manager/_types/utils.py
|
|
11
25
|
src/general_manager/api/__init__.py
|
|
12
26
|
src/general_manager/api/graphql.py
|
|
13
27
|
src/general_manager/api/mutation.py
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""Convenience access to GeneralManager core components."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import TYPE_CHECKING, Any
|
|
6
|
+
|
|
7
|
+
from general_manager.public_api_registry import GENERAL_MANAGER_EXPORTS
|
|
8
|
+
from general_manager.utils.public_api import build_module_dir, resolve_export
|
|
9
|
+
|
|
10
|
+
__all__ = list(GENERAL_MANAGER_EXPORTS)
|
|
11
|
+
|
|
12
|
+
_MODULE_MAP = GENERAL_MANAGER_EXPORTS
|
|
13
|
+
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from general_manager._types.general_manager import * # noqa: F401,F403
|
|
16
|
+
|
|
17
|
+
def __getattr__(name: str) -> Any:
|
|
18
|
+
return resolve_export(
|
|
19
|
+
name,
|
|
20
|
+
module_all=__all__,
|
|
21
|
+
module_map=_MODULE_MAP,
|
|
22
|
+
module_globals=globals(),
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def __dir__() -> list[str]:
|
|
27
|
+
return build_module_dir(module_all=__all__, module_globals=globals())
|