{"id":7737,"date":"2024-05-28T11:55:13","date_gmt":"2024-05-28T18:55:13","guid":{"rendered":"https:\/\/jeremywhittaker.com\/?p=7737"},"modified":"2024-05-28T11:58:51","modified_gmt":"2024-05-28T18:58:51","slug":"automating-notification-updates-on-court-cases-for-maricopa-county-superior-court","status":"publish","type":"post","link":"https:\/\/new.jeremywhittaker.com\/index.php\/2024\/05\/28\/automating-notification-updates-on-court-cases-for-maricopa-county-superior-court\/","title":{"rendered":"Automating notification updates on court cases for Maricopa County Superior Court"},"content":{"rendered":"\n<p>Recently, I needed real-time updates for a court case affecting a house I was purchasing. Instead of constantly checking the case manually, I wrote a Python script to automate this process. The script monitors court case information, party details, case documents, and the case calendar. Whenever it detects an update, it sends an email notification.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"752\" height=\"393\" data-src=\"https:\/\/new.jeremywhittaker.com\/wp-content\/uploads\/2024\/05\/image-1.png\" alt=\"\" class=\"wp-image-7739 lazyload\" data-srcset=\"https:\/\/new.jeremywhittaker.com\/wp-content\/uploads\/2024\/05\/image-1.png 752w, https:\/\/new.jeremywhittaker.com\/wp-content\/uploads\/2024\/05\/image-1-300x157.png 300w, https:\/\/new.jeremywhittaker.com\/wp-content\/uploads\/2024\/05\/image-1-500x261.png 500w\" data-sizes=\"(max-width: 752px) 100vw, 752px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 752px; --smush-placeholder-aspect-ratio: 752\/393;\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">How It Works<\/h2>\n\n\n\n<p>The script downloads the latest court case information and saves it to the <code>.\/data\/<\/code> directory in the following CSV formats:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>{case_number}_case_information.csv<\/code><\/li>\n\n\n\n<li><code>{case_number}_party_information.csv<\/code><\/li>\n\n\n\n<li><code>{case_number}_case_documents.csv<\/code><\/li>\n\n\n\n<li><code>{case_number}_case_calendar.csv<\/code><\/li>\n<\/ul>\n\n\n\n<p>If there are new updates, it emails the specific rows with the changes.<\/p>\n\n\n\n<p><br><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">{case_number}_case_information.csv\n{case_number}_party_information.csv\n{case_number}_case_documents.csv\n{case_number}_case_calendar.csv<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Gmail JSON file<\/h2>\n\n\n\n<p><br><\/p>\n\n\n\n<p>To send emails, you need a JSON file to access your Gmail account. Follow these steps:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Go to the Google Cloud Console<\/strong>:\n<ul class=\"wp-block-list\">\n<li>Visit <a href=\"https:\/\/console.cloud.google.com\/welcome?project=trading-algo-329823\">Google Cloud Console<\/a>.<\/li>\n\n\n\n<li>If you haven&#8217;t already, sign in with your Google account.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Create a New Project<\/strong> (if you don&#8217;t already have one):\n<ul class=\"wp-block-list\">\n<li>Click on the project dropdown at the top and select &#8220;New Project.&#8221;<\/li>\n\n\n\n<li>Enter a name for your project and click &#8220;Create.&#8221;<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Enable the Gmail API<\/strong>:\n<ul class=\"wp-block-list\">\n<li>In the Google Cloud Console, go to the &#8220;APIs &amp; Services&#8221; dashboard.<\/li>\n\n\n\n<li>Click on &#8220;Enable APIs and Services.&#8221;<\/li>\n\n\n\n<li>Search for &#8220;Gmail API&#8221; and click on it.<\/li>\n\n\n\n<li>Click &#8220;Enable&#8221; to enable the Gmail API for your project.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Create Credentials<\/strong>:\n<ul class=\"wp-block-list\">\n<li>Go to the &#8220;Credentials&#8221; tab on the left sidebar.<\/li>\n\n\n\n<li>Click on &#8220;Create Credentials&#8221; and select &#8220;OAuth 2.0 Client ID.&#8221;<\/li>\n\n\n\n<li>You may be prompted to configure the OAuth consent screen. If so, follow the instructions to set up the consent screen (you can fill in minimal information for internal use).<\/li>\n\n\n\n<li>Choose &#8220;Desktop app&#8221; for the application type and give it a name.<\/li>\n\n\n\n<li>Click &#8220;Create.&#8221;<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Download the JSON File<\/strong>:\n<ul class=\"wp-block-list\">\n<li>After creating the credentials, you will see a section with your newly created OAuth 2.0 Client ID.<\/li>\n\n\n\n<li>Click the &#8220;Download&#8221; button to download the JSON file containing your client secrets.<\/li>\n\n\n\n<li>Rename this file to <code>credentials.json<\/code> and place it in the same directory as your script or specify the correct path in your script.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">Code<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">import os\nimport pickle\nimport base64\nfrom google_auth_oauthlib.flow import InstalledAppFlow\nfrom googleapiclient.discovery import build\nfrom googleapiclient.errors import HttpError\nfrom google.auth.transport.requests import Request\nimport requests\nfrom bs4 import BeautifulSoup\nimport logging\nimport csv\nimport pandas as pd\nfrom email.mime.text import MIMEText\n\nlogging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')\n\n# If modifying these SCOPES, delete the file token.pickle.\nSCOPES = ['https:\/\/www.googleapis.com\/auth\/gmail.send']\n\ndef get_credentials():\n    creds = None\n    if os.path.exists('\/home\/shared\/algos\/monitor_court_case\/token.pickle'):\n        with open('\/home\/shared\/algos\/monitor_court_case\/token.pickle', 'rb') as token:\n            creds = pickle.load(token)\n    if not creds or not creds.valid:\n        if creds and creds.expired and creds.refresh_token:\n            try:\n                creds.refresh(Request())\n            except Exception as e:\n                if os.path.exists('\/home\/shared\/algos\/monitor_court_case\/token.pickle'):\n                    os.remove('\/home\/shared\/algos\/monitor_court_case\/token.pickle')\n                flow = InstalledAppFlow.from_client_secrets_file('credentials.json', SCOPES)\n                creds = flow.run_local_server(port=0)\n        else:\n            flow = InstalledAppFlow.from_client_secrets_file('credentials.json', SCOPES)\n            creds = flow.run_local_server(port=0)\n        with open('\/home\/shared\/algos\/monitor_court_case\/token.pickle', 'wb') as token:\n            pickle.dump(creds, token)\n    return creds\n\n\ndef send_email(subject, body, recipients):\n    creds = get_credentials()\n    service = build('gmail', 'v1', credentials=creds)\n\n    to_addresses = \", \".join(recipients)\n    message = {\n        'raw': base64.urlsafe_b64encode(\n            f\"From: me\\nTo: {to_addresses}\\nSubject: {subject}\\nContent-Type: text\/html; charset=UTF-8\\n\\n{body}\".encode(\n                \"utf-8\")).decode(\"utf-8\")\n    }\n\n    try:\n        message = (service.users().messages().send(userId=\"me\", body=message).execute())\n        logging.info(f\"Message Id: {message['id']}\")\n        return message\n    except HttpError as error:\n        logging.error(f'An error occurred: {error}')\n        return None\n\ndef create_html_table(df):\n    return df.to_html(index=False)\n\ndef fetch_webpage(url):\n    response = requests.get(url)\n    response.raise_for_status()\n    soup = BeautifulSoup(response.content, 'html.parser')\n    return soup\n\ndef parse_case_information(soup):\n    div = soup.find('div', id='tblForms')\n    rows = []\n    if div:\n        headers = [\"Case Number\", \"Judge\", \"File Date\", \"Location\", \"Case Type\"]\n        rows.append(headers)\n        case_info = {}\n        data_divs = div.find_all('div', class_='row g-0 py-0')\n        for data_div in data_divs:\n            key_elements = data_div.find_all('div', class_='col-4 col-lg-3 bold-font')\n            value_elements = data_div.find_all('div', class_='col-8 col-lg-3')\n            for key_elem, value_elem in zip(key_elements, value_elements):\n                key = key_elem.get_text(strip=True).replace(':', '')\n                value = value_elem.get_text(strip=True)\n                case_info[key] = value\n        rows.append([\n            case_info.get(\"Case Number\", \"\"),\n            case_info.get(\"Judge\", \"\"),\n            case_info.get(\"File Date\", \"\"),\n            case_info.get(\"Location\", \"\"),\n            case_info.get(\"Case Type\", \"\")\n        ])\n    return rows\n\ndef parse_party_information(soup):\n    div = soup.find('div', class_='zebraRowTable grid-um')\n    rows = []\n    if div:\n        headers = [\"Party Name\", \"Relationship\", \"Sex\", \"Attorney\"]\n        rows.append(headers)\n        data_divs = div.find_all('div', class_='row g-0 pt-3 pb-3', id='tblForms2')\n        for data_div in data_divs:\n            party_name = data_div.find('div', class_='col-8 col-lg-4').get_text(strip=True)\n            relationship = data_div.find('div', class_='col-8 col-lg-3').get_text(strip=True)\n            sex = data_div.find('div', class_='col-8 col-lg-2').get_text(strip=True)\n            attorney = data_div.find('div', class_='col-8 col-lg-3').get_text(strip=True)\n            cols = [party_name, relationship, sex, attorney]\n            logging.debug(f\"Parsed row: {cols}\")\n            rows.append(cols)\n    return rows\n\ndef parse_case_documents(soup):\n    div = soup.find('div', id='tblForms3')\n    rows = []\n    if div:\n        headers = [\"Filing Date\", \"Description\", \"Docket Date\", \"Filing Party\", \"Note\"]\n        rows.append(headers)\n        data_divs = div.find_all('div', class_='row g-0')\n        for data_div in data_divs:\n            cols = [col.get_text(strip=True) for col in\n                    data_div.find_all('div', class_=['col-lg-2', 'col-lg-5', 'col-lg-3'])]\n\n            note_text = \"\"\n            note_div = data_div.find('div', class_='col-8 pl-3 emphasis')\n            if note_div:\n                note_text = note_div.get_text(strip=True).replace(\"NOTE:\", \"\").strip()\n\n            if len(cols) >= 5:\n                cols[4] = note_text  # Update the existing 5th column (Note)\n            else:\n                cols.append(note_text)  # Append note text if columns are less than 5\n\n            if any(cols):\n                rows.append(cols)\n    return rows\n\ndef parse_case_calendar(soup):\n    div = soup.find('div', id='tblForms4')\n    rows = []\n    if div:\n        headers = [\"Date\", \"Time\", \"Event\"]\n        rows.append(headers)\n        data_divs = div.find_all('div', class_='row g-0')\n        current_row = []\n        for data_div in data_divs:\n            cols = [col.get_text(strip=True) for col in data_div.find_all('div', class_=['col-lg-2', 'col-lg-8'])]\n            if cols:\n                current_row.extend(cols)\n                if len(current_row) == 3:\n                    rows.append(current_row)\n                    current_row = []\n    return rows\n\ndef save_table_to_csv(table, csv_filename):\n    if table:\n        with open(csv_filename, 'w', newline='') as csvfile:\n            writer = csv.writer(csvfile)\n            for row in table:\n                writer.writerow(row)\n        logging.info(f\"Table saved to {csv_filename}\")\n    else:\n        logging.warning(f\"No data found to save in {csv_filename}\")\n\n\ndef compare_dates_and_save_table(new_table, csv_filename, date_column, recipients):\n    if not os.path.exists(csv_filename):\n        logging.info(f\"{csv_filename} does not exist. Creating new file.\")\n        save_table_to_csv(new_table, csv_filename)\n        return\n\n    old_table_df = pd.read_csv(csv_filename)\n    new_table_df = pd.DataFrame(new_table[1:], columns=new_table[0])\n\n    old_dates = set(old_table_df[date_column])\n    new_dates = set(new_table_df[date_column])\n\n    new_rows = new_table_df[new_table_df[date_column].isin(new_dates - old_dates)]\n\n    if not new_rows.empty:\n        logging.info(f\"Changes detected in {csv_filename}. Updating file.\")\n        logging.info(f'Here are the new rows \\n {new_rows} \\n Here is the new table \\n {new_table_df}')\n        logging.info(f\"New rows:\\n{new_rows.to_string(index=False)}\")\n        html_table = create_html_table(new_rows)\n        email_body = f\"\"\"\n        &lt;h2>Changes detected in court case {case_number}&lt;\/h2>\n        {html_table}\n        \"\"\"\n        send_email(f\"Changes detected in court case {case_number}\", email_body, recipients)\n        save_table_to_csv(new_table, csv_filename)\n    else:\n        logging.info(f\"No changes detected in {csv_filename}\")\n\n\nif __name__ == \"__main__\":\n    case_number = 'FN2020-096853'\n    url = f\"https:\/\/www.superiorcourt.maricopa.gov\/docket\/FamilyCourtCases\/caseInfo.asp?caseNumber={case_number}\"\n\n    data_dir = '.\/data'\n    os.makedirs(data_dir, exist_ok=True)\n\n    recipients = ['email@email.com', 'email@email.com', 'email@email.com']  # Add the recipient email addresses here\n\n    soup = fetch_webpage(url)\n\n    case_information_table = parse_case_information(soup)\n    party_information_table = parse_party_information(soup)\n    case_documents_table = parse_case_documents(soup)\n    case_calendar_table = parse_case_calendar(soup)\n\n    save_table_to_csv(case_information_table, os.path.join(data_dir, f\"\/home\/shared\/algos\/monitor_court_case\/data\/{case_number}_case_information.csv\"))\n    save_table_to_csv(party_information_table, os.path.join(data_dir, f\"\/home\/shared\/algos\/monitor_court_case\/data\/{case_number}_party_information.csv\"))\n    compare_dates_and_save_table(case_documents_table, os.path.join(data_dir, f\"\/home\/shared\/algos\/monitor_court_case\/data\/{case_number}_case_documents.csv\"), \"Filing Date\", recipients)\n    compare_dates_and_save_table(case_calendar_table, os.path.join(data_dir, f\"\/home\/shared\/algos\/monitor_court_case\/data\/{case_number}_case_calendar.csv\"), \"Date\", recipients)<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Recently, I needed real-time updates for a court case affecting a house I was purchasing. Instead of constantly checking the case manually, I wrote a Python script to&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-7737","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.2 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Automating notification updates on court cases for Maricopa County Superior Court - Jeremy Whittaker<\/title>\n<meta name=\"robots\" content=\"noindex, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Automating notification updates on court cases for Maricopa County Superior Court - Jeremy Whittaker\" \/>\n<meta property=\"og:description\" content=\"Recently, I needed real-time updates for a court case affecting a house I was purchasing. Instead of constantly checking the case manually, I wrote a Python script to...\" \/>\n<meta property=\"og:url\" content=\"https:\/\/new.jeremywhittaker.com\/index.php\/2024\/05\/28\/automating-notification-updates-on-court-cases-for-maricopa-county-superior-court\/\" \/>\n<meta property=\"og:site_name\" content=\"Jeremy Whittaker\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/WhittakerJeremy\" \/>\n<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/WhittakerJeremy\" \/>\n<meta property=\"article:published_time\" content=\"2024-05-28T18:55:13+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-05-28T18:58:51+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/new.jeremywhittaker.com\/wp-content\/uploads\/2024\/05\/image-1.png\" \/>\n<meta name=\"author\" content=\"JeremyWhittaker\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"JeremyWhittaker\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"2 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/new.jeremywhittaker.com\/index.php\/2024\/05\/28\/automating-notification-updates-on-court-cases-for-maricopa-county-superior-court\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/new.jeremywhittaker.com\/index.php\/2024\/05\/28\/automating-notification-updates-on-court-cases-for-maricopa-county-superior-court\/\"},\"author\":{\"name\":\"JeremyWhittaker\",\"@id\":\"https:\/\/new.jeremywhittaker.com\/#\/schema\/person\/ed0edfdefb3e180693efef453372980c\"},\"headline\":\"Automating notification updates on court cases for Maricopa County Superior Court\",\"datePublished\":\"2024-05-28T18:55:13+00:00\",\"dateModified\":\"2024-05-28T18:58:51+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/new.jeremywhittaker.com\/index.php\/2024\/05\/28\/automating-notification-updates-on-court-cases-for-maricopa-county-superior-court\/\"},\"wordCount\":333,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/new.jeremywhittaker.com\/#\/schema\/person\/ed0edfdefb3e180693efef453372980c\"},\"image\":{\"@id\":\"https:\/\/new.jeremywhittaker.com\/index.php\/2024\/05\/28\/automating-notification-updates-on-court-cases-for-maricopa-county-superior-court\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/new.jeremywhittaker.com\/wp-content\/uploads\/2024\/05\/image-1.png\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/new.jeremywhittaker.com\/index.php\/2024\/05\/28\/automating-notification-updates-on-court-cases-for-maricopa-county-superior-court\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/new.jeremywhittaker.com\/index.php\/2024\/05\/28\/automating-notification-updates-on-court-cases-for-maricopa-county-superior-court\/\",\"url\":\"https:\/\/new.jeremywhittaker.com\/index.php\/2024\/05\/28\/automating-notification-updates-on-court-cases-for-maricopa-county-superior-court\/\",\"name\":\"Automating notification updates on court cases for Maricopa County Superior Court - Jeremy Whittaker\",\"isPartOf\":{\"@id\":\"https:\/\/new.jeremywhittaker.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/new.jeremywhittaker.com\/index.php\/2024\/05\/28\/automating-notification-updates-on-court-cases-for-maricopa-county-superior-court\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/new.jeremywhittaker.com\/index.php\/2024\/05\/28\/automating-notification-updates-on-court-cases-for-maricopa-county-superior-court\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/new.jeremywhittaker.com\/wp-content\/uploads\/2024\/05\/image-1.png\",\"datePublished\":\"2024-05-28T18:55:13+00:00\",\"dateModified\":\"2024-05-28T18:58:51+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/new.jeremywhittaker.com\/index.php\/2024\/05\/28\/automating-notification-updates-on-court-cases-for-maricopa-county-superior-court\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/new.jeremywhittaker.com\/index.php\/2024\/05\/28\/automating-notification-updates-on-court-cases-for-maricopa-county-superior-court\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/new.jeremywhittaker.com\/index.php\/2024\/05\/28\/automating-notification-updates-on-court-cases-for-maricopa-county-superior-court\/#primaryimage\",\"url\":\"https:\/\/new.jeremywhittaker.com\/wp-content\/uploads\/2024\/05\/image-1.png\",\"contentUrl\":\"https:\/\/new.jeremywhittaker.com\/wp-content\/uploads\/2024\/05\/image-1.png\",\"width\":752,\"height\":393},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/new.jeremywhittaker.com\/index.php\/2024\/05\/28\/automating-notification-updates-on-court-cases-for-maricopa-county-superior-court\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/new.jeremywhittaker.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Automating notification updates on court cases for Maricopa County Superior Court\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/new.jeremywhittaker.com\/#website\",\"url\":\"https:\/\/new.jeremywhittaker.com\/\",\"name\":\"Jeremy Whittaker\",\"description\":\"Research, software, markets, housing, and energy\",\"publisher\":{\"@id\":\"https:\/\/new.jeremywhittaker.com\/#\/schema\/person\/ed0edfdefb3e180693efef453372980c\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/new.jeremywhittaker.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/new.jeremywhittaker.com\/#\/schema\/person\/ed0edfdefb3e180693efef453372980c\",\"name\":\"JeremyWhittaker\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/secure.gravatar.com\/avatar\/c8ac20e6dfa86b5f27ce9bffee4851099770cbea5ae7338a274865bfbc8c0218?s=96&d=retro&r=g\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/c8ac20e6dfa86b5f27ce9bffee4851099770cbea5ae7338a274865bfbc8c0218?s=96&d=retro&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/c8ac20e6dfa86b5f27ce9bffee4851099770cbea5ae7338a274865bfbc8c0218?s=96&d=retro&r=g\",\"caption\":\"JeremyWhittaker\"},\"logo\":{\"@id\":\"https:\/\/secure.gravatar.com\/avatar\/c8ac20e6dfa86b5f27ce9bffee4851099770cbea5ae7338a274865bfbc8c0218?s=96&d=retro&r=g\"},\"sameAs\":[\"http:\/\/www.jeremywhittaker.com\",\"https:\/\/www.facebook.com\/WhittakerJeremy\",\"https:\/\/www.linkedin.com\/in\/jeremywhittaker\/\"],\"url\":\"https:\/\/new.jeremywhittaker.com\/index.php\/author\/jeremywhittaker\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Automating notification updates on court cases for Maricopa County Superior Court - Jeremy Whittaker","robots":{"index":"noindex","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"og_locale":"en_US","og_type":"article","og_title":"Automating notification updates on court cases for Maricopa County Superior Court - Jeremy Whittaker","og_description":"Recently, I needed real-time updates for a court case affecting a house I was purchasing. Instead of constantly checking the case manually, I wrote a Python script to...","og_url":"https:\/\/new.jeremywhittaker.com\/index.php\/2024\/05\/28\/automating-notification-updates-on-court-cases-for-maricopa-county-superior-court\/","og_site_name":"Jeremy Whittaker","article_publisher":"https:\/\/www.facebook.com\/WhittakerJeremy","article_author":"https:\/\/www.facebook.com\/WhittakerJeremy","article_published_time":"2024-05-28T18:55:13+00:00","article_modified_time":"2024-05-28T18:58:51+00:00","og_image":[{"url":"https:\/\/new.jeremywhittaker.com\/wp-content\/uploads\/2024\/05\/image-1.png","type":"","width":"","height":""}],"author":"JeremyWhittaker","twitter_card":"summary_large_image","twitter_misc":{"Written by":"JeremyWhittaker","Est. reading time":"2 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/new.jeremywhittaker.com\/index.php\/2024\/05\/28\/automating-notification-updates-on-court-cases-for-maricopa-county-superior-court\/#article","isPartOf":{"@id":"https:\/\/new.jeremywhittaker.com\/index.php\/2024\/05\/28\/automating-notification-updates-on-court-cases-for-maricopa-county-superior-court\/"},"author":{"name":"JeremyWhittaker","@id":"https:\/\/new.jeremywhittaker.com\/#\/schema\/person\/ed0edfdefb3e180693efef453372980c"},"headline":"Automating notification updates on court cases for Maricopa County Superior Court","datePublished":"2024-05-28T18:55:13+00:00","dateModified":"2024-05-28T18:58:51+00:00","mainEntityOfPage":{"@id":"https:\/\/new.jeremywhittaker.com\/index.php\/2024\/05\/28\/automating-notification-updates-on-court-cases-for-maricopa-county-superior-court\/"},"wordCount":333,"commentCount":0,"publisher":{"@id":"https:\/\/new.jeremywhittaker.com\/#\/schema\/person\/ed0edfdefb3e180693efef453372980c"},"image":{"@id":"https:\/\/new.jeremywhittaker.com\/index.php\/2024\/05\/28\/automating-notification-updates-on-court-cases-for-maricopa-county-superior-court\/#primaryimage"},"thumbnailUrl":"https:\/\/new.jeremywhittaker.com\/wp-content\/uploads\/2024\/05\/image-1.png","inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/new.jeremywhittaker.com\/index.php\/2024\/05\/28\/automating-notification-updates-on-court-cases-for-maricopa-county-superior-court\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/new.jeremywhittaker.com\/index.php\/2024\/05\/28\/automating-notification-updates-on-court-cases-for-maricopa-county-superior-court\/","url":"https:\/\/new.jeremywhittaker.com\/index.php\/2024\/05\/28\/automating-notification-updates-on-court-cases-for-maricopa-county-superior-court\/","name":"Automating notification updates on court cases for Maricopa County Superior Court - Jeremy Whittaker","isPartOf":{"@id":"https:\/\/new.jeremywhittaker.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/new.jeremywhittaker.com\/index.php\/2024\/05\/28\/automating-notification-updates-on-court-cases-for-maricopa-county-superior-court\/#primaryimage"},"image":{"@id":"https:\/\/new.jeremywhittaker.com\/index.php\/2024\/05\/28\/automating-notification-updates-on-court-cases-for-maricopa-county-superior-court\/#primaryimage"},"thumbnailUrl":"https:\/\/new.jeremywhittaker.com\/wp-content\/uploads\/2024\/05\/image-1.png","datePublished":"2024-05-28T18:55:13+00:00","dateModified":"2024-05-28T18:58:51+00:00","breadcrumb":{"@id":"https:\/\/new.jeremywhittaker.com\/index.php\/2024\/05\/28\/automating-notification-updates-on-court-cases-for-maricopa-county-superior-court\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/new.jeremywhittaker.com\/index.php\/2024\/05\/28\/automating-notification-updates-on-court-cases-for-maricopa-county-superior-court\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/new.jeremywhittaker.com\/index.php\/2024\/05\/28\/automating-notification-updates-on-court-cases-for-maricopa-county-superior-court\/#primaryimage","url":"https:\/\/new.jeremywhittaker.com\/wp-content\/uploads\/2024\/05\/image-1.png","contentUrl":"https:\/\/new.jeremywhittaker.com\/wp-content\/uploads\/2024\/05\/image-1.png","width":752,"height":393},{"@type":"BreadcrumbList","@id":"https:\/\/new.jeremywhittaker.com\/index.php\/2024\/05\/28\/automating-notification-updates-on-court-cases-for-maricopa-county-superior-court\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/new.jeremywhittaker.com\/"},{"@type":"ListItem","position":2,"name":"Automating notification updates on court cases for Maricopa County Superior Court"}]},{"@type":"WebSite","@id":"https:\/\/new.jeremywhittaker.com\/#website","url":"https:\/\/new.jeremywhittaker.com\/","name":"Jeremy Whittaker","description":"Research, software, markets, housing, and energy","publisher":{"@id":"https:\/\/new.jeremywhittaker.com\/#\/schema\/person\/ed0edfdefb3e180693efef453372980c"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/new.jeremywhittaker.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/new.jeremywhittaker.com\/#\/schema\/person\/ed0edfdefb3e180693efef453372980c","name":"JeremyWhittaker","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/c8ac20e6dfa86b5f27ce9bffee4851099770cbea5ae7338a274865bfbc8c0218?s=96&d=retro&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/c8ac20e6dfa86b5f27ce9bffee4851099770cbea5ae7338a274865bfbc8c0218?s=96&d=retro&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/c8ac20e6dfa86b5f27ce9bffee4851099770cbea5ae7338a274865bfbc8c0218?s=96&d=retro&r=g","caption":"JeremyWhittaker"},"logo":{"@id":"https:\/\/secure.gravatar.com\/avatar\/c8ac20e6dfa86b5f27ce9bffee4851099770cbea5ae7338a274865bfbc8c0218?s=96&d=retro&r=g"},"sameAs":["http:\/\/www.jeremywhittaker.com","https:\/\/www.facebook.com\/WhittakerJeremy","https:\/\/www.linkedin.com\/in\/jeremywhittaker\/"],"url":"https:\/\/new.jeremywhittaker.com\/index.php\/author\/jeremywhittaker\/"}]}},"_links":{"self":[{"href":"https:\/\/new.jeremywhittaker.com\/index.php\/wp-json\/wp\/v2\/posts\/7737","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/new.jeremywhittaker.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/new.jeremywhittaker.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/new.jeremywhittaker.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/new.jeremywhittaker.com\/index.php\/wp-json\/wp\/v2\/comments?post=7737"}],"version-history":[{"count":7,"href":"https:\/\/new.jeremywhittaker.com\/index.php\/wp-json\/wp\/v2\/posts\/7737\/revisions"}],"predecessor-version":[{"id":7747,"href":"https:\/\/new.jeremywhittaker.com\/index.php\/wp-json\/wp\/v2\/posts\/7737\/revisions\/7747"}],"wp:attachment":[{"href":"https:\/\/new.jeremywhittaker.com\/index.php\/wp-json\/wp\/v2\/media?parent=7737"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/new.jeremywhittaker.com\/index.php\/wp-json\/wp\/v2\/categories?post=7737"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/new.jeremywhittaker.com\/index.php\/wp-json\/wp\/v2\/tags?post=7737"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}