pipen-cli-gbatch 0.0.4__tar.gz → 0.0.5__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.

Potentially problematic release.


This version of pipen-cli-gbatch might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pipen-cli-gbatch
3
- Version: 0.0.4
3
+ Version: 0.0.5
4
4
  Summary: A pipen cli plugin to run command via Google Cloud Batch
5
5
  License: MIT
6
6
  Author: pwwang
@@ -79,7 +79,7 @@ from pipen.cli import CLIPlugin
79
79
  from pipen.scheduler import GbatchScheduler
80
80
  from pipen_poplog import LogsPopulator
81
81
 
82
- __version__ = "0.0.4"
82
+ __version__ = "0.0.5"
83
83
  __all__ = ("CliGbatchPlugin", "CliGbatchDaemon")
84
84
 
85
85
 
@@ -551,10 +551,10 @@ class XquteCliGbatchPlugin: # pragma: no cover
551
551
 
552
552
  def _clear_residues(self):
553
553
  """Clear any remaining log residues and display them."""
554
- if self.stdout_populator.residue:
554
+ if self.stdout_populator and self.stdout_populator.residue:
555
555
  logger.info(f"/STDOUT {self.stdout_populator.residue}")
556
556
  self.stdout_populator.residue = ""
557
- if self.stderr_populator.residue:
557
+ if self.stderr_populator and self.stderr_populator.residue:
558
558
  logger.error(f"/STDERR {self.stderr_populator.residue}")
559
559
  self.stderr_populator.residue = ""
560
560
 
@@ -595,15 +595,17 @@ class XquteCliGbatchPlugin: # pragma: no cover
595
595
  # Make it less frequent
596
596
  return
597
597
 
598
- stdout_lines = self.stdout_populator.populate()
599
- self.stdout_populator.increment_counter(len(stdout_lines))
600
- for line in stdout_lines:
601
- logger.info(f"/STDOUT {line}")
598
+ if self.stderr_populator:
599
+ stdout_lines = self.stdout_populator.populate()
600
+ self.stdout_populator.increment_counter(len(stdout_lines))
601
+ for line in stdout_lines:
602
+ logger.info(f"/STDOUT {line}")
602
603
 
603
- stderr_lines = self.stderr_populator.populate()
604
- self.stderr_populator.increment_counter(len(stderr_lines))
605
- for line in stderr_lines:
606
- logger.error(f"/STDERR {line}")
604
+ if self.stderr_populator:
605
+ stderr_lines = self.stderr_populator.populate()
606
+ self.stderr_populator.increment_counter(len(stderr_lines))
607
+ for line in stderr_lines:
608
+ logger.error(f"/STDERR {line}")
607
609
 
608
610
  @plugin.impl
609
611
  async def on_job_killed(self, scheduler, job):
@@ -802,6 +804,22 @@ class CliGbatchPlugin(CLIPlugin): # pragma: no cover
802
804
 
803
805
  setattr(known_parsed, key, val)
804
806
 
807
+ mount_as_cwd = getattr(known_parsed, "mount_as_cwd", None)
808
+ cwd = getattr(known_parsed, "cwd", None)
809
+ delattr(known_parsed, "mount_as_cwd")
810
+ if mount_as_cwd and cwd:
811
+ print(
812
+ "\033[1;4mError\033[0m: --mount-as-cwd and --cwd "
813
+ "cannot be used together.\n"
814
+ )
815
+ sys.exit(1)
816
+
817
+ mount = getattr(known_parsed, "mount", None) or []
818
+ if mount_as_cwd:
819
+ mount.append(f"{mount_as_cwd}:/mnt/disks/.cwd")
820
+ setattr(known_parsed, "mount", mount)
821
+ setattr(known_parsed, "cwd", "/mnt/disks/.cwd")
822
+
805
823
  return known_parsed
806
824
 
807
825
  def exec_command(self, args: Namespace) -> None:
@@ -128,6 +128,14 @@ You can also mount a file like `INFILE=gs://my-bucket/inputs/file.txt`. The pare
128
128
  and the file will be available at `/mnt/disks/INFILE/inputs/file.txt` in the VM. `$INFILE` can also be used in the command/script to refer to the mounted path.
