sveltekit-python-vercel 0.1.0 → 0.3.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 CHANGED
@@ -1,22 +1,34 @@
1
+ <p align="middle">
1
2
  <img width="100" alt="image" src="https://user-images.githubusercontent.com/20548516/218344678-d41f4c4a-6b1b-48cc-8553-2b9fbe2169d6.png"/>
2
3
  <img width="100" alt="image" src="https://camo.githubusercontent.com/f1ac9955f30176e6183aeeeac1b77354c7a132696fdc77c06ef0f0bec30f258c/68747470733a2f2f6861636b616461792e636f6d2f77702d636f6e74656e742f75706c6f6164732f323031392f30392f707974686f6e2d6c6f676f2e706e67"/>
3
4
  <img width="100" alt="image" src="https://camo.githubusercontent.com/add2c9721e333f0043ac938f3dadbc26a282776e01b95b308fcaba5afaf74ae3/68747470733a2f2f6173736574732e76657263656c2e636f6d2f696d6167652f75706c6f61642f76313538383830353835382f7265706f7369746f726965732f76657263656c2f6c6f676f2e706e67"/>
5
+ </p>
4
6
 
5
7
  # sveltekit-python-vercel
6
8
 
7
9
  Write Python endpoints in [SvelteKit](https://kit.svelte.dev/) and seamlessly deploy them to Vercel.
8
10
 
11
+ - [Current Features](#current-features)
12
+ - [Installing](#installing)
13
+ - [Testing Locally](#testing-locally)
14
+ - [Deploying to Vercel](#deploying-to-vercel)
15
+ - [Example](#example)
16
+ - [Backend Caveats](#backend-caveats)
17
+ - [Fork of `sveltekit-modal`](#fork-of-sveltekit-modal)
18
+ - [Possible future plans](#possible-future-plans)
19
+
9
20
  **This is very much in beta.**
10
21
 
11
22
  ## Current Features
12
23
 
13
24
  - Write `+server.py` files nearly the same way you would write `+server.js` files
14
- - These functions deploy automatically to Vercel Serverless
25
+ - Deploy (quasi) automatically to Vercel Serverless
15
26
 
16
27
  ## Installing
17
28
 
18
29
  - Open or set up your SvelteKit project
19
- - Install with `npm i -D sveltekit-python-vercel`
30
+ - Install SvelteKit's Vercel adapter: `pnpm i -D @sveltejs/adapter-vercel`
31
+ - Install with `pnpm i -D sveltekit-python-vercel`
20
32
  - Update your `vite.config.js`
21
33
 
22
34
  ```javascript
@@ -34,7 +46,7 @@ Write Python endpoints in [SvelteKit](https://kit.svelte.dev/) and seamlessly de
34
46
  - Update your `svelte.config.js`:
35
47
 
36
48
  ```javascript
37
- import adapter from "@sveltejs/adapter-vercel";
49
+ import adapter from "@sveltejs/adapter-vercel"; // Use the vercel adapter
38
50
  import { vitePreprocess } from "@sveltejs/kit/vite";
39
51
 
40
52
  /** @type {import('@sveltejs/kit').Config} */
@@ -50,8 +62,10 @@ Write Python endpoints in [SvelteKit](https://kit.svelte.dev/) and seamlessly de
50
62
  ```
51
63
 
52
64
  - Update your `vercel.json`
65
+
53
66
  - The build command prepares all your endpoints and copies them to the `/api` directory where Vercel looks for functions
54
67
  - Functions and Routes tell Vercel how to run and redirect function calls
68
+
55
69
  ```json
56
70
  {
57
71
  "buildCommand": "node ./node_modules/sveltekit-python-vercel/esm/src/vite/sveltekit_python_vercel/bin.mjs; vite build",
@@ -72,7 +86,8 @@ Write Python endpoints in [SvelteKit](https://kit.svelte.dev/) and seamlessly de
72
86
  - Write some `+server.py` endpoints. See the example section below.
73
87
 
74
88
  ## Testing Locally
75
- Using [Poetry](https://python-poetry.org/) to manage your virtual environments with this package is recommended.
89
+
90
+ Using [Poetry](https://python-poetry.org/) to manage your virtual environments with this package is recommended.
76
91
 
77
92
  - Run `poetry init` to create a new virtual environment, and follow the steps. Or simply create a `pyproject.toml` like the one below.
78
93
 
@@ -94,15 +109,38 @@ Using [Poetry](https://python-poetry.org/) to manage your virtual environments w
94
109
  requires = ["poetry-core"]
95
110
  build-backend = "poetry.core.masonry.api"
96
111
  ```
112
+
97
113
  - Required packages are python3.9 (that is what Vercel's runtime uses), `fastapi`, and `uvicorn`.
98
114
  - Install whatever other dependencies you need from pypi using `poetry add package-name`
99
115
 
116
+ - Enter your virtual env with `poetry shell`
100
117
  - Run `pnpm dev` or `npm dev`
118
+ - You should see both the usual SvelteKit server start as well as the unvicorn server (by default on `http://0.0.0.0:8000`) in the console.
119
+
120
+ ## Deploying to Vercel
121
+
122
+ - At the moment this requires a tiny bit of extra labor besides just pushing to your repository. I believe this is because of the way Vercel looks for serverless functions, but I hope to make this a bit easier in the future.
123
+
124
+ - When you make changes to your python endpoints, you have to manually regenerate the `/api` folder by running:
125
+ 1. `poetry export -f requirements.txt --output requirements.txt --without-hashes`
126
+ 2. `node ./node_modules/sveltekit-python-vercel/esm/src/vite/sveltekit_python_vercel/bin.mjs`
127
+ - Then commit `requirements.txt` and the changes in `/api` and push.
101
128
 
129
+ Note:
130
+
131
+ - To make this a bit smoother, you can add a script to you `package.json`:
132
+ ```json
133
+ "scripts": {
134
+ ...
135
+ "py-update": "poetry export -f requirements.txt --output requirements.txt --without-hashes; node ./node_modules/sveltekit-python-vercel/esm/src/vite/sveltekit_python_vercel/bin.mjs"
136
+ }
137
+ ```
138
+ - and then just run `pnpm py-update`
102
139
 
103
140
  ## Example
104
141
 
105
142
  - Frontend: `/src/routes/py/+page.svelte`
143
+
106
144
  ```html
107
145
  <script lang="ts">
108
146
  let a = 0;
@@ -110,12 +148,12 @@ Using [Poetry](https://python-poetry.org/) to manage your virtual environments w
110
148
  let total = 0;
111
149
 
112
150
  async function pyAddPost() {
113
- const response = await fetch('/py', {
114
- method: 'POST',
151
+ const response = await fetch("/py", {
152
+ method: "POST",
115
153
  body: JSON.stringify({ a, b }),
116
154
  headers: {
117
- 'content-type': 'application/json'
118
- }
155
+ "content-type": "application/json",
156
+ },
119
157
  });
120
158
  let res = await response.json();
121
159
  total = res.sum;
@@ -123,10 +161,10 @@ Using [Poetry](https://python-poetry.org/) to manage your virtual environments w
123
161
 
124
162
  async function pyAddGet() {
125
163
  const response = await fetch(`/py?a=${a}&b=${b}`, {
126
- method: 'GET',
164
+ method: "GET",
127
165
  headers: {
128
- 'content-type': 'application/json'
129
- }
166
+ "content-type": "application/json",
167
+ },
130
168
  });
131
169
 
132
170
  let res = await response.json();
@@ -138,9 +176,9 @@ Using [Poetry](https://python-poetry.org/) to manage your virtual environments w
138
176
 
139
177
  <h3>POST Example</h3>
140
178
  <form>
141
- <input type="number" name="a" placeholder="Number 1" bind:value={a} />
142
- <input type="number" name="b" placeholder="Number 2" bind:value={b} />
143
- <button on:click|preventDefault={pyAddPost}>Add</button>
179
+ <input type="number" name="a" placeholder="Number 1" bind:value="{a}" />
180
+ <input type="number" name="b" placeholder="Number 2" bind:value="{b}" />
181
+ <button on:click|preventDefault="{pyAddPost}">Add</button>
144
182
  </form>
145
183
  <h4>Total: {total}</h4>
146
184
 
@@ -148,14 +186,15 @@ Using [Poetry](https://python-poetry.org/) to manage your virtual environments w
148
186
 
149
187
  <h3>GET Example</h3>
150
188
  <form>
151
- <input type="number" name="a" placeholder="Number 1" bind:value={a} />
152
- <input type="number" name="b" placeholder="Number 2" bind:value={b} />
153
- <button on:click|preventDefault={pyAddGet}>Add</button>
189
+ <input type="number" name="a" placeholder="Number 1" bind:value="{a}" />
190
+ <input type="number" name="b" placeholder="Number 2" bind:value="{b}" />
191
+ <button on:click|preventDefault="{pyAddGet}">Add</button>
154
192
  </form>
155
193
  <h4>Total: {total}</h4>
156
194
  ```
157
195
 
158
196
  - Backend: `/src/routes/py/+server.py`
197
+
159
198
  ```python
160
199
  from pydantic import BaseModel
161
200
 
@@ -174,10 +213,15 @@ Using [Poetry](https://python-poetry.org/) to manage your virtual environments w
174
213
 
175
214
  ```
176
215
 
177
- ## Caveats
216
+ ### Backend Caveats
178
217
 
179
218
  There are currently a few things that have to be worked around.
180
219
 
220
+ - `GET` endpoints are directly fed the parameters from the url, so when you define an endpoint
221
+ - All other endpoints are fed the body as a JSON. The recommended way to deal with this is to use a pydantic model and pass it as the singular input to the function.
222
+
223
+ See the example above.
224
+
181
225
  ## Fork of `sveltekit-modal`
182
226
 
183
227
  Check out the awesome [sveltekit-modal](https://github.com/semicognitive/sveltekit-modal) package by [@semicognitive](https://github.com/semicognitive), the original way to get your python code running in SvelteKit. Modal even has GPU support for running an entire ML stack within SvelteKit.
@@ -25,7 +25,8 @@ for module_path in glob.glob(str(root_dir / 'src/routes/**/+server.py'), recursi
25
25
 
26
26
  # replace the root_dir with api_dir
27
27
  api_route = api_dir / Path(module_path).absolute().relative_to(root_dir / "src/routes")
28
-
28
+ api_route = Path(str(api_route).replace('[', '{').replace(']', '}'))
29
+
29
30
  if not api_route.parent.exists():
30
31
  api_route.parent.mkdir(parents=True)
31
32
 
@@ -22,6 +22,9 @@ for module_path in glob.glob('./**/+server.py', recursive=True):
22
22
 
23
23
  api_route = module_path[1:] if module_path.startswith('./') else module_path
24
24
  api_route = str(Path(api_route).parent)
25
+
26
+ # Replace square brackets with curly brackets
27
+ api_route = api_route.replace('[', '{').replace(']', '}')
25
28
 
26
29
  mod = importlib.import_module(module_name, module_package)
27
30
 
@@ -52,6 +52,9 @@ if __name__ == "__main__":
52
52
  # Convert the relative path to a string and remove the file extension
53
53
  api_path = "/" + str(rel_path.parent)
54
54
 
55
+ # Replace square brackets with curly brackets
56
+ api_path = api_path.replace('[', '{').replace(']', '}')
57
+
55
58
  print("ADDING API PATH:", rel_path, api_path)
56
59
 
57
60
  if hasattr(mod, 'GET'):
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "module": "./esm/mod.js",
3
3
  "types": "./types/mod.d.ts",
4
4
  "name": "sveltekit-python-vercel",
5
- "version": "v0.1.0",
5
+ "version": "v0.3.0",
6
6
  "description": "Write Sveltekit server endpoints in Python and seamlessly deploy to Vercel",
7
7
  "repository": {
8
8
  "type": "git",