Skip to content

Commit eb6544b

Browse files
committed
feat: Introduce GAMES list and refactor CLI configuration
- Added a GAMES list to `games.py` for predefined heavy applications. - Updated `__init__.py` to export GAMES for easier access. - Refactored CLI to use `fortscript.yaml` instead of `config.yaml`. - Removed obsolete `config.yaml` file from CLI directory. - Enhanced backend simulator and main scripts to utilize GAMES list. - Improved logging and code formatting across various modules. - Added new example project demonstrating the use of GAMES list.
1 parent bb1a61f commit eb6544b

13 files changed

Lines changed: 708 additions & 163 deletions

File tree

README_ptBR.md

Lines changed: 324 additions & 65 deletions
Large diffs are not rendered by default.

src/fortscript/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
11
from .main import FortScript as FortScript
2+
from .games import GAMES as GAMES
3+
4+
__all__ = ["FortScript", "GAMES"]

src/fortscript/cli/cli.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ def main():
2020
"""Main entry point for the CLI."""
2121
# Configure logging with Rich
2222
logging.basicConfig(
23-
level="INFO",
24-
format="%(message)s",
25-
datefmt="[%X]",
26-
handlers=[RichHandler(rich_tracebacks=True, show_path=False)]
23+
level='INFO',
24+
format='%(message)s',
25+
datefmt='[%X]',
26+
handlers=[RichHandler(rich_tracebacks=True, show_path=False)],
2727
)
2828

2929
# Minimalist and elegant header
@@ -36,7 +36,7 @@ def main():
3636

3737
# Path for the global config
3838
config_path = os.path.join(
39-
os.path.dirname(os.path.abspath(__file__)), 'config.yaml'
39+
os.path.dirname(os.path.abspath(__file__)), 'fortscript.yaml'
4040
)
4141

4242
app = FortScript(config_path=config_path)

src/fortscript/cookbook/project_with_arguments/backend_simulator.py

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,13 @@
1010

1111
def simulate_requests():
1212
"""Simulates a developer backend logging API requests."""
13-
methods = ["GET", "POST", "PUT", "DELETE"]
14-
endpoints = ["/api/v1/users", "/api/v1/auth/login",
15-
"/api/v1/products", "/api/v1/orders"]
13+
methods = ['GET', 'POST', 'PUT', 'DELETE']
14+
endpoints = [
15+
'/api/v1/users',
16+
'/api/v1/auth/login',
17+
'/api/v1/products',
18+
'/api/v1/orders',
19+
]
1620

1721
logs = []
1822

@@ -25,11 +29,11 @@ def simulate_requests():
2529
latency = random.randint(10, 500)
2630

2731
log_entry = {
28-
"time": time.strftime("%H:%M:%S"),
29-
"method": method,
30-
"endpoint": endpoint,
31-
"status": status,
32-
"latency": f"{latency}ms"
32+
'time': time.strftime('%H:%M:%S'),
33+
'method': method,
34+
'endpoint': endpoint,
35+
'status': status,
36+
'latency': f'{latency}ms',
3337
}
3438

3539
logs.append(log_entry)
@@ -38,24 +42,31 @@ def simulate_requests():
3842

3943
# Create a nice UI table
4044
table = Table(
41-
title="[bold blue]Developer Backend Simulator - Service A[/bold blue]")
42-
table.add_column("Time", style="dim")
43-
table.add_column("Method", style="bold")
44-
table.add_column("Endpoint", style="cyan")
45+
title='[bold blue]Developer Backend Simulator - Service A[/bold blue]'
46+
)
47+
table.add_column('Time', style='dim')
48+
table.add_column('Method', style='bold')
49+
table.add_column('Endpoint', style='cyan')
4550
table.add_column(
46-
"Status", style="green" if status < 400 else "red")
47-
table.add_column("Latency", style="magenta")
51+
'Status', style='green' if status < 400 else 'red'
52+
)
53+
table.add_column('Latency', style='magenta')
4854

4955
for log in logs:
50-
table.add_row(log["time"], log["method"], log["endpoint"], str(
51-
log["status"]), log["latency"])
56+
table.add_row(
57+
log['time'],
58+
log['method'],
59+
log['endpoint'],
60+
str(log['status']),
61+
log['latency'],
62+
)
5263

5364
live.update(table)
5465
time.sleep(random.uniform(0.5, 2.0))
5566

5667

57-
if __name__ == "__main__":
68+
if __name__ == '__main__':
5869
try:
5970
simulate_requests()
6071
except KeyboardInterrupt:
61-
console.print("\n[yellow]Shutting down Backend Simulator...[/yellow]")
72+
console.print('\n[yellow]Shutting down Backend Simulator...[/yellow]')

src/fortscript/cookbook/project_with_arguments/main.py

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,50 +4,49 @@
44
from fortscript import FortScript
55

66
# Basic logging configuration for the cookbook example
7-
logging.basicConfig(format="%(message)s")
7+
logging.basicConfig(format='%(message)s')
88

