GeneralManager 0.15.1__tar.gz → 0.16.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.

Potentially problematic release.


This version of GeneralManager might be problematic. Click here for more details.

Files changed (92) hide show
  1. {generalmanager-0.15.1/src/GeneralManager.egg-info → generalmanager-0.16.0}/PKG-INFO +42 -82
  2. generalmanager-0.16.0/README.md +108 -0
  3. {generalmanager-0.15.1 → generalmanager-0.16.0}/pyproject.toml +1 -1
  4. {generalmanager-0.15.1 → generalmanager-0.16.0/src/GeneralManager.egg-info}/PKG-INFO +42 -82
  5. {generalmanager-0.15.1 → generalmanager-0.16.0}/src/GeneralManager.egg-info/SOURCES.txt +13 -0
  6. generalmanager-0.16.0/src/general_manager/__init__.py +27 -0
  7. generalmanager-0.16.0/src/general_manager/_types/__init__.py +3 -0
  8. generalmanager-0.16.0/src/general_manager/_types/api.py +18 -0
  9. generalmanager-0.16.0/src/general_manager/_types/bucket.py +16 -0
  10. generalmanager-0.16.0/src/general_manager/_types/cache.py +20 -0
  11. generalmanager-0.16.0/src/general_manager/_types/factory.py +44 -0
  12. generalmanager-0.16.0/src/general_manager/_types/general_manager.py +28 -0
  13. generalmanager-0.16.0/src/general_manager/_types/interface.py +18 -0
  14. generalmanager-0.16.0/src/general_manager/_types/manager.py +18 -0
  15. generalmanager-0.16.0/src/general_manager/_types/measurement.py +16 -0
  16. generalmanager-0.16.0/src/general_manager/_types/permission.py +14 -0
  17. generalmanager-0.16.0/src/general_manager/_types/rule.py +12 -0
  18. generalmanager-0.16.0/src/general_manager/_types/utils.py +30 -0
  19. generalmanager-0.16.0/src/general_manager/api/__init__.py +28 -0
  20. generalmanager-0.16.0/src/general_manager/bucket/__init__.py +28 -0
  21. generalmanager-0.16.0/src/general_manager/cache/__init__.py +28 -0
  22. generalmanager-0.16.0/src/general_manager/factory/__init__.py +28 -0
  23. generalmanager-0.16.0/src/general_manager/interface/__init__.py +28 -0
  24. generalmanager-0.16.0/src/general_manager/manager/__init__.py +28 -0
  25. generalmanager-0.16.0/src/general_manager/measurement/__init__.py +28 -0
  26. {generalmanager-0.15.1 → generalmanager-0.16.0}/src/general_manager/permission/__init__.py +8 -12
  27. generalmanager-0.16.0/src/general_manager/public_api_registry.py +160 -0
  28. {generalmanager-0.15.1 → generalmanager-0.16.0}/src/general_manager/rule/__init__.py +7 -6
  29. generalmanager-0.16.0/src/general_manager/utils/__init__.py +28 -0
  30. generalmanager-0.15.1/README.md +0 -148
  31. generalmanager-0.15.1/src/general_manager/__init__.py +0 -49
  32. generalmanager-0.15.1/src/general_manager/api/__init__.py +0 -36
  33. generalmanager-0.15.1/src/general_manager/bucket/__init__.py +0 -32
  34. generalmanager-0.15.1/src/general_manager/cache/__init__.py +0 -38
  35. generalmanager-0.15.1/src/general_manager/factory/__init__.py +0 -34
  36. generalmanager-0.15.1/src/general_manager/interface/__init__.py +0 -36
  37. generalmanager-0.15.1/src/general_manager/manager/__init__.py +0 -36
  38. generalmanager-0.15.1/src/general_manager/measurement/__init__.py +0 -37
  39. generalmanager-0.15.1/src/general_manager/utils/__init__.py +0 -44
  40. {generalmanager-0.15.1 → generalmanager-0.16.0}/LICENSE +0 -0
  41. {generalmanager-0.15.1 → generalmanager-0.16.0}/setup.cfg +0 -0
  42. {generalmanager-0.15.1 → generalmanager-0.16.0}/src/GeneralManager.egg-info/dependency_links.txt +0 -0
  43. {generalmanager-0.15.1 → generalmanager-0.16.0}/src/GeneralManager.egg-info/requires.txt +0 -0
  44. {generalmanager-0.15.1 → generalmanager-0.16.0}/src/GeneralManager.egg-info/top_level.txt +0 -0
  45. {generalmanager-0.15.1 → generalmanager-0.16.0}/src/general_manager/api/graphql.py +0 -0
  46. {generalmanager-0.15.1 → generalmanager-0.16.0}/src/general_manager/api/mutation.py +0 -0
  47. {generalmanager-0.15.1 → generalmanager-0.16.0}/src/general_manager/api/property.py +0 -0
  48. {generalmanager-0.15.1 → generalmanager-0.16.0}/src/general_manager/apps.py +0 -0
  49. {generalmanager-0.15.1 → generalmanager-0.16.0}/src/general_manager/bucket/baseBucket.py +0 -0
  50. {generalmanager-0.15.1 → generalmanager-0.16.0}/src/general_manager/bucket/calculationBucket.py +0 -0
  51. {generalmanager-0.15.1 → generalmanager-0.16.0}/src/general_manager/bucket/databaseBucket.py +0 -0
  52. {generalmanager-0.15.1 → generalmanager-0.16.0}/src/general_manager/bucket/groupBucket.py +0 -0
  53. {generalmanager-0.15.1 → generalmanager-0.16.0}/src/general_manager/cache/cacheDecorator.py +0 -0
  54. {generalmanager-0.15.1 → generalmanager-0.16.0}/src/general_manager/cache/cacheTracker.py +0 -0
  55. {generalmanager-0.15.1 → generalmanager-0.16.0}/src/general_manager/cache/dependencyIndex.py +0 -0
  56. {generalmanager-0.15.1 → generalmanager-0.16.0}/src/general_manager/cache/modelDependencyCollector.py +0 -0
  57. {generalmanager-0.15.1 → generalmanager-0.16.0}/src/general_manager/cache/signals.py +0 -0
  58. {generalmanager-0.15.1 → generalmanager-0.16.0}/src/general_manager/factory/autoFactory.py +0 -0
  59. {generalmanager-0.15.1 → generalmanager-0.16.0}/src/general_manager/factory/factories.py +0 -0
  60. {generalmanager-0.15.1 → generalmanager-0.16.0}/src/general_manager/factory/factoryMethods.py +0 -0
  61. {generalmanager-0.15.1 → generalmanager-0.16.0}/src/general_manager/interface/baseInterface.py +0 -0
  62. {generalmanager-0.15.1 → generalmanager-0.16.0}/src/general_manager/interface/calculationInterface.py +0 -0
  63. {generalmanager-0.15.1 → generalmanager-0.16.0}/src/general_manager/interface/databaseBasedInterface.py +0 -0
  64. {generalmanager-0.15.1 → generalmanager-0.16.0}/src/general_manager/interface/databaseInterface.py +0 -0
  65. {generalmanager-0.15.1 → generalmanager-0.16.0}/src/general_manager/interface/models.py +0 -0
  66. {generalmanager-0.15.1 → generalmanager-0.16.0}/src/general_manager/interface/readOnlyInterface.py +0 -0
  67. {generalmanager-0.15.1 → generalmanager-0.16.0}/src/general_manager/manager/generalManager.py +0 -0
  68. {generalmanager-0.15.1 → generalmanager-0.16.0}/src/general_manager/manager/groupManager.py +0 -0
  69. {generalmanager-0.15.1 → generalmanager-0.16.0}/src/general_manager/manager/input.py +0 -0
  70. {generalmanager-0.15.1 → generalmanager-0.16.0}/src/general_manager/manager/meta.py +0 -0
  71. {generalmanager-0.15.1 → generalmanager-0.16.0}/src/general_manager/measurement/measurement.py +0 -0
  72. {generalmanager-0.15.1 → generalmanager-0.16.0}/src/general_manager/measurement/measurementField.py +0 -0
  73. {generalmanager-0.15.1 → generalmanager-0.16.0}/src/general_manager/permission/basePermission.py +0 -0
  74. {generalmanager-0.15.1 → generalmanager-0.16.0}/src/general_manager/permission/fileBasedPermission.py +0 -0
  75. {generalmanager-0.15.1 → generalmanager-0.16.0}/src/general_manager/permission/managerBasedPermission.py +0 -0
  76. {generalmanager-0.15.1 → generalmanager-0.16.0}/src/general_manager/permission/mutationPermission.py +0 -0
  77. {generalmanager-0.15.1 → generalmanager-0.16.0}/src/general_manager/permission/permissionChecks.py +0 -0
  78. {generalmanager-0.15.1 → generalmanager-0.16.0}/src/general_manager/permission/permissionDataManager.py +0 -0
  79. {generalmanager-0.15.1 → generalmanager-0.16.0}/src/general_manager/permission/utils.py +0 -0
  80. {generalmanager-0.15.1 → generalmanager-0.16.0}/src/general_manager/rule/handler.py +0 -0
  81. {generalmanager-0.15.1 → generalmanager-0.16.0}/src/general_manager/rule/rule.py +0 -0
  82. {generalmanager-0.15.1 → generalmanager-0.16.0}/src/general_manager/utils/argsToKwargs.py +0 -0
  83. {generalmanager-0.15.1 → generalmanager-0.16.0}/src/general_manager/utils/filterParser.py +0 -0
  84. {generalmanager-0.15.1 → generalmanager-0.16.0}/src/general_manager/utils/formatString.py +0 -0
  85. {generalmanager-0.15.1 → generalmanager-0.16.0}/src/general_manager/utils/jsonEncoder.py +0 -0
  86. {generalmanager-0.15.1 → generalmanager-0.16.0}/src/general_manager/utils/makeCacheKey.py +0 -0
  87. {generalmanager-0.15.1 → generalmanager-0.16.0}/src/general_manager/utils/noneToZero.py +0 -0
  88. {generalmanager-0.15.1 → generalmanager-0.16.0}/src/general_manager/utils/pathMapping.py +0 -0
  89. {generalmanager-0.15.1 → generalmanager-0.16.0}/src/general_manager/utils/public_api.py +0 -0
  90. {generalmanager-0.15.1 → generalmanager-0.16.0}/src/general_manager/utils/testing.py +0 -0
  91. {generalmanager-0.15.1 → generalmanager-0.16.0}/tests/test_settings.py +0 -0
  92. {generalmanager-0.15.1 → generalmanager-0.16.0}/tests/test_urls.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: GeneralManager
