unitlab 2.3.17__py3-none-any.whl → 2.3.18__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.
@@ -206,7 +206,7 @@ class CloudflareAPITunnel:
206
206
  print(" Assuming routes are configured in dashboard.")
207
207
  return True
208
208
 
209
- def create_device_tunnel(self):
209
+ def create_device_tunnel(self, retry_on_fail=True):
210
210
  """
211
211
  Create a unique tunnel for this device if it doesn't exist
212
212
  """
@@ -372,11 +372,27 @@ class CloudflareAPITunnel:
372
372
  self.create_dns_records()
373
373
  self.update_tunnel_config()
374
374
 
375
+ # Check if we need to recreate the tunnel
376
+ if device_tunnel and device_tunnel.get('needs_recreation'):
377
+ print("🔄 Recreating tunnel due to access issues...")
378
+ # Delete the old tunnel
379
+ tunnel_id = device_tunnel['id']
380
+ delete_url = f"{self.api_base}/accounts/{self.account_id}/tunnels/{tunnel_id}"
381
+ delete_response = requests.delete(delete_url, headers=self.headers)
382
+ if delete_response.status_code in [200, 204, 404]:
383
+ print(f" ✅ Deleted old tunnel")
384
+ # Try creating a new one with a timestamp suffix
385
+ import time
386
+ self.clean_device_id = f"{self.device_id.replace(' ', '').replace('-', '').replace('.', '').replace('_', '')[:24]}-{int(time.time())}"
387
+ device_tunnel = self.create_device_tunnel(retry_on_fail=False)
388
+ if device_tunnel:
389
+ print(f" ✅ Created new tunnel")
390
+
375
391
  if not device_tunnel:
376
392
  print("❌ Could not create/find device tunnel")
377
393
  # Fallback to shared tunnel if API fails
378
394
  print("⚠️ Falling back to shared tunnel...")
379
- service_token = "eyJhIjoiYzkxMTkyYWUyMGE1ZDQzZjY1ZTA4NzU1MGQ4ZGM4OWIiLCJ0IjoiMDc3N2ZjMTAtNDljNC00NzJkLTg2NjEtZjYwZDgwZDYxODRkIiwicyI6Ik9XRTNaak5tTVdVdE1tWTRaUzAwTmpoakLTazBaalF0WXpjek1tSm1ZVGt4WlRRMCJ9"
395
+ service_token = "eyJhIjoiYzkxMTkyYWUyMGE1ZDQzZjY1ZTA4NzU1MGQ4ZGM4OWIiLCJ0IjoiMDc3N2ZjMTAtNDljNC00NzJkLTg2NjEtZjYwZDgwZDYxODRkIiwicyI6Ik9XRTNaak5tTVdVdE1tWTRaUzAwTmpoakLTazBmalF0WXpjek1tSm1ZVGt4WlRRMCJ9"
380
396
  cmd = [
381
397
  cloudflared_path,
382
398
  "tunnel",
@@ -402,12 +418,22 @@ class CloudflareAPITunnel:
402
418
  self._save_tunnel_credentials(device_tunnel)
403
419
  # Continue to use credentials below
404
420
  else:
405
- print("⚠️ No stored credentials, using tunnel token...")
421
+ print("⚠️ No stored credentials, requesting tunnel token...")
406
422
  # Get token for this tunnel
407
423
  token_url = f"{self.api_base}/accounts/{self.account_id}/tunnels/{tunnel_id}/token"
424
+ print(f" Token URL: {token_url}")
425
+
408
426
  token_response = requests.get(token_url, headers=self.headers)
427
+ print(f" Token response status: {token_response.status_code}")
428
+
409
429
  if token_response.status_code == 200:
410
- token = token_response.json()['result']
430
+ result = token_response.json()
431
+ if 'result' in result:
432
+ token = result['result']
433
+ print(f" ✅ Got tunnel token")
434
+ else:
435
+ print(f" ❌ No token in response: {result}")
436
+ return None
411
437
 
412
438
  # Check if config file exists with ingress rules
413
439
  if config_file.exists():
@@ -432,8 +458,20 @@ class CloudflareAPITunnel:
432
458
  "--token", token
433
459
  ]
434
460
  else:
435
- print("❌ Could not get tunnel token")
436
- return None
461
+ print(f"❌ Could not get tunnel token: {token_response.status_code}")
462
+ if token_response.text:
463
+ print(f" Error: {token_response.text}")
464
+
465
+ # If 404, tunnel doesn't exist or we don't have access
466
+ if token_response.status_code == 404:
467
+ print(f"🔄 Tunnel not accessible (404), will try to recreate...")
468
+ # Mark for recreation
469
+ device_tunnel['needs_recreation'] = True
470
+ return None
471
+ else:
472
+ print(f" ℹ️ Token endpoint returned {token_response.status_code}")
473
+ print(f" This might mean the tunnel needs to be recreated manually")
474
+ return None
437
475
 
