diff --git a/.gitignore b/.gitignore index 99a63397..cd60373b 100644 --- a/.gitignore +++ b/.gitignore @@ -76,3 +76,5 @@ __pycache__/ # PyInstaller *.manifest *.spec + +my-project/ diff --git a/README.md b/README.md index 2518e78d..32e6d92b 100644 --- a/README.md +++ b/README.md @@ -4,14 +4,15 @@ Create and deploy generative (LLMs and [difussers](https://github.com/huggingface/diffusers)) applications (chatbots and APIs) in seconds. - **Open:** Use any model (OpenAI, Llama, Groq, Midjourney) and any library like (LangChainl, DSPy). -- **Intuitive:** No need to learn an app framework (streamlit, flask), simply use stdin and stdout. -- **Scalable:** Engineers can esily integrate your app with Docker or use Hal9's self-service enterprise cloud. +- **Intuitive:** No need to learn app frameworks (flask), simply use stdin and stdout, or write file to disk. +- **Scalable:** Engineers can integrate your app with scalable technilogies (Docker, Kubernetes, etc) +- **Powerful:** Using an OS process (stdin, stdout, files) as our app contract, enables long-running agents, multiple programming languages, and complex system dependencies. Focus on AI (RAG, fine-tuning, aligment, training) and skip engineering tasks (frontend development, backend integration, deployment, operations). ## Getting started -To create and deploy a chatbot in 10 seconds run the following: +To create and share a chatbot in seconds by running the following commands: ```bash pip install hal9 @@ -35,8 +36,6 @@ hal9 create my-project --template langchain A template provides ready to use code with specific technologies and use cases. If you already have code, you can skip this step. -Send a PR if you want to add additional templates. - ## Development To make changes to your project, open `my-project/` in your IDE and modify `my-project/app.py`. @@ -53,47 +52,37 @@ export OPENAI_KEY=YOUR_OPENAI_KEY If you customized your template with `--template` make sure to set the correct key, for example `export GROQ_KEY=YOUR_GROQ_KEY`. -## Runtime - -Run your application as follows, +You can then run your application locally with: -```python -python app.py +```bash +hal9 run . ``` -Use the command line tool to enter prompts, type `` twice to send the prompt to your code. Replies will be streamed back to console. - -From the parent folder, you can also run your application as follows: +or ```bash +cd .. hal9 run my-project ``` -## Deployment +This command is just a convenience wrapper over `python app.py` -We currently support Docker and `hal9.com`. Developers can send PR's with additional technologies or providers. +## Deployment -### Docker +The deploy command will prepare for deployment your generative app. -To deploy your project through Docker run: +For example, you can prepare deployment as a generative app (Hal9), an API (Flask), a data app (Streamlit), or a container (Docker). ```bash -docker build . -docker run . +hal9 deploy my-project --target hal9 +hal9 deploy my-project --target docker ``` -Your backend and frontend engineers can then easily consume this as an API. You can share the `my-project/` path as a GitHub repo with your infrastructure team for them to deploy to your cloud provider. There are GitHub actions available to build and deploy Docker images. +Eeach command is tasked with preparing the deployment of your project folder. For example, `--target docker` will create a `Dockerfile` file that gets this project ready to run in cloud containers. -### Hal9 +For personal use, `--target hal9` supports a free tier at `hal9.com`; enterprise support is also available to deploy with `--target hal9 --url hal9.yourcompany.com` -To deploy to `hal9.com` run: +## Contributing -```bash -hal9 deploy my-project --target hal9.com -``` - -When Hal9 runs in your own cloud you can replace `--target hal9.com` with the correct domain, for example: +Pull Requests are welcomed to consider additional application templates or deployment targets. See [CONTIBUTE.md](CONTIBUTE.md). -```bash -hal9 deploy my-project --target hal9.acme.com -``` diff --git a/python/hal9/cli.py b/python/hal9/cli.py index bdd3c94c..b7b47d4d 100644 --- a/python/hal9/cli.py +++ b/python/hal9/cli.py @@ -16,7 +16,7 @@ def cli(): @click.command() @click.argument('path') -def create(path): +def create(path :str): """ Create Project @@ -26,7 +26,7 @@ def create(path): @click.command() @click.argument('path') -def run(path): +def run(path :str): """ Run Project @@ -36,13 +36,14 @@ def run(path): @click.command() @click.argument('path') -def deploy(path): +@click.option('--target', default="hal9", help='Deployment target') +def deploy(path :str, target :str): """ Deploy Project PATH: The path to the project. Required argument. """ - print(f'Deploying {path}') + api_deploy(path, target) cli.add_command(create) cli.add_command(run) diff --git a/python/hal9/create.py b/python/hal9/create.py index d6de5db9..4ae02db0 100644 --- a/python/hal9/create.py +++ b/python/hal9/create.py @@ -13,8 +13,8 @@ def create(path :str, template :str) -> str: The template to use. """ - current_dir = Path(__file__).parent - template_path = current_dir / "templates" / template + package_dir = Path(__file__).parent + template_path = package_dir / "templates" / template os.makedirs(path, exist_ok=True) diff --git a/python/hal9/deploy.py b/python/hal9/deploy.py index b7a3ae56..d939d9b0 100644 --- a/python/hal9/deploy.py +++ b/python/hal9/deploy.py @@ -1,8 +1,8 @@ -import requests -import time -import tempfile -import sys -import runpy +from hal9.targets.docker import deploy as deploy_docker + +targets = { + 'docker': deploy_docker, +} def deploy(path :str, target :str) -> str: """Deploy an application @@ -15,18 +15,7 @@ def deploy(path :str, target :str) -> str: The deployment target, defaults to 'hal9.com'. """ - response = requests.post('https://api.hal9.com/api/v1/deploy', json = { - 'name': 'name', - 'title': 'title', - 'description': 'description', - 'access': 'access', - 'code': 'code', - 'prompt': 'prompt', - 'thumbnail': 'thumbnail', - 'token': 'token', - 'user': 'user', - }) - - if not response.ok: - print('Failed to deploy') - exit() \ No newline at end of file + if target in targets: + targets[target](path) + else: + raise Exception(f"Deployment target '{target}' is unsupported.") diff --git a/python/hal9/targets/docker.py b/python/hal9/targets/docker.py new file mode 100644 index 00000000..3f3b18ee --- /dev/null +++ b/python/hal9/targets/docker.py @@ -0,0 +1,10 @@ +import shutil +from pathlib import Path + +def deploy(path :str) -> str: + package_dir = Path(__file__).parent.parent + source_path = package_dir / 'templates' / 'docker' / 'Dockerfile' + destination_path = Path(path) / 'Dockerfile' + + print(f'Copying {source_path} to {destination_path}') + shutil.copy(source_path, destination_path) diff --git a/python/hal9/targets/hal9.py b/python/hal9/targets/hal9.py new file mode 100644 index 00000000..534ead78 --- /dev/null +++ b/python/hal9/targets/hal9.py @@ -0,0 +1,20 @@ +import requests + +def deploy(path :str) -> str: + response = requests.post('https://api.hal9.com/api/v1/deploy', json = { + 'name': 'name', + 'title': 'title', + 'description': 'description', + 'access': 'access', + 'code': 'code', + 'prompt': 'prompt', + 'thumbnail': 'thumbnail', + 'token': 'token', + 'user': 'user', + }) + + if not response.ok: + print('Failed to deploy') + exit() + + return \ No newline at end of file diff --git a/python/hal9/templates/docker/Dockerfile b/python/hal9/templates/docker/Dockerfile new file mode 100644 index 00000000..5f21bcd8 --- /dev/null +++ b/python/hal9/templates/docker/Dockerfile @@ -0,0 +1,3 @@ +FROM python:3.11-slim + +RUN apt-get update diff --git a/python/pyproject.toml b/python/pyproject.toml index 58fb820b..0a391c54 100644 --- a/python/pyproject.toml +++ b/python/pyproject.toml @@ -1,10 +1,10 @@ [tool.poetry] name = "hal9" -version = "2.0.4" +version = "2.0.5" description = "" authors = ["Javier Luraschi "] readme = "README.md" -include = ["templates/openai/app.py"] +include = ["templates/openai/app.py", "templates/docker/Dockerfile"] [tool.poetry.dependencies] python = ">=3.8,<3.9.7 || >3.9.7,<4.0" diff --git a/python/test/app.py b/python/test/app.py deleted file mode 100644 index 30c08761..00000000 --- a/python/test/app.py +++ /dev/null @@ -1,3 +0,0 @@ - -name = input("What's your name? ") -print(f"Hello {name}")