superset-showtime 0.6.6__py3-none-any.whl → 0.6.7__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.

Potentially problematic release.


This version of superset-showtime might be problematic. Click here for more details.

showtime/__init__.py CHANGED
@@ -4,7 +4,7 @@
4
4
  Circus tent emoji state tracking for Apache Superset ephemeral environments.
5
5
  """
6
6
 
7
- __version__ = "0.6.6"
7
+ __version__ = "0.6.7"
8
8
  __author__ = "Maxime Beauchemin"
9
9
  __email__ = "maximebeauchemin@gmail.com"
10
10
 
showtime/cli.py CHANGED
@@ -8,6 +8,7 @@ from typing import Dict, Optional
8
8
 
9
9
  import typer
10
10
  from rich.console import Console
11
+ from rich.progress import Progress, SpinnerColumn, TextColumn
11
12
  from rich.table import Table
12
13
 
13
14
  from .core.github import GitHubError, GitHubInterface
@@ -172,7 +173,15 @@ def status(
172
173
  ) -> None:
173
174
  """Show environment status for PR"""
174
175
  try:
175
- pr = PullRequest.from_id(pr_number)
176
+ # Show spinner while fetching PR status
177
+ with Progress(
178
+ SpinnerColumn(),
179
+ TextColumn("[progress.description]{task.description}"),
180
+ console=Console(),
181
+ transient=True,
182
+ ) as progress:
183
+ progress.add_task(description=f"🎪 Fetching status for PR #{pr_number}...", total=None)
184
+ pr = PullRequest.from_id(pr_number)
176
185
 
177
186
  # Use PullRequest method for data
178
187
  status_data = pr.get_status()
@@ -183,8 +192,9 @@ def status(
183
192
 
184
193
  show_data = status_data["show"]
185
194
 
186
- # Create status table
187
- table = Table(title=f"🎪 Environment Status - PR #{pr_number}")
195
+ # Create status table with clickable PR link
196
+ pr_url = f"https://github.com/apache/superset/pull/{pr_number}"
197
+ table = Table(title=f"🎪 Environment Status - [link={pr_url}]PR #{pr_number}[/link]")
188
198
  table.add_column("Property", style="cyan")
189
199
  table.add_column("Value", style="white")
190
200
 
@@ -193,10 +203,11 @@ def status(
193
203
  status_display = STATUS_DISPLAY.get(show_data["status"], "❓")
194
204
  table.add_row("Status", f"{status_display} {show_data['status'].title()}")
195
205
  table.add_row("Environment", f"`{show_data['sha']}`")
196
- table.add_row("AWS Service", f"`{show_data['aws_service_name']}`")
206
+ table.add_row("Service Name", f"`{show_data['aws_service_name']}`")
197
207
 
198
208
  if show_data["ip"]:
199
- table.add_row("URL", f"http://{show_data['ip']}:8080")
209
+ superset_url = f"http://{show_data['ip']}:8080"
210
+ table.add_row("Superset URL", f"[link={superset_url}]{superset_url}[/link]")
200
211
  if show_data["created_at"]:
201
212
  table.add_row("Created", show_data["created_at"])
202
213
 
@@ -205,6 +216,13 @@ def status(
205
216
  if show_data["requested_by"]:
206
217
  table.add_row("Requested by", f"@{show_data['requested_by']}")
207
218
 
219
+ # Add AWS Console URLs - clickable
220
+ from .core.github_messages import get_aws_console_urls
221
+
222
+ aws_urls = get_aws_console_urls(show_data["aws_service_name"])
223
+ table.add_row("AWS Logs", f"[link={aws_urls['logs']}]View Logs ↗[/link]")
224
+ table.add_row("AWS Service", f"[link={aws_urls['service']}]View Service ↗[/link]")
225
+
208
226
  # Show active triggers
209
227
  trigger_labels = [label for label in pr.labels if "showtime-trigger-" in label]
210
228
  if trigger_labels:
@@ -289,8 +307,16 @@ def list(
289
307
  ) -> None:
290
308
  """List all environments"""
291
309
  try:
292
- # Use PullRequest method for data collection
293
- all_environments = PullRequest.list_all_environments()
310
+ # Show spinner while fetching environments
311
+ with Progress(
312
+ SpinnerColumn(),
313
+ TextColumn("[progress.description]{task.description}"),
314
+ console=Console(),
315
+ transient=True,
316
+ ) as progress:
317
+ progress.add_task(description="🎪 Fetching environments...", total=None)
318
+ # Use PullRequest method for data collection
319
+ all_environments = PullRequest.list_all_environments()
294
320
 
295
321
  if not all_environments:
296
322
  p("🎪 No environments currently running")
@@ -328,8 +354,9 @@ def list(
328
354
  table.add_column("TTL", style="yellow", min_width=6)
329
355
  table.add_column("User", style="magenta", min_width=10)
330
356
 
331
- # Sort by PR number, then by show type (active first, then building, then orphaned)
332
- type_priority = {"active": 1, "building": 2, "orphaned": 3}
357
+ # Sort by PR number, then by show type (active first, then building, then orphaned, legacy last)
358
+ # TODO: Remove after legacy cleanup - legacy type priority
359
+ type_priority = {"active": 1, "building": 2, "orphaned": 3, "legacy": 4}
333
360
  sorted_envs = sorted(
334
361
  filtered_envs,
335
362
  key=lambda e: (
@@ -348,6 +375,8 @@ def list(
348
375
  type_display = "🎯" # Active environment (has pointer)
349
376
  elif show_type == "building":
350
377
  type_display = "🔨" # Building environment (hammer is single-width)
378
+ elif show_type == "legacy": # TODO: Remove after legacy cleanup
379
+ type_display = "⚠️" # Legacy environment (no SHA in service name)
351
380
  else:
352
381
  type_display = "👻" # Orphaned environment (no pointer)
353
382
 
@@ -374,17 +403,26 @@ def list(
374
403
  # Simple status display - just emoji
375
404
  status_display = "🟢" if show_data["status"] == "running" else "❌"
376
405
 
406
+ # TODO: Remove after legacy cleanup - handle missing legacy fields
407
+ sha_display = show_data["sha"] if show_data["sha"] != "-" else "-"
408
+ ttl_display = show_data["ttl"] if show_data["ttl"] else "-"
409
+ user_display = (
410
+ f"@{show_data['requested_by']}"
411
+ if show_data["requested_by"] and show_data["requested_by"] != "-"
412
+ else "-"
413
+ )
414
+
377
415
  table.add_row(
378
416
  clickable_pr,
379
417
  f"{show_data['aws_service_name']}-service",
380
418
  type_display,
381
419
  status_display,
382
- show_data["sha"],
420
+ sha_display,
383
421
  age_display,
384
422
  superset_url,
385
423
  aws_logs_link,
386
- show_data["ttl"],
387
- f"@{show_data['requested_by']}" if show_data["requested_by"] else "-",
424
+ ttl_display,
425
+ user_display,
388
426
  )
389
427
 
390
428
  p(table)
@@ -646,10 +646,15 @@ class PullRequest:
646
646
  pr_numbers = get_github().find_prs_with_shows()
647
647
 
648
648
  all_environments = []
649
+ github_service_names = set() # Track services we found via GitHub
650
+
649
651
  for pr_number in pr_numbers:
650
652
  pr = cls.from_id(pr_number)
651
653
  # Show ALL environments, not just current_show
652
654
  for show in pr.shows:
655
+ # Track this service name for later
656
+ github_service_names.add(show.ecs_service_name)
657
+
653
658
  # Determine show type based on pointer presence
654
659
  show_type = "orphaned" # Default
655
660
 
@@ -674,10 +679,64 @@ class PullRequest:
674
679
  "age": show.age_display(), # Add age display
675
680
  "aws_service_name": show.aws_service_name,
676
681
  "show_type": show_type, # New field for display
682
+ "is_legacy": False, # Regular environment
677
683
  },
678
684
  }
679
685
  all_environments.append(environment_data)
680
686
 
687
+ # TODO: Remove after legacy cleanup - Find AWS-only services (legacy pr-XXXXX-service format)
688
+ try:
689
+ from .aws import get_aws
690
+ from .service_name import ServiceName
691
+
692
+ aws = get_aws()
693
+ aws_services = aws.list_circus_environments()
694
+
695
+ for aws_service in aws_services:
696
+ service_name_str = aws_service.get("service_name", "")
697
+
698
+ # Skip if we already have this from GitHub
699
+ if service_name_str in github_service_names:
700
+ continue
701
+
702
+ # Parse the service name to get PR number
703
+ try:
704
+ svc = ServiceName.from_service_name(service_name_str)
705
+
706
+ # Legacy services have no SHA
707
+ is_legacy = svc.sha is None
708
+
709
+ # Add as a legacy/orphaned environment
710
+ environment_data = {
711
+ "pr_number": svc.pr_number,
712
+ "status": "active", # Keep for compatibility
713
+ "show": {
714
+ "sha": svc.sha or "-", # Show dash for missing SHA
715
+ "status": aws_service["status"].lower()
716
+ if aws_service.get("status")
717
+ else "running",
718
+ "ip": aws_service.get("ip"),
719
+ "ttl": None, # Legacy environments have no TTL labels
720
+ "requested_by": "-", # Unknown user for legacy
721
+ "created_at": None, # Will show as "-" in display
722
+ "age": "-", # Unknown age
723
+ "aws_service_name": svc.base_name, # pr-XXXXX or pr-XXXXX-sha format
724
+ "show_type": "legacy"
725
+ if is_legacy
726
+ else "orphaned", # Mark as legacy type
727
+ "is_legacy": is_legacy, # Flag for display formatting
728
+ },
729
+ }
730
+ all_environments.append(environment_data)
731
+
732
+ except ValueError:
733
+ # Skip services that don't match our pattern
734
+ continue
735
+
736
+ except Exception:
737
+ # If AWS lookup fails, just show GitHub-based environments
738
+ pass
739
+
681
740
  return all_environments
682
741
 
683
742
  def _determine_action(self, target_sha: str) -> str:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: superset-showtime
3
- Version: 0.6.6
3
+ Version: 0.6.7
4
4
  Summary: 🎪 Apache Superset ephemeral environment management with circus tent emoji state tracking
5
5
  Project-URL: Homepage, https://github.com/apache/superset-showtime
6
6
  Project-URL: Documentation, https://superset-showtime.readthedocs.io/
@@ -1,6 +1,6 @@
1
- showtime/__init__.py,sha256=bt0MtNlw2hIVZqnlWzbnKBcl21Y7mwUeYRPXNjM287g,448
1
+ showtime/__init__.py,sha256=2Ky3eSk7FJq4kHOp0cH41haCJ3X8gZ5WpzxUqKXRnNM,448
2
2
  showtime/__main__.py,sha256=EVaDaTX69yIhCzChg99vqvFSCN4ELstEt7Mpb9FMZX8,109
3
- showtime/cli.py,sha256=HgGl_QqpgjauR0dd9ZC8WdfQSDWBamlbDms6ezazAXw,32428
3
+ showtime/cli.py,sha256=uGqtmFHXTZd8vMWuoGZ6BLVWzuY34hMx-GMCkgvqvKk,34369
4
4
  showtime/core/__init__.py,sha256=54hbdFNGrzuNMBdraezfjT8Zi6g221pKlJ9mREnKwCw,34
5
5
  showtime/core/aws.py,sha256=7ifPmYryeuLR2c7RtGGzge8Ny9H6ZL40mDESiM1_fi8,34065
6
6
  showtime/core/constants.py,sha256=ssHiswRorqp2CnsZOebz2zqGsnDlMy9aeTQy8gju9fY,290
@@ -10,12 +10,12 @@ showtime/core/git_validation.py,sha256=2V9BSEjubGG4EHKZjcOUGYDWddNpB9uBZ_EVdU00C
10
10
  showtime/core/github.py,sha256=klUxIzUZRE7iQhG36A0lrtgnt6sTkmUjFazaXGgMlCY,12940
11
11
  showtime/core/github_messages.py,sha256=LDYAbVHMEwJaldeJy0ddKe91oRV3RVsUNAXo-RU5oDs,7490
12
12
  showtime/core/label_colors.py,sha256=gSe7EIMl4YjWkIgKHUvuaRSwgEB_B-NYQBxFFlF8Z3s,4065
13
- showtime/core/pull_request.py,sha256=VMAwcf6bAdYiEeGmsaTWt5BhpA1--rgS8A84R5UcHeI,42342
13
+ showtime/core/pull_request.py,sha256=vFlv6pTR3xI5jSODEaQh_af7CUA5kf1StQqQhmzVczI,44964
14
14
  showtime/core/service_name.py,sha256=ZgYzlgnMdMqqatCMVarSyzv9Za9njxDSfIvgYd0LUIY,3126
15
15
  showtime/core/show.py,sha256=VzjOeUG2ra2tdDIzO1EHkZiEt-kMznRk9O2PQ7VuE4I,10224
16
16
  showtime/core/sync_state.py,sha256=oe1lTWWPzfvEAzLBAowdsSJZIdmm5NN-RewzpYTj8zE,4147
17
17
  showtime/data/ecs-task-definition.json,sha256=d-NLkIhvr4C6AnwDfDIwUTx-6KFMH9wRkt6pVCbqZY4,2365
18
- superset_showtime-0.6.6.dist-info/METADATA,sha256=ZBNN-bgaUQ9I3-gaIyClKz1Ii5jQQZXkUKMdG7dH2sM,12052
19
- superset_showtime-0.6.6.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
20
- superset_showtime-0.6.6.dist-info/entry_points.txt,sha256=rDW7oZ57mqyBUS4N_3_R7bZNGVHB-104jwmY-hHC_ck,85
21
- superset_showtime-0.6.6.dist-info/RECORD,,
18
+ superset_showtime-0.6.7.dist-info/METADATA,sha256=_2odjOOHSF_gh7E__iGf2oa4p7a0XV-Ow3qsgW2DVEw,12052
19
+ superset_showtime-0.6.7.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
20
+ superset_showtime-0.6.7.dist-info/entry_points.txt,sha256=rDW7oZ57mqyBUS4N_3_R7bZNGVHB-104jwmY-hHC_ck,85
21
+ superset_showtime-0.6.7.dist-info/RECORD,,