438
476
  # Only use credentials if we haven't already set cmd with token
439
477
  if cmd is None and creds_file.exists():
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: unitlab
3
- Version: 2.3.17
3
+ Version: 2.3.18
4
4
  Home-page: https://github.com/teamunitlab/unitlab-sdk
5
5
  Author: Unitlab Inc.
6
6
  Author-email: team@unitlab.ai
@@ -2,15 +2,15 @@ unitlab/__init__.py,sha256=Wtk5kQ_MTlxtd3mxJIn2qHVK5URrVcasMMPjD3BtrVM,214
2
2
  unitlab/__main__.py,sha256=6Hs2PV7EYc5Tid4g4OtcLXhqVHiNYTGzSBdoOnW2HXA,29
3
3
  unitlab/binary_manager.py,sha256=Q1v2Odm0hk_3g7jfDUJQfkjEbUbSjtuyo2JDUyWjDrk,5468
4
4
  unitlab/client.py,sha256=V5fTgbprmMsnMwD_FPn7oZh0KK6hdnqB4BYuY4D-JRw,24558
5
- unitlab/cloudflare_api_tunnel.py,sha256=yVovEvLsjNFOv02pv9KU76Q8kZSf-IGe_G9ghkF2n64,25495
5
+ unitlab/cloudflare_api_tunnel.py,sha256=xFBYFNF3j8NKOn02uayd63PT3hXRskaSDVkv4IvhgFc,27933
6
6
  unitlab/exceptions.py,sha256=68Tr6LreEzjQ3Vns8HAaWdtewtkNUJOvPazbf6NSnXU,950
7
7
  unitlab/main.py,sha256=7gPZ_2n90sxDnq9oGZVKOkuifr-k7w2Tq3ZIldAUE8I,5877
8
8
  unitlab/tunnel_config.py,sha256=7CiAqasfg26YQfJYXapCBQPSoqw4jIx6yR64saybLLo,8312
9
9
  unitlab/tunnel_service_token.py,sha256=ji96a4s4W2cFJrHZle0zBD85Ac_T862-gCKzBUomrxM,3125
10
10
  unitlab/utils.py,sha256=83ekAxxfXecFTg76Z62BGDybC_skKJHYoLyawCD9wGM,1920
11
- unitlab-2.3.17.dist-info/LICENSE.md,sha256=Gn7RRvByorAcAaM-WbyUpsgi5ED1-bKFFshbWfYYz2Y,1069
12
- unitlab-2.3.17.dist-info/METADATA,sha256=vwinORqbWDCEvNcS-fekSwMoly9rnyhzcKK2OWdAYDA,844
13
- unitlab-2.3.17.dist-info/WHEEL,sha256=iAkIy5fosb7FzIOwONchHf19Qu7_1wCWyFNR5gu9nU0,91
14
- unitlab-2.3.17.dist-info/entry_points.txt,sha256=ig-PjKEqSCj3UTdyANgEi4tsAU84DyXdaOJ02NHX4bY,45
15
- unitlab-2.3.17.dist-info/top_level.txt,sha256=Al4ZlTYE3fTJK2o6YLCDMH5_DjuQkffRBMxgmWbKaqQ,8
16
- unitlab-2.3.17.dist-info/RECORD,,
11
+ unitlab-2.3.18.dist-info/LICENSE.md,sha256=Gn7RRvByorAcAaM-WbyUpsgi5ED1-bKFFshbWfYYz2Y,1069
12
+ unitlab-2.3.18.dist-info/METADATA,sha256=jj2M2b0arjx5rRk9su03o5JqSy1lF0pVnq7aQPPgbhk,844
13
+ unitlab-2.3.18.dist-info/WHEEL,sha256=iAkIy5fosb7FzIOwONchHf19Qu7_1wCWyFNR5gu9nU0,91
14
+ unitlab-2.3.18.dist-info/entry_points.txt,sha256=ig-PjKEqSCj3UTdyANgEi4tsAU84DyXdaOJ02NHX4bY,45
15
+ unitlab-2.3.18.dist-info/top_level.txt,sha256=Al4ZlTYE3fTJK2o6YLCDMH5_DjuQkffRBMxgmWbKaqQ,8
16
+ unitlab-2.3.18.dist-info/RECORD,,