Skip to content

Howto submit condor jobs from inside a Jupyter Notebook

Here is a jupyter notebook that submits jobs into the NAF :)

Download jupyter example notebook here

Link to HTCondor Python Bindings documentation

{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fe09e40e",
   "metadata": {},
   "outputs": [],
   "source": [
    "pip install htcondor==24.4.0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "94c3a4d7",
   "metadata": {},
   "outputs": [],
   "source": [
    "import htcondor  # for submitting jobs, querying HTCondor daemons, etc.\n",
    "import classad   # for interacting with ClassAds, HTCondor's internal data format\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "73d26486",
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "hostname_job = htcondor.Submit({\n",
    "    \"executable\": \"/bin/hostname\",  # the program to run on the execute node\n",
    "    \"output\": \"hostname.out\",       # anything the job prints to standard output will end up in this file\n",
    "    \"error\": \"hostname.err\",        # anything the job prints to standard error will end up in this file\n",
    "    \"log\": \"hostname.log\",          # this file will contain a record of what happened to the job\n",
    "    \"request_cpus\": \"1\",            # how many CPU cores we want\n",
    "    \"request_memory\": \"128MB\",      # how much memory we want\n",
    "    \"request_disk\": \"128MB\",        # how much disk space we want\n",
    "    \"MY.SendCredential\" : \"True\",      # Send KRB ticket with job \n",
    "})\n",
    "\n",
    "print(hostname_job)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "633d02e4",
   "metadata": {},
   "outputs": [],
   "source": [
    "coll = htcondor.Collector(\"bird-htc-master21.desy.de\")\n",
    "schedd_ad = coll.locate(htcondor.DaemonTypes.Schedd, \"bird-htc-sched23.desy.de\")\n",
    "credd_ad = coll.locate(htcondor.DaemonTypes.Credd, \"bird-htc-sched23.desy.de\")\n",
    "print(schedd_ad['MyAddress'])\n",
    "print(credd_ad['MyAddress'])\n",
    "#dir(credd_ad)\n",
    "object_methods = [method_name for method_name in dir(coll)\n",
    "                  if callable(getattr(coll, method_name))]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "344616e7",
   "metadata": {},
   "outputs": [],
   "source": [
    "schedd = htcondor.Schedd(schedd_ad)       # get the Python representation of the scheduler\n",
    "credd = htcondor.Credd(credd_ad)          # get the Python representation of the Cred host \n",
    "credd.add_user_cred(htcondor.CredTypes.Kerberos, None)\n",
    "#ticket = htcondor.Credd.query_user_cred(\"Kerberos\",user=chbeyer) \n",
    "submit_result = schedd.submit(hostname_job)  # submit the job\n",
    "cluster_id = (submit_result.cluster())               # print the job's ClusterId\n",
    "print(cluster_id)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9906fd1a",
   "metadata": {},
   "outputs": [],
   "source": [
    "# query job \n",
    "print(schedd.query(projection=['ClusterId','ProcId','Cmd','Args', 'JobStatus'], constraint=f\"ClusterId=={submit_result.cluster()}\"))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f1e9002d",
   "metadata": {},
   "outputs": [],
   "source": [
    "# query history \n",
    "\n",
    "for ad in schedd.history(\n",
    "    constraint='Owner == \"chbeyer\"',\n",
    "    projection=['ProcId', 'ClusterId', 'JobStatus'],\n",
    "    match=2,  # limit to 2 returned results\n",
    "):\n",
    "    print(ad)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5c375ec4",
   "metadata": {},
   "outputs": [],
   "source": [
    "# query all jobs on this sched\n",
    "q = schedd.query(projection=['ClusterId','ProcId','Cmd','Args', 'JobStatus'])\n",
    "\n",
    "for job in q:\n",
    "    print(f'{job.get(\"ClusterId\")}.{job.get(\"ProcId\")} status: {htcondor.JobStatus(job.get(\"JobStatus\")).name}')\n",
    "    print(job)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2532b189",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}