orchify 0.1.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 orchify might be problematic. Click here for more details.
- orchify-0.1.0/LICENSE +21 -0
- orchify-0.1.0/MANIFEST.in +9 -0
- orchify-0.1.0/PKG-INFO +163 -0
- orchify-0.1.0/README.md +138 -0
- orchify-0.1.0/orchify/__init__.py +9 -0
- orchify-0.1.0/orchify/cli.py +150 -0
- orchify-0.1.0/orchify/generator.py +17 -0
- orchify-0.1.0/orchify.egg-info/PKG-INFO +163 -0
- orchify-0.1.0/orchify.egg-info/SOURCES.txt +14 -0
- orchify-0.1.0/orchify.egg-info/dependency_links.txt +1 -0
- orchify-0.1.0/orchify.egg-info/entry_points.txt +2 -0
- orchify-0.1.0/orchify.egg-info/requires.txt +6 -0
- orchify-0.1.0/orchify.egg-info/top_level.txt +1 -0
- orchify-0.1.0/pyproject.toml +39 -0
- orchify-0.1.0/setup.cfg +4 -0
- orchify-0.1.0/tests/test_cli.py +0 -0
orchify-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Sattyam jain
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
orchify-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: orchify
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: AI-driven Dockerfile generator for any Python project
|
|
5
|
+
Author-email: Sattyam Jain <you@example.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/yourusername/Orchify
|
|
8
|
+
Project-URL: Repository, https://github.com/yourusername/Orchify
|
|
9
|
+
Project-URL: Documentation, https://yourusername.github.io/Orchify
|
|
10
|
+
Keywords: docker,cli,ai,devops,automation
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Requires-Python: >=3.8
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
License-File: LICENSE
|
|
18
|
+
Requires-Dist: click
|
|
19
|
+
Requires-Dist: agno
|
|
20
|
+
Requires-Dist: mcp
|
|
21
|
+
Requires-Dist: anthropic
|
|
22
|
+
Requires-Dist: openai
|
|
23
|
+
Requires-Dist: jinja2
|
|
24
|
+
Dynamic: license-file
|
|
25
|
+
|
|
26
|
+
# Orchify
|
|
27
|
+
[](https://pypi.org/project/orchify) [](https://pypi.org/project/orchify)
|
|
28
|
+
|
|
29
|
+
AI-driven Dockerfile and .dockerignore generator for **any** Python project.
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## 🚀 Overview
|
|
34
|
+
|
|
35
|
+
Orchify is a command-line tool that uses AI agents (via Agno and the Model Context Protocol) to:
|
|
36
|
+
|
|
37
|
+
1. **Scan** a Python project and analyze its structure, dependencies, and entrypoints.
|
|
38
|
+
2. **Generate** a production-grade, multi-stage **Dockerfile** and corresponding **.dockerignore**—tailored to the project—without manual template editing.
|
|
39
|
+
|
|
40
|
+
Whether you're containerizing a microservice, a Flask app, or a complex multi-package repository, Orchify will craft best-practice container configurations in seconds.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## đź”§ Features
|
|
45
|
+
|
|
46
|
+
- **Framework Agnostic**: Works with plain Python scripts, Flask, FastAPI, Django, and more.
|
|
47
|
+
- **AI-Powered**: Leverages Anthropic Claude or OpenAI GPT models to write idiomatic Dockerfiles.
|
|
48
|
+
- **Two-Step Workflow**: `scan` → `gen` for clear separation of analysis and generation.
|
|
49
|
+
- **Production-Ready**: Generates multi-stage builds, non-root users, cache optimizations.
|
|
50
|
+
- **Customizable**: Override prompts, model choices, output paths via CLI flags.
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## 📦 Installation
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
pip install orchify
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Or from source:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
git clone https://github.com/yourusername/Orchify.git
|
|
64
|
+
cd Orchify
|
|
65
|
+
docker run -it --rm \
|
|
66
|
+
-v "$PWD":/workspace \
|
|
67
|
+
python:3.11-slim bash -c "pip install -e ."
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## 🔨 Usage
|
|
73
|
+
|
|
74
|
+
Orchify exposes three primary commands via the `orchify` CLI:
|
|
75
|
+
|
|
76
|
+
### 1. `hello`
|
|
77
|
+
|
|
78
|
+
A sanity-check command:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
orchify hello
|
|
82
|
+
# đź‘‹ Welcome to Orchify!
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### 2. `scan`
|
|
86
|
+
|
|
87
|
+
Analyze your project and write out `orchify.json` metadata.
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
orchify scan \
|
|
91
|
+
--dir /path/to/your/project \
|
|
92
|
+
--prompt "Summarize my project for Dockerfile generation"
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
**Options:**
|
|
96
|
+
|
|
97
|
+
- `-d, --dir` <path>: Project directory (default: current directory).
|
|
98
|
+
- `-p, --prompt` <text>: Custom AI analysis prompt.
|
|
99
|
+
|
|
100
|
+
### 3. `gen`
|
|
101
|
+
|
|
102
|
+
Generate `Dockerfile` and `.dockerignore` based on the scan metadata.
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
orchify gen \
|
|
106
|
+
--model-id claude-3-7-sonnet-latest \
|
|
107
|
+
--output Dockerfile
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
**Options:**
|
|
111
|
+
|
|
112
|
+
- `-m, --model-id` <model>: Anthropic/OpenAI model to use.
|
|
113
|
+
- `-o, --output` <path>: Path for the generated Dockerfile (default: `Dockerfile`).
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## ⚙️ Configuration
|
|
118
|
+
|
|
119
|
+
Orchify uses environment variables to authenticate with AI providers:
|
|
120
|
+
|
|
121
|
+
| Variable | Description |
|
|
122
|
+
|----------------------|----------------------------------|
|
|
123
|
+
| `ANTHROPIC_API_KEY` | Your Anthropic Claude API token. |
|
|
124
|
+
| `OPENAI_API_KEY` | Your OpenAI API key (optional). |
|
|
125
|
+
|
|
126
|
+
Set them in your shell or `.env` before running commands.
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## 🛠️ Development
|
|
131
|
+
|
|
132
|
+
From your dev clone:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
# Install editable
|
|
136
|
+
pip install -e .
|
|
137
|
+
|
|
138
|
+
# Run tests
|
|
139
|
+
pytest tests/
|
|
140
|
+
|
|
141
|
+
# Lint & format
|
|
142
|
+
flake8 orchify tests
|
|
143
|
+
black orchify tests
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## 🤝 Contributing
|
|
149
|
+
|
|
150
|
+
Contributions, issues, and feature requests are welcome!
|
|
151
|
+
|
|
152
|
+
1. Fork the repo.
|
|
153
|
+
2. Create a feature branch: `git checkout -b feature/awesome`.
|
|
154
|
+
3. Commit your changes and push.
|
|
155
|
+
4. Open a Pull Request.
|
|
156
|
+
|
|
157
|
+
Please adhere to the existing code style and add tests for any new functionality.
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## đź“„ License
|
|
162
|
+
|
|
163
|
+
This project is licensed under the **MIT License**. See [LICENSE](LICENSE) for details.
|
orchify-0.1.0/README.md
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# Orchify
|
|
2
|
+
[](https://pypi.org/project/orchify) [](https://pypi.org/project/orchify)
|
|
3
|
+
|
|
4
|
+
AI-driven Dockerfile and .dockerignore generator for **any** Python project.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 🚀 Overview
|
|
9
|
+
|
|
10
|
+
Orchify is a command-line tool that uses AI agents (via Agno and the Model Context Protocol) to:
|
|
11
|
+
|
|
12
|
+
1. **Scan** a Python project and analyze its structure, dependencies, and entrypoints.
|
|
13
|
+
2. **Generate** a production-grade, multi-stage **Dockerfile** and corresponding **.dockerignore**—tailored to the project—without manual template editing.
|
|
14
|
+
|
|
15
|
+
Whether you're containerizing a microservice, a Flask app, or a complex multi-package repository, Orchify will craft best-practice container configurations in seconds.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## đź”§ Features
|
|
20
|
+
|
|
21
|
+
- **Framework Agnostic**: Works with plain Python scripts, Flask, FastAPI, Django, and more.
|
|
22
|
+
- **AI-Powered**: Leverages Anthropic Claude or OpenAI GPT models to write idiomatic Dockerfiles.
|
|
23
|
+
- **Two-Step Workflow**: `scan` → `gen` for clear separation of analysis and generation.
|
|
24
|
+
- **Production-Ready**: Generates multi-stage builds, non-root users, cache optimizations.
|
|
25
|
+
- **Customizable**: Override prompts, model choices, output paths via CLI flags.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## 📦 Installation
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
pip install orchify
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Or from source:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
git clone https://github.com/yourusername/Orchify.git
|
|
39
|
+
cd Orchify
|
|
40
|
+
docker run -it --rm \
|
|
41
|
+
-v "$PWD":/workspace \
|
|
42
|
+
python:3.11-slim bash -c "pip install -e ."
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## 🔨 Usage
|
|
48
|
+
|
|
49
|
+
Orchify exposes three primary commands via the `orchify` CLI:
|
|
50
|
+
|
|
51
|
+
### 1. `hello`
|
|
52
|
+
|
|
53
|
+
A sanity-check command:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
orchify hello
|
|
57
|
+
# đź‘‹ Welcome to Orchify!
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### 2. `scan`
|
|
61
|
+
|
|
62
|
+
Analyze your project and write out `orchify.json` metadata.
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
orchify scan \
|
|
66
|
+
--dir /path/to/your/project \
|
|
67
|
+
--prompt "Summarize my project for Dockerfile generation"
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**Options:**
|
|
71
|
+
|
|
72
|
+
- `-d, --dir` <path>: Project directory (default: current directory).
|
|
73
|
+
- `-p, --prompt` <text>: Custom AI analysis prompt.
|
|
74
|
+
|
|
75
|
+
### 3. `gen`
|
|
76
|
+
|
|
77
|
+
Generate `Dockerfile` and `.dockerignore` based on the scan metadata.
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
orchify gen \
|
|
81
|
+
--model-id claude-3-7-sonnet-latest \
|
|
82
|
+
--output Dockerfile
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
**Options:**
|
|
86
|
+
|
|
87
|
+
- `-m, --model-id` <model>: Anthropic/OpenAI model to use.
|
|
88
|
+
- `-o, --output` <path>: Path for the generated Dockerfile (default: `Dockerfile`).
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## ⚙️ Configuration
|
|
93
|
+
|
|
94
|
+
Orchify uses environment variables to authenticate with AI providers:
|
|
95
|
+
|
|
96
|
+
| Variable | Description |
|
|
97
|
+
|----------------------|----------------------------------|
|
|
98
|
+
| `ANTHROPIC_API_KEY` | Your Anthropic Claude API token. |
|
|
99
|
+
| `OPENAI_API_KEY` | Your OpenAI API key (optional). |
|
|
100
|
+
|
|
101
|
+
Set them in your shell or `.env` before running commands.
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## 🛠️ Development
|
|
106
|
+
|
|
107
|
+
From your dev clone:
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
# Install editable
|
|
111
|
+
pip install -e .
|
|
112
|
+
|
|
113
|
+
# Run tests
|
|
114
|
+
pytest tests/
|
|
115
|
+
|
|
116
|
+
# Lint & format
|
|
117
|
+
flake8 orchify tests
|
|
118
|
+
black orchify tests
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## 🤝 Contributing
|
|
124
|
+
|
|
125
|
+
Contributions, issues, and feature requests are welcome!
|
|
126
|
+
|
|
127
|
+
1. Fork the repo.
|
|
128
|
+
2. Create a feature branch: `git checkout -b feature/awesome`.
|
|
129
|
+
3. Commit your changes and push.
|
|
130
|
+
4. Open a Pull Request.
|
|
131
|
+
|
|
132
|
+
Please adhere to the existing code style and add tests for any new functionality.
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## đź“„ License
|
|
137
|
+
|
|
138
|
+
This project is licensed under the **MIT License**. See [LICENSE](LICENSE) for details.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"""Orchify: AI-driven Dockerfile and .dockerignore generator for Python projects."""
|
|
2
|
+
|
|
3
|
+
__version__ = "0.1.0"
|
|
4
|
+
|
|
5
|
+
# Optional: expose your main entry-point and generator helper at package level
|
|
6
|
+
from .cli import main # so you can programmatically invoke Orchify
|
|
7
|
+
from .generator import render_dockerfile
|
|
8
|
+
|
|
9
|
+
__all__ = ["__version__", "main", "render_dockerfile"]
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import re
|
|
3
|
+
|
|
4
|
+
import click
|
|
5
|
+
import asyncio
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from agno.agent import Agent
|
|
8
|
+
from agno.models.anthropic import Claude
|
|
9
|
+
from agno.tools.mcp import MCPTools
|
|
10
|
+
from mcp import ClientSession, StdioServerParameters
|
|
11
|
+
from mcp.client.stdio import stdio_client
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@click.group()
|
|
15
|
+
def main():
|
|
16
|
+
"""Orchify CLI"""
|
|
17
|
+
pass
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@main.command()
|
|
21
|
+
def hello():
|
|
22
|
+
"""Prints a welcome message."""
|
|
23
|
+
click.echo("đź‘‹ Welcome to Orchify!")
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@main.command()
|
|
27
|
+
@click.option(
|
|
28
|
+
"--prompt", "-p", default="Read and summarize the entire project structure."
|
|
29
|
+
)
|
|
30
|
+
@click.option(
|
|
31
|
+
"--dir",
|
|
32
|
+
"-d",
|
|
33
|
+
default=".",
|
|
34
|
+
type=click.Path(exists=True, file_okay=False, dir_okay=True),
|
|
35
|
+
)
|
|
36
|
+
def scan(prompt: str, dir: str):
|
|
37
|
+
"""
|
|
38
|
+
Spin up an MCP filesystem server via Agno, stream back
|
|
39
|
+
agent responses, and write orchify.json metadata.
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
async def _run_mcp():
|
|
43
|
+
project_path = Path(dir).resolve()
|
|
44
|
+
server_params = StdioServerParameters(
|
|
45
|
+
command="npx",
|
|
46
|
+
args=["-y", "@modelcontextprotocol/server-filesystem", str(project_path)],
|
|
47
|
+
)
|
|
48
|
+
async with stdio_client(server_params) as (read, write):
|
|
49
|
+
async with ClientSession(read, write) as session:
|
|
50
|
+
# 1. Initialize MCP tools & agent
|
|
51
|
+
mcp_tools = MCPTools(session=session)
|
|
52
|
+
await mcp_tools.initialize()
|
|
53
|
+
agent = Agent(
|
|
54
|
+
model=Claude(id="claude-3-7-sonnet-latest"),
|
|
55
|
+
tools=[mcp_tools],
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
# 2. Stream the natural-language summary
|
|
59
|
+
await agent.aprint_response(prompt, stream=True)
|
|
60
|
+
|
|
61
|
+
# 3. AFTER the AI summary, collect structured metadata
|
|
62
|
+
# (you can make this smarter by inspecting session.tools, etc.)
|
|
63
|
+
# For now we'll use simple heuristics:
|
|
64
|
+
dep_file = (
|
|
65
|
+
"requirements.txt" if (project_path / "requirements.txt").exists() else None
|
|
66
|
+
)
|
|
67
|
+
install_cmd = f"pip install --no-cache-dir -r {dep_file}" if dep_file else ""
|
|
68
|
+
src_dirs = []
|
|
69
|
+
for p in project_path.iterdir():
|
|
70
|
+
name = p.name
|
|
71
|
+
# skip hidden, egg-info, IDE, and tests
|
|
72
|
+
if (
|
|
73
|
+
name.startswith(".")
|
|
74
|
+
or name.endswith(".egg-info")
|
|
75
|
+
or name in {"tests", ".idea"}
|
|
76
|
+
):
|
|
77
|
+
continue
|
|
78
|
+
# include packages (has __init__.py) or any .py script
|
|
79
|
+
if p.is_dir():
|
|
80
|
+
if (p / "__init__.py").exists() or any(
|
|
81
|
+
f.suffix == ".py" for f in p.iterdir()
|
|
82
|
+
):
|
|
83
|
+
src_dirs.append(name)
|
|
84
|
+
elif p.suffix == ".py":
|
|
85
|
+
src_dirs.append(name)
|
|
86
|
+
# Example entrypoint: try to look for a uvicorn or flask runner in your codebase.
|
|
87
|
+
entrypoint = ["python", "-m", "orchify.cli", "hello"]
|
|
88
|
+
|
|
89
|
+
metadata = {
|
|
90
|
+
"python_base": "python:3.11-slim",
|
|
91
|
+
"dependency_file": dep_file,
|
|
92
|
+
"install_cmd": install_cmd,
|
|
93
|
+
"source_dirs": src_dirs,
|
|
94
|
+
"entrypoint_list": entrypoint,
|
|
95
|
+
"cache_dirs": ["__pycache__"],
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
# 4. Write orchify.json next to your project root
|
|
99
|
+
meta_path = project_path / "orchify.json"
|
|
100
|
+
meta_path.write_text(json.dumps(metadata, indent=2))
|
|
101
|
+
click.echo(f"đź”– Wrote metadata to {meta_path}")
|
|
102
|
+
|
|
103
|
+
# run it
|
|
104
|
+
asyncio.run(_run_mcp())
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
@main.command()
|
|
108
|
+
@click.option("--model-id", "-m", default="claude-3-7-sonnet-latest")
|
|
109
|
+
@click.option("--output", "-o", default="Dockerfile")
|
|
110
|
+
def gen(model_id: str, output: str):
|
|
111
|
+
meta = json.loads(Path("orchify.json").read_text())
|
|
112
|
+
prompt = f"""
|
|
113
|
+
You are an expert DevOps engineer. Generate a production-grade, multi-stage Dockerfile and a matching .dockerignore for a generic Python project, **with absolutely no commentary**—just the files themselves.
|
|
114
|
+
|
|
115
|
+
Project metadata:
|
|
116
|
+
• Base image: {meta['python_base']}
|
|
117
|
+
• Install command: {meta['install_cmd']}
|
|
118
|
+
• Source dirs: {meta['source_dirs']}
|
|
119
|
+
• Entrypoint: {meta['entrypoint_list']}
|
|
120
|
+
• Cache dirs: {meta['cache_dirs']}
|
|
121
|
+
|
|
122
|
+
Output **only** two sections wrapped in these tags:
|
|
123
|
+
|
|
124
|
+
<DOCKERFILE>
|
|
125
|
+
# content of Dockerfile …
|
|
126
|
+
</DOCKERFILE>
|
|
127
|
+
<DOCKERIGNORE>
|
|
128
|
+
# content of .dockerignore …
|
|
129
|
+
</DOCKERIGNORE>
|
|
130
|
+
"""
|
|
131
|
+
|
|
132
|
+
agent = Agent(model=Claude(id=model_id), tools=[])
|
|
133
|
+
raw = agent.run(prompt)
|
|
134
|
+
text = raw.content if hasattr(raw, "content") else str(raw)
|
|
135
|
+
|
|
136
|
+
# extract Dockerfile
|
|
137
|
+
m_df = re.search(r"<DOCKERFILE>(.*?)</DOCKERFILE>", text, re.DOTALL)
|
|
138
|
+
if not m_df:
|
|
139
|
+
raise click.ClickException("Missing <DOCKERFILE> section")
|
|
140
|
+
dockerfile = m_df.group(1).strip()
|
|
141
|
+
|
|
142
|
+
# extract .dockerignore
|
|
143
|
+
m_di = re.search(r"<DOCKERIGNORE>(.*?)</DOCKERIGNORE>", text, re.DOTALL)
|
|
144
|
+
if not m_di:
|
|
145
|
+
raise click.ClickException("Missing <DOCKERIGNORE> section")
|
|
146
|
+
dockerignore = m_di.group(1).strip()
|
|
147
|
+
|
|
148
|
+
Path(output).write_text(dockerfile)
|
|
149
|
+
Path(".dockerignore").write_text(dockerignore)
|
|
150
|
+
click.echo("✨ Written Dockerfile and .dockerignore.")
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import jinja2
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def render_dockerfile(context: dict, template_dir: Path):
|
|
6
|
+
env = jinja2.Environment(
|
|
7
|
+
loader=jinja2.FileSystemLoader(str(template_dir)),
|
|
8
|
+
autoescape=False,
|
|
9
|
+
trim_blocks=True,
|
|
10
|
+
lstrip_blocks=True,
|
|
11
|
+
)
|
|
12
|
+
docker_tmpl = env.get_template("Dockerfile.j2")
|
|
13
|
+
ignore_tmpl = env.get_template(".dockerignore.j2")
|
|
14
|
+
|
|
15
|
+
dockerfile = docker_tmpl.render(**context)
|
|
16
|
+
dockerignore = ignore_tmpl.render(**context)
|
|
17
|
+
return dockerfile, dockerignore
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: orchify
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: AI-driven Dockerfile generator for any Python project
|
|
5
|
+
Author-email: Sattyam Jain <you@example.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/yourusername/Orchify
|
|
8
|
+
Project-URL: Repository, https://github.com/yourusername/Orchify
|
|
9
|
+
Project-URL: Documentation, https://yourusername.github.io/Orchify
|
|
10
|
+
Keywords: docker,cli,ai,devops,automation
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Requires-Python: >=3.8
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
License-File: LICENSE
|
|
18
|
+
Requires-Dist: click
|
|
19
|
+
Requires-Dist: agno
|
|
20
|
+
Requires-Dist: mcp
|
|
21
|
+
Requires-Dist: anthropic
|
|
22
|
+
Requires-Dist: openai
|
|
23
|
+
Requires-Dist: jinja2
|
|
24
|
+
Dynamic: license-file
|
|
25
|
+
|
|
26
|
+
# Orchify
|
|
27
|
+
[](https://pypi.org/project/orchify) [](https://pypi.org/project/orchify)
|
|
28
|
+
|
|
29
|
+
AI-driven Dockerfile and .dockerignore generator for **any** Python project.
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## 🚀 Overview
|
|
34
|
+
|
|
35
|
+
Orchify is a command-line tool that uses AI agents (via Agno and the Model Context Protocol) to:
|
|
36
|
+
|
|
37
|
+
1. **Scan** a Python project and analyze its structure, dependencies, and entrypoints.
|
|
38
|
+
2. **Generate** a production-grade, multi-stage **Dockerfile** and corresponding **.dockerignore**—tailored to the project—without manual template editing.
|
|
39
|
+
|
|
40
|
+
Whether you're containerizing a microservice, a Flask app, or a complex multi-package repository, Orchify will craft best-practice container configurations in seconds.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## đź”§ Features
|
|
45
|
+
|
|
46
|
+
- **Framework Agnostic**: Works with plain Python scripts, Flask, FastAPI, Django, and more.
|
|
47
|
+
- **AI-Powered**: Leverages Anthropic Claude or OpenAI GPT models to write idiomatic Dockerfiles.
|
|
48
|
+
- **Two-Step Workflow**: `scan` → `gen` for clear separation of analysis and generation.
|
|
49
|
+
- **Production-Ready**: Generates multi-stage builds, non-root users, cache optimizations.
|
|
50
|
+
- **Customizable**: Override prompts, model choices, output paths via CLI flags.
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## 📦 Installation
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
pip install orchify
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Or from source:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
git clone https://github.com/yourusername/Orchify.git
|
|
64
|
+
cd Orchify
|
|
65
|
+
docker run -it --rm \
|
|
66
|
+
-v "$PWD":/workspace \
|
|
67
|
+
python:3.11-slim bash -c "pip install -e ."
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## 🔨 Usage
|
|
73
|
+
|
|
74
|
+
Orchify exposes three primary commands via the `orchify` CLI:
|
|
75
|
+
|
|
76
|
+
### 1. `hello`
|
|
77
|
+
|
|
78
|
+
A sanity-check command:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
orchify hello
|
|
82
|
+
# đź‘‹ Welcome to Orchify!
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### 2. `scan`
|
|
86
|
+
|
|
87
|
+
Analyze your project and write out `orchify.json` metadata.
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
orchify scan \
|
|
91
|
+
--dir /path/to/your/project \
|
|
92
|
+
--prompt "Summarize my project for Dockerfile generation"
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
**Options:**
|
|
96
|
+
|
|
97
|
+
- `-d, --dir` <path>: Project directory (default: current directory).
|
|
98
|
+
- `-p, --prompt` <text>: Custom AI analysis prompt.
|
|
99
|
+
|
|
100
|
+
### 3. `gen`
|
|
101
|
+
|
|
102
|
+
Generate `Dockerfile` and `.dockerignore` based on the scan metadata.
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
orchify gen \
|
|
106
|
+
--model-id claude-3-7-sonnet-latest \
|
|
107
|
+
--output Dockerfile
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
**Options:**
|
|
111
|
+
|
|
112
|
+
- `-m, --model-id` <model>: Anthropic/OpenAI model to use.
|
|
113
|
+
- `-o, --output` <path>: Path for the generated Dockerfile (default: `Dockerfile`).
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## ⚙️ Configuration
|
|
118
|
+
|
|
119
|
+
Orchify uses environment variables to authenticate with AI providers:
|
|
120
|
+
|
|
121
|
+
| Variable | Description |
|
|
122
|
+
|----------------------|----------------------------------|
|
|
123
|
+
| `ANTHROPIC_API_KEY` | Your Anthropic Claude API token. |
|
|
124
|
+
| `OPENAI_API_KEY` | Your OpenAI API key (optional). |
|
|
125
|
+
|
|
126
|
+
Set them in your shell or `.env` before running commands.
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## 🛠️ Development
|
|
131
|
+
|
|
132
|
+
From your dev clone:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
# Install editable
|
|
136
|
+
pip install -e .
|
|
137
|
+
|
|
138
|
+
# Run tests
|
|
139
|
+
pytest tests/
|
|
140
|
+
|
|
141
|
+
# Lint & format
|
|
142
|
+
flake8 orchify tests
|
|
143
|
+
black orchify tests
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## 🤝 Contributing
|
|
149
|
+
|
|
150
|
+
Contributions, issues, and feature requests are welcome!
|
|
151
|
+
|
|
152
|
+
1. Fork the repo.
|
|
153
|
+
2. Create a feature branch: `git checkout -b feature/awesome`.
|
|
154
|
+
3. Commit your changes and push.
|
|
155
|
+
4. Open a Pull Request.
|
|
156
|
+
|
|
157
|
+
Please adhere to the existing code style and add tests for any new functionality.
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## đź“„ License
|
|
162
|
+
|
|
163
|
+
This project is licensed under the **MIT License**. See [LICENSE](LICENSE) for details.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
MANIFEST.in
|
|
3
|
+
README.md
|
|
4
|
+
pyproject.toml
|
|
5
|
+
orchify/__init__.py
|
|
6
|
+
orchify/cli.py
|
|
7
|
+
orchify/generator.py
|
|
8
|
+
orchify.egg-info/PKG-INFO
|
|
9
|
+
orchify.egg-info/SOURCES.txt
|
|
10
|
+
orchify.egg-info/dependency_links.txt
|
|
11
|
+
orchify.egg-info/entry_points.txt
|
|
12
|
+
orchify.egg-info/requires.txt
|
|
13
|
+
orchify.egg-info/top_level.txt
|
|
14
|
+
tests/test_cli.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
orchify
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "orchify"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "AI-driven Dockerfile generator for any Python project"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.8"
|
|
7
|
+
license = { text = "MIT" }
|
|
8
|
+
authors = [{ name="Sattyam Jain", email="you@example.com" }]
|
|
9
|
+
keywords = ["docker","cli","ai","devops","automation"]
|
|
10
|
+
classifiers = [
|
|
11
|
+
"Programming Language :: Python :: 3",
|
|
12
|
+
"Programming Language :: Python :: 3.8",
|
|
13
|
+
"License :: OSI Approved :: MIT License",
|
|
14
|
+
"Operating System :: OS Independent",
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
dependencies = [
|
|
18
|
+
"click",
|
|
19
|
+
"agno",
|
|
20
|
+
"mcp",
|
|
21
|
+
"anthropic",
|
|
22
|
+
"openai",
|
|
23
|
+
"jinja2"
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
[project.urls]
|
|
27
|
+
Homepage = "https://github.com/yourusername/Orchify"
|
|
28
|
+
Repository = "https://github.com/yourusername/Orchify"
|
|
29
|
+
Documentation = "https://yourusername.github.io/Orchify"
|
|
30
|
+
|
|
31
|
+
[project.scripts]
|
|
32
|
+
orchify = "orchify.cli:main"
|
|
33
|
+
|
|
34
|
+
[build-system]
|
|
35
|
+
requires = ["setuptools>=61.0","wheel","build"]
|
|
36
|
+
build-backend = "setuptools.build_meta"
|
|
37
|
+
|
|
38
|
+
[tool.setuptools]
|
|
39
|
+
include-package-data = true
|
orchify-0.1.0/setup.cfg
ADDED
|
File without changes
|