flowstash-cli 0.4.2__tar.gz → 0.5.1__tar.gz

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.
Files changed (48) hide show
  1. {flowstash_cli-0.4.2 → flowstash_cli-0.5.1}/PKG-INFO +2 -2
  2. {flowstash_cli-0.4.2 → flowstash_cli-0.5.1}/pyproject.toml +2 -2
  3. {flowstash_cli-0.4.2 → flowstash_cli-0.5.1}/src/flowstash/cli/commands/deploy.py +4 -5
  4. {flowstash_cli-0.4.2 → flowstash_cli-0.5.1}/src/flowstash/cli/commands/project.py +4 -3
  5. {flowstash_cli-0.4.2 → flowstash_cli-0.5.1}/src/flowstash/cli/core/api_client.py +2 -2
  6. {flowstash_cli-0.4.2 → flowstash_cli-0.5.1}/src/flowstash/cli/main.py +7 -7
  7. {flowstash_cli-0.4.2 → flowstash_cli-0.5.1}/src/flowstash/cli/templates/AGENTS.md +9 -7
  8. {flowstash_cli-0.4.2 → flowstash_cli-0.5.1}/src/flowstash/cli/templates/_config/shared/clients/demoClient.yaml +2 -1
  9. {flowstash_cli-0.4.2 → flowstash_cli-0.5.1}/src/flowstash/cli/__init__.py +0 -0
  10. {flowstash_cli-0.4.2 → flowstash_cli-0.5.1}/src/flowstash/cli/commands/__init__.py +0 -0
  11. {flowstash_cli-0.4.2 → flowstash_cli-0.5.1}/src/flowstash/cli/commands/apikey.py +0 -0
  12. {flowstash_cli-0.4.2 → flowstash_cli-0.5.1}/src/flowstash/cli/commands/auth.py +0 -0
  13. {flowstash_cli-0.4.2 → flowstash_cli-0.5.1}/src/flowstash/cli/commands/build.py +0 -0
  14. {flowstash_cli-0.4.2 → flowstash_cli-0.5.1}/src/flowstash/cli/commands/client.py +0 -0
  15. {flowstash_cli-0.4.2 → flowstash_cli-0.5.1}/src/flowstash/cli/commands/run.py +0 -0
  16. {flowstash_cli-0.4.2 → flowstash_cli-0.5.1}/src/flowstash/cli/commands/webhook.py +0 -0
  17. {flowstash_cli-0.4.2 → flowstash_cli-0.5.1}/src/flowstash/cli/core/__init__.py +0 -0
  18. {flowstash_cli-0.4.2 → flowstash_cli-0.5.1}/src/flowstash/cli/core/auth_server.py +0 -0
  19. {flowstash_cli-0.4.2 → flowstash_cli-0.5.1}/src/flowstash/cli/core/builder.py +0 -0
  20. {flowstash_cli-0.4.2 → flowstash_cli-0.5.1}/src/flowstash/cli/core/config.py +0 -0
  21. {flowstash_cli-0.4.2 → flowstash_cli-0.5.1}/src/flowstash/cli/core/docker_utils.py +0 -0
  22. {flowstash_cli-0.4.2 → flowstash_cli-0.5.1}/src/flowstash/cli/core/patcher.py +0 -0
  23. {flowstash_cli-0.4.2 → flowstash_cli-0.5.1}/src/flowstash/cli/templates/README.md +0 -0
  24. {flowstash_cli-0.4.2 → flowstash_cli-0.5.1}/src/flowstash/cli/templates/_.dockerignore +0 -0
  25. {flowstash_cli-0.4.2 → flowstash_cli-0.5.1}/src/flowstash/cli/templates/_.flowstash +0 -0
  26. {flowstash_cli-0.4.2 → flowstash_cli-0.5.1}/src/flowstash/cli/templates/_api_main.py +0 -0
  27. {flowstash_cli-0.4.2 → flowstash_cli-0.5.1}/src/flowstash/cli/templates/_config/[env]/(backend-asyncio)/backend.yaml +0 -0
  28. {flowstash_cli-0.4.2 → flowstash_cli-0.5.1}/src/flowstash/cli/templates/_config/[env]/(backend-dramatiq)/backend.yaml +0 -0
  29. {flowstash_cli-0.4.2 → flowstash_cli-0.5.1}/src/flowstash/cli/templates/_config/[env]/(backend-managed)/backend.yaml +0 -0
  30. {flowstash_cli-0.4.2 → flowstash_cli-0.5.1}/src/flowstash/cli/templates/_config/[env]/(observability-logfile)/observability.yaml +0 -0
  31. {flowstash_cli-0.4.2 → flowstash_cli-0.5.1}/src/flowstash/cli/templates/_config/[env]/(observability-managed)/observability.yaml +0 -0
  32. {flowstash_cli-0.4.2 → flowstash_cli-0.5.1}/src/flowstash/cli/templates/_config/shared/backend.yaml +0 -0
  33. {flowstash_cli-0.4.2 → flowstash_cli-0.5.1}/src/flowstash/cli/templates/_config/shared/clients.yaml +0 -0
  34. {flowstash_cli-0.4.2 → flowstash_cli-0.5.1}/src/flowstash/cli/templates/_deployment/[env]/(backend-asyncio)/docker-compose.yaml +0 -0
  35. {flowstash_cli-0.4.2 → flowstash_cli-0.5.1}/src/flowstash/cli/templates/_deployment/[env]/(backend-dramatiq)/docker-compose.yaml +0 -0
  36. {flowstash_cli-0.4.2 → flowstash_cli-0.5.1}/src/flowstash/cli/templates/_deployment/shared/api.Dockerfile +0 -0
  37. {flowstash_cli-0.4.2 → flowstash_cli-0.5.1}/src/flowstash/cli/templates/_deployment/shared/worker.Dockerfile +0 -0
  38. {flowstash_cli-0.4.2 → flowstash_cli-0.5.1}/src/flowstash/cli/templates/_pyproject.toml +0 -0
  39. {flowstash_cli-0.4.2 → flowstash_cli-0.5.1}/src/flowstash/cli/templates/_src/_api/__init__.py +0 -0
  40. {flowstash_cli-0.4.2 → flowstash_cli-0.5.1}/src/flowstash/cli/templates/_src/_api/_routes/webhooks.py +0 -0
  41. {flowstash_cli-0.4.2 → flowstash_cli-0.5.1}/src/flowstash/cli/templates/_src/_shared/__init__.py +0 -0
  42. {flowstash_cli-0.4.2 → flowstash_cli-0.5.1}/src/flowstash/cli/templates/_src/_shared/clients/client.py +0 -0
  43. {flowstash_cli-0.4.2 → flowstash_cli-0.5.1}/src/flowstash/cli/templates/_src/_shared/models/models.py +0 -0
  44. {flowstash_cli-0.4.2 → flowstash_cli-0.5.1}/src/flowstash/cli/templates/_src/_shared/tasks/sharedTasks.py +0 -0
  45. {flowstash_cli-0.4.2 → flowstash_cli-0.5.1}/src/flowstash/cli/templates/_src/_worker/__init__.py +0 -0
  46. {flowstash_cli-0.4.2 → flowstash_cli-0.5.1}/src/flowstash/cli/templates/_src/_worker/tasks/tasks.py +0 -0
  47. {flowstash_cli-0.4.2 → flowstash_cli-0.5.1}/src/flowstash/cli/templates/_worker_main.py +0 -0
  48. {flowstash_cli-0.4.2 → flowstash_cli-0.5.1}/src/flowstash/cli/ui/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: flowstash-cli
