hape 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.
- hape-0.2.0/LICENSE.md +24 -0
- hape-0.2.0/PKG-INFO +272 -0
- hape-0.2.0/README.md +248 -0
- hape-0.2.0/hape/__init__.py +0 -0
- hape-0.2.0/hape/bootstrap.py +18 -0
- hape-0.2.0/hape/cli.py +19 -0
- hape-0.2.0/hape/config.py +89 -0
- hape-0.2.0/hape/controllers/__init__.py +0 -0
- hape-0.2.0/hape/controllers/deployment_cost_controller.py +7 -0
- hape-0.2.0/hape/controllers/git_controller.py +39 -0
- hape-0.2.0/hape/enums/__init__.py +0 -0
- hape-0.2.0/hape/enums/kube_context_enum.py +6 -0
- hape-0.2.0/hape/hape_cli/__init__.py +0 -0
- hape-0.2.0/hape/hape_cli/argument_parsers/__init__.py +0 -0
- hape-0.2.0/hape/hape_cli/argument_parsers/init_argument_parser.py +21 -0
- hape-0.2.0/hape/hape_cli/argument_parsers/main_argument_parser.py +28 -0
- hape-0.2.0/hape/hape_cli/cli.py +19 -0
- hape-0.2.0/hape/hape_cli/controllers/__init__.py +0 -0
- hape-0.2.0/hape/hape_cli/controllers/init_controller.py +11 -0
- hape-0.2.0/hape/hape_cli/models/__init__.py +0 -0
- hape-0.2.0/hape/hape_cli/models/init_model.py +107 -0
- hape-0.2.0/hape/logging.py +59 -0
- hape-0.2.0/hape/models/__init__.py +0 -0
- hape-0.2.0/hape/models/deployment_cost_model.py +26 -0
- hape-0.2.0/hape/models/git_model.py +31 -0
- hape-0.2.0/hape/models/gitlab_model.py +61 -0
- hape-0.2.0/hape/playground.py +72 -0
- hape-0.2.0/hape/services/__init__.py +0 -0
- hape-0.2.0/hape/services/file_service.py +126 -0
- hape-0.2.0/hape/services/git_service.py +127 -0
- hape-0.2.0/hape/services/gitlab_service.py +61 -0
- hape-0.2.0/hape/services/kubernetes_service.py +126 -0
- hape-0.2.0/hape.egg-info/PKG-INFO +272 -0
- hape-0.2.0/hape.egg-info/SOURCES.txt +38 -0
- hape-0.2.0/hape.egg-info/dependency_links.txt +1 -0
- hape-0.2.0/hape.egg-info/entry_points.txt +2 -0
- hape-0.2.0/hape.egg-info/requires.txt +1 -0
- hape-0.2.0/hape.egg-info/top_level.txt +1 -0
- hape-0.2.0/setup.cfg +4 -0
- hape-0.2.0/setup.py +27 -0
hape-0.2.0/LICENSE.md
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Owned by Hazem Ataya from Syria, born in 1994
|
|
4
|
+
|
|
5
|
+
Copyright (c) 2024 Hazem Ataya
|
|
6
|
+
|
|
7
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
in the Software without restriction, including without limitation the rights
|
|
10
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
furnished to do so, subject to the following conditions:
|
|
13
|
+
|
|
14
|
+
The above copyright notice and this permission notice shall be included in all
|
|
15
|
+
copies or substantial portions of the Software.
|
|
16
|
+
|
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
SOFTWARE.
|
|
24
|
+
|
hape-0.2.0/PKG-INFO
ADDED
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
|
+
Name: hape
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: HAPE Framework: Build an Automation Tool With Ease
|
|
5
|
+
Home-page: https://github.com/hazemataya94/hape-framework
|
|
6
|
+
Author: Hazem Ataya
|
|
7
|
+
Author-email: hazem.ataya94@gmail.com
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Requires-Python: >=3.9
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
License-File: LICENSE.md
|
|
14
|
+
Requires-Dist: python-dotenv
|
|
15
|
+
Dynamic: author
|
|
16
|
+
Dynamic: author-email
|
|
17
|
+
Dynamic: classifier
|
|
18
|
+
Dynamic: description
|
|
19
|
+
Dynamic: description-content-type
|
|
20
|
+
Dynamic: home-page
|
|
21
|
+
Dynamic: requires-dist
|
|
22
|
+
Dynamic: requires-python
|
|
23
|
+
Dynamic: summary
|
|
24
|
+
|
|
25
|
+
# HAPE Framework: Overview & Vision
|
|
26
|
+
|
|
27
|
+
## What is HAPE Framework?
|
|
28
|
+
HAPE Framework is a lightweight and extensible Python framework designed to help platform engineers build customized CLI and API-driven platforms with minimal effort. It provides a structured way to develop orchestrators for managing infrastructure, CI/CD pipelines, cloud resources, and other platform engineering needs.
|
|
29
|
+
|
|
30
|
+
HAPE is built around abstraction and automation, allowing engineers to define and manage resources like AWS, Kubernetes, GitHub, GitLab, ArgoCD, Prometheus, Grafana, HashiCorp Vault, and many others in a unified manner. It eliminates the need to manually integrate multiple packages for each tool, offering a streamlined way to build self-service developer portals and engineering platforms.
|
|
31
|
+
|
|
32
|
+
## Where It All Started
|
|
33
|
+
Modern organizations manage hundreds of microservices, each with its own infrastructure, CI/CD, monitoring, and deployment configurations. This complexity increases the cognitive load on developers and slows down platform operations.
|
|
34
|
+
|
|
35
|
+
HAPE Framework aims to reduce this complexity by enabling platform engineers to build opinionated, yet flexible automation tools that simplify onboarding, deployment, and operations.
|
|
36
|
+
|
|
37
|
+
With HAPE, developers can interact with a CLI or API to create, deploy, and manage their services without diving into complex configurations. The framework also supports custom workflows, state management via databases, and integration with existing DevOps tools.
|
|
38
|
+
|
|
39
|
+
## Core Principles
|
|
40
|
+
- **Abstraction & Modularity** – Developers work with high-level constructs rather than low-level implement- ation details.
|
|
41
|
+
- **CLI & API Driven** – HAPE enables both CLI and API-based interactions, making it ideal for automation.
|
|
42
|
+
- **Extensibility** – Supports custom workflows, integrations, and automation logic.
|
|
43
|
+
- **Minimal Cognitive Load** – Aims to provide intuitive commands and automation, so platform engineers don’t need to reinvent the wheel.
|
|
44
|
+
- **Infrastructure & CI/CD Agnostic** – Can be adapted to any cloud provider, DevOps stack, or orchestration tool.
|
|
45
|
+
- **State Management via Database** – Unlike static configuration-based tools, HAPE tracks states dynamically using a database.
|
|
46
|
+
|
|
47
|
+
## Key Features
|
|
48
|
+
- Automated CRUD generation for platform services (e.g., hape crud --create ServiceName {...}).
|
|
49
|
+
- Built-in CLI framework that can be extended for various platform engineering use cases.
|
|
50
|
+
- Pre-built integrations with cloud providers and DevOps tools.
|
|
51
|
+
- Simplified orchestration of deployments, CI/CD, monitoring, and permissions.
|
|
52
|
+
- Database-backed state tracking for workflows and configurations.
|
|
53
|
+
- Python-based, for efficiency and language simplicity.
|
|
54
|
+
- Supports automation beyond platform engineering, making it useful for multiple domains.
|
|
55
|
+
|
|
56
|
+
## Vision for the Future
|
|
57
|
+
HAPE Framework aims to become the go-to tool for building Internal Developer Platforms (IDPs) and self-service DevOps automation. It envisions a future where platform engineers can quickly spin up customizable automation platforms without needing to start from scratch.
|
|
58
|
+
|
|
59
|
+
The framework enables users to build fully managed solutions for CI/CD, infrastructure provisioning, developer access, cost monitoring, and more. The long-term goal is to foster open-source community contributions to extend integrations and functionality.
|
|
60
|
+
|
|
61
|
+
### Automated Workflow Execution
|
|
62
|
+
|
|
63
|
+
To create Create/READ/UPDATE/DELETE (CRUD) for a model deployment-cost to process cost for Kubernetes deployment, all you need is to run:
|
|
64
|
+
```
|
|
65
|
+
$ hape crud --create deployment-cost """
|
|
66
|
+
{
|
|
67
|
+
"id": ["int","autoincrement"],
|
|
68
|
+
"service-name": ["string"],
|
|
69
|
+
"pod-cpu": ["string"],
|
|
70
|
+
"pod-ram": ["string"],
|
|
71
|
+
"autoscaling": ["bool"],
|
|
72
|
+
"min-replicas": ["int",""],
|
|
73
|
+
"max-replicas": ["int",""],
|
|
74
|
+
"current-replicas": ["int"],
|
|
75
|
+
"pod-cost": ["string"],
|
|
76
|
+
"number-of-pods": ["int"],
|
|
77
|
+
"total-cost": ["float"],
|
|
78
|
+
"cost-unit": ["string"]
|
|
79
|
+
}
|
|
80
|
+
"""
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Once the autogenerated files are created, you'll be able to run:
|
|
84
|
+
```
|
|
85
|
+
$ myawesomeplatform deployment-cost --help
|
|
86
|
+
|
|
87
|
+
usage: myawesomeplatform deployment-cost [-h] {save,get,get-all,delete,delete-all} ...
|
|
88
|
+
|
|
89
|
+
positional arguments:
|
|
90
|
+
{save,get,get-all,delete,delete-all}
|
|
91
|
+
save Save DeploymentCost object based on passed arguments or filters
|
|
92
|
+
get Get DeploymentCost object based on passed arguments or filters
|
|
93
|
+
get-all Get-all DeploymentCost objects based on passed arguments or filters
|
|
94
|
+
delete Delete DeploymentCost object based on passed arguments or filters
|
|
95
|
+
delete-all Delete-all DeploymentCost objects based on passed arguments or filters
|
|
96
|
+
|
|
97
|
+
options:
|
|
98
|
+
-h, --help show this help message and exit
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
and run:
|
|
102
|
+
```
|
|
103
|
+
$ myawesomeplatform deployment-cost save --help
|
|
104
|
+
|
|
105
|
+
usage: myawesomeplatform deployment-cost save [-h] [--id ID] [--created-at CREATED_AT] [--service-name SERVICE_NAME] [--pod-cpu POD_CPU]
|
|
106
|
+
[--pod-ram POD_RAM] [--autoscaling AUTOSCALING] [--min-replicas MIN_REPLICAS] [--max-replicas MAX_REPLICAS]
|
|
107
|
+
[--current-replicas CURRENT_REPLICAS] [--pod-cost POD_COST] [--number-of-pods NUMBER_OF_PODS]
|
|
108
|
+
[--total-cost TOTAL_COST] [--cost-unit COST_UNIT]
|
|
109
|
+
|
|
110
|
+
options:
|
|
111
|
+
-h, --help show this help message and exit
|
|
112
|
+
--id ID Value for id type int
|
|
113
|
+
--created-at CREATED_AT
|
|
114
|
+
Value for created-at type str
|
|
115
|
+
--service-name SERVICE_NAME
|
|
116
|
+
Value for service-name type str
|
|
117
|
+
--pod-cpu POD_CPU Value for pod-cpu type str
|
|
118
|
+
--pod-ram POD_RAM Value for pod-ram type str
|
|
119
|
+
--autoscaling AUTOSCALING
|
|
120
|
+
Value for autoscaling type <lambda>
|
|
121
|
+
--min-replicas MIN_REPLICAS
|
|
122
|
+
Value for min-replicas type int
|
|
123
|
+
--max-replicas MAX_REPLICAS
|
|
124
|
+
Value for max-replicas type int
|
|
125
|
+
--current-replicas CURRENT_REPLICAS
|
|
126
|
+
Value for current-replicas type int
|
|
127
|
+
--pod-cost POD_COST Value for pod-cost type float
|
|
128
|
+
--number-of-pods NUMBER_OF_PODS
|
|
129
|
+
Value for number-of-pods type int
|
|
130
|
+
--total-cost TOTAL_COST
|
|
131
|
+
Value for total-cost type float
|
|
132
|
+
--cost-unit COST_UNIT
|
|
133
|
+
Value for cost-unit type str
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
This level of automation makes HAPE a powerful framework for platform engineers to manage infrastructure, CI/CD, and service deployments with ease.
|
|
137
|
+
|
|
138
|
+
### How It Will Be Used
|
|
139
|
+
HAPE enables developers to quickly initialize and structure their platform projects with minimal setup. They install HAPE Framework via PyPI and initialize a new project effortlessly:
|
|
140
|
+
```
|
|
141
|
+
$ pip install hape-framework
|
|
142
|
+
$ hape init --name myawesomeplatform
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
This initializes a well-structured project with predefined directories:
|
|
146
|
+
```
|
|
147
|
+
myawesomeplatform/
|
|
148
|
+
│── dockerfiles/ (Copied from HAPE Framework)
|
|
149
|
+
│── Makefile (Copied from HAPE Framework)
|
|
150
|
+
│── src/
|
|
151
|
+
│ ├── migrations/
|
|
152
|
+
│ ├── models/
|
|
153
|
+
│ ├── controllers/
|
|
154
|
+
│ ├── services/
|
|
155
|
+
│ ├── utils/
|
|
156
|
+
│ ├── config/
|
|
157
|
+
│ ├── tests/
|
|
158
|
+
│── docs/
|
|
159
|
+
│── scripts/
|
|
160
|
+
│── setup.py
|
|
161
|
+
│── README.md
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
### CRUD Creation
|
|
166
|
+
To create a CRUD functionality for a model:
|
|
167
|
+
```
|
|
168
|
+
hape crud --create MyModel '{"id": ["int", "autoincrement"], "value": ["string", "nullable"]}'
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
This generates the following files
|
|
172
|
+
- **Model**
|
|
173
|
+
```
|
|
174
|
+
from hape.base.model import Model
|
|
175
|
+
from sqlalchemy import Column, String
|
|
176
|
+
|
|
177
|
+
class MyModel(Model):
|
|
178
|
+
__tablename__ = "mymodel"
|
|
179
|
+
id = Column(Integer, primary_key=True, autoincrement=True)
|
|
180
|
+
value = Column(String(255), nullable=False)
|
|
181
|
+
|
|
182
|
+
def __init__(self, **kwargs):
|
|
183
|
+
filtered_kwargs = {key: kwargs[key] for key in self.__table__.columns.keys() if key in kwargs}
|
|
184
|
+
super().__init__(**filtered_kwargs)
|
|
185
|
+
for key, value in filtered_kwargs.items():
|
|
186
|
+
setattr(self, key, value)
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
- **Controller**
|
|
190
|
+
```
|
|
191
|
+
from hape.base.model_controller import ModelController
|
|
192
|
+
from myawesomeplatform.src.models.mymodel import MyModel
|
|
193
|
+
|
|
194
|
+
class MyModelController(ModelController):
|
|
195
|
+
model = MyModel
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
- **View (CLI/Argument Parser)**
|
|
199
|
+
```
|
|
200
|
+
from hape.base.model_argument_parser import ModelArgumentParser
|
|
201
|
+
from myawesomeplatform.src.models.mymodel import MyModel
|
|
202
|
+
from myawesomeplatform.src.controllers.mymodel_controller import MyModelController
|
|
203
|
+
|
|
204
|
+
class MyModelArgumentParser(ModelArgumentParser):
|
|
205
|
+
def __init__(self):
|
|
206
|
+
super().__init__(MyModel, MyModelController)
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
- **Migration File**
|
|
210
|
+
```
|
|
211
|
+
from alembic import op
|
|
212
|
+
import sqlalchemy as sa
|
|
213
|
+
|
|
214
|
+
revision = '001_mymodel_creation'
|
|
215
|
+
down_revision = None
|
|
216
|
+
branch_labels = None
|
|
217
|
+
depends_on = None
|
|
218
|
+
|
|
219
|
+
def upgrade():
|
|
220
|
+
op.create_table(
|
|
221
|
+
'my_model',
|
|
222
|
+
sa.Column('id', sa.Integer, primary_key=True, autoincrement=True),
|
|
223
|
+
sa.Column('value', sa.String(255), nullable=False)
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
def downgrade():
|
|
227
|
+
op.drop_table('my_model')
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
The files are generated, then the migration autoruns to create the table in the database.
|
|
231
|
+
|
|
232
|
+
Then can package the cli and publish to your private PyPI, to be able to use the auto-create functionality. E,g:
|
|
233
|
+
```
|
|
234
|
+
$ myawesomeplatform mymodel save --value "example"
|
|
235
|
+
$ myawesomeplatform mymodel get --id 2
|
|
236
|
+
$ myawesomeplatform mymodel get-all
|
|
237
|
+
$ myawesomeplatform mymodel delete --id 2
|
|
238
|
+
$ myawesomeplatform mymodel delete-all
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
HAPE enables developers to quickly initialize and structure their platform projects with minimal setup.
|
|
242
|
+
|
|
243
|
+
### Install & Upgrade Latest Version
|
|
244
|
+
Anyone can install HAPE Framework using `pip`.
|
|
245
|
+
```
|
|
246
|
+
$ pip install hape-framework
|
|
247
|
+
$ hape init --name myawesomeplatform
|
|
248
|
+
```
|
|
249
|
+
This generates a well-structured project with predefined directories for migrations, models, controllers, services, repositories, and more. The framework follows an MVC-inspired architecture where:
|
|
250
|
+
|
|
251
|
+
Updating the framework is as simple as:
|
|
252
|
+
```
|
|
253
|
+
pip install --upgrade hape-framework
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
### Using Prebuilt HAPE Services
|
|
257
|
+
Developers can use any services, classes, or models that are provided with the public framework in their own private platform by importing them:
|
|
258
|
+
```
|
|
259
|
+
from hape.logging import logger
|
|
260
|
+
|
|
261
|
+
from hape.config import Config
|
|
262
|
+
|
|
263
|
+
from hape.models.deployment_cost_model import DeploymentCost
|
|
264
|
+
|
|
265
|
+
from hape.services.kubernetes_service import KubernetesService
|
|
266
|
+
|
|
267
|
+
from hape.argument_parsers.config_argument_parser import ConfigArgumentParser
|
|
268
|
+
```
|
|
269
|
+
This allows developers to leverage HAPE’s built-in functionalities while maintaining the flexibility to extend and integrate with their custom platform setup.
|
|
270
|
+
|
|
271
|
+
# Author
|
|
272
|
+
Hazem Ataya: hazem.ataya94@gmail.com
|
hape-0.2.0/README.md
ADDED
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
# HAPE Framework: Overview & Vision
|
|
2
|
+
|
|
3
|
+
## What is HAPE Framework?
|
|
4
|
+
HAPE Framework is a lightweight and extensible Python framework designed to help platform engineers build customized CLI and API-driven platforms with minimal effort. It provides a structured way to develop orchestrators for managing infrastructure, CI/CD pipelines, cloud resources, and other platform engineering needs.
|
|
5
|
+
|
|
6
|
+
HAPE is built around abstraction and automation, allowing engineers to define and manage resources like AWS, Kubernetes, GitHub, GitLab, ArgoCD, Prometheus, Grafana, HashiCorp Vault, and many others in a unified manner. It eliminates the need to manually integrate multiple packages for each tool, offering a streamlined way to build self-service developer portals and engineering platforms.
|
|
7
|
+
|
|
8
|
+
## Where It All Started
|
|
9
|
+
Modern organizations manage hundreds of microservices, each with its own infrastructure, CI/CD, monitoring, and deployment configurations. This complexity increases the cognitive load on developers and slows down platform operations.
|
|
10
|
+
|
|
11
|
+
HAPE Framework aims to reduce this complexity by enabling platform engineers to build opinionated, yet flexible automation tools that simplify onboarding, deployment, and operations.
|
|
12
|
+
|
|
13
|
+
With HAPE, developers can interact with a CLI or API to create, deploy, and manage their services without diving into complex configurations. The framework also supports custom workflows, state management via databases, and integration with existing DevOps tools.
|
|
14
|
+
|
|
15
|
+
## Core Principles
|
|
16
|
+
- **Abstraction & Modularity** – Developers work with high-level constructs rather than low-level implement- ation details.
|
|
17
|
+
- **CLI & API Driven** – HAPE enables both CLI and API-based interactions, making it ideal for automation.
|
|
18
|
+
- **Extensibility** – Supports custom workflows, integrations, and automation logic.
|
|
19
|
+
- **Minimal Cognitive Load** – Aims to provide intuitive commands and automation, so platform engineers don’t need to reinvent the wheel.
|
|
20
|
+
- **Infrastructure & CI/CD Agnostic** – Can be adapted to any cloud provider, DevOps stack, or orchestration tool.
|
|
21
|
+
- **State Management via Database** – Unlike static configuration-based tools, HAPE tracks states dynamically using a database.
|
|
22
|
+
|
|
23
|
+
## Key Features
|
|
24
|
+
- Automated CRUD generation for platform services (e.g., hape crud --create ServiceName {...}).
|
|
25
|
+
- Built-in CLI framework that can be extended for various platform engineering use cases.
|
|
26
|
+
- Pre-built integrations with cloud providers and DevOps tools.
|
|
27
|
+
- Simplified orchestration of deployments, CI/CD, monitoring, and permissions.
|
|
28
|
+
- Database-backed state tracking for workflows and configurations.
|
|
29
|
+
- Python-based, for efficiency and language simplicity.
|
|
30
|
+
- Supports automation beyond platform engineering, making it useful for multiple domains.
|
|
31
|
+
|
|
32
|
+
## Vision for the Future
|
|
33
|
+
HAPE Framework aims to become the go-to tool for building Internal Developer Platforms (IDPs) and self-service DevOps automation. It envisions a future where platform engineers can quickly spin up customizable automation platforms without needing to start from scratch.
|
|
34
|
+
|
|
35
|
+
The framework enables users to build fully managed solutions for CI/CD, infrastructure provisioning, developer access, cost monitoring, and more. The long-term goal is to foster open-source community contributions to extend integrations and functionality.
|
|
36
|
+
|
|
37
|
+
### Automated Workflow Execution
|
|
38
|
+
|
|
39
|
+
To create Create/READ/UPDATE/DELETE (CRUD) for a model deployment-cost to process cost for Kubernetes deployment, all you need is to run:
|
|
40
|
+
```
|
|
41
|
+
$ hape crud --create deployment-cost """
|
|
42
|
+
{
|
|
43
|
+
"id": ["int","autoincrement"],
|
|
44
|
+
"service-name": ["string"],
|
|
45
|
+
"pod-cpu": ["string"],
|
|
46
|
+
"pod-ram": ["string"],
|
|
47
|
+
"autoscaling": ["bool"],
|
|
48
|
+
"min-replicas": ["int",""],
|
|
49
|
+
"max-replicas": ["int",""],
|
|
50
|
+
"current-replicas": ["int"],
|
|
51
|
+
"pod-cost": ["string"],
|
|
52
|
+
"number-of-pods": ["int"],
|
|
53
|
+
"total-cost": ["float"],
|
|
54
|
+
"cost-unit": ["string"]
|
|
55
|
+
}
|
|
56
|
+
"""
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Once the autogenerated files are created, you'll be able to run:
|
|
60
|
+
```
|
|
61
|
+
$ myawesomeplatform deployment-cost --help
|
|
62
|
+
|
|
63
|
+
usage: myawesomeplatform deployment-cost [-h] {save,get,get-all,delete,delete-all} ...
|
|
64
|
+
|
|
65
|
+
positional arguments:
|
|
66
|
+
{save,get,get-all,delete,delete-all}
|
|
67
|
+
save Save DeploymentCost object based on passed arguments or filters
|
|
68
|
+
get Get DeploymentCost object based on passed arguments or filters
|
|
69
|
+
get-all Get-all DeploymentCost objects based on passed arguments or filters
|
|
70
|
+
delete Delete DeploymentCost object based on passed arguments or filters
|
|
71
|
+
delete-all Delete-all DeploymentCost objects based on passed arguments or filters
|
|
72
|
+
|
|
73
|
+
options:
|
|
74
|
+
-h, --help show this help message and exit
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
and run:
|
|
78
|
+
```
|
|
79
|
+
$ myawesomeplatform deployment-cost save --help
|
|
80
|
+
|
|
81
|
+
usage: myawesomeplatform deployment-cost save [-h] [--id ID] [--created-at CREATED_AT] [--service-name SERVICE_NAME] [--pod-cpu POD_CPU]
|
|
82
|
+
[--pod-ram POD_RAM] [--autoscaling AUTOSCALING] [--min-replicas MIN_REPLICAS] [--max-replicas MAX_REPLICAS]
|
|
83
|
+
[--current-replicas CURRENT_REPLICAS] [--pod-cost POD_COST] [--number-of-pods NUMBER_OF_PODS]
|
|
84
|
+
[--total-cost TOTAL_COST] [--cost-unit COST_UNIT]
|
|
85
|
+
|
|
86
|
+
options:
|
|
87
|
+
-h, --help show this help message and exit
|
|
88
|
+
--id ID Value for id type int
|
|
89
|
+
--created-at CREATED_AT
|
|
90
|
+
Value for created-at type str
|
|
91
|
+
--service-name SERVICE_NAME
|
|
92
|
+
Value for service-name type str
|
|
93
|
+
--pod-cpu POD_CPU Value for pod-cpu type str
|
|
94
|
+
--pod-ram POD_RAM Value for pod-ram type str
|
|
95
|
+
--autoscaling AUTOSCALING
|
|
96
|
+
Value for autoscaling type <lambda>
|
|
97
|
+
--min-replicas MIN_REPLICAS
|
|
98
|
+
Value for min-replicas type int
|
|
99
|
+
--max-replicas MAX_REPLICAS
|
|
100
|
+
Value for max-replicas type int
|
|
101
|
+
--current-replicas CURRENT_REPLICAS
|
|
102
|
+
Value for current-replicas type int
|
|
103
|
+
--pod-cost POD_COST Value for pod-cost type float
|
|
104
|
+
--number-of-pods NUMBER_OF_PODS
|
|
105
|
+
Value for number-of-pods type int
|
|
106
|
+
--total-cost TOTAL_COST
|
|
107
|
+
Value for total-cost type float
|
|
108
|
+
--cost-unit COST_UNIT
|
|
109
|
+
Value for cost-unit type str
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
This level of automation makes HAPE a powerful framework for platform engineers to manage infrastructure, CI/CD, and service deployments with ease.
|
|
113
|
+
|
|
114
|
+
### How It Will Be Used
|
|
115
|
+
HAPE enables developers to quickly initialize and structure their platform projects with minimal setup. They install HAPE Framework via PyPI and initialize a new project effortlessly:
|
|
116
|
+
```
|
|
117
|
+
$ pip install hape-framework
|
|
118
|
+
$ hape init --name myawesomeplatform
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
This initializes a well-structured project with predefined directories:
|
|
122
|
+
```
|
|
123
|
+
myawesomeplatform/
|
|
124
|
+
│── dockerfiles/ (Copied from HAPE Framework)
|
|
125
|
+
│── Makefile (Copied from HAPE Framework)
|
|
126
|
+
│── src/
|
|
127
|
+
│ ├── migrations/
|
|
128
|
+
│ ├── models/
|
|
129
|
+
│ ├── controllers/
|
|
130
|
+
│ ├── services/
|
|
131
|
+
│ ├── utils/
|
|
132
|
+
│ ├── config/
|
|
133
|
+
│ ├── tests/
|
|
134
|
+
│── docs/
|
|
135
|
+
│── scripts/
|
|
136
|
+
│── setup.py
|
|
137
|
+
│── README.md
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
### CRUD Creation
|
|
142
|
+
To create a CRUD functionality for a model:
|
|
143
|
+
```
|
|
144
|
+
hape crud --create MyModel '{"id": ["int", "autoincrement"], "value": ["string", "nullable"]}'
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
This generates the following files
|
|
148
|
+
- **Model**
|
|
149
|
+
```
|
|
150
|
+
from hape.base.model import Model
|
|
151
|
+
from sqlalchemy import Column, String
|
|
152
|
+
|
|
153
|
+
class MyModel(Model):
|
|
154
|
+
__tablename__ = "mymodel"
|
|
155
|
+
id = Column(Integer, primary_key=True, autoincrement=True)
|
|
156
|
+
value = Column(String(255), nullable=False)
|
|
157
|
+
|
|
158
|
+
def __init__(self, **kwargs):
|
|
159
|
+
filtered_kwargs = {key: kwargs[key] for key in self.__table__.columns.keys() if key in kwargs}
|
|
160
|
+
super().__init__(**filtered_kwargs)
|
|
161
|
+
for key, value in filtered_kwargs.items():
|
|
162
|
+
setattr(self, key, value)
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
- **Controller**
|
|
166
|
+
```
|
|
167
|
+
from hape.base.model_controller import ModelController
|
|
168
|
+
from myawesomeplatform.src.models.mymodel import MyModel
|
|
169
|
+
|
|
170
|
+
class MyModelController(ModelController):
|
|
171
|
+
model = MyModel
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
- **View (CLI/Argument Parser)**
|
|
175
|
+
```
|
|
176
|
+
from hape.base.model_argument_parser import ModelArgumentParser
|
|
177
|
+
from myawesomeplatform.src.models.mymodel import MyModel
|
|
178
|
+
from myawesomeplatform.src.controllers.mymodel_controller import MyModelController
|
|
179
|
+
|
|
180
|
+
class MyModelArgumentParser(ModelArgumentParser):
|
|
181
|
+
def __init__(self):
|
|
182
|
+
super().__init__(MyModel, MyModelController)
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
- **Migration File**
|
|
186
|
+
```
|
|
187
|
+
from alembic import op
|
|
188
|
+
import sqlalchemy as sa
|
|
189
|
+
|
|
190
|
+
revision = '001_mymodel_creation'
|
|
191
|
+
down_revision = None
|
|
192
|
+
branch_labels = None
|
|
193
|
+
depends_on = None
|
|
194
|
+
|
|
195
|
+
def upgrade():
|
|
196
|
+
op.create_table(
|
|
197
|
+
'my_model',
|
|
198
|
+
sa.Column('id', sa.Integer, primary_key=True, autoincrement=True),
|
|
199
|
+
sa.Column('value', sa.String(255), nullable=False)
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
def downgrade():
|
|
203
|
+
op.drop_table('my_model')
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
The files are generated, then the migration autoruns to create the table in the database.
|
|
207
|
+
|
|
208
|
+
Then can package the cli and publish to your private PyPI, to be able to use the auto-create functionality. E,g:
|
|
209
|
+
```
|
|
210
|
+
$ myawesomeplatform mymodel save --value "example"
|
|
211
|
+
$ myawesomeplatform mymodel get --id 2
|
|
212
|
+
$ myawesomeplatform mymodel get-all
|
|
213
|
+
$ myawesomeplatform mymodel delete --id 2
|
|
214
|
+
$ myawesomeplatform mymodel delete-all
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
HAPE enables developers to quickly initialize and structure their platform projects with minimal setup.
|
|
218
|
+
|
|
219
|
+
### Install & Upgrade Latest Version
|
|
220
|
+
Anyone can install HAPE Framework using `pip`.
|
|
221
|
+
```
|
|
222
|
+
$ pip install hape-framework
|
|
223
|
+
$ hape init --name myawesomeplatform
|
|
224
|
+
```
|
|
225
|
+
This generates a well-structured project with predefined directories for migrations, models, controllers, services, repositories, and more. The framework follows an MVC-inspired architecture where:
|
|
226
|
+
|
|
227
|
+
Updating the framework is as simple as:
|
|
228
|
+
```
|
|
229
|
+
pip install --upgrade hape-framework
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### Using Prebuilt HAPE Services
|
|
233
|
+
Developers can use any services, classes, or models that are provided with the public framework in their own private platform by importing them:
|
|
234
|
+
```
|
|
235
|
+
from hape.logging import logger
|
|
236
|
+
|
|
237
|
+
from hape.config import Config
|
|
238
|
+
|
|
239
|
+
from hape.models.deployment_cost_model import DeploymentCost
|
|
240
|
+
|
|
241
|
+
from hape.services.kubernetes_service import KubernetesService
|
|
242
|
+
|
|
243
|
+
from hape.argument_parsers.config_argument_parser import ConfigArgumentParser
|
|
244
|
+
```
|
|
245
|
+
This allows developers to leverage HAPE’s built-in functionalities while maintaining the flexibility to extend and integrate with their custom platform setup.
|
|
246
|
+
|
|
247
|
+
# Author
|
|
248
|
+
Hazem Ataya: hazem.ataya94@gmail.com
|
|
File without changes
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from hape.logging import logger
|
|
2
|
+
from hape.config import Config
|
|
3
|
+
from hape.models.deployment_cost_model import DeploymentCost
|
|
4
|
+
|
|
5
|
+
def bootstrap_application():
|
|
6
|
+
logger.info("Checking configurations.")
|
|
7
|
+
Config.check_variables()
|
|
8
|
+
|
|
9
|
+
session = Config.get_db_session()
|
|
10
|
+
try:
|
|
11
|
+
DeploymentCost.initialize_from_sqlalchemy(DeploymentCost)
|
|
12
|
+
logger.info("Database initialized successfully!")
|
|
13
|
+
except Exception as e:
|
|
14
|
+
logger.error(f"Error initializing database: {e}")
|
|
15
|
+
finally:
|
|
16
|
+
session.close()
|
|
17
|
+
|
|
18
|
+
logger.info("Application started!")
|
hape-0.2.0/hape/cli.py
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from hape.bootstrap import bootstrap_application
|
|
2
|
+
from hape.argument_parsers.main_argument_parser import MainArgumentParser
|
|
3
|
+
|
|
4
|
+
class CLI:
|
|
5
|
+
|
|
6
|
+
@classmethod
|
|
7
|
+
def main():
|
|
8
|
+
bootstrap_application()
|
|
9
|
+
|
|
10
|
+
main_parser = MainArgumentParser()
|
|
11
|
+
|
|
12
|
+
parser = main_parser.create_parser()
|
|
13
|
+
args = parser.parse_args()
|
|
14
|
+
|
|
15
|
+
if args.command is None:
|
|
16
|
+
parser.print_help()
|
|
17
|
+
return
|
|
18
|
+
|
|
19
|
+
main_parser.run_action(args)
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import json
|
|
3
|
+
from dotenv import load_dotenv
|
|
4
|
+
from sqlalchemy import create_engine
|
|
5
|
+
from sqlalchemy.orm import sessionmaker
|
|
6
|
+
from sqlalchemy.exc import OperationalError
|
|
7
|
+
from sqlalchemy.sql import text
|
|
8
|
+
from hape.logging import logger
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class Config:
|
|
13
|
+
_env_loaded = False
|
|
14
|
+
_db_session = None
|
|
15
|
+
_required_env_variables = ["HAPE_GITLAB_TOKEN", "HAPE_GITLAB_DOMAIN", "HAPE_MARIADB_HOST", "HAPE_MARIADB_USERNAME", "HAPE_MARIADB_PASSWORD", "HAPE_MARIADB_DATABASE"]
|
|
16
|
+
|
|
17
|
+
@staticmethod
|
|
18
|
+
def check_variables():
|
|
19
|
+
for variable in Config._required_env_variables:
|
|
20
|
+
Config._get_env_value(variable)
|
|
21
|
+
|
|
22
|
+
@staticmethod
|
|
23
|
+
def _load_environment():
|
|
24
|
+
if not Config._env_loaded:
|
|
25
|
+
if os.path.exists(".env"):
|
|
26
|
+
load_dotenv()
|
|
27
|
+
Config._env_loaded = True
|
|
28
|
+
|
|
29
|
+
@staticmethod
|
|
30
|
+
def _get_env_value(env):
|
|
31
|
+
Config._load_environment()
|
|
32
|
+
env_value = os.getenv(env)
|
|
33
|
+
|
|
34
|
+
if not env_value and env in Config._required_env_variables:
|
|
35
|
+
logger.error(f"""One or more of the required environment variables is missing.
|
|
36
|
+
|
|
37
|
+
To set the value of the environment variable run:
|
|
38
|
+
$ export ENV_VARIABLE_NAME="value"
|
|
39
|
+
|
|
40
|
+
The following environment variables are required:
|
|
41
|
+
{json.dumps(Config._required_env_variables, indent=4)}
|
|
42
|
+
""")
|
|
43
|
+
exit(1)
|
|
44
|
+
return env_value
|
|
45
|
+
|
|
46
|
+
@staticmethod
|
|
47
|
+
def get_db_url():
|
|
48
|
+
return f"mysql+pymysql://{Config.get_mysql_username()}:{Config.get_mysql_password()}@{Config.get_mysql_host()}/{Config.get_mysql_database()}"
|
|
49
|
+
|
|
50
|
+
@staticmethod
|
|
51
|
+
def get_db_session() -> sessionmaker:
|
|
52
|
+
if not Config._db_session:
|
|
53
|
+
try:
|
|
54
|
+
DATABASE_URL = Config.get_db_url()
|
|
55
|
+
engine = create_engine(DATABASE_URL, echo=True)
|
|
56
|
+
with engine.connect() as connection:
|
|
57
|
+
connection.execute(text("SELECT 1"))
|
|
58
|
+
|
|
59
|
+
Config._db_session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
|
|
60
|
+
logger.info("Database seassion created successfully.")
|
|
61
|
+
except OperationalError:
|
|
62
|
+
logger.error("Error: Unable to connect to the database. Please check the configuration.")
|
|
63
|
+
raise
|
|
64
|
+
|
|
65
|
+
return Config._db_session()
|
|
66
|
+
|
|
67
|
+
@staticmethod
|
|
68
|
+
def get_gitlab_token():
|
|
69
|
+
return Config._get_env_value("HAPE_GITLAB_TOKEN")
|
|
70
|
+
|
|
71
|
+
@staticmethod
|
|
72
|
+
def get_gitlab_domain():
|
|
73
|
+
return Config._get_env_value("HAPE_GITLAB_DOMAIN")
|
|
74
|
+
|
|
75
|
+
@staticmethod
|
|
76
|
+
def get_mysql_host():
|
|
77
|
+
return Config._get_env_value("HAPE_MARIADB_HOST")
|
|
78
|
+
|
|
79
|
+
@staticmethod
|
|
80
|
+
def get_mysql_username():
|
|
81
|
+
return Config._get_env_value("HAPE_MARIADB_USERNAME")
|
|
82
|
+
|
|
83
|
+
@staticmethod
|
|
84
|
+
def get_mysql_password():
|
|
85
|
+
return Config._get_env_value("HAPE_MARIADB_PASSWORD")
|
|
86
|
+
|
|
87
|
+
@staticmethod
|
|
88
|
+
def get_mysql_database():
|
|
89
|
+
return Config._get_env_value("HAPE_MARIADB_DATABASE")
|
|
File without changes
|