3
- Version: 0.15.1
3
+ Version: 0.16.0
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
@@ -73,129 +73,89 @@ Dynamic: license-file
73
73
 
74
74
  ## Overview
75
75
 
76
- GeneralManager is a powerful and flexible framework designed for managing and processing data. It provides a modular structure that enables developers to implement complex business logic efficiently. The module is written entirely in Python and uses Django as the backend framework.
76
+ 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
77
 
78
- ## Key Features
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.
78
+ ## Documentation
88
79
 
89
- ### 3. **GraphQL Integration**
90
- - Automatic generation of GraphQL interfaces for all models.
91
- - Support for custom queries and mutations.
80
+ 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
81
 
93
- ### 4. **Permission System**
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.
82
+ ## Key Features
101
83
 
102
- ### 6. **Data Distribution and Calculations**
103
- - **Volume Distribution**: Automatically calculates and distributes volume over multiple years.
104
- - **Commercial Calculations**: Calculates total volume, shipping costs, and revenue for projects.
84
+ - **Domain-first modelling**: Describe rich business entities in plain Python and let GeneralManager project them onto the Django ORM.
85
+ - **GraphQL without boilerplate**: Generate a complete API, then extend it with custom queries and mutations when needed.
86
+ - **Attribute-based access control**: Enforce permissions with `ManagerBasedPermission` down to single fields and operations.
87
+ - **Deterministic calculations**: Ship reusable interfaces e.g. for volume distributions, KPI calculations, and derived data.
88
+ - **Factory-powered testing**: Create large, realistic datasets quickly for demos, QA, and load tests.
89
+ - **Composable interfaces**: Connect to databases, spreadsheets, or computed sources with the same consistent abstractions.
105
90
 