99
# Define the absolute path to our backend simulator
1010
base_dir = os.path.dirname(os.path.abspath(__file__))
11-
backend_path = os.path.join(base_dir, "backend_simulator.py")
11+
backend_path = os.path.join(base_dir, 'backend_simulator.py')
1212

1313
# Configuration for a typical developer development stack
1414
# These projects will be started automatically when system resources are stable
1515
development_projects = [
16-
{
17-
'name': 'API Gateway Simulator',
18-
'path': backend_path
19-
}
16+
{'name': 'API Gateway Simulator', 'path': backend_path}
2017
]
2118

2219
# Define heavy applications that should pause our dev stack
2320
# (e.g., when you want to play a game or render a video)
2421
productivity_blockers = [
2522
{'name': 'Chrome (Heavy Usage)', 'process': 'chrome.exe'},
2623
{'name': 'High-End Game', 'process': 'cyberpunk2077.exe'},
27-
{'name': 'Video Editor', 'process': 'premiere.exe'}
24+
{'name': 'Video Editor', 'process': 'premiere.exe'},
2825
]
2926

3027

3128
def on_pause():
32-
print(">>> [Event] Development stack PAUSED. Enjoy your game!")
29+
print('>>> [Event] Development stack PAUSED. Enjoy your game!')
3330

3431

3532
def on_resume():
36-
print(">>> [Event] System stable. Returning to development mode...")
33+
print('>>> [Event] System stable. Returning to development mode...')
3734

3835

3936
# Initialize FortScript with our custom configuration and events
4037
app = FortScript(
4138
projects=development_projects,
4239
heavy_process=productivity_blockers,
4340
ram_threshold=90, # Pause if RAM usage exceeds 90%
44-
ram_safe=80, # Resume only when RAM falls below 80% (Hysteresis)
41+
ram_safe=80, # Resume only when RAM falls below 80% (Hysteresis)
4542
on_pause=on_pause,
4643
on_resume=on_resume,
47-
log_level="DEBUG" # Show detailed logs for debugging
44+
log_level='DEBUG', # Show detailed logs for debugging
4845
)
4946

50-
if __name__ == "__main__":
51-
print("--- FortScript: Developer Productivity Case ---")
52-
print("Scenario: Managing a local backend stack that pauses during heavy tasks.")
47+
if __name__ == '__main__':
48+
print('--- FortScript: Developer Productivity Case ---')
49+
print(
50+
'Scenario: Managing a local backend stack that pauses during heavy tasks.'
51+
)
5352
app.run()
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import random
2+
import time
3+
4+
# Minimalist simulator without external dependencies (rich) for stability in this test
5+
def simulate_requests():
6+
"""Simulates a developer backend logging API requests."""
7+
methods = ['GET', 'POST', 'PUT', 'DELETE']
8+
endpoints = [
9+
'/api/v1/users',
10+
'/api/v1/auth/login',
11+
'/api/v1/products',
12+
'/api/v1/orders',
13+
]
14+
15+
print("Backend Simulator Started. Press Ctrl+C to stop.")
16+
17+
while True:
18+
method = random.choice(methods)
19+
endpoint = random.choice(endpoints)
20+
status = random.choice([200, 201, 400, 404, 500])
21+
latency = random.randint(10, 500)
22+
timestamp = time.strftime('%H:%M:%S')
23+
24+
print(f"[{timestamp}] {method} {endpoint} -> {status} ({latency}ms)")
25+
time.sleep(random.uniform(0.5, 2.0))
26+
27+
if __name__ == '__main__':
28+
try:
29+
simulate_requests()
30+
except KeyboardInterrupt:
31+
print('\nShutting down Backend Simulator...')
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import logging
2+
import os
3+
import sys
4+
5+
# Ensure we can import fortscript from source
6+
current_dir = os.path.dirname(os.path.abspath(__file__))
7+
src_path = os.path.abspath(os.path.join(current_dir, "../../../"))
8+
if src_path not in sys.path:
9+
sys.path.insert(0, src_path)
10+
11+
from fortscript import FortScript, GAMES
12+
13+
# Basic logging configuration
14+
logging.basicConfig(format='%(message)s')
15+
16+
# Define the absolute path to our backend simulator
17+
base_dir = os.path.dirname(os.path.abspath(__file__))
18+
backend_path = os.path.join(base_dir, 'backend_simulator.py')
19+
20+
# Configuration for a typical developer development stack
21+
development_projects = [
22+
{'name': 'Backend API Simulator', 'path': backend_path}
23+
]
24+
25+
def on_pause():
26+
print('>>> [Event] Game detected! Development stack PAUSED.')
27+
28+
def on_resume():
29+
print('>>> [Event] No games running. Resuming development stack...')
30+
31+
# Initialize FortScript utilizing the imported GAMES list
32+
# This demonstrates how to use the built-in list of heavy processes
33+
app = FortScript(
34+
projects=development_projects,
35+
heavy_process=GAMES, # Using the imported list directly
36+
ram_threshold=95,
37+
ram_safe=85,
38+
on_pause=on_pause,
39+
on_resume=on_resume,
40+
log_level='DEBUG',
41+
)
42+
43+
if __name__ == '__main__':
44+
print('--- FortScript: Built-in Games List Example ---')
45+
print('This example uses the pre-defined "GAMES" list from the library.')
46+
print(f'Loaded {len(GAMES)} game definitions automatically.')
47+
48+
# We will not call app.run() here to avoid blocking the CI/Interactive session indefinitely
49+
# but we will simulate the check to prove it works.
50+
51+
print("\n--- Verifying Configuration ---")
52+
print(f"Projects configured: {len(app.projects)}")
53+
print(f"Heavy processes monitored: {len(app.heavy_processes)}")
54+
55+
# Check if the first game in the list is correctly monitored
56+
first_game = GAMES[0]['name']
57+
print(f"First monitored game: {first_game}")
58+
59+
print("\n✅ Setup complete. To run the full loop, uncomment 'app.run()' in the code.")
60+
app.run()