129
129
  """
130
130
 
131
+ [[groups.arguments]]
132
+ flags = ["--mount-as-cwd"]
133
+ type = "str"
134
+ help = """The directory to mount as the current working directory of the command.
135
+ This is a shortcut for `--mount <cloudpath>:/mnt/disks/.cwd --cwd /mnt/disks/.cwd`.
136
+ The <cloudpath> must be a Google Storage Bucket path (gs://...).
137
+ """
138
+
131
139
  [[groups.arguments]]
132
140
  flags = ["--service-account"]
133
141
  type = "str"
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "pipen-cli-gbatch"
3
- version = "0.0.4"
3
+ version = "0.0.5"
4
4
  description = "A pipen cli plugin to run command via Google Cloud Batch"
5
5
  authors = ["pwwang <pwwang@pwwang.com>"]
6
6
  license = "MIT"
@@ -17,7 +17,7 @@ entry_points = \
17
17
 
18
18
  setup_kwargs = {
19
19
  'name': 'pipen-cli-gbatch',
20
- 'version': '0.0.4',
20
+ 'version': '0.0.5',
21
21
  'description': 'A pipen cli plugin to run command via Google Cloud Batch',
22
22
  'long_description': '# pipen-cli-gbatch\n\nA pipen CLI plugin to run commands via Google Cloud Batch.\n\nThe idea is to submit the command using xqute and use the gbatch scheduler to run it on Google Cloud Batch.\n\n## Installation\n\n```bash\npip install pipen-cli-gbatch\n```\n\n## Usage\n\n### Basic Command Execution\n\nTo run a command like:\n\n```bash\npython myscript.py --input input.txt --output output.txt\n```\n\nYou can run it with:\n\n```bash\npipen gbatch -- python myscript.py --input input.txt --output output.txt\n```\n\n### With Configuration File\n\nIn order to provide configurations like we do for a normal pipen pipeline, you can also provide a config file (the `[pipen-cli-gbatch]` section will be used):\n\n```bash\npipen gbatch @config.toml -- \\\n python myscript.py --input input.txt --output output.txt\n```\n\n### Detached Mode\n\nWe can also use the `--nowait` option to run the command in a detached mode:\n\n```bash\npipen gbatch --nowait -- \\\n python myscript.py --input input.txt --output output.txt\n```\n\nOr by default, it will wait for the command to complete:\n\n```bash\npipen gbatch -- \\\n python myscript.py --input input.txt --output output.txt\n```\n\nWhile waiting, the running logs will be pulled and shown in the terminal.\n\n### View Logs\n\nWhen running in detached mode, one can also pull the logs later by:\n\n```bash\npipen gbatch --view-logs -- \\\n python myscript.py --input input.txt --output output.txt\n\n# or just provide the workdir\npipen gbatch --view-logs --workdir gs://my-bucket/workdir\n```\n\n## Configuration\n\nBecause the daemon pipeline is running on Google Cloud Batch, a Google Storage Bucket path is required for the workdir. For example: `gs://my-bucket/workdir`\n\nA unique job ID will be generated per the name (`--name`) and workdir, so that if the same command is run again with the same name and workdir, it will not start a new job, but just attach to the existing job and pull the logs.\n\nIf `--name` is not provided in the command line, it will try to grab the name (`--name`) from the command line arguments after `--`, or else use "name" from the root section of the configuration file, with a "GbatchDaemon" suffix. If nothing can be found, a default name "PipenGbatchDaemon" will be used.\n\nThen a workdir `{workdir}/<daemon pipeline name>/` will be created to store the meta information.\n\nWith `--profile` provided, the scheduler options (`scheduler_opts`) defined in `~/.pipen.toml` and `./.pipen.toml` will be used as default.\n\n## All Options\n\n```bash\n> pipen gbatch --help\nUsage: pipen gbatch [-h] [--nowait | --view-logs {all,stdout,stderr}] [--workdir WORKDIR]\n [--error-strategy {retry,halt}] [--num-retries NUM_RETRIES] [--prescript PRESCRIPT]\n [--postscript POSTSCRIPT] [--jobname-prefix JOBNAME_PREFIX] [--recheck-interval RECHECK_INTERVAL]\n [--cwd CWD] [--project PROJECT] [--location LOCATION] [--mount MOUNT]\n [--service-account SERVICE_ACCOUNT] [--network NETWORK] [--subnetwork SUBNETWORK]\n [--no-external-ip-address] [--machine-type MACHINE_TYPE] [--provisioning-model {STANDARD,SPOT}]\n [--image-uri IMAGE_URI] [--entrypoint ENTRYPOINT] [--commands COMMANDS] [--runnables RUNNABLES]\n [--allocationPolicy ALLOCATIONPOLICY] [--taskGroups TASKGROUPS] [--labels LABELS] [--gcloud GCLOUD]\n [--name NAME] [--profile PROFILE] [--version]\n [--loglevel {DEBUG,INFO,WARNING,ERROR,CRITICAL,debug,info,warning,error,critical}]\n ...\n\nSimplify running commands via Google Cloud Batch.\n\nKey Options:\n The key options to run the command.\n\n --workdir WORKDIR The workdir (a Google Storage Bucket path is required) to store the meta information of the\n daemon pipeline.\n If not provided, the one from the command will be used.\n command The command passed after `--` to run, with all its arguments. Note that the command should be\n provided after `--`.\n\nScheduler Options:\n The options to configure the gbatch scheduler.\n\n --error-strategy {retry,halt}\n The strategy when there is error happened [default: halt]\n --num-retries NUM_RETRIES\n The number of retries when there is error happened. Only valid when --error-strategy is \'retry\'.\n [default: 0]\n --prescript PRESCRIPT\n The prescript to run before the main command.\n --postscript POSTSCRIPT\n The postscript to run after the main command.\n --jobname-prefix JOBNAME_PREFIX\n The prefix of the name prefix of the daemon job.\n If not provided, try to generate one from the command to run.\n If the command is also not provided, use \'pipen-gbatch-daemon\' as the prefix.\n --recheck-interval RECHECK_INTERVAL\n The interval to recheck the job status, each takes about 0.1 seconds. [default: 600]\n --cwd CWD The working directory to run the command. If not provided, the current directory is used. You\n can pass either a mounted path (inside the VM) or a Google Storage Bucket path (gs://...). If a\n Google Storage Bucket path is provided, the mounted path will be inferred from the mounted paths\n of the VM.\n --project PROJECT The Google Cloud project to run the job.\n --location LOCATION The location to run the job.\n --mount MOUNT The list of mounts to mount to the VM, each in the format of SOURCE:TARGET, where SOURCE must be\n either a Google Storage Bucket path (gs://...). [default: []]\n --service-account SERVICE_ACCOUNT\n The service account to run the job.\n --network NETWORK The network to run the job.\n --subnetwork SUBNETWORK\n The subnetwork to run the job.\n --no-external-ip-address\n Whether to disable external IP address for the VM.\n --machine-type MACHINE_TYPE\n The machine type of the VM.\n --provisioning-model {STANDARD,SPOT}\n The provisioning model of the VM.\n --image-uri IMAGE_URI\n The custom image URI of the VM.\n --entrypoint ENTRYPOINT\n The entry point of the container to run the command.\n --commands COMMANDS The list of commands to run in the container, each as a separate string. [default: []]\n --runnables RUNNABLES\n The JSON string of extra settings of runnables add to the job.json.\n Refer to https://cloud.google.com/batch/docs/reference/rest/v1/projects.locations.jobs#Runnable\n for details.\n You can have an extra key \'order\' for each runnable, where negative values mean to run before\n the main command,\n and positive values mean to run after the main command.\n --allocationPolicy ALLOCATIONPOLICY\n The JSON string of extra settings of allocationPolicy add to the job.json. Refer to\n https://cloud.google.com/batch/docs/reference/rest/v1/projects.locations.jobs#AllocationPolicy\n for details. [default: {}]\n --taskGroups TASKGROUPS\n The JSON string of extra settings of taskGroups add to the job.json. Refer to\n https://cloud.google.com/batch/docs/reference/rest/v1/projects.locations.jobs#TaskGroup for\n details. [default: []]\n --labels LABELS The JSON string of labels to add to the job. Refer to\n https://cloud.google.com/batch/docs/reference/rest/v1/projects.locations.jobs#Job.FIELDS.labels\n for details. [default: {}]\n --gcloud GCLOUD The path to the gcloud command. [default: gcloud]\n\nOptions:\n -h, --help show this help message and exit\n --nowait Run the command in a detached mode without waiting for its completion. [default: False]\n --view-logs {all,stdout,stderr}\n View the logs of a job.\n --name NAME The name of the daemon pipeline.\n If not provided, try to generate one from the command to run.\n If the command is also not provided, use \'PipenCliGbatchDaemon\' as the name.\n --profile PROFILE Use the `scheduler_opts` as the Scheduler Options of a given profile from pipen configuration\n files,\n including ~/.pipen.toml and ./pipen.toml.\n Note that if not provided, nothing will be loaded from the configuration files.\n --version Show the version of the pipen-cli-gbatch package. [default: False]\n --loglevel {DEBUG,INFO,WARNING,ERROR,CRITICAL,debug,info,warning,error,critical}\n Set the logging level for the daemon process. [default: INFO]\n\nExamples:\n \u200b\n # Run a command and wait for it to complete\n > pipen gbatch --workdir gs://my-bucket/workdir -- \\\n python myscript.py --input input.txt --output output.txt\n\n # Use named mounts\n > pipen gbatch --workdir gs://my-bucket/workdir --mount INFILE=gs://bucket/path/to/file \\\n --mount OUTDIR=gs://bucket/path/to/outdir -- \\\n cat $INFILE > $OUTDIR/output.txt\n \u200b\n # Run a command in a detached mode\n > pipen gbatch --nowait --project $PROJECT --location $LOCATION \\\n --workdir gs://my-bucket/workdir -- \\\n python myscript.py --input input.txt --output output.txt\n \u200b\n # If you have a profile defined in ~/.pipen.toml or ./.pipen.toml\n > pipen gbatch --profile myprofile -- \\\n python myscript.py --input input.txt --output output.txt\n \u200b\n # View the logs of a previously run command\n > pipen gbatch --view-logs all --name my-daemon-name \\\n --workdir gs://my-bucket/workdir\n```\n\n## API\n\nThe API can also be used to run commands programmatically:\n\n```python\nimport asyncio\nfrom pipen_cli_gbatch import CliGbatchDaemon\n\npipe = CliGbatchDaemon(config_for_daemon, command)\nasyncio.run(pipe.run())\n```\n\nNote that the daemon pipeline will always be running without caching, so that the command will always be executed when the pipeline is run.\n',
23
23
  'author': 'pwwang',