106
- ## Usage
91
+ ## Quick Start
107
92
 
108
93
  ### Installation
109
94
 
110
- Install the module via `pip`:
95
+ Install the package from PyPI:
111
96
 
112
97
  ```bash
113
98
  pip install GeneralManager
114
99
  ```
115
100
 
116
- ### Example Code
117
-
118
- The following example demonstrates how to create a GeneralManager and generate sample data (in this case 10 projects):
101
+ ### Minimal example
119
102
 
120
103
  ```python
104
+ from datetime import date
105
+ from typing import Optional
106
+
107
+ from django.db.models import CharField, DateField
108
+
121
109
  from general_manager import GeneralManager
122
110
  from general_manager.interface.database import DatabaseInterface
123
- from general_manager.measurement import MeasurementField, Measurement
111
+ from general_manager.measurement import Measurement, MeasurementField
124
112
  from general_manager.permission import ManagerBasedPermission
125
113
 
114
+
126
115
  class Project(GeneralManager):
127
116
  name: str
128
117
  start_date: Optional[date]
129
118
  end_date: Optional[date]
130
119
  total_capex: Optional[Measurement]
131
- derivative_list: DatabaseBucket[Derivative]
132
120
 
133
121
  class Interface(DatabaseInterface):
134
122
  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
123
  start_date = DateField(null=True, blank=True)
138
124
  end_date = DateField(null=True, blank=True)
139
125
  total_capex = MeasurementField(base_unit="EUR", null=True, blank=True)
140
126
 
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
127
  class Permission(ManagerBasedPermission):
161
- __read__ = ["ends_with:name:X-771", "public"]
162
- __create__ = ["admin", "isMatchingKeyAccount"]
163
- __update__ = ["admin", "isMatchingKeyAccount", "isProjectTeamMember"]
164
- __delete__ = ["admin", "isMatchingKeyAccount", "isProjectTeamMember"]
128
+ __read__ = ["public"]
129
+ __create__ = ["isAdmin"]
130
+ __update__ = ["isAdmin"]
165
131
 
166
- total_capex = {"update": ["isSalesResponsible", "isProjectManager"]}
167
132
 
168
133
  Project.Factory.createBatch(10)
169
134
  ```
