rapidkit 0.10.0
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.
- package/LICENSE +21 -0
- package/README.md +508 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +366 -0
- package/package.json +86 -0
- package/templates/kits/fastapi-standard/README.md.j2 +30 -0
- package/templates/kits/fastapi-standard/kit.json +70 -0
- package/templates/kits/fastapi-standard/kit.yaml +120 -0
- package/templates/kits/fastapi-standard/pyproject.toml.j2 +41 -0
- package/templates/kits/fastapi-standard/src/__init__.py.j2 +3 -0
- package/templates/kits/fastapi-standard/src/cli.py.j2 +333 -0
- package/templates/kits/fastapi-standard/src/main.py.j2 +41 -0
- package/templates/kits/fastapi-standard/src/modules/__init__.py.j2 +3 -0
- package/templates/kits/fastapi-standard/src/routing/__init__.py.j2 +13 -0
- package/templates/kits/fastapi-standard/src/routing/health.py.j2 +13 -0
- package/templates/kits/fastapi-standard/tests/__init__.py.j2 +1 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {Command}from'commander';import i from'chalk';import {promises}from'fs';import*as h from'fs-extra';import y from'path';import oe from'inquirer';import W from'ora';import {execa}from'execa';import ee from'os';import ce from'nunjucks';import {fileURLToPath}from'url';import he from'validate-npm-package-name';var G=class{debugEnabled=false;setDebug(e){this.debugEnabled=e;}debug(e,...o){this.debugEnabled&&console.log(i.gray(`[DEBUG] ${e}`),...o);}info(e,...o){console.log(i.blue(e),...o);}success(e,...o){console.log(i.green(e),...o);}warn(e,...o){console.log(i.yellow(e),...o);}error(e,...o){console.error(i.red(e),...o);}step(e,o,r){console.log(i.cyan(`
|
|
3
|
+
[${e}/${o}]`),i.white(r));}},s=new G;var te=".rapidkitrc.json";async function z(){let t=y.join(ee.homedir(),te);try{let e=await promises.readFile(t,"utf-8"),o=JSON.parse(e);return s.debug(`Loaded config from ${t}`),o}catch{return s.debug("No user config found, using defaults"),{}}}function $(t){return process.env.RAPIDKIT_DEV_PATH||t.testRapidKitPath||void 0}var g=class extends Error{constructor(o,r,n){super(o);this.code=r;this.details=n;this.name="RapidKitError",Error.captureStackTrace(this,this.constructor);}},x=class extends g{constructor(e,o){let r=o?`Python ${e}+ required, found ${o}`:`Python ${e}+ not found`;super(r,"PYTHON_NOT_FOUND","Please install Python from https://www.python.org/downloads/");}},F=class extends g{constructor(){super("Poetry is not installed","POETRY_NOT_FOUND","Install Poetry from https://python-poetry.org/docs/#installation");}},N=class extends g{constructor(){super("pipx is not installed","PIPX_NOT_FOUND","Install pipx from https://pypa.github.io/pipx/installation/");}},T=class extends g{constructor(e){super(`Directory "${e}" already exists`,"DIRECTORY_EXISTS","Please choose a different name or remove the existing directory");}},k=class extends g{constructor(e,o){super(`Invalid project name: "${e}"`,"INVALID_PROJECT_NAME",o);}},I=class extends g{constructor(e,o){let r=`Installation failed at: ${e}`,n=`${o.message}
|
|
4
|
+
|
|
5
|
+
Troubleshooting:
|
|
6
|
+
- Check your internet connection
|
|
7
|
+
- Verify Python/Poetry installation
|
|
8
|
+
- Try running with --debug flag for more details`;super(r,"INSTALLATION_ERROR",n);}},E=class extends g{constructor(){super("RapidKit Python package is not yet available on PyPI","RAPIDKIT_NOT_AVAILABLE",`Available options:
|
|
9
|
+
1. Demo mode: npx rapidkit my-workspace --demo
|
|
10
|
+
2. Test mode: npx rapidkit my-workspace --test-mode (requires local RapidKit)
|
|
11
|
+
3. Wait for official PyPI release (coming soon)`);}};async function U(t,e){let{skipGit:o=false,testMode:r=false,demoMode:n=false,dryRun:m=false,userConfig:p={}}=e,a=t,l=y.resolve(process.cwd(),a);if(await h.pathExists(l))throw new T(a);if(m){await le(l,a,n,p);return}if(n){await se(l,a,o);return}let f=await oe.prompt([{type:"list",name:"pythonVersion",message:"Select Python version for RapidKit:",choices:["3.10","3.11","3.12"],default:p.pythonVersion||"3.11"},{type:"list",name:"installMethod",message:"How would you like to install RapidKit?",choices:[{name:"\u{1F3AF} Poetry (Recommended - includes virtual env)",value:"poetry"},{name:"\u{1F4E6} pip with venv (Standard)",value:"venv"},{name:"\u{1F527} pipx (Global isolated install)",value:"pipx"}],default:p.defaultInstallMethod||"poetry"}]);s.step(1,3,"Setting up RapidKit environment");let u=W("Creating directory").start();try{if(await h.ensureDir(l),u.succeed("Directory created"),f.installMethod==="poetry"?await ie(l,f.pythonVersion,u,r,p):f.installMethod==="venv"?await re(l,f.pythonVersion,u,r,p):await ne(l,u,r,p),await ae(l,f.installMethod),u.succeed("RapidKit environment ready!"),!e.skipGit){u.start("Initializing git repository");try{await execa("git",["init"],{cwd:l}),await h.outputFile(y.join(l,".gitignore"),`.venv/
|
|
12
|
+
__pycache__/
|
|
13
|
+
*.pyc
|
|
14
|
+
.env
|
|
15
|
+
.rapidkit-workspace/
|
|
16
|
+
`,"utf-8"),await execa("git",["add","."],{cwd:l}),await execa("git",["commit","-m","Initial commit: RapidKit environment"],{cwd:l}),u.succeed("Git repository initialized");}catch{u.warn("Could not initialize git repository");}}if(console.log(i.green(`
|
|
17
|
+
\u2728 RapidKit environment created successfully!
|
|
18
|
+
`)),console.log(i.cyan("\u{1F4C2} Location:"),i.white(l)),console.log(i.cyan(`\u{1F680} Get started:
|
|
19
|
+
`)),console.log(i.white(` cd ${a}`)),f.installMethod==="poetry"){let v="source $(poetry env info --path)/bin/activate";try{let{stdout:A}=await execa("poetry",["--version"]),D=A.match(/Poetry.*?(\d+)\.(\d+)/);D&&(parseInt(D[1])>=2?v="source $(poetry env info --path)/bin/activate":v="poetry shell");}catch{}console.log(i.white(` ${v} # Or: poetry run rapidkit`)),console.log(i.white(" rapidkit create # Interactive mode")),console.log(i.white(" cd <project-name> && poetry install && rapidkit run dev"));}else f.installMethod==="venv"?(console.log(i.white(" source .venv/bin/activate # On Windows: .venv\\Scripts\\activate")),console.log(i.white(" rapidkit create # Interactive mode")),console.log(i.white(" cd <project-name> && pip install -r requirements.txt && rapidkit run dev"))):(console.log(i.white(" rapidkit create # Interactive mode")),console.log(i.white(" cd <project-name> && rapidkit run dev")));console.log(i.white(`
|
|
20
|
+
\u{1F4A1} For more information, check the README.md file.`)),console.log(i.cyan(`
|
|
21
|
+
\u{1F4DA} RapidKit commands:`)),console.log(i.white(" rapidkit create - Create a new project (interactive)")),console.log(i.white(" rapidkit run dev - Run development server")),console.log(i.white(" rapidkit add module <name> - Add a module (e.g., settings)")),console.log(i.white(" rapidkit list - List available kits")),console.log(i.white(" rapidkit modules - List available modules")),console.log(i.white(` rapidkit --help - Show all commands
|
|
22
|
+
`));}catch(v){u.fail("Failed to create RapidKit environment"),console.error(i.red(`
|
|
23
|
+
\u274C Error:`),v);try{await h.remove(l);}catch{}process.exit(1);}}async function ie(t,e,o,r,n){o.start("Checking Poetry installation");try{await execa("poetry",["--version"]),o.succeed("Poetry found");}catch{throw new F}o.start("Initializing Poetry project"),await execa("poetry",["init","--no-interaction","--python",`^${e}`],{cwd:t});let m=y.join(t,"pyproject.toml"),a=(await promises.readFile(m,"utf-8")).replace("[tool.poetry]",`[tool.poetry]
|
|
24
|
+
package-mode = false`);if(await promises.writeFile(m,a,"utf-8"),o.succeed("Poetry project initialized"),o.start("Installing RapidKit"),r){let l=$(n||{});if(!l)throw new I("Test mode installation",new Error("No local RapidKit path configured. Set RAPIDKIT_DEV_PATH environment variable."));s.debug(`Installing from local path: ${l}`),o.text="Installing RapidKit from local path (test mode)",await execa("poetry",["add",l],{cwd:t});}else {o.text="Installing RapidKit from PyPI";try{await execa("poetry",["add","rapidkit"],{cwd:t});}catch{throw new E}}o.succeed("RapidKit installed");}async function re(t,e,o,r,n){o.start(`Checking Python ${e}`);let m="python3";try{let{stdout:a}=await execa(m,["--version"]),l=a.match(/Python (\d+\.\d+)/)?.[1];if(l&&parseFloat(l)<parseFloat(e))throw new x(e,l);o.succeed(`Python ${l} found`);}catch(a){throw a instanceof x?a:new x(e)}o.start("Creating virtual environment"),await execa(m,["-m","venv",".venv"],{cwd:t}),o.succeed("Virtual environment created"),o.start("Installing RapidKit");let p=y.join(t,".venv","bin","pip");if(await execa(p,["install","--upgrade","pip"],{cwd:t}),r){let a=$(n||{});if(!a)throw new I("Test mode installation",new Error("No local RapidKit path configured. Set RAPIDKIT_DEV_PATH environment variable."));s.debug(`Installing from local path: ${a}`),o.text="Installing RapidKit from local path (test mode)",await execa(p,["install","-e",a],{cwd:t});}else {o.text="Installing RapidKit from PyPI";try{await execa(p,["install","rapidkit"],{cwd:t});}catch{throw new E}}o.succeed("RapidKit installed");}async function ne(t,e,o,r){e.start("Checking pipx installation");try{await execa("pipx",["--version"]),e.succeed("pipx found");}catch{throw new N}if(e.start("Installing RapidKit globally with pipx"),o){let n=$(r||{});if(!n)throw new I("Test mode installation",new Error("No local RapidKit path configured. Set RAPIDKIT_DEV_PATH environment variable."));s.debug(`Installing from local path: ${n}`),e.text="Installing RapidKit from local path (test mode)",await execa("pipx",["install","-e",n]);}else {e.text="Installing RapidKit from PyPI";try{await execa("pipx",["install","rapidkit"]);}catch{throw new E}}e.succeed("RapidKit installed globally"),await h.outputFile(y.join(t,".rapidkit-global"),`RapidKit installed globally with pipx
|
|
25
|
+
`,"utf-8");}async function ae(t,e){let r=`# RapidKit Workspace
|
|
26
|
+
|
|
27
|
+
This directory contains a RapidKit development environment.
|
|
28
|
+
|
|
29
|
+
## Installation Method
|
|
30
|
+
|
|
31
|
+
**${e==="poetry"?"Poetry":e==="venv"?"Python venv + pip":"pipx (global)"}**
|
|
32
|
+
|
|
33
|
+
## Getting Started
|
|
34
|
+
|
|
35
|
+
### 1. Activate Environment
|
|
36
|
+
|
|
37
|
+
\`\`\`bash
|
|
38
|
+
${e==="poetry"?`source $(poetry env info --path)/bin/activate
|
|
39
|
+
# Or simply use: poetry run rapidkit <command>`:e==="venv"?"source .venv/bin/activate # On Windows: .venv\\Scripts\\activate":"N/A (globally installed)"}
|
|
40
|
+
\`\`\`
|
|
41
|
+
|
|
42
|
+
### 2. Create Your First Project
|
|
43
|
+
|
|
44
|
+
\`\`\`bash
|
|
45
|
+
# Interactive mode (recommended):
|
|
46
|
+
rapidkit create
|
|
47
|
+
# Follow the prompts to choose kit and project name
|
|
48
|
+
|
|
49
|
+
# Or specify directly:
|
|
50
|
+
rapidkit create project fastapi.standard my-project
|
|
51
|
+
|
|
52
|
+
# With poetry run (no activation needed):
|
|
53
|
+
poetry run rapidkit create
|
|
54
|
+
\`\`\`
|
|
55
|
+
|
|
56
|
+
Interactive mode will guide you through selecting a kit and configuring your project.
|
|
57
|
+
|
|
58
|
+
### 3. Navigate and Run
|
|
59
|
+
|
|
60
|
+
\`\`\`bash
|
|
61
|
+
cd my-project
|
|
62
|
+
# Install dependencies:
|
|
63
|
+
poetry install
|
|
64
|
+
|
|
65
|
+
# Run the server (simplest way):
|
|
66
|
+
rapidkit run dev
|
|
67
|
+
|
|
68
|
+
# Or with poetry run:
|
|
69
|
+
poetry run rapidkit run dev
|
|
70
|
+
|
|
71
|
+
# Or manually:
|
|
72
|
+
uvicorn src.main:app --reload
|
|
73
|
+
\`\`\`
|
|
74
|
+
|
|
75
|
+
### 4. Add Modules (Optional)
|
|
76
|
+
|
|
77
|
+
\`\`\`bash
|
|
78
|
+
# Add common modules to your project:
|
|
79
|
+
rapidkit add module settings
|
|
80
|
+
rapidkit add module logging
|
|
81
|
+
rapidkit add module database
|
|
82
|
+
|
|
83
|
+
# List available modules:
|
|
84
|
+
rapidkit modules list
|
|
85
|
+
\`\`\`
|
|
86
|
+
|
|
87
|
+
## Available Commands
|
|
88
|
+
|
|
89
|
+
- \`rapidkit create\` - Create a new project (interactive)
|
|
90
|
+
- \`rapidkit create project <kit> <name>\` - Create project with specific kit
|
|
91
|
+
- \`rapidkit run dev\` - Run development server
|
|
92
|
+
- \`rapidkit add module <name>\` - Add a module (e.g., \`rapidkit add module settings\`)
|
|
93
|
+
- \`rapidkit list\` - List available kits
|
|
94
|
+
- \`rapidkit modules\` - List available modules
|
|
95
|
+
- \`rapidkit upgrade\` - Upgrade RapidKit
|
|
96
|
+
- \`rapidkit doctor\` - Check system requirements
|
|
97
|
+
- \`rapidkit --help\` - Show all commands
|
|
98
|
+
|
|
99
|
+
## RapidKit Documentation
|
|
100
|
+
|
|
101
|
+
For full documentation, visit: [RapidKit Docs](https://rapidkit.dev) *(or appropriate URL)*
|
|
102
|
+
|
|
103
|
+
## Workspace Structure
|
|
104
|
+
|
|
105
|
+
\`\`\`
|
|
106
|
+
${e==="venv"?".venv/ # Python virtual environment":""}
|
|
107
|
+
${e==="poetry"?"pyproject.toml # Poetry configuration":""}
|
|
108
|
+
my-project/ # Your RapidKit projects go here
|
|
109
|
+
README.md # This file
|
|
110
|
+
\`\`\`
|
|
111
|
+
|
|
112
|
+
## Troubleshooting
|
|
113
|
+
|
|
114
|
+
If you encounter issues:
|
|
115
|
+
|
|
116
|
+
1. Ensure Python 3.10+ is installed: \`python3 --version\`
|
|
117
|
+
2. Check RapidKit installation: \`rapidkit --version\`
|
|
118
|
+
3. Run diagnostics: \`rapidkit doctor\`
|
|
119
|
+
4. Visit RapidKit documentation or GitHub issues
|
|
120
|
+
`;await promises.writeFile(y.join(t,"README.md"),r,"utf-8");}async function se(t,e,o){let r=W("Creating demo workspace").start();try{await h.ensureDir(t),r.succeed("Directory created"),r.start("Setting up demo kit generator");let n=JSON.stringify({name:`${e}-workspace`,version:"1.0.0",private:!0,description:"RapidKit demo workspace",scripts:{generate:"node generate-demo.js"}},null,2);await promises.writeFile(y.join(t,"package.json"),n,"utf-8"),await promises.writeFile(y.join(t,"generate-demo.js"),`#!/usr/bin/env node
|
|
121
|
+
/**
|
|
122
|
+
* Demo Kit Generator - Create FastAPI demo projects
|
|
123
|
+
*
|
|
124
|
+
* This workspace contains bundled RapidKit templates that you can use
|
|
125
|
+
* to generate demo projects without installing Python RapidKit.
|
|
126
|
+
*
|
|
127
|
+
* Usage:
|
|
128
|
+
* npm run generate <project-name>
|
|
129
|
+
* node generate-demo.js <project-name>
|
|
130
|
+
*
|
|
131
|
+
* Example:
|
|
132
|
+
* npm run generate my-api
|
|
133
|
+
*/
|
|
134
|
+
|
|
135
|
+
const { execSync } = require('child_process');
|
|
136
|
+
const path = require('path');
|
|
137
|
+
|
|
138
|
+
const projectName = process.argv[2];
|
|
139
|
+
|
|
140
|
+
if (!projectName) {
|
|
141
|
+
console.error('\\n\u274C Please provide a project name');
|
|
142
|
+
console.log('\\nUsage: npm run generate <project-name>\\n');
|
|
143
|
+
console.log('Example: npm run generate my-api\\n');
|
|
144
|
+
process.exit(1);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Use npx to run rapidkit in demo mode, targeting the current directory
|
|
148
|
+
const targetPath = path.join(process.cwd(), projectName);
|
|
149
|
+
|
|
150
|
+
try {
|
|
151
|
+
console.log(\`\\nGenerating demo project: \${projectName}...\\n\`);
|
|
152
|
+
execSync(\`npx rapidkit "\${projectName}" --demo-only\`, {
|
|
153
|
+
stdio: 'inherit',
|
|
154
|
+
cwd: process.cwd(),
|
|
155
|
+
});
|
|
156
|
+
console.log(\`\\n\u2705 Demo project created at: \${targetPath}\\n\`);
|
|
157
|
+
} catch (_error) {
|
|
158
|
+
console.error('\\n\u274C Failed to generate demo project\\n');
|
|
159
|
+
process.exit(1);
|
|
160
|
+
}
|
|
161
|
+
`,"utf-8");try{await execa("chmod",["+x",y.join(t,"generate-demo.js")]);}catch{}let p=`# RapidKit Demo Workspace
|
|
162
|
+
|
|
163
|
+
Welcome to your RapidKit demo workspace! This environment lets you generate FastAPI demo projects using bundled RapidKit templates, without needing to install Python RapidKit.
|
|
164
|
+
|
|
165
|
+
## \u{1F680} Quick Start
|
|
166
|
+
|
|
167
|
+
### Generate Your First Demo Project
|
|
168
|
+
|
|
169
|
+
\`\`\`bash
|
|
170
|
+
# Generate a demo project:
|
|
171
|
+
node generate-demo.js my-api
|
|
172
|
+
|
|
173
|
+
# Navigate to the project:
|
|
174
|
+
cd my-api
|
|
175
|
+
|
|
176
|
+
# Install dependencies:
|
|
177
|
+
poetry install
|
|
178
|
+
|
|
179
|
+
# Run the development server:
|
|
180
|
+
poetry run python -m src.main
|
|
181
|
+
\`\`\`
|
|
182
|
+
|
|
183
|
+
Your API will be available at \`http://localhost:8000\`
|
|
184
|
+
|
|
185
|
+
## \u{1F4E6} Generate Multiple Projects
|
|
186
|
+
|
|
187
|
+
You can create multiple demo projects in this workspace:
|
|
188
|
+
|
|
189
|
+
\`\`\`bash
|
|
190
|
+
node generate-demo.js api-service
|
|
191
|
+
node generate-demo.js auth-service
|
|
192
|
+
node generate-demo.js data-service
|
|
193
|
+
\`\`\`
|
|
194
|
+
|
|
195
|
+
Each project is independent and has its own dependencies.
|
|
196
|
+
|
|
197
|
+
## \u{1F3AF} What's Included
|
|
198
|
+
|
|
199
|
+
Each generated demo project contains:
|
|
200
|
+
|
|
201
|
+
- **FastAPI Application** - Modern async web framework
|
|
202
|
+
- **Routing System** - Organized API routes
|
|
203
|
+
- **Module System** - Extensible module architecture
|
|
204
|
+
- **CLI Commands** - Built-in command system
|
|
205
|
+
- **Testing Setup** - pytest configuration
|
|
206
|
+
- **Poetry Configuration** - Dependency management
|
|
207
|
+
|
|
208
|
+
## \u{1F4DA} Next Steps
|
|
209
|
+
|
|
210
|
+
1. **Explore the Generated Code** - Check out \`src/main.py\` and \`src/routing/\`
|
|
211
|
+
2. **Add Routes** - Create new endpoints in \`src/routing/\`
|
|
212
|
+
3. **Install Full RapidKit** - For advanced features: \`pipx install rapidkit\`
|
|
213
|
+
4. **Read the Documentation** - Visit [RapidKit Docs](https://rapidkit.dev)
|
|
214
|
+
|
|
215
|
+
## \u26A0\uFE0F Demo Mode Limitations
|
|
216
|
+
|
|
217
|
+
This is a demo workspace with:
|
|
218
|
+
- \u2705 Pre-built FastAPI templates
|
|
219
|
+
- \u2705 Project generation without Python RapidKit
|
|
220
|
+
- \u274C No RapidKit CLI commands (\`rapidkit create\`, \`rapidkit add module\`)
|
|
221
|
+
- \u274C No interactive module system
|
|
222
|
+
|
|
223
|
+
For full RapidKit features, install the Python package:
|
|
224
|
+
|
|
225
|
+
\`\`\`bash
|
|
226
|
+
pipx install rapidkit
|
|
227
|
+
\`\`\`
|
|
228
|
+
|
|
229
|
+
## \u{1F6E0}\uFE0F Workspace Structure
|
|
230
|
+
|
|
231
|
+
\`\`\`
|
|
232
|
+
${e}/
|
|
233
|
+
\u251C\u2500\u2500 generate-demo.js # Demo project generator
|
|
234
|
+
\u251C\u2500\u2500 README.md # This file
|
|
235
|
+
\u2514\u2500\u2500 my-api/ # Your generated projects go here
|
|
236
|
+
\`\`\`
|
|
237
|
+
|
|
238
|
+
## \u{1F4A1} Tips
|
|
239
|
+
|
|
240
|
+
- Run \`node generate-demo.js --help\` for more options (coming soon)
|
|
241
|
+
- Each project can have different configurations
|
|
242
|
+
- Demo projects are production-ready FastAPI applications
|
|
243
|
+
- You can copy and modify templates as needed
|
|
244
|
+
|
|
245
|
+
---
|
|
246
|
+
|
|
247
|
+
**Generated with RapidKit** | [GitHub](https://github.com/getrapidkit/rapidkit-npm)
|
|
248
|
+
`;if(await promises.writeFile(y.join(t,"README.md"),p,"utf-8"),r.succeed("Demo workspace setup complete"),!o){r.start("Initializing git repository");try{await execa("git",["init"],{cwd:t}),await h.outputFile(y.join(t,".gitignore"),`# Dependencies
|
|
249
|
+
node_modules/
|
|
250
|
+
|
|
251
|
+
# Generated projects
|
|
252
|
+
*/
|
|
253
|
+
!generate-demo.js
|
|
254
|
+
!README.md
|
|
255
|
+
|
|
256
|
+
# Python
|
|
257
|
+
__pycache__/
|
|
258
|
+
*.pyc
|
|
259
|
+
.venv/
|
|
260
|
+
.env
|
|
261
|
+
`,"utf-8"),await execa("git",["add","."],{cwd:t}),await execa("git",["commit","-m","Initial commit: Demo workspace"],{cwd:t}),r.succeed("Git repository initialized");}catch{r.warn("Could not initialize git repository");}}console.log(i.green(`
|
|
262
|
+
\u2728 Demo workspace created successfully!
|
|
263
|
+
`)),console.log(i.cyan("\u{1F4C2} Location:"),i.white(t)),console.log(i.cyan(`\u{1F680} Get started:
|
|
264
|
+
`)),console.log(i.white(` cd ${e}`)),console.log(i.white(" node generate-demo.js my-api")),console.log(i.white(" cd my-api")),console.log(i.white(" poetry install")),console.log(i.white(" poetry run python -m src.main")),console.log(),console.log(i.yellow("\u{1F4A1} Note:"),"This is a demo workspace. For full RapidKit features:"),console.log(i.cyan(" pipx install rapidkit")),console.log();}catch(n){throw r.fail("Failed to create demo workspace"),n}}async function le(t,e,o,r){console.log(i.cyan(`
|
|
265
|
+
\u{1F50D} Dry-run mode - showing what would be created:
|
|
266
|
+
`)),console.log(i.white("\u{1F4C2} Project path:"),t),console.log(i.white("\u{1F4E6} Project type:"),o?"Demo workspace":"Full RapidKit environment"),o?(console.log(i.white(`
|
|
267
|
+
\u{1F4DD} Files to create:`)),console.log(i.gray(" - package.json")),console.log(i.gray(" - generate-demo.js (project generator)")),console.log(i.gray(" - README.md")),console.log(i.gray(" - .gitignore")),console.log(i.white(`
|
|
268
|
+
\u{1F3AF} Capabilities:`)),console.log(i.gray(" - Generate multiple FastAPI demo projects")),console.log(i.gray(" - No Python RapidKit installation required")),console.log(i.gray(" - Bundled templates included"))):(console.log(i.white(`
|
|
269
|
+
\u2699\uFE0F Configuration:`)),console.log(i.gray(` - Python version: ${r.pythonVersion||"3.11"}`)),console.log(i.gray(` - Install method: ${r.defaultInstallMethod||"poetry"}`)),console.log(i.gray(` - Git initialization: ${r.skipGit?"No":"Yes"}`)),console.log(i.white(`
|
|
270
|
+
\u{1F4DD} Files to create:`)),console.log(i.gray(" - pyproject.toml (Poetry) or .venv/ (venv)")),console.log(i.gray(" - README.md")),console.log(i.gray(" - .gitignore")),console.log(i.white(`
|
|
271
|
+
\u{1F3AF} Next steps after creation:`)),console.log(i.gray(" 1. Install RapidKit Python package")),console.log(i.gray(" 2. Create projects with rapidkit CLI")),console.log(i.gray(" 3. Add modules and customize"))),console.log(i.white(`
|
|
272
|
+
\u{1F4A1} To proceed with actual creation, run without --dry-run flag
|
|
273
|
+
`));}var me=fileURLToPath(import.meta.url),ge=y.dirname(me);async function Y(t,e){let o=W("Generating FastAPI demo project...").start();try{let r=y.resolve(ge,".."),n=y.join(r,"templates","kits","fastapi-standard"),m=ce.configure(n,{autoescape:!1,trimBlocks:!0,lstripBlocks:!0}),p={project_name:e.project_name,author:e.author||"RapidKit User",description:e.description||"FastAPI service generated with RapidKit",app_version:e.app_version||"0.1.0",license:e.license||"MIT"},a=["src/main.py.j2","src/__init__.py.j2","src/cli.py.j2","src/routing/__init__.py.j2","src/routing/health.py.j2","src/modules/__init__.py.j2","tests/__init__.py.j2","README.md.j2","pyproject.toml.j2"];for(let f of a){let u=y.join(n,f),v=await promises.readFile(u,"utf-8"),A=m.renderString(v,p),D=f.replace(/\.j2$/,""),O=y.join(t,D);await promises.mkdir(y.dirname(O),{recursive:!0}),await promises.writeFile(O,A);}await promises.writeFile(y.join(t,".gitignore"),`# Python
|
|
274
|
+
__pycache__/
|
|
275
|
+
*.py[cod]
|
|
276
|
+
*$py.class
|
|
277
|
+
*.so
|
|
278
|
+
.Python
|
|
279
|
+
build/
|
|
280
|
+
develop-eggs/
|
|
281
|
+
dist/
|
|
282
|
+
downloads/
|
|
283
|
+
eggs/
|
|
284
|
+
.eggs/
|
|
285
|
+
lib/
|
|
286
|
+
lib64/
|
|
287
|
+
parts/
|
|
288
|
+
sdist/
|
|
289
|
+
var/
|
|
290
|
+
wheels/
|
|
291
|
+
*.egg-info/
|
|
292
|
+
.installed.cfg
|
|
293
|
+
*.egg
|
|
294
|
+
|
|
295
|
+
# Virtual environments
|
|
296
|
+
.venv/
|
|
297
|
+
venv/
|
|
298
|
+
ENV/
|
|
299
|
+
env/
|
|
300
|
+
|
|
301
|
+
# IDEs
|
|
302
|
+
.vscode/
|
|
303
|
+
.idea/
|
|
304
|
+
*.swp
|
|
305
|
+
*.swo
|
|
306
|
+
*~
|
|
307
|
+
|
|
308
|
+
# OS
|
|
309
|
+
.DS_Store
|
|
310
|
+
Thumbs.db
|
|
311
|
+
|
|
312
|
+
# Project specific
|
|
313
|
+
.env
|
|
314
|
+
.env.local
|
|
315
|
+
`),o.succeed("FastAPI demo project generated!"),console.log(`
|
|
316
|
+
${i.green("\u2728 Demo project created successfully!")}
|
|
317
|
+
|
|
318
|
+
${i.bold("\u{1F4C2} Project structure:")}
|
|
319
|
+
${t}/
|
|
320
|
+
\u251C\u2500\u2500 src/
|
|
321
|
+
\u2502 \u251C\u2500\u2500 main.py # FastAPI application
|
|
322
|
+
\u2502 \u251C\u2500\u2500 cli.py # CLI commands
|
|
323
|
+
\u2502 \u251C\u2500\u2500 routing/ # API routes
|
|
324
|
+
\u2502 \u2514\u2500\u2500 modules/ # Module system
|
|
325
|
+
\u251C\u2500\u2500 tests/ # Test suite
|
|
326
|
+
\u251C\u2500\u2500 pyproject.toml # Poetry configuration
|
|
327
|
+
\u2514\u2500\u2500 README.md
|
|
328
|
+
|
|
329
|
+
${i.bold("\u{1F680} Get started:")}
|
|
330
|
+
cd ${y.basename(t)}
|
|
331
|
+
poetry install
|
|
332
|
+
poetry run python -m src.main
|
|
333
|
+
|
|
334
|
+
${i.bold("\u{1F4DA} Next steps:")}
|
|
335
|
+
\u2022 Add RapidKit modules: poetry add rapidkit
|
|
336
|
+
\u2022 Read the README.md for more information
|
|
337
|
+
\u2022 Start building your API!
|
|
338
|
+
|
|
339
|
+
${i.yellow("Note:")} This is a standalone demo. For full RapidKit features and modules,
|
|
340
|
+
install RapidKit Python package: ${i.cyan("pipx install rapidkit")}
|
|
341
|
+
`);}catch(r){throw o.fail("Failed to generate demo project"),r}}var ye="rapidkit",L="1.0.0-beta.7";async function H(){try{s.debug("Checking for updates...");let{stdout:t}=await execa("npm",["view",ye,"version"],{timeout:3e3}),e=t.trim();e&&e!==L?(console.log(i.yellow(`
|
|
342
|
+
\u26A0\uFE0F Update available: ${L} \u2192 ${e}`)),console.log(i.cyan(`Run: npm install -g rapidkit@latest
|
|
343
|
+
`))):s.debug("You are using the latest version");}catch{s.debug("Could not check for updates");}}function B(){return L}function V(t){let e=he(t);if(!e.validForNewPackages){let r=e.errors||[],n=e.warnings||[],m=[...r,...n];throw new k(t,`NPM validation failed: ${m.join(", ")}`)}if(!/^[a-z][a-z0-9_-]*$/.test(t))throw new k(t,"Must start with a lowercase letter and contain only lowercase letters, numbers, hyphens, and underscores");if(["test","tests","src","dist","build","lib","python","pip","poetry","node","npm","rapidkit","rapidkit"].includes(t.toLowerCase()))throw new k(t,`"${t}" is a reserved name. Please choose a different name.`);if(t.length<2)throw new k(t,"Name must be at least 2 characters long");if(t.length>214)throw new k(t,"Name must be less than 214 characters");return true}var w=null,M=false,X=new Command;X.name("rapidkit").description("Create a RapidKit development environment or workspace").version(B()).argument("[directory-name]","Name of the workspace or project directory").option("--skip-git","Skip git initialization").option("--test-mode","Install RapidKit from local path (for development/testing only)").option("--demo","Create workspace with demo kit templates (no Python installation required)").option("--demo-only","Generate a demo project in current directory (used by demo workspace)").option("--debug","Enable debug logging").option("--dry-run","Show what would be created without creating it").option("--no-update-check","Skip checking for updates").action(async(t,e)=>{try{e.debug&&(s.setDebug(!0),s.debug("Debug mode enabled"));let o=await z();if(s.debug("User config loaded",o),e.updateCheck!==!1&&await H(),console.log(i.blue.bold(`
|
|
344
|
+
\u{1F680} Welcome to RapidKit!
|
|
345
|
+
`)),e.demoOnly){let n=t||"my-fastapi-project";try{V(n);}catch(a){throw a instanceof g&&(s.error(`
|
|
346
|
+
\u274C ${a.message}`),a.details&&s.warn(`\u{1F4A1} ${a.details}
|
|
347
|
+
`),process.exit(1)),a}let m=y.resolve(process.cwd(),n);if(w=m,e.dryRun){console.log(i.cyan(`
|
|
348
|
+
\u{1F50D} Dry-run mode - showing what would be created:
|
|
349
|
+
`)),console.log(i.white("\u{1F4C2} Project path:"),m),console.log(i.white("\u{1F4E6} Project type:"),"FastAPI demo project"),console.log(i.white("\u{1F4DD} Files to create:")),console.log(i.gray(" - src/main.py")),console.log(i.gray(" - src/cli.py")),console.log(i.gray(" - src/routing/")),console.log(i.gray(" - tests/")),console.log(i.gray(" - pyproject.toml")),console.log(i.gray(` - README.md
|
|
350
|
+
`));return}let p=await oe.prompt([{type:"input",name:"project_name",message:"Project name (snake_case):",default:n.replace(/-/g,"_"),validate:a=>/^[a-z][a-z0-9_]*$/.test(a)?!0:"Please use snake_case (lowercase with underscores)"},{type:"input",name:"author",message:"Author name:",default:process.env.USER||"RapidKit User"},{type:"input",name:"description",message:"Project description:",default:"FastAPI service generated with RapidKit"}]);await Y(m,p);return}let r=t||"rapidkit-workspace";try{V(r);}catch(n){throw n instanceof g&&(s.error(`
|
|
351
|
+
\u274C ${n.message}`),n.details&&s.warn(`\u{1F4A1} ${n.details}
|
|
352
|
+
`),process.exit(1)),n}if(w=y.resolve(process.cwd(),r),e.demo){console.log(i.gray(`This will create a workspace with demo kit templates.
|
|
353
|
+
You can generate demo projects inside without installing Python RapidKit.
|
|
354
|
+
`)),await U(r,{skipGit:e.skipGit||o.skipGit,testMode:!1,demoMode:!0,dryRun:e.dryRun,userConfig:o});return}console.log(i.yellow.bold(`\u26A0\uFE0F BETA NOTICE
|
|
355
|
+
`)),console.log(i.yellow(`RapidKit Python package is not yet available on PyPI.
|
|
356
|
+
Full installation mode will be available soon.
|
|
357
|
+
`)),console.log(i.cyan(`For now, please use one of these options:
|
|
358
|
+
`)),console.log(i.white(" 1. Demo mode (recommended):")),console.log(i.gray(` npx rapidkit my-workspace --demo
|
|
359
|
+
`)),console.log(i.white(" 2. Test mode (if you have local RapidKit):")),console.log(i.gray(` npx rapidkit my-workspace --test-mode
|
|
360
|
+
`)),e.testMode||(console.log(i.red(`\u274C Cannot proceed without --demo or --test-mode flag.
|
|
361
|
+
`)),process.exit(1)),console.log(i.yellow(`\u26A0\uFE0F Running in TEST MODE - Installing from local path
|
|
362
|
+
`)),await U(r,{skipGit:e.skipGit||o.skipGit,testMode:e.testMode,demoMode:!1,dryRun:e.dryRun,userConfig:o});}catch(o){o instanceof g?(s.error(`
|
|
363
|
+
\u274C ${o.message}`),o.details&&s.warn(`\u{1F4A1} ${o.details}`),s.debug("Error code:",o.code)):(s.error(`
|
|
364
|
+
\u274C An unexpected error occurred:`),console.error(o)),process.exit(1);}finally{w=null;}});process.on("SIGINT",async()=>{if(!M){if(M=true,console.log(i.yellow(`
|
|
365
|
+
|
|
366
|
+
\u26A0\uFE0F Interrupted by user`)),w&&await h.pathExists(w)){console.log(i.gray("Cleaning up partial installation..."));try{await h.remove(w),console.log(i.green("\u2713 Cleanup complete"));}catch(t){s.debug("Cleanup failed:",t);}}process.exit(130);}});process.on("SIGTERM",async()=>{if(!M){if(M=true,s.debug("Received SIGTERM"),w&&await h.pathExists(w))try{await h.remove(w);}catch(t){s.debug("Cleanup failed:",t);}process.exit(143);}});X.parse();
|
package/package.json
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "rapidkit",
|
|
3
|
+
"version": "0.10.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Create RapidKit projects with a single command - The official CLI for RapidKit framework",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"rapidkit",
|
|
8
|
+
"cli",
|
|
9
|
+
"create",
|
|
10
|
+
"fastapi",
|
|
11
|
+
"nestjs",
|
|
12
|
+
"backend",
|
|
13
|
+
"microservices",
|
|
14
|
+
"generator",
|
|
15
|
+
"scaffold"
|
|
16
|
+
],
|
|
17
|
+
"author": "RapidKit Team",
|
|
18
|
+
"license": "MIT",
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "git+https://github.com/getrapidkit/rapidkit-npm.git"
|
|
22
|
+
},
|
|
23
|
+
"bin": {
|
|
24
|
+
"rapidkit": "dist/index.js"
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"dist",
|
|
28
|
+
"templates"
|
|
29
|
+
],
|
|
30
|
+
"scripts": {
|
|
31
|
+
"build": "tsup",
|
|
32
|
+
"build:watch": "tsup --watch",
|
|
33
|
+
"dev": "tsup --watch",
|
|
34
|
+
"prepare": "husky",
|
|
35
|
+
"test": "vitest run",
|
|
36
|
+
"test:watch": "vitest",
|
|
37
|
+
"test:coverage": "vitest run --coverage",
|
|
38
|
+
"test:e2e": "vitest run src/__tests__/e2e.test.ts",
|
|
39
|
+
"lint": "eslint src --ext .ts",
|
|
40
|
+
"lint:fix": "eslint src --ext .ts --fix",
|
|
41
|
+
"format": "prettier --write \"src/**/*.ts\"",
|
|
42
|
+
"format:check": "prettier --check \"src/**/*.ts\"",
|
|
43
|
+
"typecheck": "tsc --noEmit",
|
|
44
|
+
"validate": "npm run typecheck && npm run lint && npm run format:check && npm test",
|
|
45
|
+
"security": "npm audit --audit-level=moderate",
|
|
46
|
+
"bundle-size": "npm run build && du -sh dist/ && ls -lh dist/"
|
|
47
|
+
},
|
|
48
|
+
"dependencies": {
|
|
49
|
+
"chalk": "^5.3.0",
|
|
50
|
+
"commander": "^12.1.0",
|
|
51
|
+
"execa": "^9.3.1",
|
|
52
|
+
"fs-extra": "^11.2.0",
|
|
53
|
+
"inquirer": "^9.2.23",
|
|
54
|
+
"nunjucks": "^3.2.4",
|
|
55
|
+
"ora": "^8.0.1",
|
|
56
|
+
"validate-npm-package-name": "^5.0.1"
|
|
57
|
+
},
|
|
58
|
+
"devDependencies": {
|
|
59
|
+
"@types/fs-extra": "^11.0.4",
|
|
60
|
+
"@types/inquirer": "^9.0.7",
|
|
61
|
+
"@types/node": "^20.14.0",
|
|
62
|
+
"@types/nunjucks": "^3.2.6",
|
|
63
|
+
"@types/validate-npm-package-name": "^4.0.2",
|
|
64
|
+
"@typescript-eslint/eslint-plugin": "^8.46.2",
|
|
65
|
+
"@typescript-eslint/parser": "^8.46.2",
|
|
66
|
+
"@vitest/coverage-v8": "^2.0.0",
|
|
67
|
+
"@vitest/ui": "^2.0.0",
|
|
68
|
+
"eslint": "^8.57.1",
|
|
69
|
+
"husky": "^9.1.7",
|
|
70
|
+
"lint-staged": "^15.5.2",
|
|
71
|
+
"prettier": "^3.6.2",
|
|
72
|
+
"tsup": "^8.5.0",
|
|
73
|
+
"typescript": "^5.5.0",
|
|
74
|
+
"vitest": "^2.0.0"
|
|
75
|
+
},
|
|
76
|
+
"engines": {
|
|
77
|
+
"node": ">=18.0.0"
|
|
78
|
+
},
|
|
79
|
+
"lint-staged": {
|
|
80
|
+
"*.ts": [
|
|
81
|
+
"eslint --fix",
|
|
82
|
+
"prettier --write"
|
|
83
|
+
]
|
|
84
|
+
},
|
|
85
|
+
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
|
|
86
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# {{ project_name | replace('_', ' ') | title }}
|
|
2
|
+
|
|
3
|
+
A minimal FastAPI service generated with the **FastAPI Standard Kit**. All domain-specific capabilities (configuration, logging, persistence, observability, authentication, etc.) are provided by RapidKit modules.
|
|
4
|
+
|
|
5
|
+
## Quick start
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
poetry install
|
|
9
|
+
poetry run dev
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Available commands
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
poetry run dev # ๐ Start development server with hot reload
|
|
16
|
+
poetry run start # โก Start production server
|
|
17
|
+
poetry run build # ๐ฆ Build project for production
|
|
18
|
+
poetry run test # ๐งช Run tests
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Project layout
|
|
22
|
+
|
|
23
|
+
- `src/main.py` โ FastAPI application entrypoint
|
|
24
|
+
- `src/routing/` โ Core routers (health) and anchors for module routers
|
|
25
|
+
- `src/modules/` โ Module bootstrap anchors
|
|
26
|
+
- `pyproject.toml` โ Poetry configuration and dependencies
|
|
27
|
+
|
|
28
|
+
## Adding features
|
|
29
|
+
|
|
30
|
+
Use `rapidkit add module <module-name>` to install optional capabilities. Modules inject imports, routes, and services through the anchors defined in `src/main.py` and `src/routing/__init__.py`.
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "fastapi-standard",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Standard FastAPI starter kit with basic project structure",
|
|
5
|
+
"author": "RapidKit Team",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"rapidkit_min_version": "2.0.0",
|
|
8
|
+
"python_min_version": "3.10",
|
|
9
|
+
"tags": ["fastapi", "python", "api", "backend", "microservices"],
|
|
10
|
+
"features": [
|
|
11
|
+
"FastAPI application setup",
|
|
12
|
+
"Routing system with health check",
|
|
13
|
+
"Module system for extensibility",
|
|
14
|
+
"CLI commands via Poetry scripts",
|
|
15
|
+
"Testing setup with pytest",
|
|
16
|
+
"Code quality tools (black, ruff, mypy)"
|
|
17
|
+
],
|
|
18
|
+
"files": [
|
|
19
|
+
"src/main.py",
|
|
20
|
+
"src/__init__.py",
|
|
21
|
+
"src/cli.py",
|
|
22
|
+
"src/routing/__init__.py",
|
|
23
|
+
"src/routing/health.py",
|
|
24
|
+
"src/modules/__init__.py",
|
|
25
|
+
"tests/__init__.py",
|
|
26
|
+
"README.md",
|
|
27
|
+
"pyproject.toml"
|
|
28
|
+
],
|
|
29
|
+
"variables": {
|
|
30
|
+
"project_name": {
|
|
31
|
+
"type": "string",
|
|
32
|
+
"description": "Project name (snake_case)",
|
|
33
|
+
"required": true,
|
|
34
|
+
"pattern": "^[a-z][a-z0-9_]*$"
|
|
35
|
+
},
|
|
36
|
+
"author": {
|
|
37
|
+
"type": "string",
|
|
38
|
+
"description": "Project author name",
|
|
39
|
+
"default": "RapidKit User"
|
|
40
|
+
},
|
|
41
|
+
"description": {
|
|
42
|
+
"type": "string",
|
|
43
|
+
"description": "Project description",
|
|
44
|
+
"default": "FastAPI service generated with RapidKit"
|
|
45
|
+
},
|
|
46
|
+
"app_version": {
|
|
47
|
+
"type": "string",
|
|
48
|
+
"description": "Initial version number",
|
|
49
|
+
"default": "0.1.0",
|
|
50
|
+
"pattern": "^\\d+\\.\\d+\\.\\d+$"
|
|
51
|
+
},
|
|
52
|
+
"license": {
|
|
53
|
+
"type": "string",
|
|
54
|
+
"description": "Project license",
|
|
55
|
+
"default": "MIT",
|
|
56
|
+
"enum": ["MIT", "Apache-2.0", "BSD-3-Clause", "GPL-3.0", "Proprietary"]
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
"dependencies": {
|
|
60
|
+
"required": {
|
|
61
|
+
"python": "^3.10",
|
|
62
|
+
"poetry": "^1.5.0"
|
|
63
|
+
},
|
|
64
|
+
"python_packages": {
|
|
65
|
+
"fastapi": "^0.100.0",
|
|
66
|
+
"uvicorn": "^0.23.0",
|
|
67
|
+
"pydantic": "^2.0.0"
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|