3
- Version: 0.4.2
3
+ Version: 0.5.1
4
4
  Summary: CLI for the flowstash Managed Platform
5
5
  Author: juraj.bezdek@gmail.com
6
6
  Author-email: juraj.bezdek@gmail.com
@@ -9,7 +9,7 @@ Classifier: Programming Language :: Python :: 3
9
9
  Classifier: Programming Language :: Python :: 3.11
10
10
  Classifier: Programming Language :: Python :: 3.12
11
11
  Classifier: Programming Language :: Python :: 3.13
12
- Requires-Dist: flowstash-runtime (>=0.4.2,<0.5.0)
12
+ Requires-Dist: flowstash-runtime (>=0.5.1,<0.6.0)
13
13
  Requires-Dist: httpx (>=0.27.0)
14
14
  Requires-Dist: keyring (>=25.0.0)
15
15
  Requires-Dist: libcst (>=1.1.0)
@@ -1,11 +1,11 @@
1
1
  [project]
2
2
  name = "flowstash-cli"
3
- version = "0.4.2"
3
+ version = "0.5.1"
4
4
  description = "CLI for the flowstash Managed Platform"
5
5
  authors = [{name = "juraj.bezdek@gmail.com", email = "juraj.bezdek@gmail.com"}]
6
6
  requires-python = ">=3.11"
