render-create 0.1.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/README.md +207 -0
- package/dist/cli.d.ts +6 -0
- package/dist/cli.js +45 -0
- package/dist/commands/check.d.ts +8 -0
- package/dist/commands/check.js +96 -0
- package/dist/commands/init.d.ts +12 -0
- package/dist/commands/init.js +1201 -0
- package/dist/commands/sync.d.ts +8 -0
- package/dist/commands/sync.js +126 -0
- package/dist/types.d.ts +246 -0
- package/dist/types.js +4 -0
- package/dist/utils.d.ts +53 -0
- package/dist/utils.js +142 -0
- package/package.json +65 -0
- package/templates/LINTING_SETUP.md +205 -0
- package/templates/README_TEMPLATE.md +68 -0
- package/templates/STYLE_GUIDE.md +241 -0
- package/templates/assets/favicon.png +0 -0
- package/templates/assets/favicon.svg +17 -0
- package/templates/biome.json +43 -0
- package/templates/cursor/rules/drizzle.mdc +165 -0
- package/templates/cursor/rules/fastify.mdc +132 -0
- package/templates/cursor/rules/general.mdc +112 -0
- package/templates/cursor/rules/nextjs.mdc +89 -0
- package/templates/cursor/rules/python.mdc +89 -0
- package/templates/cursor/rules/react.mdc +200 -0
- package/templates/cursor/rules/sqlalchemy.mdc +205 -0
- package/templates/cursor/rules/tailwind.mdc +139 -0
- package/templates/cursor/rules/typescript.mdc +112 -0
- package/templates/cursor/rules/vite.mdc +169 -0
- package/templates/cursor/rules/workflows.mdc +349 -0
- package/templates/docker-compose.example.yml +55 -0
- package/templates/drizzle/db-index.ts +15 -0
- package/templates/drizzle/drizzle.config.ts +10 -0
- package/templates/drizzle/schema.ts +12 -0
- package/templates/env.example +15 -0
- package/templates/fastapi/app/__init__.py +1 -0
- package/templates/fastapi/app/config.py +12 -0
- package/templates/fastapi/app/database.py +16 -0
- package/templates/fastapi/app/models.py +13 -0
- package/templates/fastapi/main.py +22 -0
- package/templates/fastify/index.ts +40 -0
- package/templates/github/CODEOWNERS +10 -0
- package/templates/github/ISSUE_TEMPLATE/bug_report.md +39 -0
- package/templates/github/ISSUE_TEMPLATE/feature_request.md +23 -0
- package/templates/github/PULL_REQUEST_TEMPLATE.md +25 -0
- package/templates/gitignore/node.gitignore +41 -0
- package/templates/gitignore/python.gitignore +49 -0
- package/templates/multi-api/README.md +60 -0
- package/templates/multi-api/gitignore +28 -0
- package/templates/multi-api/node-api/drizzle.config.ts +10 -0
- package/templates/multi-api/node-api/package-simple.json +13 -0
- package/templates/multi-api/node-api/package.json +16 -0
- package/templates/multi-api/node-api/src/db/index.ts +13 -0
- package/templates/multi-api/node-api/src/db/schema.ts +9 -0
- package/templates/multi-api/node-api/src/index-simple.ts +36 -0
- package/templates/multi-api/node-api/src/index.ts +50 -0
- package/templates/multi-api/node-api/tsconfig.json +20 -0
- package/templates/multi-api/python-api/app/__init__.py +1 -0
- package/templates/multi-api/python-api/app/config.py +12 -0
- package/templates/multi-api/python-api/app/database.py +16 -0
- package/templates/multi-api/python-api/app/models.py +13 -0
- package/templates/multi-api/python-api/main-simple.py +25 -0
- package/templates/multi-api/python-api/main.py +44 -0
- package/templates/multi-api/python-api/requirements-simple.txt +3 -0
- package/templates/multi-api/python-api/requirements.txt +8 -0
- package/templates/next/globals.css +126 -0
- package/templates/next/layout.tsx +34 -0
- package/templates/next/next.config.static.ts +10 -0
- package/templates/next/page-fullstack.tsx +120 -0
- package/templates/next/page.tsx +72 -0
- package/templates/presets.json +581 -0
- package/templates/ruff.toml +30 -0
- package/templates/tsconfig.base.json +17 -0
- package/templates/vite/index.css +127 -0
- package/templates/vite/vite.config.ts +7 -0
- package/templates/worker/py/cron.py +53 -0
- package/templates/worker/py/worker.py +95 -0
- package/templates/worker/py/workflow.py +73 -0
- package/templates/worker/ts/cron.ts +49 -0
- package/templates/worker/ts/worker.ts +84 -0
- package/templates/worker/ts/workflow.ts +67 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import Fastify from "fastify";
|
|
2
|
+
import cors from "@fastify/cors";
|
|
3
|
+
import { db } from "./db";
|
|
4
|
+
import { users } from "./db/schema";
|
|
5
|
+
|
|
6
|
+
const fastify = Fastify({
|
|
7
|
+
logger: true,
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
// Register plugins
|
|
11
|
+
fastify.register(cors, {
|
|
12
|
+
origin: true,
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
// Health check endpoint
|
|
16
|
+
fastify.get("/health", async () => {
|
|
17
|
+
return { status: "ok" };
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
// Example: Get all users
|
|
21
|
+
fastify.get("/users", async () => {
|
|
22
|
+
const allUsers = await db.select().from(users);
|
|
23
|
+
return allUsers;
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
// Start server
|
|
27
|
+
const start = async () => {
|
|
28
|
+
try {
|
|
29
|
+
const host = process.env.HOST ?? "0.0.0.0";
|
|
30
|
+
const port = Number(process.env.PORT) || 3000;
|
|
31
|
+
|
|
32
|
+
await fastify.listen({ host, port });
|
|
33
|
+
console.log(`Server running at http://${host}:${port}`);
|
|
34
|
+
} catch (err) {
|
|
35
|
+
fastify.log.error(err);
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
start();
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Bug Report
|
|
3
|
+
about: Report a bug to help us improve
|
|
4
|
+
title: '[Bug] '
|
|
5
|
+
labels: bug
|
|
6
|
+
assignees: ''
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Description
|
|
10
|
+
|
|
11
|
+
<!-- Clear description of the bug -->
|
|
12
|
+
|
|
13
|
+
## Steps to Reproduce
|
|
14
|
+
|
|
15
|
+
1.
|
|
16
|
+
2.
|
|
17
|
+
3.
|
|
18
|
+
|
|
19
|
+
## Expected Behavior
|
|
20
|
+
|
|
21
|
+
<!-- What should happen -->
|
|
22
|
+
|
|
23
|
+
## Actual Behavior
|
|
24
|
+
|
|
25
|
+
<!-- What actually happens -->
|
|
26
|
+
|
|
27
|
+
## Environment
|
|
28
|
+
|
|
29
|
+
- OS:
|
|
30
|
+
- Node/Python version:
|
|
31
|
+
- Browser (if applicable):
|
|
32
|
+
|
|
33
|
+
## Screenshots
|
|
34
|
+
|
|
35
|
+
<!-- If applicable, add screenshots -->
|
|
36
|
+
|
|
37
|
+
## Additional Context
|
|
38
|
+
|
|
39
|
+
<!-- Any other context about the problem -->
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Feature Request
|
|
3
|
+
about: Suggest a new feature or improvement
|
|
4
|
+
title: '[Feature] '
|
|
5
|
+
labels: enhancement
|
|
6
|
+
assignees: ''
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Problem
|
|
10
|
+
|
|
11
|
+
<!-- What problem does this feature solve? -->
|
|
12
|
+
|
|
13
|
+
## Proposed Solution
|
|
14
|
+
|
|
15
|
+
<!-- How should this work? -->
|
|
16
|
+
|
|
17
|
+
## Alternatives Considered
|
|
18
|
+
|
|
19
|
+
<!-- Any alternative solutions you've thought about -->
|
|
20
|
+
|
|
21
|
+
## Additional Context
|
|
22
|
+
|
|
23
|
+
<!-- Any other context, mockups, or examples -->
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
## Summary
|
|
2
|
+
|
|
3
|
+
<!-- Brief description of what this PR does -->
|
|
4
|
+
|
|
5
|
+
## Changes
|
|
6
|
+
|
|
7
|
+
<!-- List the main changes -->
|
|
8
|
+
|
|
9
|
+
-
|
|
10
|
+
|
|
11
|
+
## Test Plan
|
|
12
|
+
|
|
13
|
+
<!-- How did you test these changes? -->
|
|
14
|
+
|
|
15
|
+
- [ ] Tested locally
|
|
16
|
+
- [ ] Added/updated tests
|
|
17
|
+
- [ ] Verified in staging
|
|
18
|
+
|
|
19
|
+
## Checklist
|
|
20
|
+
|
|
21
|
+
- [ ] Code follows project style guide
|
|
22
|
+
- [ ] Self-reviewed the code
|
|
23
|
+
- [ ] Added comments where needed
|
|
24
|
+
- [ ] Updated documentation if needed
|
|
25
|
+
- [ ] No new warnings or errors
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Dependencies
|
|
2
|
+
node_modules/
|
|
3
|
+
.pnp
|
|
4
|
+
.pnp.js
|
|
5
|
+
|
|
6
|
+
# Build outputs
|
|
7
|
+
dist/
|
|
8
|
+
build/
|
|
9
|
+
.next/
|
|
10
|
+
out/
|
|
11
|
+
|
|
12
|
+
# Environment
|
|
13
|
+
.env
|
|
14
|
+
.env.local
|
|
15
|
+
.env.development.local
|
|
16
|
+
.env.test.local
|
|
17
|
+
.env.production.local
|
|
18
|
+
|
|
19
|
+
# Logs
|
|
20
|
+
npm-debug.log*
|
|
21
|
+
yarn-debug.log*
|
|
22
|
+
yarn-error.log*
|
|
23
|
+
.pnpm-debug.log*
|
|
24
|
+
|
|
25
|
+
# Testing
|
|
26
|
+
coverage/
|
|
27
|
+
.nyc_output/
|
|
28
|
+
|
|
29
|
+
# IDE
|
|
30
|
+
.idea/
|
|
31
|
+
.vscode/
|
|
32
|
+
*.swp
|
|
33
|
+
*.swo
|
|
34
|
+
.DS_Store
|
|
35
|
+
|
|
36
|
+
# TypeScript
|
|
37
|
+
*.tsbuildinfo
|
|
38
|
+
|
|
39
|
+
# Misc
|
|
40
|
+
.cache/
|
|
41
|
+
.turbo/
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# Virtual environments
|
|
7
|
+
venv/
|
|
8
|
+
.venv/
|
|
9
|
+
env/
|
|
10
|
+
.env/
|
|
11
|
+
|
|
12
|
+
# Environment variables
|
|
13
|
+
.env
|
|
14
|
+
.env.local
|
|
15
|
+
.env.*.local
|
|
16
|
+
|
|
17
|
+
# Distribution / packaging
|
|
18
|
+
dist/
|
|
19
|
+
build/
|
|
20
|
+
*.egg-info/
|
|
21
|
+
*.egg
|
|
22
|
+
|
|
23
|
+
# Testing
|
|
24
|
+
.pytest_cache/
|
|
25
|
+
.coverage
|
|
26
|
+
htmlcov/
|
|
27
|
+
.tox/
|
|
28
|
+
.nox/
|
|
29
|
+
|
|
30
|
+
# Type checking
|
|
31
|
+
.mypy_cache/
|
|
32
|
+
.pytype/
|
|
33
|
+
|
|
34
|
+
# IDE
|
|
35
|
+
.idea/
|
|
36
|
+
.vscode/
|
|
37
|
+
*.swp
|
|
38
|
+
*.swo
|
|
39
|
+
.DS_Store
|
|
40
|
+
|
|
41
|
+
# Jupyter
|
|
42
|
+
.ipynb_checkpoints/
|
|
43
|
+
|
|
44
|
+
# Logs
|
|
45
|
+
*.log
|
|
46
|
+
|
|
47
|
+
# Database
|
|
48
|
+
*.db
|
|
49
|
+
*.sqlite3
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# {{PROJECT_NAME}}
|
|
2
|
+
|
|
3
|
+
A multi-backend API demo showcasing both **Node.js** and **Python** implementations side-by-side.
|
|
4
|
+
|
|
5
|
+
## Project Structure
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
├── node-api/ # Fastify (Node.js)
|
|
9
|
+
│ ├── src/
|
|
10
|
+
│ │ └── index.ts # API entry point
|
|
11
|
+
│ └── package.json
|
|
12
|
+
├── python-api/ # FastAPI (Python)
|
|
13
|
+
│ ├── main.py # API entry point
|
|
14
|
+
│ └── requirements.txt
|
|
15
|
+
└── render.yaml # Render Blueprint (both services)
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Local Development
|
|
19
|
+
|
|
20
|
+
### Node API
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
cd node-api
|
|
24
|
+
npm install
|
|
25
|
+
npm run dev
|
|
26
|
+
# Runs on http://localhost:3001
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Python API
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
cd python-api
|
|
33
|
+
python -m venv .venv
|
|
34
|
+
source .venv/bin/activate
|
|
35
|
+
pip install -r requirements.txt
|
|
36
|
+
uvicorn main:app --reload --port 3002
|
|
37
|
+
# Runs on http://localhost:3002
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## API Endpoints
|
|
41
|
+
|
|
42
|
+
Both APIs expose the same endpoints for comparison:
|
|
43
|
+
|
|
44
|
+
| Endpoint | Description |
|
|
45
|
+
|-----------------|--------------------------------|
|
|
46
|
+
| `GET /health` | Health check |
|
|
47
|
+
| `GET /api/hello`| Hello message with timestamp |
|
|
48
|
+
|
|
49
|
+
## Deploy to Render
|
|
50
|
+
|
|
51
|
+
[](https://render.com/deploy)
|
|
52
|
+
|
|
53
|
+
Or manually:
|
|
54
|
+
1. Push this repo to GitHub
|
|
55
|
+
2. Connect to Render
|
|
56
|
+
3. Use the `render.yaml` Blueprint
|
|
57
|
+
|
|
58
|
+
The Blueprint creates:
|
|
59
|
+
- **node-api** - Node.js web service (Fastify)
|
|
60
|
+
- **python-api** - Python web service (FastAPI)
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Node
|
|
2
|
+
node_modules/
|
|
3
|
+
dist/
|
|
4
|
+
*.log
|
|
5
|
+
.env
|
|
6
|
+
.env.local
|
|
7
|
+
|
|
8
|
+
# Python
|
|
9
|
+
__pycache__/
|
|
10
|
+
*.py[cod]
|
|
11
|
+
*$py.class
|
|
12
|
+
.venv/
|
|
13
|
+
venv/
|
|
14
|
+
*.egg-info/
|
|
15
|
+
.eggs/
|
|
16
|
+
|
|
17
|
+
# IDE
|
|
18
|
+
.idea/
|
|
19
|
+
.vscode/
|
|
20
|
+
*.swp
|
|
21
|
+
*.swo
|
|
22
|
+
|
|
23
|
+
# OS
|
|
24
|
+
.DS_Store
|
|
25
|
+
Thumbs.db
|
|
26
|
+
|
|
27
|
+
# Drizzle
|
|
28
|
+
drizzle/
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{PROJECT_NAME}}-node-api",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "tsx watch src/index.ts",
|
|
8
|
+
"build": "tsc",
|
|
9
|
+
"start": "node dist/index.js",
|
|
10
|
+
"lint": "biome check .",
|
|
11
|
+
"format": "biome check --write ."
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{PROJECT_NAME}}-node-api",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "tsx watch src/index.ts",
|
|
8
|
+
"build": "tsc",
|
|
9
|
+
"start": "node dist/index.js",
|
|
10
|
+
"lint": "biome check .",
|
|
11
|
+
"format": "biome check --write .",
|
|
12
|
+
"db:generate": "drizzle-kit generate",
|
|
13
|
+
"db:migrate": "drizzle-kit migrate",
|
|
14
|
+
"db:studio": "drizzle-kit studio"
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { drizzle } from "drizzle-orm/postgres-js";
|
|
2
|
+
import postgres from "postgres";
|
|
3
|
+
import * as schema from "./schema";
|
|
4
|
+
|
|
5
|
+
const connectionString = process.env.DATABASE_URL;
|
|
6
|
+
|
|
7
|
+
const client = connectionString
|
|
8
|
+
? postgres(connectionString)
|
|
9
|
+
: postgres("postgres://placeholder:placeholder@localhost:5432/placeholder");
|
|
10
|
+
|
|
11
|
+
export const db = drizzle(client, { schema });
|
|
12
|
+
|
|
13
|
+
export const isDatabaseConfigured = !!connectionString;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { pgTable, serial, text, timestamp } from "drizzle-orm/pg-core";
|
|
2
|
+
|
|
3
|
+
export const users = pgTable("users", {
|
|
4
|
+
id: serial("id").primaryKey(),
|
|
5
|
+
name: text("name").notNull(),
|
|
6
|
+
email: text("email").notNull().unique(),
|
|
7
|
+
createdAt: timestamp("created_at").defaultNow().notNull(),
|
|
8
|
+
updatedAt: timestamp("updated_at").defaultNow().notNull(),
|
|
9
|
+
});
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import Fastify from "fastify";
|
|
2
|
+
import cors from "@fastify/cors";
|
|
3
|
+
|
|
4
|
+
const fastify = Fastify({
|
|
5
|
+
logger: true,
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
// Register CORS
|
|
9
|
+
await fastify.register(cors, {
|
|
10
|
+
origin: true,
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
// Health check endpoint
|
|
14
|
+
fastify.get("/health", async () => {
|
|
15
|
+
return { status: "ok", service: "node-api" };
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
// Example API endpoint
|
|
19
|
+
fastify.get("/api/hello", async () => {
|
|
20
|
+
return { message: "Hello from Node.js (Fastify)!", timestamp: new Date().toISOString() };
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
// Start server
|
|
24
|
+
const start = async () => {
|
|
25
|
+
try {
|
|
26
|
+
const host = process.env.HOST || "0.0.0.0";
|
|
27
|
+
const port = Number(process.env.PORT) || 3001;
|
|
28
|
+
await fastify.listen({ port, host });
|
|
29
|
+
console.log(`Node API listening on ${host}:${port}`);
|
|
30
|
+
} catch (err) {
|
|
31
|
+
fastify.log.error(err);
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
start();
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import Fastify from "fastify";
|
|
2
|
+
import cors from "@fastify/cors";
|
|
3
|
+
import { db } from "./db";
|
|
4
|
+
import { users } from "./db/schema";
|
|
5
|
+
|
|
6
|
+
const fastify = Fastify({
|
|
7
|
+
logger: true,
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
// Register plugins
|
|
11
|
+
fastify.register(cors, {
|
|
12
|
+
origin: true,
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
// Health check endpoint
|
|
16
|
+
fastify.get("/health", async () => {
|
|
17
|
+
return { status: "ok", service: "node-api" };
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
// Example: Get all users
|
|
21
|
+
fastify.get("/users", async () => {
|
|
22
|
+
const allUsers = await db.select().from(users);
|
|
23
|
+
return allUsers;
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
// API info
|
|
27
|
+
fastify.get("/", async () => {
|
|
28
|
+
return {
|
|
29
|
+
service: "{{PROJECT_NAME}} Node API",
|
|
30
|
+
runtime: "Node.js + Fastify",
|
|
31
|
+
orm: "Drizzle",
|
|
32
|
+
endpoints: ["/", "/health", "/users"],
|
|
33
|
+
};
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
// Start server
|
|
37
|
+
const start = async () => {
|
|
38
|
+
try {
|
|
39
|
+
const host = process.env.HOST ?? "0.0.0.0";
|
|
40
|
+
const port = Number(process.env.PORT) || 3001;
|
|
41
|
+
|
|
42
|
+
await fastify.listen({ host, port });
|
|
43
|
+
console.log(`Node API running at http://${host}:${port}`);
|
|
44
|
+
} catch (err) {
|
|
45
|
+
fastify.log.error(err);
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
start();
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "NodeNext",
|
|
5
|
+
"moduleResolution": "NodeNext",
|
|
6
|
+
"lib": ["ES2022"],
|
|
7
|
+
"outDir": "./dist",
|
|
8
|
+
"rootDir": "./src",
|
|
9
|
+
"strict": true,
|
|
10
|
+
"esModuleInterop": true,
|
|
11
|
+
"skipLibCheck": true,
|
|
12
|
+
"forceConsistentCasingInFileNames": true,
|
|
13
|
+
"resolveJsonModule": true,
|
|
14
|
+
"declaration": true,
|
|
15
|
+
"declarationMap": true,
|
|
16
|
+
"sourceMap": true
|
|
17
|
+
},
|
|
18
|
+
"include": ["src/**/*"],
|
|
19
|
+
"exclude": ["node_modules", "dist"]
|
|
20
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# App package
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from sqlalchemy import create_engine
|
|
2
|
+
from sqlalchemy.orm import sessionmaker, declarative_base
|
|
3
|
+
from app.config import settings
|
|
4
|
+
|
|
5
|
+
engine = create_engine(settings.database_url)
|
|
6
|
+
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
|
|
7
|
+
|
|
8
|
+
Base = declarative_base()
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def get_db():
|
|
12
|
+
db = SessionLocal()
|
|
13
|
+
try:
|
|
14
|
+
yield db
|
|
15
|
+
finally:
|
|
16
|
+
db.close()
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from sqlalchemy import Column, Integer, String, DateTime
|
|
2
|
+
from sqlalchemy.sql import func
|
|
3
|
+
from app.database import Base
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class User(Base):
|
|
7
|
+
__tablename__ = "users"
|
|
8
|
+
|
|
9
|
+
id = Column(Integer, primary_key=True, index=True)
|
|
10
|
+
name = Column(String, nullable=False)
|
|
11
|
+
email = Column(String, unique=True, nullable=False, index=True)
|
|
12
|
+
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
|
13
|
+
updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now())
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
from datetime import datetime
|
|
2
|
+
|
|
3
|
+
from fastapi import FastAPI
|
|
4
|
+
from fastapi.middleware.cors import CORSMiddleware
|
|
5
|
+
|
|
6
|
+
app = FastAPI(title="Python API")
|
|
7
|
+
|
|
8
|
+
# CORS middleware
|
|
9
|
+
app.add_middleware(
|
|
10
|
+
CORSMiddleware,
|
|
11
|
+
allow_origins=["*"],
|
|
12
|
+
allow_credentials=True,
|
|
13
|
+
allow_methods=["*"],
|
|
14
|
+
allow_headers=["*"],
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@app.get("/health")
|
|
19
|
+
async def health_check():
|
|
20
|
+
return {"status": "ok", "service": "python-api"}
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@app.get("/api/hello")
|
|
24
|
+
async def hello():
|
|
25
|
+
return {"message": "Hello from Python (FastAPI)!", "timestamp": datetime.now().isoformat()}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
from fastapi import FastAPI, Depends
|
|
2
|
+
from fastapi.middleware.cors import CORSMiddleware
|
|
3
|
+
from sqlalchemy.orm import Session
|
|
4
|
+
from app.config import settings
|
|
5
|
+
from app.database import engine, get_db
|
|
6
|
+
from app import models
|
|
7
|
+
|
|
8
|
+
# Create database tables
|
|
9
|
+
models.Base.metadata.create_all(bind=engine)
|
|
10
|
+
|
|
11
|
+
app = FastAPI(
|
|
12
|
+
title=f"{settings.app_name} Python API",
|
|
13
|
+
version="0.1.0",
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
# CORS
|
|
17
|
+
app.add_middleware(
|
|
18
|
+
CORSMiddleware,
|
|
19
|
+
allow_origins=["*"],
|
|
20
|
+
allow_credentials=True,
|
|
21
|
+
allow_methods=["*"],
|
|
22
|
+
allow_headers=["*"],
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@app.get("/health")
|
|
27
|
+
async def health_check():
|
|
28
|
+
return {"status": "ok", "service": "python-api"}
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@app.get("/users")
|
|
32
|
+
async def get_users(db: Session = Depends(get_db)):
|
|
33
|
+
users = db.query(models.User).all()
|
|
34
|
+
return users
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@app.get("/")
|
|
38
|
+
async def root():
|
|
39
|
+
return {
|
|
40
|
+
"service": f"{settings.app_name} Python API",
|
|
41
|
+
"runtime": "Python + FastAPI",
|
|
42
|
+
"orm": "SQLAlchemy",
|
|
43
|
+
"endpoints": ["/", "/health", "/users"],
|
|
44
|
+
}
|