pywire 0.1.0__py3-none-any.whl
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.
- pywire/__init__.py +2 -0
- pywire/cli/__init__.py +1 -0
- pywire/cli/generators.py +48 -0
- pywire/cli/main.py +309 -0
- pywire/cli/tui.py +563 -0
- pywire/cli/validate.py +26 -0
- pywire/client/.prettierignore +8 -0
- pywire/client/.prettierrc +7 -0
- pywire/client/build.mjs +73 -0
- pywire/client/eslint.config.js +46 -0
- pywire/client/package.json +39 -0
- pywire/client/pnpm-lock.yaml +2971 -0
- pywire/client/src/core/app.ts +263 -0
- pywire/client/src/core/dom-updater.test.ts +78 -0
- pywire/client/src/core/dom-updater.ts +321 -0
- pywire/client/src/core/index.ts +5 -0
- pywire/client/src/core/transport-manager.test.ts +179 -0
- pywire/client/src/core/transport-manager.ts +159 -0
- pywire/client/src/core/transports/base.ts +122 -0
- pywire/client/src/core/transports/http.ts +142 -0
- pywire/client/src/core/transports/index.ts +13 -0
- pywire/client/src/core/transports/websocket.ts +97 -0
- pywire/client/src/core/transports/webtransport.ts +149 -0
- pywire/client/src/dev/dev-app.ts +93 -0
- pywire/client/src/dev/error-trace.test.ts +97 -0
- pywire/client/src/dev/error-trace.ts +76 -0
- pywire/client/src/dev/index.ts +4 -0
- pywire/client/src/dev/status-overlay.ts +63 -0
- pywire/client/src/events/handler.test.ts +318 -0
- pywire/client/src/events/handler.ts +454 -0
- pywire/client/src/pywire.core.ts +22 -0
- pywire/client/src/pywire.dev.ts +27 -0
- pywire/client/tsconfig.json +17 -0
- pywire/client/vitest.config.ts +15 -0
- pywire/compiler/__init__.py +6 -0
- pywire/compiler/ast_nodes.py +304 -0
- pywire/compiler/attributes/__init__.py +6 -0
- pywire/compiler/attributes/base.py +24 -0
- pywire/compiler/attributes/conditional.py +37 -0
- pywire/compiler/attributes/events.py +55 -0
- pywire/compiler/attributes/form.py +37 -0
- pywire/compiler/attributes/loop.py +75 -0
- pywire/compiler/attributes/reactive.py +34 -0
- pywire/compiler/build.py +28 -0
- pywire/compiler/build_artifacts.py +342 -0
- pywire/compiler/codegen/__init__.py +5 -0
- pywire/compiler/codegen/attributes/__init__.py +6 -0
- pywire/compiler/codegen/attributes/base.py +19 -0
- pywire/compiler/codegen/attributes/events.py +35 -0
- pywire/compiler/codegen/directives/__init__.py +6 -0
- pywire/compiler/codegen/directives/base.py +16 -0
- pywire/compiler/codegen/directives/path.py +53 -0
- pywire/compiler/codegen/generator.py +2341 -0
- pywire/compiler/codegen/template.py +2178 -0
- pywire/compiler/directives/__init__.py +7 -0
- pywire/compiler/directives/base.py +20 -0
- pywire/compiler/directives/component.py +33 -0
- pywire/compiler/directives/context.py +93 -0
- pywire/compiler/directives/layout.py +49 -0
- pywire/compiler/directives/no_spa.py +24 -0
- pywire/compiler/directives/path.py +71 -0
- pywire/compiler/directives/props.py +88 -0
- pywire/compiler/exceptions.py +19 -0
- pywire/compiler/interpolation/__init__.py +6 -0
- pywire/compiler/interpolation/base.py +28 -0
- pywire/compiler/interpolation/jinja.py +272 -0
- pywire/compiler/parser.py +750 -0
- pywire/compiler/paths.py +29 -0
- pywire/compiler/preprocessor.py +43 -0
- pywire/core/wire.py +119 -0
- pywire/py.typed +0 -0
- pywire/runtime/__init__.py +7 -0
- pywire/runtime/aioquic_server.py +194 -0
- pywire/runtime/app.py +889 -0
- pywire/runtime/compile_error_page.py +195 -0
- pywire/runtime/debug.py +203 -0
- pywire/runtime/dev_server.py +434 -0
- pywire/runtime/dev_server.py.broken +268 -0
- pywire/runtime/error_page.py +64 -0
- pywire/runtime/error_renderer.py +23 -0
- pywire/runtime/escape.py +23 -0
- pywire/runtime/files.py +40 -0
- pywire/runtime/helpers.py +97 -0
- pywire/runtime/http_transport.py +253 -0
- pywire/runtime/loader.py +272 -0
- pywire/runtime/logging.py +72 -0
- pywire/runtime/page.py +384 -0
- pywire/runtime/pydantic_integration.py +52 -0
- pywire/runtime/router.py +229 -0
- pywire/runtime/server.py +25 -0
- pywire/runtime/style_collector.py +31 -0
- pywire/runtime/upload_manager.py +76 -0
- pywire/runtime/validation.py +449 -0
- pywire/runtime/websocket.py +665 -0
- pywire/runtime/webtransport_handler.py +195 -0
- pywire/templates/error/404.html +11 -0
- pywire/templates/error/500.html +38 -0
- pywire/templates/error/base.html +207 -0
- pywire/templates/error/compile_error.html +31 -0
- pywire-0.1.0.dist-info/METADATA +50 -0
- pywire-0.1.0.dist-info/RECORD +104 -0
- pywire-0.1.0.dist-info/WHEEL +4 -0
- pywire-0.1.0.dist-info/entry_points.txt +2 -0
- pywire-0.1.0.dist-info/licenses/LICENSE +201 -0
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
"""WebTransport handler using ASGI standard.
|
|
2
|
+
|
|
3
|
+
Handles 'webtransport' scope type from Hypercorn.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import json
|
|
7
|
+
from typing import Any, Dict, Set
|
|
8
|
+
|
|
9
|
+
from pywire.runtime.page import BasePage
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class WebTransportHandler:
|
|
13
|
+
"""Handles WebTransport connections."""
|
|
14
|
+
|
|
15
|
+
def __init__(self, app: Any) -> None:
|
|
16
|
+
self.app = app
|
|
17
|
+
# Store active sessions/connections
|
|
18
|
+
# For WebTransport, the 'scope' is the connection identifier
|
|
19
|
+
self.active_connections: Set[Any] = set()
|
|
20
|
+
|
|
21
|
+
# Map connection -> current page instance
|
|
22
|
+
self.connection_pages: Dict[Any, BasePage] = {}
|
|
23
|
+
|
|
24
|
+
async def handle(self, scope: dict[str, Any], receive: Any, send: Any) -> None:
|
|
25
|
+
"""Handle ASGI webtransport scope."""
|
|
26
|
+
print("DEBUG: WebTransport handler started")
|
|
27
|
+
# Active streams buffer: stream_id -> bytes
|
|
28
|
+
streams: Dict[int, bytearray] = {}
|
|
29
|
+
|
|
30
|
+
# 1. Wait for connection request
|
|
31
|
+
try:
|
|
32
|
+
message = await receive()
|
|
33
|
+
print(f"DEBUG: WebTransport received initial message: {message['type']}")
|
|
34
|
+
if message["type"] != "webtransport.connect":
|
|
35
|
+
print(f"DEBUG: Unexpected message type: {message['type']}")
|
|
36
|
+
return
|
|
37
|
+
except Exception as e:
|
|
38
|
+
print(f"DEBUG: Error receiving connect message: {e}")
|
|
39
|
+
return
|
|
40
|
+
|
|
41
|
+
# 2. Accept connection
|
|
42
|
+
await send({"type": "webtransport.accept"})
|
|
43
|
+
print("DEBUG: WebTransport connection accepted")
|
|
44
|
+
|
|
45
|
+
# Register connection (using the receive channel as ID or scope object)
|
|
46
|
+
# Since scope is mutable dictionary, we use its id() or just the object if stable
|
|
47
|
+
connection_id = id(scope)
|
|
48
|
+
self.active_connections.add(connection_id)
|
|
49
|
+
|
|
50
|
+
try:
|
|
51
|
+
while True:
|
|
52
|
+
message = await receive()
|
|
53
|
+
msg_type = message["type"]
|
|
54
|
+
# print(f"DEBUG: Received WT message: {msg_type}")
|
|
55
|
+
|
|
56
|
+
if msg_type == "webtransport.stream.connect":
|
|
57
|
+
# New bidirectional stream opened by client
|
|
58
|
+
stream_id = message["stream_id"]
|
|
59
|
+
streams[stream_id] = bytearray()
|
|
60
|
+
# print(f"DEBUG: Stream {stream_id} connected")
|
|
61
|
+
|
|
62
|
+
elif msg_type == "webtransport.stream.receive":
|
|
63
|
+
stream_id = message["stream_id"]
|
|
64
|
+
data = message.get("data", b"")
|
|
65
|
+
|
|
66
|
+
if stream_id not in streams:
|
|
67
|
+
# Stream might have been accepted implicitly or we missed connect
|
|
68
|
+
streams[stream_id] = bytearray()
|
|
69
|
+
|
|
70
|
+
streams[stream_id].extend(data)
|
|
71
|
+
|
|
72
|
+
# Check if stream is finished (some impls use 'more_body', others 'fin')
|
|
73
|
+
# Hypercorn uses 'more_body' (True if more coming)
|
|
74
|
+
more_body = message.get("more_body", False)
|
|
75
|
+
|
|
76
|
+
if not more_body:
|
|
77
|
+
# Full message received
|
|
78
|
+
payload = streams[stream_id]
|
|
79
|
+
del streams[stream_id] # Clear buffer
|
|
80
|
+
|
|
81
|
+
# Process message
|
|
82
|
+
try:
|
|
83
|
+
json_data = json.loads(payload.decode("utf-8"))
|
|
84
|
+
await self._handle_message(
|
|
85
|
+
json_data, scope, send, stream_id
|
|
86
|
+
)
|
|
87
|
+
except Exception as e:
|
|
88
|
+
print(f"WebTransport message error: {e}")
|
|
89
|
+
|
|
90
|
+
elif msg_type == "webtransport.disconnect":
|
|
91
|
+
break
|
|
92
|
+
|
|
93
|
+
except Exception as e:
|
|
94
|
+
print(f"WebTransport handler error: {e}")
|
|
95
|
+
finally:
|
|
96
|
+
self.active_connections.discard(connection_id)
|
|
97
|
+
if connection_id in self.connection_pages:
|
|
98
|
+
del self.connection_pages[connection_id]
|
|
99
|
+
|
|
100
|
+
async def _handle_message(
|
|
101
|
+
self, data: dict[str, Any], scope: dict[str, Any], send: Any, stream_id: int
|
|
102
|
+
) -> None:
|
|
103
|
+
"""Handle decoded JSON message."""
|
|
104
|
+
msg_type = data.get("type")
|
|
105
|
+
connection_id = id(scope)
|
|
106
|
+
|
|
107
|
+
if msg_type == "event":
|
|
108
|
+
# Handle event
|
|
109
|
+
if connection_id in self.connection_pages:
|
|
110
|
+
page = self.connection_pages[connection_id]
|
|
111
|
+
handler_name = data.get("handler")
|
|
112
|
+
event_data = data.get("data", {})
|
|
113
|
+
|
|
114
|
+
try:
|
|
115
|
+
if handler_name and isinstance(handler_name, str):
|
|
116
|
+
# Execute handler
|
|
117
|
+
response = await page.handle_event(handler_name, event_data)
|
|
118
|
+
else:
|
|
119
|
+
raise ValueError("Invalid handler name")
|
|
120
|
+
|
|
121
|
+
# If response is HTML, send update
|
|
122
|
+
if hasattr(response, "body"):
|
|
123
|
+
html = bytes(response.body).decode("utf-8")
|
|
124
|
+
response_data = {"type": "update", "html": html}
|
|
125
|
+
await self._send_response(send, stream_id, response_data)
|
|
126
|
+
|
|
127
|
+
except Exception as e:
|
|
128
|
+
# Send error response (no print - response is sufficient)
|
|
129
|
+
await self._send_response(
|
|
130
|
+
send, stream_id, {"type": "error", "error": str(e)}
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
elif msg_type == "init":
|
|
134
|
+
# Initialize page for this connection (similar to WS)
|
|
135
|
+
# Parse path and instantiate page
|
|
136
|
+
path = data.get("path", "/")
|
|
137
|
+
match = self.app.router.match(path)
|
|
138
|
+
if match:
|
|
139
|
+
page_class, params, variant_name = match
|
|
140
|
+
# Mock request object? Or extract from scope
|
|
141
|
+
# We need a Request-like object for Page init
|
|
142
|
+
from starlette.requests import Request
|
|
143
|
+
|
|
144
|
+
request = Request(scope)
|
|
145
|
+
query = dict(request.query_params)
|
|
146
|
+
|
|
147
|
+
# Build path info dict
|
|
148
|
+
path_info = {}
|
|
149
|
+
if hasattr(page_class, "__routes__"):
|
|
150
|
+
for name in page_class.__routes__.keys():
|
|
151
|
+
path_info[name] = name == variant_name
|
|
152
|
+
elif hasattr(page_class, "__route__"):
|
|
153
|
+
path_info["main"] = True
|
|
154
|
+
|
|
155
|
+
# Build URL helper
|
|
156
|
+
from pywire.runtime.router import URLHelper
|
|
157
|
+
|
|
158
|
+
url_helper = None
|
|
159
|
+
if hasattr(page_class, "__routes__"):
|
|
160
|
+
url_helper = URLHelper(page_class.__routes__)
|
|
161
|
+
|
|
162
|
+
page = page_class(
|
|
163
|
+
request, params, query, path=path_info, url=url_helper
|
|
164
|
+
)
|
|
165
|
+
if hasattr(self.app, "get_user"):
|
|
166
|
+
page.user = self.app.get_user(request)
|
|
167
|
+
|
|
168
|
+
self.connection_pages[connection_id] = page
|
|
169
|
+
|
|
170
|
+
async def _send_response(
|
|
171
|
+
self, send: Any, stream_id: int, data: dict[str, Any]
|
|
172
|
+
) -> None:
|
|
173
|
+
"""Send response back on the same stream."""
|
|
174
|
+
payload = json.dumps(data).encode("utf-8")
|
|
175
|
+
await send(
|
|
176
|
+
{
|
|
177
|
+
"type": "webtransport.stream.send",
|
|
178
|
+
"stream_id": stream_id,
|
|
179
|
+
"data": payload,
|
|
180
|
+
"finish": True, # Close the stream after sending
|
|
181
|
+
}
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
async def broadcast_reload(self) -> None:
|
|
185
|
+
"""Broadcast reload to all active WebTransport connections."""
|
|
186
|
+
# For broadcast, we must initiate a NEW stream for each connection
|
|
187
|
+
# But we don't have reference to 'send' callable for each connection here!
|
|
188
|
+
# The 'send' is only available inside the 'handle' loop.
|
|
189
|
+
|
|
190
|
+
# This is a problem with the simple loop approach.
|
|
191
|
+
# We need a way to inject messages into the handle loops.
|
|
192
|
+
pass
|
|
193
|
+
|
|
194
|
+
# Solution: Use an asyncio.Queue for each connection, and have the handle loop
|
|
195
|
+
# wait for EITHER 'receive()' OR 'queue.get()'.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{% extends "error/base.html" %}
|
|
2
|
+
|
|
3
|
+
{% block title %}{{ title }} - PyWire{% endblock %}
|
|
4
|
+
|
|
5
|
+
{% block header %}{{ title }}{% endblock %}
|
|
6
|
+
|
|
7
|
+
{% block content %}
|
|
8
|
+
<div class="error-location error-404">
|
|
9
|
+
<div class="exc-msg">{{ message }}</div>
|
|
10
|
+
</div>
|
|
11
|
+
{% endblock %}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{% extends "error/base.html" %}
|
|
2
|
+
|
|
3
|
+
{% block title %}{{ exc_type }}{% endblock %}
|
|
4
|
+
|
|
5
|
+
{% block header %}{{ exc_type }}{% endblock %}
|
|
6
|
+
|
|
7
|
+
{% block content %}
|
|
8
|
+
<div class="exc-msg">{{ exc_msg }}</div>
|
|
9
|
+
|
|
10
|
+
{% if is_framework_error %}
|
|
11
|
+
<div class="alert alert-warning">
|
|
12
|
+
<strong>Potential Framework Bug</strong>
|
|
13
|
+
<p>This error seems to originate from within PyWire. If you believe this is a bug,
|
|
14
|
+
please <a href="{{ github_url }}" target="_blank" class="issue-link">open an issue
|
|
15
|
+
on GitHub</a>.</p>
|
|
16
|
+
</div>
|
|
17
|
+
{% endif %}
|
|
18
|
+
|
|
19
|
+
<h2>Traceback</h2>
|
|
20
|
+
<div class="frames">
|
|
21
|
+
{% for frame in frames %}
|
|
22
|
+
<div class="frame {% if frame.is_user_code %}frame-user{% else %}frame-vendor{% endif %}">
|
|
23
|
+
<div class="frame-header">
|
|
24
|
+
<span class="func">{{ frame.func_name }}</span>
|
|
25
|
+
<span class="file">{{ frame.short_filename }}:{{ frame.lineno }}</span>
|
|
26
|
+
</div>
|
|
27
|
+
<div class="code-context">
|
|
28
|
+
{% for line in frame.context %}
|
|
29
|
+
<div class="{% if line.is_current %}line-current{% else %}line{% endif %}">
|
|
30
|
+
<span class="line-num">{{ line.num }}</span>
|
|
31
|
+
<span class="code">{{ line.content }}</span>
|
|
32
|
+
</div>
|
|
33
|
+
{% endfor %}
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
{% endfor %}
|
|
37
|
+
</div>
|
|
38
|
+
{% endblock %}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
<title>{% block title %}PyWire Error{% endblock %}</title>
|
|
6
|
+
<style>
|
|
7
|
+
:root {
|
|
8
|
+
--bg-color: #1a1a1a;
|
|
9
|
+
--text-color: #e0e0e0;
|
|
10
|
+
--accent-color: #ff6b6b;
|
|
11
|
+
--secondary-color: #aaa;
|
|
12
|
+
--code-bg: #222;
|
|
13
|
+
--border-color: #333;
|
|
14
|
+
--highlight-bg: #3c1e1e;
|
|
15
|
+
--highlight-text: #ffcccc;
|
|
16
|
+
--highlight-border: #ff6b6b;
|
|
17
|
+
--file-color: #ffd43b;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
body {
|
|
21
|
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
|
22
|
+
background: var(--bg-color);
|
|
23
|
+
color: var(--text-color);
|
|
24
|
+
margin: 0;
|
|
25
|
+
padding: 20px;
|
|
26
|
+
line-height: 1.5;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.container {
|
|
30
|
+
max-width: 1000px;
|
|
31
|
+
margin: 0 auto;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.header-block {
|
|
35
|
+
border-bottom: 1px solid var(--border-color);
|
|
36
|
+
padding-bottom: 20px;
|
|
37
|
+
margin-bottom: 20px;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
h1 {
|
|
41
|
+
color: var(--accent-color);
|
|
42
|
+
font-size: 24px;
|
|
43
|
+
margin-bottom: 5px;
|
|
44
|
+
margin-top: 0;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
h3 {
|
|
48
|
+
color: var(--secondary-color);
|
|
49
|
+
font-size: 16px;
|
|
50
|
+
margin-top: 30px;
|
|
51
|
+
margin-bottom: 10px;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.exc-msg {
|
|
55
|
+
font-size: 18px;
|
|
56
|
+
color: #fff;
|
|
57
|
+
margin-bottom: 20px;
|
|
58
|
+
font-weight: 500;
|
|
59
|
+
white-space: pre-wrap;
|
|
60
|
+
font-family: monospace;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/* Code Context */
|
|
64
|
+
.error-location {
|
|
65
|
+
background: #2d2d2d;
|
|
66
|
+
border-radius: 8px;
|
|
67
|
+
padding: 15px;
|
|
68
|
+
margin-bottom: 20px;
|
|
69
|
+
border-left: 4px solid var(--accent-color);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.file-info {
|
|
73
|
+
color: var(--file-color);
|
|
74
|
+
font-family: monospace;
|
|
75
|
+
font-size: 14px;
|
|
76
|
+
margin-bottom: 10px;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.code-context {
|
|
80
|
+
padding: 10px 0;
|
|
81
|
+
background: var(--code-bg);
|
|
82
|
+
font-family: "Fira Code", monospace;
|
|
83
|
+
font-size: 13px;
|
|
84
|
+
overflow-x: auto;
|
|
85
|
+
border-radius: 4px;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.line {
|
|
89
|
+
padding: 2px 15px;
|
|
90
|
+
color: #888;
|
|
91
|
+
display: flex;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.line-current {
|
|
95
|
+
padding: 2px 15px;
|
|
96
|
+
background: var(--highlight-bg);
|
|
97
|
+
color: var(--highlight-text);
|
|
98
|
+
display: flex;
|
|
99
|
+
border-left: 3px solid var(--highlight-border);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.line-num {
|
|
103
|
+
width: 40px;
|
|
104
|
+
text-align: right;
|
|
105
|
+
margin-right: 15px;
|
|
106
|
+
opacity: 0.5;
|
|
107
|
+
user-select: none;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.code {
|
|
111
|
+
white-space: pre;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/* Traceback */
|
|
115
|
+
.traceback-section {
|
|
116
|
+
margin-top: 20px;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.traceback {
|
|
120
|
+
background: var(--code-bg);
|
|
121
|
+
padding: 15px;
|
|
122
|
+
border-radius: 8px;
|
|
123
|
+
font-size: 12px;
|
|
124
|
+
overflow-x: auto;
|
|
125
|
+
color: #ccc;
|
|
126
|
+
white-space: pre-wrap;
|
|
127
|
+
word-break: break-word;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
.frames {
|
|
131
|
+
display: flex;
|
|
132
|
+
flex-direction: column;
|
|
133
|
+
gap: 15px;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
.frame {
|
|
137
|
+
background: #2d2d2d;
|
|
138
|
+
border-radius: 8px;
|
|
139
|
+
overflow: hidden;
|
|
140
|
+
border: 1px solid var(--border-color);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.frame-user {
|
|
144
|
+
border-left: 4px solid #69db7c;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
.frame-vendor {
|
|
148
|
+
border-left: 4px solid #74c0fc;
|
|
149
|
+
opacity: 0.8;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.frame-header {
|
|
153
|
+
padding: 10px 15px;
|
|
154
|
+
background: var(--border-color);
|
|
155
|
+
display: flex;
|
|
156
|
+
justify-content: space-between;
|
|
157
|
+
font-family: monospace;
|
|
158
|
+
font-size: 14px;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.func {
|
|
162
|
+
color: var(--file-color);
|
|
163
|
+
font-weight: bold;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
.file {
|
|
167
|
+
color: var(--secondary-color);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/* Alerts */
|
|
171
|
+
.alert {
|
|
172
|
+
background: #3d2800;
|
|
173
|
+
border: 1px solid #fcc419;
|
|
174
|
+
color: #fcc419;
|
|
175
|
+
padding: 15px;
|
|
176
|
+
border-radius: 8px;
|
|
177
|
+
margin-bottom: 20px;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
.issue-link {
|
|
181
|
+
color: var(--file-color);
|
|
182
|
+
text-decoration: underline;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/* 404 Specifics */
|
|
186
|
+
.error-404 {
|
|
187
|
+
border-left: 6px solid var(--accent-color);
|
|
188
|
+
}
|
|
189
|
+
</style>
|
|
190
|
+
</head>
|
|
191
|
+
|
|
192
|
+
<body>
|
|
193
|
+
<div class="container">
|
|
194
|
+
<div class="header-block">
|
|
195
|
+
<h1>{% block header %}{% endblock %}</h1>
|
|
196
|
+
</div>
|
|
197
|
+
|
|
198
|
+
{% block content %}{% endblock %}
|
|
199
|
+
|
|
200
|
+
</div>
|
|
201
|
+
<!-- Client Script -->
|
|
202
|
+
{% if script_url %}
|
|
203
|
+
<script src="{{ script_url }}"></script>
|
|
204
|
+
{% endif %}
|
|
205
|
+
</body>
|
|
206
|
+
|
|
207
|
+
</html>
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{% extends "error/base.html" %}
|
|
2
|
+
|
|
3
|
+
{% block title %}PyWire Syntax Error{% endblock %}
|
|
4
|
+
|
|
5
|
+
{% block header %}PyWire Syntax Error{% endblock %}
|
|
6
|
+
|
|
7
|
+
{% block content %}
|
|
8
|
+
<div class="error-location">
|
|
9
|
+
<div class="file-info">{{ file_display }}{% if error_line %}:{{ error_line }}{% endif %}</div>
|
|
10
|
+
<div class="exc-msg">{{ error_message }}</div>
|
|
11
|
+
</div>
|
|
12
|
+
|
|
13
|
+
{% if context_lines %}
|
|
14
|
+
<div class="code-context">
|
|
15
|
+
{% for line in context_lines %}
|
|
16
|
+
<div class="{% if line.is_current %}line-current{% else %}line{% endif %}">
|
|
17
|
+
<span class="line-num">{{ line.num }}</span>
|
|
18
|
+
<span class="code">{{ line.content }}</span>
|
|
19
|
+
</div>
|
|
20
|
+
{% endfor %}
|
|
21
|
+
</div>
|
|
22
|
+
{% endif %}
|
|
23
|
+
|
|
24
|
+
{% if traceback_text %}
|
|
25
|
+
<div class="traceback-section">
|
|
26
|
+
<h3>Full Traceback</h3>
|
|
27
|
+
<pre class="traceback">{{ traceback_text }}</pre>
|
|
28
|
+
</div>
|
|
29
|
+
{% endif %}
|
|
30
|
+
|
|
31
|
+
{% endblock %}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pywire
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: HTML-over-the-wire Python web framework
|
|
5
|
+
Author-email: Reece Holmdahl <reece@pywire.dev>
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Requires-Python: >=3.11
|
|
8
|
+
Requires-Dist: jinja2>=3.1.0
|
|
9
|
+
Requires-Dist: lxml>=4.9.0
|
|
10
|
+
Requires-Dist: msgpack>=1.0.0
|
|
11
|
+
Requires-Dist: pydantic>=2.0.0
|
|
12
|
+
Requires-Dist: rich-click>=1.9.6
|
|
13
|
+
Requires-Dist: starlette>=0.35.0
|
|
14
|
+
Requires-Dist: textual>=7.4.0
|
|
15
|
+
Requires-Dist: uvicorn[standard]>=0.27.0
|
|
16
|
+
Requires-Dist: watchfiles>=0.21.0
|
|
17
|
+
Provides-Extra: dev
|
|
18
|
+
Requires-Dist: black>=23.0.0; extra == 'dev'
|
|
19
|
+
Requires-Dist: coverage>=7.3.0; extra == 'dev'
|
|
20
|
+
Requires-Dist: httpx>=0.23.0; extra == 'dev'
|
|
21
|
+
Requires-Dist: msgpack-types; extra == 'dev'
|
|
22
|
+
Requires-Dist: mypy>=1.7.0; extra == 'dev'
|
|
23
|
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
|
|
24
|
+
Requires-Dist: pytest-cov>=4.1.0; extra == 'dev'
|
|
25
|
+
Requires-Dist: pytest>=7.4.0; extra == 'dev'
|
|
26
|
+
Requires-Dist: ruff>=0.1.0; extra == 'dev'
|
|
27
|
+
Requires-Dist: tox-uv>=1.0.0; extra == 'dev'
|
|
28
|
+
Requires-Dist: tox>=4.0.0; extra == 'dev'
|
|
29
|
+
Provides-Extra: http3
|
|
30
|
+
Requires-Dist: aioquic>=0.9.0; extra == 'http3'
|
|
31
|
+
Requires-Dist: hypercorn>=0.14.0; extra == 'http3'
|
|
32
|
+
Description-Content-Type: text/markdown
|
|
33
|
+
|
|
34
|
+
# pywire Core
|
|
35
|
+
|
|
36
|
+
The core framework for pywire.
|
|
37
|
+
|
|
38
|
+
<!-- SUPPORT_MESSAGE_TEMPLATE_START -->
|
|
39
|
+
## ❤️ Support pywire
|
|
40
|
+
|
|
41
|
+
If pywire is helping you build, consider supporting the project. Donations cover documentation hosting, CI/CD runners, and the caffeine required for development.
|
|
42
|
+
|
|
43
|
+
[](https://github.com/sponsors/pywire)
|
|
44
|
+
[](https://ko-fi.com/reecelikesramen)
|
|
45
|
+
|
|
46
|
+
### Why sponsor?
|
|
47
|
+
* 🚀 Faster development of the core framework.
|
|
48
|
+
* 📖 Better docs and community examples.
|
|
49
|
+
* 🔧 Integration research.
|
|
50
|
+
<!-- SUPPORT_MESSAGE_TEMPLATE_END -->
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
pywire/__init__.py,sha256=Vnf8jVQs1hz9PGw9qtkvz_5SGhuLpasPeDFAuDixH7w,78
|
|
2
|
+
pywire/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
+
pywire/cli/__init__.py,sha256=SNDCMbWNEM6_UNFDVB666srR-6Ak_HKLAX2Umy2O85I,18
|
|
4
|
+
pywire/cli/generators.py,sha256=5tgXdhGJua9PhR8FkOxWaK9vHvOuFHdXOf3qamB7f3Q,1009
|
|
5
|
+
pywire/cli/main.py,sha256=cj3zBsem5Me3j3rWeLF1wUeTNGM_akX56FgWGhBuiS0,9082
|
|
6
|
+
pywire/cli/tui.py,sha256=USInBXWUUc8BpihqTdtnRrPJtW3U9c7hFBMRup0mkGs,21714
|
|
7
|
+
pywire/cli/validate.py,sha256=CPUQjFpoPcwpvAx3HvQ8Vq_w_suJ07n3oOhXKmKFwB4,769
|
|
8
|
+
pywire/client/.prettierignore,sha256=TKRNv7wugFj9ig2T6SdoCZxMi_l9X-ninE8j72JdFzM,87
|
|
9
|
+
pywire/client/.prettierrc,sha256=NwmnhqxkL9ATCDtQVOrgKBHtpN8L9niFT2j_SYmImzw,107
|
|
10
|
+
pywire/client/build.mjs,sha256=IDiYOfeHoKy7jwlIJHT5Xo2GfxWcI9-p_jTZaHI1mWk,1944
|
|
11
|
+
pywire/client/eslint.config.js,sha256=QxkvVaKeMnqSkPGDSjxQFvgfcyPWMbzct0zeMnpzQ4o,992
|
|
12
|
+
pywire/client/package.json,sha256=K4pQlex2QKefhkANWbpoBZhpOoveRACp6BkjmWKMPsk,1130
|
|
13
|
+
pywire/client/pnpm-lock.yaml,sha256=fPLYdbqVkvTTX6QheVLy0_32RHwWn90M9v6pAfondKw,78073
|
|
14
|
+
pywire/client/tsconfig.json,sha256=ZQkpS8rFm9HGjOrklve2YNuELCa4oqPnc5n02GoCuKQ,420
|
|
15
|
+
pywire/client/vitest.config.ts,sha256=8W1fK9f_o1_8k46oi223IlZlKSSkiyM_EdVHDxmNNRs,393
|
|
16
|
+
pywire/client/src/pywire.core.ts,sha256=iozCpa5g_N5xa7DNpUxW3M7Ov_NGNfxYnPdgmdisfMc,614
|
|
17
|
+
pywire/client/src/pywire.dev.ts,sha256=G0FOQOimUY-J8H_cFmYSoc9tSrv6TvwiDKD3EcUA-Q0,674
|
|
18
|
+
pywire/client/src/core/app.ts,sha256=WYfxWuSqVkA38VoPr8Cm59xXzW2tC_Bk62rgUopA36k,7401
|
|
19
|
+
pywire/client/src/core/dom-updater.test.ts,sha256=PsiK0EL3P2JYdCpjitZoZpPc2oOi0DJqjV-uOEw8FWo,2571
|
|
20
|
+
pywire/client/src/core/dom-updater.ts,sha256=rL80LVC__240bgU_PjpJDEnzmxx2wMDG_kqQK9Q6Q7A,9687
|
|
21
|
+
pywire/client/src/core/index.ts,sha256=tT_R-J_TtM_Fovm103J2w6cB-oiQZc9r1wViZ7wuV3A,215
|
|
22
|
+
pywire/client/src/core/transport-manager.test.ts,sha256=UbQrYgSXXj1j99mfCeO49rUU5U3grmNglfq28bQapbc,5534
|
|
23
|
+
pywire/client/src/core/transport-manager.ts,sha256=6_SLITzqnhGnwwvwYG5opd_y-1kVcpQEjMa_pUbAUhg,4433
|
|
24
|
+
pywire/client/src/core/transports/base.ts,sha256=fjgIUc1vQqPd3XHtbQ9S8rOKmDP8mrSg9fx4sIc_rqY,2825
|
|
25
|
+
pywire/client/src/core/transports/http.ts,sha256=4ySlDl7KXgyJbnWF6wB_yxyuvJRBfXeB16PbFucZ3RY,4070
|
|
26
|
+
pywire/client/src/core/transports/index.ts,sha256=CZZPHIOR7bRQmtrbDAvIXXR8O58VI38sEonCVubEkZQ,295
|
|
27
|
+
pywire/client/src/core/transports/websocket.ts,sha256=hVSykmEv2zCd1nITQfUHe1QhPiuIBOyYcB31iAH-r6c,2615
|
|
28
|
+
pywire/client/src/core/transports/webtransport.ts,sha256=PCsfC2DKWDPzlssjP4z6QmkfI44Tuuy3PVIeJQSF80M,4077
|
|
29
|
+
pywire/client/src/dev/dev-app.ts,sha256=8VvWzo9k7PH-rppn9VqEGNyn8uHVKDTY3w0NNFR7yjk,2494
|
|
30
|
+
pywire/client/src/dev/error-trace.test.ts,sha256=11zvMqrOpDrdQXYtqvffUPStPxQcUOYA-3jWNfMFcPE,3332
|
|
31
|
+
pywire/client/src/dev/error-trace.ts,sha256=g8mZmqG6jlIZ5lBFrBdC-c74dxcvkoUzDgZxesF2uqg,2465
|
|
32
|
+
pywire/client/src/dev/index.ts,sha256=-jQKnDjX_ANGlRrVuRRlwqocIMzUYNbN5aZIeo8SFhs,162
|
|
33
|
+
pywire/client/src/dev/status-overlay.ts,sha256=S6atJzQ7JqHXMBpuf2gIzXlOLyySV1vnJVXuhfp3jpU,1664
|
|
34
|
+
pywire/client/src/events/handler.test.ts,sha256=M8kmzf5cHY8NvlOaJR3B-2lMyNc96mwAYpgJH_DsEH0,10289
|
|
35
|
+
pywire/client/src/events/handler.ts,sha256=VxTjGQZ88tgdePJ6K3rwNbPgDptgi1On-tyQ1_uS4Tw,13788
|
|
36
|
+
pywire/compiler/__init__.py,sha256=7tIdJ8qi5lcj7R7scIwIiE-Tmi7YZknThZArIdo95MQ,177
|
|
37
|
+
pywire/compiler/ast_nodes.py,sha256=vdHtoJQvoxF_I0RmV6gs1_zd6AhyY4dCpHmqgh73Gi8,8276
|
|
38
|
+
pywire/compiler/build.py,sha256=OB-tmsSOtnNcteUvD01MSaeTI4_lBsUHVe4xITYWa_g,800
|
|
39
|
+
pywire/compiler/build_artifacts.py,sha256=OxYgooTzy95DRwaAC26s-noaevvVwVaix-KYAQOtDM0,11102
|
|
40
|
+
pywire/compiler/exceptions.py,sha256=KyvpMI17oiVSz3h2osDaa4uCMNPKSTCr1DhVYDVU85o,540
|
|
41
|
+
pywire/compiler/parser.py,sha256=VFgZs_YkyVlRuu-jzcXqKXfu_jHzN5-ZE6RBupGWbVE,29425
|
|
42
|
+
pywire/compiler/paths.py,sha256=9TLKH-xnTBmthdpQcCDJ7UrGlIyLAuGDaVrc4qI6TgA,739
|
|
43
|
+
pywire/compiler/preprocessor.py,sha256=AyMrfLpjFF-yvMYQn67sCe_G3OSeK4-Wrdh0I_0RAfU,1509
|
|
44
|
+
pywire/compiler/attributes/__init__.py,sha256=umzZ03Mmw-LrBBNue-itAVORKhcpG-f-LzKSVH4lCGs,208
|
|
45
|
+
pywire/compiler/attributes/base.py,sha256=3eJh7bmi2Y33VRPnD90-s9QMEdfbuNKIxv6F7AU_pK8,697
|
|
46
|
+
pywire/compiler/attributes/conditional.py,sha256=R746Sz-rz3-nLr-Yj71q8yNAz1-eF_5Eg8cjKXwWlAo,1328
|
|
47
|
+
pywire/compiler/attributes/events.py,sha256=o6m59fCPfcuCJJp6rPdIVFV4BFni8IVluhVa4c494Q4,1747
|
|
48
|
+
pywire/compiler/attributes/form.py,sha256=5NC8PsBP7xfSKvyV5ANLShgSl6Eszq_fHZ5NG-VCzcw,1100
|
|
49
|
+
pywire/compiler/attributes/loop.py,sha256=1UL_eBayJOxkDJrO1mhvNnA6UnVs7-riW51XFDqX6Tk,2621
|
|
50
|
+
pywire/compiler/attributes/reactive.py,sha256=vz0TXRsp_mA9iNh1WcWpiA5g6ZpHNMYiUZB-i9B_tJE,1273
|
|
51
|
+
pywire/compiler/codegen/__init__.py,sha256=RoW5xrX7mYycSxHPnS0-J46IwWGIiWF9EeJYkx1p4LI,121
|
|
52
|
+
pywire/compiler/codegen/generator.py,sha256=dZlXjarfNJ7xL3qvSK9XlnsiU6i-IYjyT1Tttt3uqHw,92851
|
|
53
|
+
pywire/compiler/codegen/template.py,sha256=jvhmY9zrMymnq44RsDRqjCeifxNz_Z3d91026Hfw3QM,90713
|
|
54
|
+
pywire/compiler/codegen/attributes/__init__.py,sha256=0wHMipg7PG2bpRjfmLkjIyYWwZTHbSJCevMoZSpmyFs,236
|
|
55
|
+
pywire/compiler/codegen/attributes/base.py,sha256=pGZHCEZ6d3NTWwQMZ_ZKxofz2aEWDw5Kwm_axL7Gi2g,577
|
|
56
|
+
pywire/compiler/codegen/attributes/events.py,sha256=OTIcvreDty4DVEGcuuqmpjD_QREZJe1imcdrB7Hl65o,1354
|
|
57
|
+
pywire/compiler/codegen/directives/__init__.py,sha256=4TD0QmOKduxkTWPuXb1GDcp8nPEzsVLvwWf__xvwp3E,232
|
|
58
|
+
pywire/compiler/codegen/directives/base.py,sha256=4QodSoVsxJvhZ4oO7Phk_jgy-AopZsMmxH8ixnhypiQ,392
|
|
59
|
+
pywire/compiler/codegen/directives/path.py,sha256=QmFJszBZvXTFOrpHrDwmAubfW7eoFFKNN5OAJ6yqMvs,1751
|
|
60
|
+
pywire/compiler/directives/__init__.py,sha256=6QioQwB0EMVlybvwZZFQO10Kayuc0SgZTs-mL_vnQMM,295
|
|
61
|
+
pywire/compiler/directives/base.py,sha256=luBrDyNPzkcFvhzlIIbfv66po7Ep0PuHQ_jMFNahXjo,581
|
|
62
|
+
pywire/compiler/directives/component.py,sha256=Ez2jT6L1yjWwy3_PVMeITgjplrCblozsh7XR2N-rm8U,1029
|
|
63
|
+
pywire/compiler/directives/context.py,sha256=OhZ1eDsiEU_d8jNbWhkIT5e4Jo245fQwnpaXwLr0Jzk,3453
|
|
64
|
+
pywire/compiler/directives/layout.py,sha256=MEF4IeV2x9QPcEyLfc6-MvKlVqq-BeBlzoWG9GuCPWA,1435
|
|
65
|
+
pywire/compiler/directives/no_spa.py,sha256=kuQPZr6IKWLYMgApNV8ruLmFIOvPUDEOdJuCdBKGFdU,749
|
|
66
|
+
pywire/compiler/directives/path.py,sha256=KGVPb4kgFWs4zXtHJ2PweYTnT27iw19bhZjMoksM0ok,2388
|
|
67
|
+
pywire/compiler/directives/props.py,sha256=loeXOtt1zYrtEIGBUtPah37DEbloiN5VAi2s98zOGvY,3440
|
|
68
|
+
pywire/compiler/interpolation/__init__.py,sha256=A-v9HVAIUB-QX6j5FFyGxkSVwNzzD49qHryKNLrIRuI,233
|
|
69
|
+
pywire/compiler/interpolation/base.py,sha256=33wIfZVMNpIl_ZPXzkWYdOiPX3jWzZ4xb0UGbjXEpyw,781
|
|
70
|
+
pywire/compiler/interpolation/jinja.py,sha256=HJEkRE0aB-YEiw7sZ6agS_zRUQlo19uj0bX21WOW8MQ,9831
|
|
71
|
+
pywire/core/wire.py,sha256=ZgjoALx_B8i4ibt8rdY0XjNLVrfZcHLQh0urWl-iwIE,3899
|
|
72
|
+
pywire/runtime/__init__.py,sha256=441hDvBWfYni7BtKlVXHEm2FWahK0MR3sIpkPkIE1zk,207
|
|
73
|
+
pywire/runtime/aioquic_server.py,sha256=n9GuK81xtc6PUT54uMhqMlGXn8NrH-ryZ6Rl9qQWt7M,6685
|
|
74
|
+
pywire/runtime/app.py,sha256=h50bmMll0wUixAYWq1FUUMBlt-zjnlqNC4K_3BqC4xY,35785
|
|
75
|
+
pywire/runtime/compile_error_page.py,sha256=sqPTqG9dv_e2uBgYuAgOcDHx0D3Gwq2liFbBRrz4_iY,8205
|
|
76
|
+
pywire/runtime/debug.py,sha256=6U-Ot1defe7eDXaAxNip4NtRPQjtjS9LNCUnk_pmmeQ,7416
|
|
77
|
+
pywire/runtime/dev_server.py,sha256=QQ2tr7bgSdM1yDwfW7h_-x7r2RZ4qsd5A59GAvbceu0,16096
|
|
78
|
+
pywire/runtime/dev_server.py.broken,sha256=cAPPLFNe6qJ-KouATG3FfIabGd-o3qCqlMGqQQF03sc,11030
|
|
79
|
+
pywire/runtime/error_page.py,sha256=fnE8Qjf1a7fjLOys6G2uDsK0VYGMZg2yGWgDagk39j0,2497
|
|
80
|
+
pywire/runtime/error_renderer.py,sha256=HNS9seD5gX4jE3L4GPsJsyxvpMTiiNo3E43trUNiuX0,701
|
|
81
|
+
pywire/runtime/escape.py,sha256=w-_TcFLG0heyenDaituVx2oir_80WjGBWnnHZe5I8Wk,517
|
|
82
|
+
pywire/runtime/files.py,sha256=RJjDhCaoKjk_x3B_71rA4EhqVjNLGU_fuwg4Cq894nY,1316
|
|
83
|
+
pywire/runtime/helpers.py,sha256=jY3bDE7hHjPaVlLmWrGvQPDEtCYFU9Alt8j0dvSZgNQ,3039
|
|
84
|
+
pywire/runtime/http_transport.py,sha256=uS3Or4uo581XSVqRB1VsEfa7Mbqr4RK5Rk0pGb-z4p8,9401
|
|
85
|
+
pywire/runtime/loader.py,sha256=rKsHYb8dx-WkxBYClHR4Gztoy1N88kLYt5CCnvA0gIg,9664
|
|
86
|
+
pywire/runtime/logging.py,sha256=wEdxro6YxvdnjwALwzMr60As2JMj_J4DIsSL8JZScvM,2286
|
|
87
|
+
pywire/runtime/page.py,sha256=tEKPUfQFQpw3T20sWsjlXLfmDr2TlNmesc_jDwcK748,14288
|
|
88
|
+
pywire/runtime/pydantic_integration.py,sha256=Fwu45Km5SHS10ZqIxCK-Ps8hBPlVY6rHzkkP7Mh8KEs,1800
|
|
89
|
+
pywire/runtime/router.py,sha256=wHr0iyAQ3_jGzMPpyxNKE9rLWD3oiQM-JAtkxX4h7SI,8172
|
|
90
|
+
pywire/runtime/server.py,sha256=hzG1NACfjasTmNZd-imORTLNxMCD-JYgkfjIRyQ3GJE,746
|
|
91
|
+
pywire/runtime/style_collector.py,sha256=H1Crk1DO1wfch2Ed4i4_sHANH5QX_HGGGlaJr7MRiIY,1147
|
|
92
|
+
pywire/runtime/upload_manager.py,sha256=n7WRwpzHqnW1CZsoshxq7YumNMFrG7Hs5CiEHP-0W4k,2346
|
|
93
|
+
pywire/runtime/validation.py,sha256=Y1_nI_dFKy3_7aXN-gCubUBhBlzgEtNEkdS1DH81tEI,16199
|
|
94
|
+
pywire/runtime/websocket.py,sha256=7sNawtxC0l_eJBEjI80DGnUqei7Ol0RX8Y7Yz3_wNxw,26949
|
|
95
|
+
pywire/runtime/webtransport_handler.py,sha256=GZIzTlv5IyEmIq2eumxFTu1XgWaPkiRFujG1vBjQNsE,7841
|
|
96
|
+
pywire/templates/error/404.html,sha256=cZavWjs-aXoSRpEy-8D0rulP7g5Sn31MsIXmkZUQnnA,256
|
|
97
|
+
pywire/templates/error/500.html,sha256=545CPh1XyhN-zdSAD8R-6Cuos6hLC--TXJy4EQHrpjM,1282
|
|
98
|
+
pywire/templates/error/base.html,sha256=nlBlBIg-VFAWtTLWky7c2igNVsFjj9M8Wyw3v3_4KGQ,4863
|
|
99
|
+
pywire/templates/error/compile_error.html,sha256=FMqU3HXYWMeiXG3eTAysNpAHH-AOPx2Apbz8f_HBvtw,837
|
|
100
|
+
pywire-0.1.0.dist-info/METADATA,sha256=AIOkF-E5UkYqWCgRRRer-c9P8v5NJLb4PaEecsVMfcE,1905
|
|
101
|
+
pywire-0.1.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
102
|
+
pywire-0.1.0.dist-info/entry_points.txt,sha256=L0n4cNLZIocOo6lG05uOoUN1GHgA_uQOHvapDAhULBI,47
|
|
103
|
+
pywire-0.1.0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
104
|
+
pywire-0.1.0.dist-info/RECORD,,
|