<img src="https://raw.githubusercontent.com/hazemataya94/hape-framework/refs/heads/main/docs/logo.png" width="100%">
# HAPE Framework: Overview & Features
## What is HAPE Framework?
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.
HAPE Framework 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.
## Idea Origin
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.
HAPE Framework aims to reduce this complexity by enabling platform engineers to build opinionated, yet flexible automation tools that simplify the work to build a platform.
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 state management via databases, and integration with existing DevOps tools.
## Done Features
### Automate everyday commands
```sh
$ make list
build Build the package in dist. Runs: bump-version.
bump-version Bump the patch version in setup.py.
clean Clean up build, cache, playground and zip files.
docker-down Stop Docker services.
docker-exec Execute a shell in the HAPE Docker container.
docker-ps List running Docker services.
docker-python Runs a Python container in playground directory.
docker-restart Restart Docker services.
docker-up Start Docker services.
freeze-cli Freeze dependencies for CLI.
freeze-dev Freeze dependencies for development.
git-hooks Install hooks in .git-hooks/ to .git/hooks/.
init-cli Install CLI dependencies.
init-dev Install development dependencies in .venv, docker-compose up -d, and create .env if not exist.
install Install the package.
list Show available commands.
migration-create Create a new database migration.
migration-run Apply the latest database migrations.
play Run hape.playground Playground.paly() and print the execution time.
publish Publish package to public PyPI, commit, tag, and push the version. Runs: test-code,build.
reset-data Deletes hello-world project from previous tests, drops and creates database hape_db.
reset-local Deletes hello-world project from previous tests, drops and creates database hape_db, runs migrations, and runs the playground.
source-env Print export statements for the environment variables from .env file.
test-cli Run a new python container, installs hape cli and runs all tests inside it.
test-code Runs containers in dockerfiles/docker-compose.yml, Deletes hello-world project from previous tests, and run all code automated tests.
zip Create a zip archive excluding local files and playground.
```
### Publish to public PyPI repository
```sh
$ make publish
🔄 Bumping patch version in setup.py...
Version updated to 0.x.x
* Creating isolated environment: venv+pip...
* Installing packages in isolated environment:
- setuptools >= 40.8.0
* Getting build dependencies for sdist...
0.x.x
.
Successfully built hape-0.x.x.tar.gz and hape-0.x.x-py3-none-any.whl
Uploading distributions to https://upload.pypi.org/legacy/
Uploading hape-0.x.x-py3-none-any.whl
100% ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 63.6/63.6 kB • 00:00 • 55.1 MB/s
Uploading hape-0.x.x.tar.gz
100% ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 54.3/54.3 kB • 00:00 • 35.6 MB/s
.
View at:
https://pypi.org/project/hape/0.x.x/
.
Pushing commits
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
.
Pushing tags
Total 0 (delta 0), reused 0 (delta 0), pack-reused 0
To github.com:hazemataya94/hape-framework.git
* [new tag] 0.x.x -> 0.x.x
Python files detected, running code tests...
Making sure hape container is running
hape hape:dev "sleep infinity" hape 9 hours ago Up 9 hours
Removing hello-world project from previous tests
Dropping and creating database hape_db
Running all tests in hape container defined in dockerfiles/docker-compose.yml
=============================================================
Running all code tests
=============================================================
Running ./tests/init-project.sh
--------------------------------
Installing tree if not installed
Deleting project hello-world if exists
Initializing project hello-world
...
$ hape crud delete --delete test-model
Deleted: hello_world/models/test_model_model.py
Deleted: hello_world/controllers/test_model_controller.py
Deleted: hello_world/argument_parsers/test_model_argument_parser.py
All model files -except the migration file- have been deleted successfully!
=============================================================
All tests finished successfully!
```
### Install latest `hape` CLI
```sh
$ make install
```
or
```sh
$ pip install --upgrade hape
```
### Support Initializing Project
```sh
$ hape init project --name hello-world
Project hello-world has been successfully initialized!
$ tree hello-world
hello-world
├── MANIFEST.in
├── Makefile
├── README.md
├── alembic.ini
├── dockerfiles
│ ├── Dockerfile.dev
│ ├── Dockerfile.prod
│ └── docker-compose.yml
├── hello_world
│ ├── __init__.py
│ ├── argument_parsers
│ │ ├── __init__.py
│ │ ├── main_argument_parser.py
│ │ └── playground_argument_parser.py
│ ├── bootstrap.py
│ ├── cli.py
│ ├── controllers
│ │ └── __init__.py
│ ├── enums
│ │ └── __init__.py
│ ├── migrations
│ │ ├── README
│ │ ├── env.py
│ │ ├── json
│ │ │ └── 000001_migration.json
│ │ ├── script.py.mako
│ │ ├── versions
│ │ │ └── 000001_migration.py
│ │ └── yaml
│ │ └── 000001_migration.yaml
│ ├── models
│ │ ├── __init__.py
│ │ └── test_model_cost_model.py
│ ├── playground.py
│ └── services
│ └── __init__.py
├── main.py
├── requirements-cli.txt
├── requirements-dev.txt
└── setup.py
```
### Generate CRUD JSON Schema
```sh
$ hape json get --model-schema
{
"valid_types": ["string", "text", "int", "bool", "float", "date", "datetime", "timestamp"],
"valid_properties": ["nullable", "required", "unique", "primary", "autoincrement", "foreign-key", "index"],
"valid_foreign_key_on_delete": ["cascade", "set-null", "set-default", "restrict", "no-action"],
"foreign_key_syntax": "foreign-key(foreign-key-model.foreign-key-attribute, on-delete=foreign-key-on-delete)",
"model-name": {
"column_name": {"valid-type": ["valid-property"]},
"id": {"valid-type": ["valid-property"]},
"updated_at": {"valid-type": []},
"name": {"valid-type": ["valid-property", "valid-property"]},
"enabled": {"valid-type": []},
}
"example-model": {
"id": {"int": ["primary"]},
"updated_at": {"timestamp": []},
"name": {"string": ["required", "unique"]},
"enabled": {"bool": []}
}
}
```
### Generate CRUD YAML Schema
```sh
$ hape yaml get --model-schema
valid_types: ["string", "text", "int", "bool", "float", "date", "datetime", "timestamp"]
valid_properties: ["nullable", "required", "unique", "primary", "autoincrement", "foreign-key", "index"]
valid_foreign_key_on_delete: ["cascade", "set-null", "set-default", "restrict", "no-action"]
foreign_key_syntax: "foreign-key(foreign-key-model.foreign-key-attribute, on-delete=foreign-key-on-delete)"
model-name:
column_name:
valid-type:
- valid-property
id:
valid-type:
- valid-property
updated_at:
valid-type: []
name:
valid-type:
- valid-property
- valid-property
enabled:
valid-type: []
example-model:
id:
int:
- primary
updated_at:
timestamp: []
name:
string:
- required
- unique
enabled:
bool: []
```
### Support CRUD Generate and Create migrations/json/model_name.json and migrations/yaml/model_name.yaml
```sh
$ hape crud generate --json '
{
"k8s-deployment": {
"id": {"int": ["primary", "autoincrement"]},
"service-name": {"string": []},
"pod-cpu": {"string": []},
"pod-ram": {"string": []},
"autoscaling": {"bool": []},
"min-replicas": {"int": ["nullable"]},
"max-replicas": {"int": ["nullable"]},
"current-replicas": {"int": []}
},
"test-deployment-cost": {
"id": {"int": ["primary", "autoincrement"]},
"test-deployment-id": {"int": ["required", "foreign-key(test-deployment.id, on-delete=cascade)"]},
"pod-cost": {"string": []},
"number-of-pods": {"int": []},
"total-cost": {"float": []}
}
}'
Generated: hello_world/argument_parsers/k8s_deployment_argument_parser.py
Generated: hello_world/controllers/k8s_deployment_controller.py
Generated: hello_world/models/k8s_deployment_model.py
Generated: hello_world/argument_parsers/test_deployment_cost_argument_parser.py
Generated: hello_world/controllers/test_deployment_cost_controller.py
Generated: hello_world/models/test_deployment_cost_model.py
Generated: hello_world/migrations/versions/000001_migration.py
Generated: hello_world/migrations/json/000001_migration.json
Generated: hello_world/migrations/yaml/000001_migration.yaml
```
## In Progress Features
### Create GitHub Project to Manage issues, tasks and future workfr
### Support CRUD CLI for CRUD generated models
```sh
$ hape k8s-deployment-cost --help
usage: hello-world k8s-deployment-cost [-h] {save,get,get-all,delete,delete-all} ...
positional arguments:
{save,get,get-all,delete,delete-all}
save Save K8SDeploymentCost object based on passed arguments or filters
get Get K8SDeploymentCost object based on passed arguments or filters
get-all Get-all K8SDeploymentCost objects based on passed arguments or filters
delete Delete K8SDeploymentCost object based on passed arguments or filters
delete-all Delete-all K8SDeploymentCost objects based on passed arguments or filters
options:
-h, --help show this help message and exit
```
## TODO Features
### Create migrations/json/model_name.json and run CRUD Geneartion for file in migrations/schema_json/{*}.json if models/file.py doesn't exist
```sh
$ export MY_JSON_FILE="""
{
"name": "deployment-cost"
"schema": {
"id": ["int","autoincrement"],
"service-name": ["string"],
"pod-cpu": ["string"],
"pod-ram": ["string"],
"autoscaling": ["bool"],
"min-replicas": ["int","nullable"],
"max-replicas": ["int","nullable"],
"current-replicas": ["int"],
"pod-cost": ["string"],
"number-of-pods": ["int"],
"total-cost": ["float"],
"cost-unit": ["string"]
}
}
"""
$ echo "${MY_JSON_FILE}" > migrations/schema_json/deployment_cost.json
$ hape crud generate
$ hape deployment-cost --help
usage: hape deployment-cost [-h] {save,get,get-all,delete,delete-all} ...
positional arguments:
{save,get,get-all,delete,delete-all}
save Save DeploymentCost object based on passed arguments or filters
get Get DeploymentCost object based on passed arguments or filters
get-all Get-all DeploymentCost objects based on passed arguments or filters
delete Delete DeploymentCost object based on passed arguments or filters
delete-all Delete-all DeploymentCost objects based on passed arguments or filters
options:
-h, --help show this help message and exit
```
### Generate CHANGELOG.md
```sh
$ hape changelog generate
$ echo "empty" > file.txt
$ git add file.txt
$ git commit -m "empty"
$ git push
$ make publish
$ hape changelog generate # generate CHANGELOG.md from scratch
$ hape changelog update # append missing versions to CHANGELOG.md
```
### Support Scalable Secure RESTful API
```sh
$ export MY_JSON_FILE="""
{
"name": "deployment-cost"
"schema": {
"id": ["int","autoincrement"],
"service-name": ["string"],
"pod-cpu": ["string"],
"pod-ram": ["string"],
"autoscaling": ["bool"],
"min-replicas": ["int","nullable"],
"max-replicas": ["int","nullable"],
"current-replicas": ["int"],
"pod-cost": ["string"],
"number-of-pods": ["int"],
"total-cost": ["float"],
"cost-unit": ["string"]
}
}
"""
$ echo "${MY_JSON_FILE}" > migrations/schema_json/deployment_cost.json
$ hape crud generate
$ hape deployment-cost --help
usage: hape deployment-cost [-h] {save,get,get-all,delete,delete-all} ...
positional arguments:
{save,get,get-all,delete,delete-all}
save Save DeploymentCost object based on passed arguments or filters
get Get DeploymentCost object based on passed arguments or filters
get-all Get-all DeploymentCost objects based on passed arguments or filters
delete Delete DeploymentCost object based on passed arguments or filters
delete-all Delete-all DeploymentCost objects based on passed arguments or filters
options:
-h, --help show this help message and exit
```
### Support Scalable Secure RESTful API
```sh
$ hape serve http --allow-cidr '0.0.0.0/0,10.0.1.0/24' --deny-cidr '10.200.0.0/24,0,10.0.1.0/24,10.107.0.0/24' --workers 2 --port 80
or
$ hape serve http --json """
{
"port": 8088
"allow-cidr": "0.0.0.0/0,10.0.1.0/24",
"deny-cidr": "10.200.0.0/24,0,10.0.1.0/24,10.107.0.0/24"
}
"""
Spawnining workers
hape-worker-random-string-1 is up
hape-worker-random-string-2 failed
hape-worker-random-string-2 restarting (up to 3 times)
hape-worker-random-string-2 is up
All workers are up
Database connection established
Any other needed step
Serving HAPE on http://127.0.0.1:8088
```
### Support CRUD Environment Variables
```sh
$ hape env add --key MY_ENV_KEY --value MY_ENV_VALUE
$ hape env get --key MY_ENV_KEY
MY_ENV_KEY=MY_ENV_VALUE
$ hape env delete --key MY_ENV_KEY
$ hape env get --key MY_ENV_KEY
MY_ENV_KEY=MY_ENV_VALUE
```
### Store Configuration in Database
```sh
$ hape config add --key MY_CONFIG_KEY --value MY_CONFIG_VALUE
$ hape config set --key MY_CONFIG_KEY --value MY_CONFIG_VALUE
$ hape config set --key MY_CONFIG_KEY --value MY_CONFIG_VALUE
$ hape config get --key MY_CONFIG_KEY
MY_CONFIG_KEY=MY_CONFIG_VALUE
$ hape config delete --key MY_CONFIG_KEY
$ hape config get --key MY_CONFIG_KEY
MY_CONFIG_KEY=MY_CONFIG_VALUE
```
### Run Using Environment Variables or Database Configuration
```sh
$ hape config set --config_source env
$ hape config set --config_source db
$ hape config set --config_env_prefix MY_ENV_PREFIX
```
Raw data
{
"_id": null,
"home_page": "https://github.com/hazemataya94/hape-framework",
"name": "hape",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.9",
"maintainer_email": null,
"keywords": null,
"author": "Hazem Ataya",
"author_email": "hazem.ataya94@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/bb/b7/f5624d5b76dc1d1b41d3b2debb82cf6c7304680968224ec8ba5b681f5f80/hape-0.2.98.tar.gz",
"platform": null,
"description": "\n<img src=\"https://raw.githubusercontent.com/hazemataya94/hape-framework/refs/heads/main/docs/logo.png\" width=\"100%\">\n\n# HAPE Framework: Overview & Features\n\n## What is HAPE Framework?\nHAPE 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. \n\nHAPE Framework 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. \n\n## Idea Origin\nModern 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. \n\nHAPE Framework aims to reduce this complexity by enabling platform engineers to build opinionated, yet flexible automation tools that simplify the work to build a platform. \n\nWith 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 state management via databases, and integration with existing DevOps tools. \n\n## Done Features\n### Automate everyday commands\n```sh\n$ make list\nbuild Build the package in dist. Runs: bump-version.\nbump-version Bump the patch version in setup.py.\nclean Clean up build, cache, playground and zip files.\ndocker-down Stop Docker services.\ndocker-exec Execute a shell in the HAPE Docker container.\ndocker-ps List running Docker services.\ndocker-python Runs a Python container in playground directory.\ndocker-restart Restart Docker services.\ndocker-up Start Docker services.\nfreeze-cli Freeze dependencies for CLI.\nfreeze-dev Freeze dependencies for development.\ngit-hooks Install hooks in .git-hooks/ to .git/hooks/.\ninit-cli Install CLI dependencies.\ninit-dev Install development dependencies in .venv, docker-compose up -d, and create .env if not exist.\ninstall Install the package.\nlist Show available commands.\nmigration-create Create a new database migration.\nmigration-run Apply the latest database migrations.\nplay Run hape.playground Playground.paly() and print the execution time.\npublish Publish package to public PyPI, commit, tag, and push the version. Runs: test-code,build.\nreset-data Deletes hello-world project from previous tests, drops and creates database hape_db.\nreset-local Deletes hello-world project from previous tests, drops and creates database hape_db, runs migrations, and runs the playground.\nsource-env Print export statements for the environment variables from .env file.\ntest-cli Run a new python container, installs hape cli and runs all tests inside it.\ntest-code Runs containers in dockerfiles/docker-compose.yml, Deletes hello-world project from previous tests, and run all code automated tests.\nzip Create a zip archive excluding local files and playground.\n```\n\n### Publish to public PyPI repository\n```sh\n$ make publish\n\ud83d\udd04 Bumping patch version in setup.py...\nVersion updated to 0.x.x\n* Creating isolated environment: venv+pip...\n* Installing packages in isolated environment:\n - setuptools >= 40.8.0\n* Getting build dependencies for sdist...\n0.x.x\n.\nSuccessfully built hape-0.x.x.tar.gz and hape-0.x.x-py3-none-any.whl\nUploading distributions to https://upload.pypi.org/legacy/\nUploading hape-0.x.x-py3-none-any.whl\n100% \u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501 63.6/63.6 kB \u2022 00:00 \u2022 55.1 MB/s\nUploading hape-0.x.x.tar.gz\n100% \u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501 54.3/54.3 kB \u2022 00:00 \u2022 35.6 MB/s\n.\nView at:\nhttps://pypi.org/project/hape/0.x.x/\n.\nPushing commits\nEnumerating objects: 5, done.\nCounting objects: 100% (5/5), done.\n.\nPushing tags\nTotal 0 (delta 0), reused 0 (delta 0), pack-reused 0\nTo github.com:hazemataya94/hape-framework.git\n * [new tag] 0.x.x -> 0.x.x\nPython files detected, running code tests...\nMaking sure hape container is running\nhape hape:dev \"sleep infinity\" hape 9 hours ago Up 9 hours \nRemoving hello-world project from previous tests\nDropping and creating database hape_db\nRunning all tests in hape container defined in dockerfiles/docker-compose.yml\n=============================================================\nRunning all code tests\n=============================================================\nRunning ./tests/init-project.sh\n--------------------------------\nInstalling tree if not installed\nDeleting project hello-world if exists\nInitializing project hello-world\n...\n$ hape crud delete --delete test-model\nDeleted: hello_world/models/test_model_model.py\nDeleted: hello_world/controllers/test_model_controller.py\nDeleted: hello_world/argument_parsers/test_model_argument_parser.py\nAll model files -except the migration file- have been deleted successfully!\n=============================================================\nAll tests finished successfully!\n```\n\n### Install latest `hape` CLI\n```sh\n$ make install\n```\nor\n```sh\n$ pip install --upgrade hape\n```\n\n### Support Initializing Project\n```sh\n$ hape init project --name hello-world\nProject hello-world has been successfully initialized!\n$ tree hello-world \nhello-world\n\u251c\u2500\u2500 MANIFEST.in\n\u251c\u2500\u2500 Makefile\n\u251c\u2500\u2500 README.md\n\u251c\u2500\u2500 alembic.ini\n\u251c\u2500\u2500 dockerfiles\n\u2502 \u251c\u2500\u2500 Dockerfile.dev\n\u2502 \u251c\u2500\u2500 Dockerfile.prod\n\u2502 \u2514\u2500\u2500 docker-compose.yml\n\u251c\u2500\u2500 hello_world\n\u2502 \u251c\u2500\u2500 __init__.py\n\u2502 \u251c\u2500\u2500 argument_parsers\n\u2502 \u2502 \u251c\u2500\u2500 __init__.py\n\u2502 \u2502 \u251c\u2500\u2500 main_argument_parser.py\n\u2502 \u2502 \u2514\u2500\u2500 playground_argument_parser.py\n\u2502 \u251c\u2500\u2500 bootstrap.py\n\u2502 \u251c\u2500\u2500 cli.py\n\u2502 \u251c\u2500\u2500 controllers\n\u2502 \u2502 \u2514\u2500\u2500 __init__.py\n\u2502 \u251c\u2500\u2500 enums\n\u2502 \u2502 \u2514\u2500\u2500 __init__.py\n\u2502 \u251c\u2500\u2500 migrations\n\u2502 \u2502 \u251c\u2500\u2500 README\n\u2502 \u2502 \u251c\u2500\u2500 env.py\n\u2502 \u2502 \u251c\u2500\u2500 json\n\u2502 \u2502 \u2502 \u2514\u2500\u2500 000001_migration.json\n\u2502 \u2502 \u251c\u2500\u2500 script.py.mako\n\u2502 \u2502 \u251c\u2500\u2500 versions\n\u2502 \u2502 \u2502 \u2514\u2500\u2500 000001_migration.py\n\u2502 \u2502 \u2514\u2500\u2500 yaml\n\u2502 \u2502 \u2514\u2500\u2500 000001_migration.yaml\n\u2502 \u251c\u2500\u2500 models\n\u2502 \u2502 \u251c\u2500\u2500 __init__.py\n\u2502 \u2502 \u2514\u2500\u2500 test_model_cost_model.py\n\u2502 \u251c\u2500\u2500 playground.py\n\u2502 \u2514\u2500\u2500 services\n\u2502 \u2514\u2500\u2500 __init__.py\n\u251c\u2500\u2500 main.py\n\u251c\u2500\u2500 requirements-cli.txt\n\u251c\u2500\u2500 requirements-dev.txt\n\u2514\u2500\u2500 setup.py\n```\n\n### Generate CRUD JSON Schema\n```sh\n$ hape json get --model-schema\n{\n \"valid_types\": [\"string\", \"text\", \"int\", \"bool\", \"float\", \"date\", \"datetime\", \"timestamp\"],\n \"valid_properties\": [\"nullable\", \"required\", \"unique\", \"primary\", \"autoincrement\", \"foreign-key\", \"index\"],\n \"valid_foreign_key_on_delete\": [\"cascade\", \"set-null\", \"set-default\", \"restrict\", \"no-action\"],\n \"foreign_key_syntax\": \"foreign-key(foreign-key-model.foreign-key-attribute, on-delete=foreign-key-on-delete)\",\n \n \"model-name\": {\n \"column_name\": {\"valid-type\": [\"valid-property\"]},\n \"id\": {\"valid-type\": [\"valid-property\"]},\n \"updated_at\": {\"valid-type\": []},\n \"name\": {\"valid-type\": [\"valid-property\", \"valid-property\"]},\n \"enabled\": {\"valid-type\": []},\n }\n \n \"example-model\": {\n \"id\": {\"int\": [\"primary\"]},\n \"updated_at\": {\"timestamp\": []},\n \"name\": {\"string\": [\"required\", \"unique\"]},\n \"enabled\": {\"bool\": []}\n }\n}\n```\n\n### Generate CRUD YAML Schema\n```sh\n$ hape yaml get --model-schema\nvalid_types: [\"string\", \"text\", \"int\", \"bool\", \"float\", \"date\", \"datetime\", \"timestamp\"]\nvalid_properties: [\"nullable\", \"required\", \"unique\", \"primary\", \"autoincrement\", \"foreign-key\", \"index\"]\nvalid_foreign_key_on_delete: [\"cascade\", \"set-null\", \"set-default\", \"restrict\", \"no-action\"]\nforeign_key_syntax: \"foreign-key(foreign-key-model.foreign-key-attribute, on-delete=foreign-key-on-delete)\"\n\nmodel-name:\n column_name:\n valid-type: \n - valid-property\n id:\n valid-type: \n - valid-property\n updated_at:\n valid-type: []\n name:\n valid-type: \n - valid-property\n - valid-property\n enabled:\n valid-type: []\n\nexample-model:\n id:\n int: \n - primary\n updated_at:\n timestamp: []\n name:\n string: \n - required\n - unique\n enabled:\n bool: []\n```\n\n### Support CRUD Generate and Create migrations/json/model_name.json and migrations/yaml/model_name.yaml\n```sh\n$ hape crud generate --json '\n{\n \"k8s-deployment\": {\n \"id\": {\"int\": [\"primary\", \"autoincrement\"]},\n \"service-name\": {\"string\": []},\n \"pod-cpu\": {\"string\": []},\n \"pod-ram\": {\"string\": []},\n \"autoscaling\": {\"bool\": []},\n \"min-replicas\": {\"int\": [\"nullable\"]},\n \"max-replicas\": {\"int\": [\"nullable\"]},\n \"current-replicas\": {\"int\": []}\n },\n \"test-deployment-cost\": {\n \"id\": {\"int\": [\"primary\", \"autoincrement\"]},\n \"test-deployment-id\": {\"int\": [\"required\", \"foreign-key(test-deployment.id, on-delete=cascade)\"]},\n \"pod-cost\": {\"string\": []},\n \"number-of-pods\": {\"int\": []},\n \"total-cost\": {\"float\": []}\n }\n}'\nGenerated: hello_world/argument_parsers/k8s_deployment_argument_parser.py\nGenerated: hello_world/controllers/k8s_deployment_controller.py\nGenerated: hello_world/models/k8s_deployment_model.py\nGenerated: hello_world/argument_parsers/test_deployment_cost_argument_parser.py\nGenerated: hello_world/controllers/test_deployment_cost_controller.py\nGenerated: hello_world/models/test_deployment_cost_model.py\nGenerated: hello_world/migrations/versions/000001_migration.py\nGenerated: hello_world/migrations/json/000001_migration.json\nGenerated: hello_world/migrations/yaml/000001_migration.yaml\n```\n\n## In Progress Features\n### Create GitHub Project to Manage issues, tasks and future workfr\n\n### Support CRUD CLI for CRUD generated models\n```sh\n$ hape k8s-deployment-cost --help\nusage: hello-world k8s-deployment-cost [-h] {save,get,get-all,delete,delete-all} ...\n\npositional arguments:\n {save,get,get-all,delete,delete-all}\n save Save K8SDeploymentCost object based on passed arguments or filters\n get Get K8SDeploymentCost object based on passed arguments or filters\n get-all Get-all K8SDeploymentCost objects based on passed arguments or filters\n delete Delete K8SDeploymentCost object based on passed arguments or filters\n delete-all Delete-all K8SDeploymentCost objects based on passed arguments or filters\n\noptions:\n -h, --help show this help message and exit\n```\n\n## TODO Features\n\n### Create migrations/json/model_name.json and run CRUD Geneartion for file in migrations/schema_json/{*}.json if models/file.py doesn't exist\n```sh\n$ export MY_JSON_FILE=\"\"\"\n{\n \"name\": \"deployment-cost\"\n \"schema\": {\n \"id\": [\"int\",\"autoincrement\"],\n \"service-name\": [\"string\"],\n \"pod-cpu\": [\"string\"],\n \"pod-ram\": [\"string\"],\n \"autoscaling\": [\"bool\"],\n \"min-replicas\": [\"int\",\"nullable\"],\n \"max-replicas\": [\"int\",\"nullable\"],\n \"current-replicas\": [\"int\"],\n \"pod-cost\": [\"string\"],\n \"number-of-pods\": [\"int\"],\n \"total-cost\": [\"float\"],\n \"cost-unit\": [\"string\"]\n }\n}\n\"\"\"\n$ echo \"${MY_JSON_FILE}\" > migrations/schema_json/deployment_cost.json\n$ hape crud generate\n$ hape deployment-cost --help\nusage: hape deployment-cost [-h] {save,get,get-all,delete,delete-all} ...\n\npositional arguments:\n {save,get,get-all,delete,delete-all}\n save Save DeploymentCost object based on passed arguments or filters\n get Get DeploymentCost object based on passed arguments or filters\n get-all Get-all DeploymentCost objects based on passed arguments or filters\n delete Delete DeploymentCost object based on passed arguments or filters\n delete-all Delete-all DeploymentCost objects based on passed arguments or filters\n\noptions:\n -h, --help show this help message and exit\n```\n\n### Generate CHANGELOG.md\n```sh\n$ hape changelog generate\n$ echo \"empty\" > file.txt\n$ git add file.txt\n$ git commit -m \"empty\"\n$ git push\n$ make publish\n$ hape changelog generate # generate CHANGELOG.md from scratch\n$ hape changelog update # append missing versions to CHANGELOG.md\n```\n\n### Support Scalable Secure RESTful API\n```sh\n$ export MY_JSON_FILE=\"\"\"\n{\n \"name\": \"deployment-cost\"\n \"schema\": {\n \"id\": [\"int\",\"autoincrement\"],\n \"service-name\": [\"string\"],\n \"pod-cpu\": [\"string\"],\n \"pod-ram\": [\"string\"],\n \"autoscaling\": [\"bool\"],\n \"min-replicas\": [\"int\",\"nullable\"],\n \"max-replicas\": [\"int\",\"nullable\"],\n \"current-replicas\": [\"int\"],\n \"pod-cost\": [\"string\"],\n \"number-of-pods\": [\"int\"],\n \"total-cost\": [\"float\"],\n \"cost-unit\": [\"string\"]\n }\n}\n\"\"\"\n$ echo \"${MY_JSON_FILE}\" > migrations/schema_json/deployment_cost.json\n$ hape crud generate\n$ hape deployment-cost --help\nusage: hape deployment-cost [-h] {save,get,get-all,delete,delete-all} ...\n\npositional arguments:\n {save,get,get-all,delete,delete-all}\n save Save DeploymentCost object based on passed arguments or filters\n get Get DeploymentCost object based on passed arguments or filters\n get-all Get-all DeploymentCost objects based on passed arguments or filters\n delete Delete DeploymentCost object based on passed arguments or filters\n delete-all Delete-all DeploymentCost objects based on passed arguments or filters\n\noptions:\n -h, --help show this help message and exit\n```\n\n### Support Scalable Secure RESTful API\n```sh\n$ hape serve http --allow-cidr '0.0.0.0/0,10.0.1.0/24' --deny-cidr '10.200.0.0/24,0,10.0.1.0/24,10.107.0.0/24' --workers 2 --port 80\nor\n$ hape serve http --json \"\"\"\n{\n \"port\": 8088\n \"allow-cidr\": \"0.0.0.0/0,10.0.1.0/24\",\n \"deny-cidr\": \"10.200.0.0/24,0,10.0.1.0/24,10.107.0.0/24\"\n}\n\"\"\"\nSpawnining workers\nhape-worker-random-string-1 is up\nhape-worker-random-string-2 failed\nhape-worker-random-string-2 restarting (up to 3 times)\nhape-worker-random-string-2 is up\nAll workers are up\nDatabase connection established\nAny other needed step\n\nServing HAPE on http://127.0.0.1:8088\n```\n\n### Support CRUD Environment Variables\n```sh\n$ hape env add --key MY_ENV_KEY --value MY_ENV_VALUE\n$ hape env get --key MY_ENV_KEY\nMY_ENV_KEY=MY_ENV_VALUE\n$ hape env delete --key MY_ENV_KEY\n$ hape env get --key MY_ENV_KEY\nMY_ENV_KEY=MY_ENV_VALUE\n```\n\n### Store Configuration in Database\n```sh\n$ hape config add --key MY_CONFIG_KEY --value MY_CONFIG_VALUE\n$ hape config set --key MY_CONFIG_KEY --value MY_CONFIG_VALUE\n$ hape config set --key MY_CONFIG_KEY --value MY_CONFIG_VALUE\n$ hape config get --key MY_CONFIG_KEY\nMY_CONFIG_KEY=MY_CONFIG_VALUE\n$ hape config delete --key MY_CONFIG_KEY\n$ hape config get --key MY_CONFIG_KEY\nMY_CONFIG_KEY=MY_CONFIG_VALUE\n```\n\n### Run Using Environment Variables or Database Configuration\n```sh\n$ hape config set --config_source env\n$ hape config set --config_source db\n$ hape config set --config_env_prefix MY_ENV_PREFIX\n```\n",
"bugtrack_url": null,
"license": null,
"summary": "HAPE Framework: Build an Automation Tool With Ease",
"version": "0.2.98",
"project_urls": {
"Homepage": "https://github.com/hazemataya94/hape-framework"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "719c7c59edf994c0628782ddd589a47db54b5e2403fc4905c5277c1bf9adc272",
"md5": "1d00df55e6fcebdb7a94ba5b7b95fe9a",
"sha256": "1ab4c15c269354ef73208ce5d8d4326b77305bda10339113bbbb90b6462652e4"
},
"downloads": -1,
"filename": "hape-0.2.98-py3-none-any.whl",
"has_sig": false,
"md5_digest": "1d00df55e6fcebdb7a94ba5b7b95fe9a",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.9",
"size": 65951,
"upload_time": "2025-02-22T18:55:48",
"upload_time_iso_8601": "2025-02-22T18:55:48.669502Z",
"url": "https://files.pythonhosted.org/packages/71/9c/7c59edf994c0628782ddd589a47db54b5e2403fc4905c5277c1bf9adc272/hape-0.2.98-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "bbb7f5624d5b76dc1d1b41d3b2debb82cf6c7304680968224ec8ba5b681f5f80",
"md5": "c783fc11cf47e56d1d2a7f6a0838794d",
"sha256": "8a2f4e5d8b70581edd1172bc1df2e34222dad10af55d248857b98419f387b624"
},
"downloads": -1,
"filename": "hape-0.2.98.tar.gz",
"has_sig": false,
"md5_digest": "c783fc11cf47e56d1d2a7f6a0838794d",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.9",
"size": 48956,
"upload_time": "2025-02-22T18:55:50",
"upload_time_iso_8601": "2025-02-22T18:55:50.749111Z",
"url": "https://files.pythonhosted.org/packages/bb/b7/f5624d5b76dc1d1b41d3b2debb82cf6c7304680968224ec8ba5b681f5f80/hape-0.2.98.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-02-22 18:55:50",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "hazemataya94",
"github_project": "hape-framework",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "hape"
}