170
135
 
171
- ### GraphQL Integration
136
+ 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
137
 
173
- The module automatically generates GraphQL endpoints for all models. You can run queries and mutations through the GraphQL URL defined in your Django settings.
138
+ ## Core Building Blocks
174
139
 
175
- Example of a GraphQL query:
140
+ - **Entities & interfaces**: Compose domain entities with database-backed or computed interfaces to control persistence and data flows.
141
+ - **Rules & validation**: Protect your data with declarative constraints and business rules that run automatically.
142
+ - **Permissions**: Implement attribute-based access control with reusable policies that match your organisation’s roles.
143
+ - **GraphQL layer**: Serve a typed schema that mirrors your models and stays in sync as you iterate.
144
+ - **Caching & calculations**: Use the built-in caching decorator and calculation helpers to keep derived data fast and reliable.
176
145
 
177
- ```graphql
178
- query {
179
- projectList {
180
- name
181
- startDate
182
- endDate
183
- totalCapex {
184
- value
185
- unit
186
- }
187
- }
188
- }
189
- ```
146
+ ## Production-Ready Extras
147
+
148
+ - Works with Postgres, SQLite, and any database supported by Django.
149
+ - Plays nicely with CI thanks to deterministic factories, typing, and code coverage.
150
+ - Ships with MkDocs documentation, auto-generated API reference, and a growing cookbook of recipes.
151
+ - Designed for teams: opinionated defaults without blocking custom extensions or overrides.
190
152
 
191
- ## Benefits
153
+ ## Use Cases
192
154
 
193
- - **Modularity**: Easy to extend and adapt.
194
- - **Flexibility**: Supports complex business logic and calculations.
195
- - **Integration**: Seamless integration with Django and GraphQL.
196
- - **Permissions**: Fine-grained permissions for users and attributes.
197
- - **Data Validation**: Automatic validation of data through rules and constraints.
198
- - **Caching**: Automatic cache generation with the `@cached` decorator to improve performance.
155
+ - Internal tooling that mirrors real-world workflows, pricing models, or asset hierarchies.
156
+ - Customer-facing platforms that combine transactional data with live calculations.
157
+ - Analytics products that need controlled data sharing between teams or clients.
158
+ - Proof-of-concept projects that must scale into production without a rewrite.
199
159
 
