local2public 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.
File without changes
local2public/cli.py ADDED
@@ -0,0 +1,61 @@
1
+ from argparse import ArgumentParser
2
+ import asyncio
3
+ import httpx
4
+
5
+ SERVER_URL = "https://l2p-beige.vercel.app" # change to your deployed server
6
+
7
+ def parse_args():
8
+ parser = ArgumentParser(description="ltp - local to public")
9
+ parser.add_argument("-p", "--port", type=int, required=True)
10
+ parser.add_argument("-n", "--name", type=str, required=True)
11
+ parser.add_argument("-v", "--verbose", action="store_true")
12
+ return parser.parse_args()
13
+
14
+ async def tunnel(local_port: int, name: str, verbose: bool):
15
+ print(f"Tunnel open: {SERVER_URL}/join/{name}/")
16
+ print("Ctrl+C to stop")
17
+
18
+ async with httpx.AsyncClient() as client:
19
+ while True:
20
+ try:
21
+ # poll for pending requests
22
+ resp = await client.get(f"{SERVER_URL}/poll/{name}", timeout=5)
23
+ requests = resp.json()
24
+
25
+ for request_id, req in requests.items():
26
+ if verbose:
27
+ print(f"→ {req['method']} {req['path']}")
28
+
29
+ try:
30
+ # forward to local server
31
+ local_resp = await client.request(
32
+ method=req["method"],
33
+ url=f"http://localhost:{local_port}{req['path']}",
34
+ content=req["body"],
35
+ timeout=10,
36
+ )
37
+ # send response back to server
38
+ await client.post(f"{SERVER_URL}/respond/{request_id}", json={
39
+ "status": local_resp.status_code,
40
+ "body": local_resp.text,
41
+ })
42
+ except Exception as e:
43
+ await client.post(f"{SERVER_URL}/respond/{request_id}", json={
44
+ "status": 502,
45
+ "body": str(e),
46
+ })
47
+
48
+ except Exception as e:
49
+ print(f"Poll error: {e}")
50
+
51
+ await asyncio.sleep(0.5)
52
+
53
+ def main():
54
+ args = parse_args()
55
+ try:
56
+ asyncio.run(tunnel(args.port, args.name, args.verbose))
57
+ except KeyboardInterrupt:
58
+ print("\nTunnel closed")
59
+
60
+ if __name__ == "__main__":
61
+ main()
@@ -0,0 +1,6 @@
1
+ Metadata-Version: 2.4
2
+ Name: local2public
3
+ Version: 0.1.0
4
+ Summary: Local to public tunnel
5
+ Requires-Python: >=3.10
6
+ Requires-Dist: httpx
@@ -0,0 +1,6 @@
1
+ local2public/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ local2public/cli.py,sha256=mRf1M8_hIVvuXf7eg22AWI15qN5gL2mBnX87YtQb1to,2296
3
+ local2public-0.1.0.dist-info/METADATA,sha256=2UKWzIVAeo-qAjENr8tRg_eCh0Aj0Ac3JL5p_5bDI5c,133
4
+ local2public-0.1.0.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
5
+ local2public-0.1.0.dist-info/entry_points.txt,sha256=WG-GZ4jSN544Ysmh1EC1RHPGrXIfuazWCJzjvL9AL0Y,37
6
+ local2public-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.30.1
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ ltp = ltp.cli:main