create-pywire-app 0.1.3__tar.gz → 0.1.4__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.
Files changed (46) hide show
  1. {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/PKG-INFO +1 -1
  2. {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/pyproject.toml +8 -2
  3. create_pywire_app-0.1.4/src/create_pywire_app/__init__.py +8 -0
  4. create_pywire_app-0.1.4/src/create_pywire_app/_version.py +34 -0
  5. {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/main.py +101 -5
  6. {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/blog/explicit/about.wire +2 -1
  7. {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/blog/explicit/blog-posts.wire +5 -11
  8. {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/blog/explicit/home.wire +5 -2
  9. {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/blog/path-based/index.wire +5 -2
  10. {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/blog/path-based/posts_index.wire +5 -2
  11. {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/blog/path-based/posts_slug.wire +3 -9
  12. {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/common/__error__.wire +1 -2
  13. {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/counter/explicit/home.wire +6 -4
  14. {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/counter/path-based/index.wire +6 -4
  15. {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/saas/explicit/auth-layout.wire.j2 +2 -1
  16. {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/saas/explicit/dashboard-pages.wire +2 -1
  17. {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/saas/explicit/landing.wire +2 -1
  18. {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/saas/explicit/login.wire +2 -1
  19. {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/saas/explicit/pricing.wire +1 -1
  20. {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/saas/path-based/dashboard__layout__.wire.j2 +2 -1
  21. {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/saas/path-based/dashboard_index.wire +0 -1
  22. {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/saas/path-based/dashboard_settings.wire +0 -1
  23. {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/saas/path-based/index.wire +0 -1
  24. {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/saas/path-based/login.wire +0 -1
  25. {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/saas/path-based/pricing.wire +2 -1
  26. create_pywire_app-0.1.3/src/create_pywire_app/__init__.py +0 -0
  27. {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/.gitignore +0 -0
  28. {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/LICENSE +0 -0
  29. {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/README.md +0 -0
  30. {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/blog/explicit/layout.wire.j2 +0 -0
  31. {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/blog/path-based/__layout__.wire.j2 +0 -0
  32. {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/blog/path-based/posts__layout__.wire.j2 +0 -0
  33. {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/common/.gitignore +0 -0
  34. {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/common/Dockerfile +0 -0
  35. {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/common/README.md.j2 +0 -0
  36. {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/common/extensions.json +0 -0
  37. {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/common/main-explicit.py.j2 +0 -0
  38. {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/common/main-path.py.j2 +0 -0
  39. {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/common/pyproject.toml.j2 +0 -0
  40. {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/common/render.yaml.j2 +0 -0
  41. {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/counter/explicit/layout.wire.j2 +0 -0
  42. {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/counter/path-based/__layout__.wire.j2 +0 -0
  43. {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/saas/explicit/public-layout.wire.j2 +0 -0
  44. {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/saas/models.py +0 -0
  45. {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/src/create_pywire_app/templates/saas/path-based/__layout__.wire.j2 +0 -0
  46. {create_pywire_app-0.1.3 → create_pywire_app-0.1.4}/tests/test_smoke.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: create-pywire-app
3
- Version: 0.1.3
3
+ Version: 0.1.4
4
4
  Summary: Init wizard for new pywire projects
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.11
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "create-pywire-app"
3
- version = "0.1.3"
3
+ dynamic = ["version"]
4
4
  description = "Init wizard for new pywire projects"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -14,7 +14,7 @@ dependencies = [
14
14
  create-pywire-app = "create_pywire_app.main:main"
15
15
 
16
16
  [build-system]
17
- requires = ["hatchling"]
17
+ requires = ["hatchling", "hatch-vcs"]
18
18
  build-backend = "hatchling.build"
19
19
 
20
20
 
@@ -44,3 +44,9 @@ include = [
44
44
  exclude = [
45
45
  "src/create_pywire_app/templates",
46
46
  ]
47
+
48
+ [tool.hatch.version]
49
+ source = "vcs"
50
+
51
+ [tool.hatch.build.hooks.vcs]
52
+ version-file = "src/create_pywire_app/_version.py"
@@ -0,0 +1,8 @@
1
+ try:
2
+ from ._version import __version__
3
+ except ImportError:
4
+ from importlib.metadata import version, PackageNotFoundError
5
+ try:
6
+ __version__ = version("create-pywire-app")
7
+ except PackageNotFoundError:
8
+ __version__ = "unknown"
@@ -0,0 +1,34 @@
1
+ # file generated by setuptools-scm
2
+ # don't change, don't track in version control
3
+
4
+ __all__ = [
5
+ "__version__",
6
+ "__version_tuple__",
7
+ "version",
8
+ "version_tuple",
9
+ "__commit_id__",
10
+ "commit_id",
11
+ ]
12
+
13
+ TYPE_CHECKING = False
14
+ if TYPE_CHECKING:
15
+ from typing import Tuple
16
+ from typing import Union
17
+
18
+ VERSION_TUPLE = Tuple[Union[int, str], ...]
19
+ COMMIT_ID = Union[str, None]
20
+ else:
21
+ VERSION_TUPLE = object
22
+ COMMIT_ID = object
23
+
24
+ version: str
25
+ __version__: str
26
+ __version_tuple__: VERSION_TUPLE
27
+ version_tuple: VERSION_TUPLE
28
+ commit_id: COMMIT_ID
29
+ __commit_id__: COMMIT_ID
30
+
31
+ __version__ = version = '0.1.4'
32
+ __version_tuple__ = version_tuple = (0, 1, 4)
33
+
34
+ __commit_id__ = commit_id = None
@@ -8,11 +8,14 @@ from pathlib import Path
8
8
  from typing import Any, Dict, List, Optional
9
9
 
10
10
  import questionary
11
+ import tomllib
11
12
  from jinja2 import Environment, PackageLoader, select_autoescape
12
13
  from rich.console import Console
13
14
  from rich.markdown import Markdown
14
15
  from rich.panel import Panel
15
16
 
17
+ from create_pywire_app import __version__
18
+
16
19
  console = Console()
17
20
 
18
21
  LOGO = r"""
@@ -27,11 +30,56 @@ LOGO = r"""
27
30
  """
28
31
 
29
32
 
33
+ def get_local_version(path: Path) -> Optional[str]:
34
+ """Try to read version from a local pyproject.toml file."""
35
+ try:
36
+ if path.exists():
37
+ with open(path, "rb") as f:
38
+ data = tomllib.load(f)
39
+ return data.get("project", {}).get("version")
40
+ except Exception:
41
+ pass
42
+ return None
43
+
44
+
30
45
  def get_version() -> str:
46
+ return __version__
47
+
48
+
49
+ def resolve_pywire_version(pywire_dep: str) -> Optional[str]:
50
+ """Resolve the actual pywire version that will be installed.
51
+
52
+ Args:
53
+ pywire_dep: Dependency spec (e.g., 'pywire', 'pywire==0.1.4', 'pywire @ /path')
54
+
55
+ Returns:
56
+ Resolved version string or None if resolution fails
57
+ """
58
+ # For local paths, we can't resolve via uv pip compile
59
+ if "@" in pywire_dep:
60
+ return None
61
+
31
62
  try:
32
- return importlib.metadata.version("create-pywire-app")
33
- except importlib.metadata.PackageNotFoundError:
34
- return "0.0.0"
63
+ # Use uv pip compile to resolve the version without installing
64
+ process = subprocess.run(
65
+ ["uv", "pip", "compile", "-", "--quiet"],
66
+ input=pywire_dep,
67
+ text=True,
68
+ capture_output=True,
69
+ check=True,
70
+ timeout=10,
71
+ )
72
+
73
+ # Parse the output for pywire==<version>
74
+ import re
75
+ match = re.search(r'pywire==([^\s]+)', process.stdout)
76
+ if match:
77
+ return match.group(1)
78
+
79
+ except (subprocess.CalledProcessError, subprocess.TimeoutExpired, FileNotFoundError):
80
+ pass
81
+
82
+ return None
35
83
 
36
84
 
37
85
  class TemplateRenderer:
@@ -277,6 +325,19 @@ class ProjectGenerator:
277
325
 
278
326
 
279
327
  def main():
328
+ # Fix for macOS when running with redirected stdin (e.g. via pipe)
329
+ # KqueueSelector fails with /dev/tty on macOS, so we force SelectSelector.
330
+ if sys.platform == "darwin":
331
+ import asyncio
332
+ import selectors
333
+
334
+ class MacOSEventLoopPolicy(asyncio.DefaultEventLoopPolicy):
335
+ def new_event_loop(self):
336
+ selector = selectors.SelectSelector()
337
+ return asyncio.SelectorEventLoop(selector)
338
+
339
+ asyncio.set_event_loop_policy(MacOSEventLoopPolicy())
340
+
280
341
  console.clear()
281
342
 
282
343
  # Parse arguments
@@ -291,16 +352,51 @@ def main():
291
352
 
292
353
  if use_local:
293
354
  pywire_dep = "pywire @ /Users/rholmdahl/projects/pywire-workspace/pywire"
294
- # We don't warn yet, wait until after LOGO
355
+ # Try to resolve actual local version for display
356
+ # In a workspace structure, we might be in src/create_pywire_app, so up 3 levels is create-pywire-app, then up 1 is workspace
357
+ # actually let's try a safer relative resolution based on known structure
358
+ # /Users/rholmdahl/projects/pywire-workspace/create-pywire-app/src/create_pywire_app/main.py
359
+ # -> create-pywire-app (repo root) = parents[2]
360
+ # -> pywire-workspace = parents[3]
361
+ workspace_root = Path(__file__).resolve().parents[3]
362
+ local_pywire_path = workspace_root / "pywire"
363
+
364
+ # Try reading _version.py first (generated by hatch-vcs)
365
+ local_pywire_version_file = local_pywire_path / "src" / "pywire" / "_version.py"
366
+ pywire_version_display = "Local (Source)"
367
+
368
+ if local_pywire_version_file.exists():
369
+ # Basic regex search for version string to avoid importing it
370
+ import re
371
+ content = local_pywire_version_file.read_text()
372
+ match = re.search(r'version = ["\']([^"\']+)["\']', content)
373
+ if match:
374
+ pywire_version_display = f"{match.group(1)} (Local)"
375
+
376
+ if pywire_version_display == "Local (Source)":
377
+ # Fallback to toml if needed, though with hatch-vcs pyproject.toml won't have it.
378
+ # but check anyway? hatch-vcs usually cleans it.
379
+ # If completely failing, just stick with "Local (Source)"
380
+ pass
381
+
295
382
  elif args.pywire_version:
296
383
  pywire_dep = f"pywire=={args.pywire_version}"
384
+ pywire_version_display = args.pywire_version
297
385
  else:
298
386
  pywire_dep = "pywire" # Latest
387
+ pywire_version_display = "Latest"
388
+
389
+ # Resolve the actual version if not local
390
+ if not use_local and pywire_version_display == "Latest":
391
+ with console.status("[dim]Resolving version...", spinner="dots"):
392
+ resolved_version = resolve_pywire_version(pywire_dep)
393
+ if resolved_version:
394
+ pywire_version_display = resolved_version
299
395
 
300
396
  tool_version = get_version()
301
397
 
302
398
  console.print(LOGO)
303
- console.print(f"[dim]v{tool_version} • The Python Web Framework[/dim]\n")
399
+ console.print(f"[dim]v{tool_version} • PyWire {pywire_version_display}[/dim]\n")
304
400
 
305
401
  if use_local:
306
402
  console.print("[yellow]WARNING: Using local pywire dependency[/yellow]")
@@ -1,7 +1,8 @@
1
1
  !path "/about"
2
2
  !layout "layout.wire"
3
3
 
4
- ---html---
4
+ --- html ---
5
+
5
6
  <section>
6
7
  <h1>About</h1>
7
8
  <p>This page shows explicit routing with semantic filenames.</p>
@@ -31,15 +31,9 @@ if path.detail:
31
31
  "select title, body from posts where slug = ?",
32
32
  (slug,),
33
33
  ).fetchone()
34
-
35
- if post:
36
- post_title = post["title"]
37
- post_body_html = markdown.markdown(post["body"])
38
- else:
39
- post_title = "Post not found"
40
- post_body_html = "<p>We couldn't find that post.</p>"
41
-
42
- ---html---
34
+
35
+ --- html ---
36
+
43
37
  <main>
44
38
  <!-- List view: /posts -->
45
39
  <section $if={path.list}>
@@ -54,8 +48,8 @@ if path.detail:
54
48
 
55
49
  <!-- Detail view: /posts/{slug} -->
56
50
  <article $if={path.detail}>
57
- <h1>{post_title}</h1>
58
- <div>{post_body_html}</div>
51
+ <h1>{post_title if post else "Post not found"}</h1>
52
+ <div>{!html markdown.markdown(post["body"]) if post else "<p>We couldn't find that post.</p>"}</div>
59
53
  <p><a href="/posts">← Back to all posts</a></p>
60
54
  </article>
61
55
  </main>
@@ -48,11 +48,14 @@ posts = cursor.execute(
48
48
  "select slug, title from posts order by id desc"
49
49
  ).fetchall()
50
50
 
51
- ---html---
51
+ --- html ---
52
+
52
53
  <section>
53
54
  <h1>Blog + Portfolio (Explicit)</h1>
54
55
  <p>Routes are declared with <code>!path</code> and files are named semantically.</p>
55
56
  <ul>
56
- {"".join([f'<li><a href="/posts/{row["slug"]}">{row["title"]}</a></li>' for row in posts])}
57
+ <li $for={post in posts} $key={post["slug"]}>
58
+ <a href="/posts/{row["slug"]}">{row["title"]}</a>
59
+ </li>
57
60
  </ul>
58
61
  </section>
@@ -45,11 +45,14 @@ posts = cursor.execute(
45
45
  "select slug, title from posts order by id desc"
46
46
  ).fetchall()
47
47
 
48
- ---html---
48
+ --- html ---
49
+
49
50
  <section>
50
51
  <h1>Blog + Portfolio</h1>
51
52
  <p>Markdown posts backed by SQLite.</p>
52
53
  <ul>
53
- {"".join([f'<li><a href="/posts/{row["slug"]}">{row["title"]}</a></li>' for row in posts])}
54
+ <li $for={post in posts} $key={post["slug"]}>
55
+ <a href="/posts/{row["slug"]}">{row["title"]}</a>
56
+ </li>
54
57
  </ul>
55
58
  </section>
@@ -12,10 +12,13 @@ posts = cursor.execute(
12
12
  "select slug, title from posts order by id desc"
13
13
  ).fetchall()
14
14
 
15
- ---html---
15
+ --- html ---
16
+
16
17
  <section>
17
18
  <h1>All posts</h1>
18
19
  <ul>
19
- {"".join([f'<li><a href="/posts/{row["slug"]}">{row["title"]}</a></li>' for row in posts])}
20
+ <li $for={post in posts} $key={post["slug"]}>
21
+ <a href="/posts/{row["slug"]}">{row["title"]}</a>
22
+ </li>
20
23
  </ul>
21
24
  </section>
@@ -14,15 +14,9 @@ post = cursor.execute(
14
14
  (slug,),
15
15
  ).fetchone()
16
16
 
17
- if post:
18
- title = post["title"]
19
- body_html = markdown.markdown(post["body"])
20
- else:
21
- title = "Post not found"
22
- body_html = "<p>We couldn't find that post.</p>"
17
+ --- html ---
23
18
 
24
- ---html---
25
19
  <article>
26
- <h1>{title}</h1>
27
- <div>{body_html}</div>
20
+ <h1>{post["title"] if post else "Post not found"}</h1>
21
+ <div>{!html markdown.markdown(post["body"]) if post else "<p>We couldn't find that post.</p>"}</div>
28
22
  </article>
@@ -1,5 +1,4 @@
1
- ---html---
2
1
  <section class="container">
3
- <h1>Something went wrong</h1>
2
+ <h1>Something went wrong ({error_code})</h1>
4
3
  <p>Try refreshing the page. If the issue persists, check the server logs.</p>
5
4
  </section>
@@ -1,11 +1,13 @@
1
1
  !path "/"
2
2
  !layout "layout.wire"
3
3
 
4
- count = 0
5
- ---html---
4
+ count = wire(0)
5
+
6
+ --- html ---
7
+
6
8
  <div class="container">
7
9
  <h1>Counter (Explicit Routing)</h1>
8
10
  <p>This page uses explicit routing via <code>!path</code>.</p>
9
- <p>Count is: {count}</p>
10
- <button @click={count += 1}>Increment</button>
11
+ <p>Count is: {count.value}</p>
12
+ <button @click={count.value += 1}>Increment</button>
11
13
  </div>
@@ -1,8 +1,10 @@
1
- count = 0
2
- ---html---
1
+ count = wire(0)
2
+
3
+ --- html ---
4
+
3
5
  <div class="container">
4
6
  <h1>Counter</h1>
5
7
  <p>Edit <code>pages/index.wire</code> to watch hot reload in action.</p>
6
- <p>Count is: {count}</p>
7
- <button @click={count += 1}>Increment</button>
8
+ <p>Count is: {count.value}</p>
9
+ <button @click={count.value += 1}>Increment</button>
8
10
  </div>
@@ -3,7 +3,8 @@ from datetime import datetime
3
3
  # TODO: Replace with real auth middleware
4
4
  user = {"id": "demo-user", "email": "demo@pywire.dev", "signed_in_at": datetime.utcnow()}
5
5
 
6
- ---html---
6
+ --- html ---
7
+
7
8
  <!DOCTYPE html>
8
9
  <html lang="en">
9
10
  <head>
@@ -11,7 +11,8 @@ settings_sections = [
11
11
  {"id": "team", "title": "Team", "description": "Invite and manage team members."},
12
12
  ]
13
13
 
14
- ---html---
14
+ --- html ---
15
+
15
16
  <main>
16
17
  <!-- Dashboard home: /dashboard -->
17
18
  <section $if={path.home}>
@@ -1,7 +1,8 @@
1
1
  !path "/"
2
2
  !layout "public-layout.wire"
3
3
 
4
- ---html---
4
+ --- html ---
5
+
5
6
  <section>
6
7
  <h1>Ship a SaaS with pywire</h1>
7
8
  <p>This starter includes Stripe + SQLAlchemy + stubbed auth.</p>
@@ -1,7 +1,8 @@
1
1
  !path "/login"
2
2
  !layout "public-layout.wire"
3
3
 
4
- ---html---
4
+ --- html ---
5
+
5
6
  <section>
6
7
  <h1>Login</h1>
7
8
  <p>TODO: Replace with pywire auth once available.</p>
@@ -5,7 +5,7 @@ import os
5
5
 
6
6
  stripe_public_key = os.environ.get("STRIPE_PUBLIC_KEY", "")
7
7
 
8
- ---html---
8
+ --- html ---
9
9
  <section>
10
10
  <h1>Pricing</h1>
11
11
  <p>Set <code>STRIPE_PUBLIC_KEY</code> to connect Stripe.</p>
@@ -3,7 +3,8 @@ from datetime import datetime
3
3
  # TODO: Replace with real auth middleware
4
4
  user = {"id": "demo-user", "email": "demo@pywire.dev", "signed_in_at": datetime.utcnow()}
5
5
 
6
- ---html---
6
+ --- html ---
7
+
7
8
  <!DOCTYPE html>
8
9
  <html lang="en">
9
10
  <head>
@@ -1,4 +1,3 @@
1
- ---html---
2
1
  <section>
3
2
  <h1>Dashboard</h1>
4
3
  <p>Welcome to your SaaS dashboard.</p>
@@ -1,4 +1,3 @@
1
- ---html---
2
1
  <section>
3
2
  <h1>Settings</h1>
4
3
  <p>Manage billing, team, and usage.</p>
@@ -1,4 +1,3 @@
1
- ---html---
2
1
  <section>
3
2
  <h1>Ship a SaaS with pywire</h1>
4
3
  <p>This starter includes Stripe + SQLAlchemy + stubbed auth.</p>
@@ -1,4 +1,3 @@
1
- ---html---
2
1
  <section>
3
2
  <h1>Login</h1>
4
3
  <p>TODO: Replace with pywire auth once available.</p>
@@ -2,7 +2,8 @@ import os
2
2
 
3
3
  stripe_public_key = os.environ.get("STRIPE_PUBLIC_KEY", "")
4
4
 
5
- ---html---
5
+ --- html ---
6
+
6
7
  <section>
7
8
  <h1>Pricing</h1>
8
9
  <p>Set <code>STRIPE_PUBLIC_KEY</code> to connect Stripe.</p>
File without changes