200
160
  ## Requirements
201
161
 
@@ -0,0 +1,108 @@
1
+ # GeneralManager
2
+
3
+ [![PyPI](https://img.shields.io/pypi/v/GeneralManager.svg)](https://pypi.org/project/GeneralManager/)
4
+ [![Python](https://img.shields.io/pypi/pyversions/GeneralManager.svg)](https://pypi.org/project/GeneralManager/)
5
+ [![Build](https://github.com/TimKleindick/general_manager/actions/workflows/test.yml/badge.svg?branch=main)](https://github.com/TimKleindick/general_manager/actions/workflows/test.yml)
6
+ [![Coverage](https://img.shields.io/codecov/c/github/TimKleindick/general_manager)](https://app.codecov.io/gh/TimKleindick/general_manager)
7
+ [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](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.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.
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "GeneralManager"
7
- version = "0.15.1"
7
+ version = "0.16.0"
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" }]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: GeneralManager
3
- Version: 0.15.1
3
+ Version: 0.16.0
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
@@ -73,129 +73,89 @@ Dynamic: license-file
73
73
 
74
74
  ## Overview
75
75
 
76
- GeneralManager is a powerful and flexible framework designed for managing and processing data. It provides a modular structure that enables developers to implement complex business logic efficiently. The module is written entirely in Python and uses Django as the backend framework.
76
+ 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
77
 
78
- ## Key Features
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.
78
+ ## Documentation
88
79
 
89
- ### 3. **GraphQL Integration**
90
- - Automatic generation of GraphQL interfaces for all models.
91
- - Support for custom queries and mutations.
80
+ 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
81
 
93
- ### 4. **Permission System**
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.
82
+ ## Key Features
101
83
 
102
- ### 6. **Data Distribution and Calculations**
103
- - **Volume Distribution**: Automatically calculates and distributes volume over multiple years.
104
- - **Commercial Calculations**: Calculates total volume, shipping costs, and revenue for projects.
84
+ - **Domain-first modelling**: Describe rich business entities in plain Python and let GeneralManager project them onto the Django ORM.
85
+ - **GraphQL without boilerplate**: Generate a complete API, then extend it with custom queries and mutations when needed.
86
+ - **Attribute-based access control**: Enforce permissions with `ManagerBasedPermission` down to single fields and operations.
87
+ - **Deterministic calculations**: Ship reusable interfaces e.g. for volume distributions, KPI calculations, and derived data.
88
+ - **Factory-powered testing**: Create large, realistic datasets quickly for demos, QA, and load tests.
89
+ - **Composable interfaces**: Connect to databases, spreadsheets, or computed sources with the same consistent abstractions.
105
90
 
106
- ## Usage
91
+ ## Quick Start
107
92
 
108
93
  ### Installation
109
94
 
110
- Install the module via `pip`:
95
+ Install the package from PyPI:
111
96
 
112
97
  ```bash
113
98
  pip install GeneralManager
114
99
  ```
115
100
 
116
- ### Example Code
117
-
118
- The following example demonstrates how to create a GeneralManager and generate sample data (in this case 10 projects):
101
+ ### Minimal example
119
102
 
120
103
  ```python
104
+ from datetime import date
105
+ from typing import Optional
106
+
107
+ from django.db.models import CharField, DateField
108
+
121
109
  from general_manager import GeneralManager
122
110
  from general_manager.interface.database import DatabaseInterface
123
- from general_manager.measurement import MeasurementField, Measurement
111
+ from general_manager.measurement import Measurement, MeasurementField
124
112
  from general_manager.permission import ManagerBasedPermission
125
113
 
114
+
126
115
  class Project(GeneralManager):
127
116
  name: str
128
117
  start_date: Optional[date]
129
118
  end_date: Optional[date]
130
119
  total_capex: Optional[Measurement]
131
- derivative_list: DatabaseBucket[Derivative]
132
120
 
133
121
  class Interface(DatabaseInterface):
134
122
  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
123
  start_date = DateField(null=True, blank=True)
138
124
  end_date = DateField(null=True, blank=True)
139
125
  total_capex = MeasurementField(base_unit="EUR", null=True, blank=True)
140
126
 
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
127
  class Permission(ManagerBasedPermission):
161
- __read__ = ["ends_with:name:X-771", "public"]
162
- __create__ = ["admin", "isMatchingKeyAccount"]
163
- __update__ = ["admin", "isMatchingKeyAccount", "isProjectTeamMember"]
164
- __delete__ = ["admin", "isMatchingKeyAccount", "isProjectTeamMember"]
128
+ __read__ = ["public"]
129
+ __create__ = ["isAdmin"]
130
+ __update__ = ["isAdmin"]
165
131
 
166
- total_capex = {"update": ["isSalesResponsible", "isProjectManager"]}
167
132
 
168
133
  Project.Factory.createBatch(10)
169
134
  ```
170
135
 
171
- ### GraphQL Integration
136
+ 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
137
 
173
- The module automatically generates GraphQL endpoints for all models. You can run queries and mutations through the GraphQL URL defined in your Django settings.
138
+ ## Core Building Blocks
174
139
 
175
- Example of a GraphQL query:
140
+ - **Entities & interfaces**: Compose domain entities with database-backed or computed interfaces to control persistence and data flows.
141
+ - **Rules & validation**: Protect your data with declarative constraints and business rules that run automatically.
142
+ - **Permissions**: Implement attribute-based access control with reusable policies that match your organisation’s roles.
143
+ - **GraphQL layer**: Serve a typed schema that mirrors your models and stays in sync as you iterate.
144
+ - **Caching & calculations**: Use the built-in caching decorator and calculation helpers to keep derived data fast and reliable.
176
145
 
177
- ```graphql
178
- query {
179
- projectList {
180
- name
181
- startDate
182
- endDate
183
- totalCapex {
184
- value
185
- unit
186
- }
187
- }
188
- }
189
- ```
146
+ ## Production-Ready Extras
147
+
148
+ - Works with Postgres, SQLite, and any database supported by Django.
149
+ - Plays nicely with CI thanks to deterministic factories, typing, and code coverage.
150
+ - Ships with MkDocs documentation, auto-generated API reference, and a growing cookbook of recipes.
151
+ - Designed for teams: opinionated defaults without blocking custom extensions or overrides.
190
152
 
191
- ## Benefits
153
+ ## Use Cases
192
154
 
193
- - **Modularity**: Easy to extend and adapt.
194
- - **Flexibility**: Supports complex business logic and calculations.
195
- - **Integration**: Seamless integration with Django and GraphQL.
196
- - **Permissions**: Fine-grained permissions for users and attributes.
197
- - **Data Validation**: Automatic validation of data through rules and constraints.
198
- - **Caching**: Automatic cache generation with the `@cached` decorator to improve performance.
155
+ - Internal tooling that mirrors real-world workflows, pricing models, or asset hierarchies.
156
+ - Customer-facing platforms that combine transactional data with live calculations.
157
+ - Analytics products that need controlled data sharing between teams or clients.
158
+ - Proof-of-concept projects that must scale into production without a rewrite.
199
159
 
200
160
  ## Requirements
201
161
 
@@ -8,6 +8,19 @@ 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/_types/__init__.py
13
+ src/general_manager/_types/api.py
14
+ src/general_manager/_types/bucket.py
15
+ src/general_manager/_types/cache.py
16
+ src/general_manager/_types/factory.py
17
+ src/general_manager/_types/general_manager.py
18
+ src/general_manager/_types/interface.py
19
+ src/general_manager/_types/manager.py
20
+ src/general_manager/_types/measurement.py
21
+ src/general_manager/_types/permission.py
22
+ src/general_manager/_types/rule.py
23
+ src/general_manager/_types/utils.py
11
24
  src/general_manager/api/__init__.py
12
25
  src/general_manager/api/graphql.py
13
26
  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())
@@ -0,0 +1,3 @@
1
+ from __future__ import annotations
2
+
3
+ __all__: list[str] = []
@@ -0,0 +1,18 @@
1
+ from __future__ import annotations
2
+
3
+ """Type-only imports for public API re-exports."""
4
+
5
+ __all__ = [
6
+ "GraphQL",
7
+ "MeasurementScalar",
8
+ "MeasurementType",
9
+ "graphQlMutation",
10
+ "graphQlProperty",
11
+ ]
12
+
13
+ from general_manager.api.graphql import GraphQL
14
+ from general_manager.api.graphql import MeasurementScalar
15
+ from general_manager.api.graphql import MeasurementType
16
+ from general_manager.api.mutation import graphQlMutation
17
+ from general_manager.api.property import graphQlProperty
18
+
@@ -0,0 +1,16 @@
1
+ from __future__ import annotations
2
+
3
+ """Type-only imports for public API re-exports."""
4
+
5
+ __all__ = [
6
+ "Bucket",
7
+ "CalculationBucket",
8
+ "DatabaseBucket",
9
+ "GroupBucket",
10
+ ]
11
+
12
+ from general_manager.bucket.baseBucket import Bucket
13
+ from general_manager.bucket.calculationBucket import CalculationBucket
14
+ from general_manager.bucket.databaseBucket import DatabaseBucket
15
+ from general_manager.bucket.groupBucket import GroupBucket
16
+
@@ -0,0 +1,20 @@
1
+ from __future__ import annotations
2
+
3
+ """Type-only imports for public API re-exports."""
4
+
5
+ __all__ = [
6
+ "CacheBackend",
7
+ "DependencyTracker",
8
+ "cached",
9
+ "invalidate_cache_key",
10
+ "record_dependencies",
11
+ "remove_cache_key_from_index",
12
+ ]
13
+
14
+ from general_manager.cache.cacheDecorator import CacheBackend
15
+ from general_manager.cache.cacheTracker import DependencyTracker
16
+ from general_manager.cache.cacheDecorator import cached
17
+ from general_manager.cache.dependencyIndex import invalidate_cache_key
18
+ from general_manager.cache.dependencyIndex import record_dependencies
19
+ from general_manager.cache.dependencyIndex import remove_cache_key_from_index
20
+
@@ -0,0 +1,44 @@
1
+ from __future__ import annotations
2
+
3
+ """Type-only imports for public API re-exports."""
4
+
5
+ __all__ = [
6
+ "AutoFactory",
7
+ "LazyBoolean",
8
+ "LazyChoice",
9
+ "LazyDateBetween",
10
+ "LazyDateTimeBetween",
11
+ "LazyDateToday",
12
+ "LazyDecimal",
13
+ "LazyDeltaDate",
14
+ "LazyFakerAddress",
15
+ "LazyFakerEmail",
16
+ "LazyFakerName",
17
+ "LazyFakerSentence",
18
+ "LazyFakerUrl",
19
+ "LazyInteger",
20
+ "LazyMeasurement",
21
+ "LazyProjectName",
22
+ "LazySequence",
23
+ "LazyUUID",
24
+ ]
25
+
26
+ from general_manager.factory.autoFactory import AutoFactory
27
+ from general_manager.factory.factoryMethods import LazyBoolean
28
+ from general_manager.factory.factoryMethods import LazyChoice
29
+ from general_manager.factory.factoryMethods import LazyDateBetween
30
+ from general_manager.factory.factoryMethods import LazyDateTimeBetween
31
+ from general_manager.factory.factoryMethods import LazyDateToday
32
+ from general_manager.factory.factoryMethods import LazyDecimal
33
+ from general_manager.factory.factoryMethods import LazyDeltaDate
34
+ from general_manager.factory.factoryMethods import LazyFakerAddress
35
+ from general_manager.factory.factoryMethods import LazyFakerEmail
36
+ from general_manager.factory.factoryMethods import LazyFakerName
37
+ from general_manager.factory.factoryMethods import LazyFakerSentence
38
+ from general_manager.factory.factoryMethods import LazyFakerUrl
39
+ from general_manager.factory.factoryMethods import LazyInteger
40
+ from general_manager.factory.factoryMethods import LazyMeasurement
41
+ from general_manager.factory.factoryMethods import LazyProjectName
42
+ from general_manager.factory.factoryMethods import LazySequence
43
+ from general_manager.factory.factoryMethods import LazyUUID
44
+