src/fortscript/cookbook/project_with_yaml_file/main.py

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,35 +4,37 @@
44
from fortscript import FortScript
55

66
# Basic logging configuration for the cookbook example
7-
logging.basicConfig(level=logging.INFO, format="%(message)s")
7+
logging.basicConfig(level=logging.INFO, format='%(message)s')
88

99
# Path to our English configuration file
1010
base_dir = os.path.dirname(os.path.abspath(__file__))
11-
config_path = os.path.join(base_dir, "config.yaml")
11+
config_path = os.path.join(base_dir, 'config.yaml')
1212

1313

1414
def alert_system():
15-
print("📢 [System Alert] Resource usage threshold reached! Pausing overlays.")
15+
print(
16+
'📢 [System Alert] Resource usage threshold reached! Pausing overlays.'
17+
)
1618

1719

1820
def welcome_back():
19-
print("✅ [System Alert] Resources cleared. Overlays are live again!")
21+
print('✅ [System Alert] Resources cleared. Overlays are live again!')
2022

2123

2224
# Initialize FortScript using the external YAML file and events
2325
app = FortScript(
24-
config_path=config_path,
25-
on_pause=alert_system,
26-
on_resume=welcome_back
26+
config_path=config_path, on_pause=alert_system, on_resume=welcome_back
2727
)
2828

2929

3030
def main():
31-
print("--- FortScript: Content Creator Case ---")
32-
print(f"Loading external configuration from: {config_path}")
33-
print("Scenario: Managing streaming overlays with settings (and log level) defined in YAML.")
31+
print('--- FortScript: Content Creator Case ---')
32+
print(f'Loading external configuration from: {config_path}')
33+
print(
34+
'Scenario: Managing streaming overlays with settings (and log level) defined in YAML.'
35+
)
3436
app.run()
3537

3638

37-
if __name__ == "__main__":
39+
if __name__ == '__main__':
3840
main()

src/fortscript/cookbook/project_with_yaml_file/overlay_controller.py

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,31 +15,32 @@ def streaming_overlay():
1515

1616
while True:
1717
elapsed = time.strftime(
18-
"%H:%M:%S", time.gmtime(time.time() - start_time))
18+
'%H:%M:%S', time.gmtime(time.time() - start_time)
19+
)
1920
cpu_usage = psutil.cpu_percent()
2021

2122
# Simulated Twitch/YouTube events
2223
status_text = (
23-
f"[bold cyan]Overlay Active[/bold cyan]\n"
24-
f"Uptime: {elapsed}\n"
25-
f"Heartbeat: [green]Stable[/green]\n"
26-
f"CPU Load: [yellow]{cpu_usage}%[/yellow]\n\n"
27-
f"[dim]Listening for stream events...[/dim]"
24+
f'[bold cyan]Overlay Active[/bold cyan]\n'
25+
f'Uptime: {elapsed}\n'
26+
f'Heartbeat: [green]Stable[/green]\n'
27+
f'CPU Load: [yellow]{cpu_usage}%[/yellow]\n\n'
28+
f'[dim]Listening for stream events...[/dim]'
2829
)
2930

3031
panel = Panel(
3132
status_text,
32-
title="[bold magenta]StreamTools Helper[/bold magenta]",
33-
subtitle="Managed by FortScript",
34-
border_style="magenta"
33+
title='[bold magenta]StreamTools Helper[/bold magenta]',
34+
subtitle='Managed by FortScript',
35+
border_style='magenta',
3536
)
3637

3738
live.update(panel)
3839
time.sleep(0.25)
3940

4041

41-
if __name__ == "__main__":
42+
if __name__ == '__main__':
4243
try:
4344
streaming_overlay()
4445
except KeyboardInterrupt:
45-
console.print("\n[magenta]StreamTools Helper Closed.[/magenta]")
46+
console.print('\n[magenta]StreamTools Helper Closed.[/magenta]')

0 commit comments

Comments
 (0)