7
7
  dependencies = [
8
- "flowstash-runtime>=0.4.2,<0.5.0",
8
+ "flowstash-runtime>=0.5.1,<0.6.0",
9
9
  "typer[all]>=0.12.0",
10
10
  "httpx>=0.27.0",
11
11
  "pyyaml>=6.0.1",
@@ -14,6 +14,7 @@ console = Console()
14
14
  # Status labels shown to the user while polling
15
15
  _STATUS_LABELS = {
16
16
  "QUEUED": "Queued, waiting for deployment to start...",
17
+ "VALIDATING": "Validating container images...",
17
18
  "DEPLOYING": "Deploying services...",
18
19
  "HEALTH_CHECK": "Health-checking API and Worker...",
19
20
  "SYNCING_SCHEDULES": "Fetching and syncing scheduled tasks...",
@@ -93,9 +94,7 @@ def deploy(
93
94
  artifact: Optional[str] = typer.Option(
94
95
  None, "--artifact", "-a", help="Artifact ID to deploy"
95
96
  ),
96
- non_interactive: bool = typer.Option(
97
- False, "--non-interactive", help="Do not ask for confirmation"
98
- ),
97
+ yes: bool = typer.Option(False, "--yes", "-y", help="Do not ask for confirmation"),
99
98
  ):
100
99
  """Deploy an artifact to the managed platform for a specified environment."""
101
100
  project_config = load_project_config()
@@ -106,7 +105,7 @@ def deploy(
106
105
  raise typer.Exit(code=1)
107
106
 
108
107
  # Ask for confirmation unless non-interactive is provided
109
- if not non_interactive:
108
+ if not yes:
110
109
  from rich.prompt import Confirm
111
110
 
112
111
  if not Confirm.ask(f"Are you sure you want to deploy to '{env}'?"):
@@ -131,7 +130,7 @@ def deploy(
131
130
 
132
131
  project_id = project_config.project_id
133
132
  if not project_id:
134
- if not non_interactive:
133
+ if not yes:
135
134
  from rich.prompt import Confirm
136
135
 
137
136
  if Confirm.ask(
@@ -556,7 +556,8 @@ def env_add(
556
556
 
557
557
  @app.command("delete")
558
558
  def env_delete(
559
- env_name: str = typer.Argument(..., help="Name of the environment to delete")
559
+ env_name: str = typer.Argument(..., help="Name of the environment to delete"),
560
+ yes: bool = typer.Option(False, "--yes", "-y", help="Skip confirmation prompt"),
560
561
  ):
561
562
  """
562
563
  [bold red]Delete an environment[/bold red] from your project.
@@ -588,7 +589,7 @@ def env_delete(
588
589
 
589
590
  from rich.prompt import Confirm
590
591
 
591
- if not Confirm.ask(
592
+ if not yes and not Confirm.ask(
592
593
  f"Are you sure you want to delete environment [bold red]{env_name}[/bold red]?"
593
594
  ):
594
595
  console.print("Cancelled.")
@@ -603,7 +604,7 @@ def env_delete(
603
604
  # Optionally delete the folder
604
605
  env_folder = root / env_name
605
606
  if env_folder.exists() and env_folder.is_dir():
606
- if Confirm.ask(
607
+ if yes or Confirm.ask(
607
608
  f"Do you also want to delete the configuration folder [bold]{env_name}/[/bold]?"
608
609
  ):
609
610
  import shutil
@@ -23,8 +23,8 @@ class APIClient:
23
23
  response.raise_for_status()
24
24
  return response.json()
25
25
 
26
- async def post(self, path: str, json: Optional[Dict[str, Any]] = None):
27
- async with httpx.AsyncClient(timeout=30.0) as client:
26
+ async def post(self, path: str, json: Optional[Dict[str, Any]] = None, timeout: float = 30.0):
27
+ async with httpx.AsyncClient(timeout=timeout) as client:
28
28
  response = await client.post(
29
29
  f"{self.base_url}{path}", json=json, headers=self._get_headers()
30
30
  )
@@ -198,6 +198,7 @@ def run(
198
198
  logs: bool = typer.Option(
199
199
  False, "--logs", help="Follow logs (useful with --detach)"
200
200
  ),
201
+ yes: bool = typer.Option(False, "--yes", "-y", help="Skip confirmation prompts"),
201
202
  ):
202
203
  """
203
204
  [bold magenta]Run[/bold magenta] the project locally using Docker Compose.
@@ -219,7 +220,7 @@ def run(
219
220
  env_mode = next((e for e in project_config.environments if e.name == env), None)
220
221
  if not env_mode:
221
222
  if env == "dev":
222
- if Confirm.ask(
223
+ if yes or Confirm.ask(
223
224
  f"Environment '{env}' not found. Would you like to set it up now?"
224
225
  ):
225
226
  project_cmds.add_environment(project_config, env_name=env)
@@ -240,6 +241,7 @@ def build(
240
241
  ctx: typer.Context,
241
242
  env: str = typer.Argument("dev", help="Environment to build (default: local)"),
242
243
  tag: str = typer.Option("latest", "--tag", "-t", help="Tag for the image"),
244
+ yes: bool = typer.Option(False, "--yes", "-y", help="Skip confirmation prompts"),
243
245
  ):
244
246
  """
245
247
  [bold yellow]Build[/bold yellow] project artifacts/images.
@@ -261,7 +263,7 @@ def build(
261
263
  env_mode = next((e for e in project_config.environments if e.name == env), None)
262
264
  if not env_mode:
263
265
  if env == "dev":
264
- if Confirm.ask(
266
+ if yes or Confirm.ask(
265
267
  f"Environment '{env}' not found. Would you like to set it up now?"
266
268
  ):
267
269
  project_cmds.add_environment(project_config, env_name=env)
@@ -284,9 +286,7 @@ def deploy(
284
286
  artifact: Optional[str] = typer.Option(
285
287
  None, "--artifact", "-a", help="Artifact ID to deploy"
286
288
  ),
287
- non_interactive: bool = typer.Option(
288
- False, "--non-interactive", help="Do not ask for confirmation"
289
- ),
289
+ yes: bool = typer.Option(False, "--yes", "-y", help="Skip confirmation prompts"),
290
290
  ):
291
291
  """
292
292
  [bold cyan]Deploy[/bold cyan] your project to the flowstash Managed Platform.
@@ -316,7 +316,7 @@ def deploy(
316
316
 
317
317
  if not env_mode:
318
318
  if env == "prod":
319
- if not non_interactive and Confirm.ask(
319
+ if yes or Confirm.ask(
320
320
  f"Environment '{env}' not found. Would you like to set it up now?"
321
321
  ):
322
322
  # We need to pass the actual project_config object to add_environment
@@ -347,7 +347,7 @@ def deploy(
347
347
  )
348
348
  raise typer.Exit(code=1)
349
349
 
350
- deploy_cmds.deploy(env=env, artifact=artifact, non_interactive=non_interactive)
350
+ deploy_cmds.deploy(env=env, artifact=artifact, yes=yes)
351
351
 
352
352
 
353
353
  @app.command()
@@ -233,15 +233,13 @@ class DemoClient(HttpClient):
233
233
  async def get_user(self, user_id: int) -> dict:
234
234
  response = await self.request("GET", f"/users/{user_id}")
235
235
  return response.json()
236
+ ```
236
237
 
237
- @classmethod
238
- def get(cls) -> DemoClient:
239
- return get_client("demoClient")
240
-
238
+ You can then resolve this custom client by name:
239
+ `demo = get_client("DemoClient")`
240
+ or
241
+ `DemoClient.get_client()`
241
242
 
242
- # You can then resolve this custom client by name:
243
- # demo = get_client("DemoClient")
244
- ```
245
243
 
246
244
  ## Logging
247
245
 
@@ -367,3 +365,7 @@ flowstash uses a tiered configuration system that allows for seamless transition
367
365
  - **`api_main.py`**: The entry point for the web server. It sets up the FastAPI application and automatically imports modules from `src/api` to register routes.
368
366
  - **`worker_main.py`**: The entry point for the background process. It connects to the task backend (like Redis) and automatically imports modules from `src/worker` to register task signatures.
369
367
 
368
+ ### Imports
369
+ Always import directly from the module level (e.g., api, worker, shared), assuming src is the root of your $PYTHONPATH.
370
+ This mirrors the Docker environment structure, ensuring cleaner code and consistency across environments. When writing tests or standalone scripts, you must either manually add src to your PYTHONPATH or configure poetry to install src as the package source.
371
+ Avoid relative imports
@@ -10,7 +10,8 @@ auth:
10
10
  token_url: "https://auth.example.com/token"
11
11
  refresh_token: null
12
12
  scopes: []
13
- extra_params: {}
13
+ # clientAuthMethod: client_secret_basic (default) # Supported values: client_secret_basic, client_secret_post
14
+ # extra_params: {}
14
15
 
15
16
  # Authentication Alternatives
16
17
  # ------------------------------------------s