# NC DMV Reservation Tools
> Dealing with DMV is often a frustrating experience. But it doesn't have to be!
Automated availability checking and monitoring for DMV offices across the state of North Carolina, tested to work on Jan 2024.
No feature will be added unless I need it myself. If you need additional features, you're welcome to contribute a PR. :)
https://teddysc.me/blog/ncdmv-reservation
- [NC DMV Reservation Tools](#nc-dmv-reservation-tools)
- [Background](#background)
- [Quick Start](#quick-start)
- [Installation](#installation)
- [Running](#running)
- [How it works](#how-it-works)
- [Continuous Monitoring](#continuous-monitoring)
- [On your local machine](#on-your-local-machine)
- [GitHub Actions](#github-actions)
- [Thoughts](#thoughts)
- [Develop](#develop)
- [Links](#links)
## Background
DMVs within reasonable distance of where I live are always completely booked, so I made this tool to help me spot when someone cancelled their appointment so I could snag it.
Since the tool was made for self-use only, currently it's hard-coded to only checks for the appointment type of `1st time Driver License Test (over 18)`. If you need additional features, you're welcome to contribute a PR. :)
I've used it to spot availability slot twice after running it for a few hours, and secured my reservation. :)
## Quick Start
### Installation
```bash
# install google-chrome / google-chrome-stable, and
# install chromedriver with your favorite package manager and put it in your $PATH
brew install chromedriver
# or sudo pacman -S chromedriver
# python3.12+ required
pipx install ncdmv-reservation
```
### Running
```
$ ncdmv-driver-license-office-availability | jq | tee ncdmv.json
[
{
"is_reservable": true,
"office_name": "Aberdeen",
"street_address": "521 S. Sandhills Blvd., Aberdeen, NC",
"zip_code": "28315"
},
{
"is_reservable": true,
"office_name": "Ahoskie",
"street_address": "242 N.C. 42 W., Ahoskie, NC",
"zip_code": "27910"
},
{
"is_reservable": true,
"office_name": "Albemarle",
"street_address": "611 Concord Road, Albemarle, NC",
"zip_code": "28001"
},
{
"is_reservable": true,
"office_name": "Andrews",
"street_address": "1440 Main St., Andrews, NC",
"zip_code": "28901"
},
{
"is_reservable": true,
"office_name": "Asheboro",
"street_address": "2754 U.S. 220 Business South, Asheboro, NC",
"zip_code": "27205"
},
...
]
```
Filtering for the DMV office you're interested in with `jq`:
```
$ <ncdmv.json jq '.[] | select(.office_name == "Raleigh West") | .is_reservable' -r
false
# so it's completely booked (the `Raleigh West` office)
```
## How it works
`ncdmv-driver-license-office-availability` spins up a chrome instance to click through the very user friendly DMV site, scrap the page, and convert it to structured JSON.
Use the `-H, --no-headless` option to see the chrome instance in action.
## Continuous Monitoring
### On your local machine
I found this approach more convenient for me.
```bash
dmv () {
ncdmv-driver-license-office-availability | jq '.[] | select(.office_name == "Raleigh West") | .is_reservable' -r
}
# replace `say` if you're not on macOS
# you can change the frequency of the check by changing the `sleep` duration
dmv_monitor() {
(while :; do [[ $(dmv) == true ]] && say 'go to dmv and reserve now'; sleep 60; done)&
}
# start monitoring every 60s, in the background
# don't close your terminal tab :)
dmv_monitor
# to stop it, run
# kill %1
# or just close the terminal tab. :)
```
### GitHub Actions
Email notification via sendgrid if the DMV office of your choice is reservable.
[The workflow file](https://gist.github.com/tddschn/a3da8a200f3599b29533e02945264d3f)
## Thoughts
After I wrote this I remembered that I should check GitHub first to see if someone else has already done it.
Fortunately, their solutions are outdated, and I did not reinvent the wheel. :)
## Develop
```
$ git clone https://github.com/tddschn/ncdmv-reservation.git
$ cd ncdmv-reservation
$ poetry install
```
## Links
- Blog post: https://teddysc.me/blog/ncdmv-reservation
- Source code: https://github.com/tddschn/ncdmv-reservation
- PyPI: https://pypi.org/project/ncdmv-reservation/
Raw data
{
"_id": null,
"home_page": "https://github.com/tddschn/ncdmv-reservation",
"name": "ncdmv-reservation",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.12,<4.0",
"maintainer_email": "",
"keywords": "ncdmv",
"author": "Teddy Xinyuan Chen",
"author_email": "45612704+tddschn@users.noreply.github.com",
"download_url": "https://files.pythonhosted.org/packages/8c/64/6add9af1fbb65b65f531d3e69d8db99c51c2b61e3757ec0f44032e766afe/ncdmv_reservation-0.1.8.tar.gz",
"platform": null,
"description": "# NC DMV Reservation Tools\n\n> Dealing with DMV is often a frustrating experience. But it doesn't have to be!\n\nAutomated availability checking and monitoring for DMV offices across the state of North Carolina, tested to work on Jan 2024.\n\nNo feature will be added unless I need it myself. If you need additional features, you're welcome to contribute a PR. :)\n\nhttps://teddysc.me/blog/ncdmv-reservation\n\n- [NC DMV Reservation Tools](#nc-dmv-reservation-tools)\n - [Background](#background)\n - [Quick Start](#quick-start)\n - [Installation](#installation)\n - [Running](#running)\n - [How it works](#how-it-works)\n - [Continuous Monitoring](#continuous-monitoring)\n - [On your local machine](#on-your-local-machine)\n - [GitHub Actions](#github-actions)\n - [Thoughts](#thoughts)\n - [Develop](#develop)\n - [Links](#links)\n\n## Background\n\nDMVs within reasonable distance of where I live are always completely booked, so I made this tool to help me spot when someone cancelled their appointment so I could snag it.\n\nSince the tool was made for self-use only, currently it's hard-coded to only checks for the appointment type of `1st time Driver License Test (over 18)`. If you need additional features, you're welcome to contribute a PR. :)\n\nI've used it to spot availability slot twice after running it for a few hours, and secured my reservation. :)\n\n## Quick Start\n\n### Installation\n\n```bash\n# install google-chrome / google-chrome-stable, and\n# install chromedriver with your favorite package manager and put it in your $PATH\nbrew install chromedriver\n# or sudo pacman -S chromedriver\n\n# python3.12+ required\npipx install ncdmv-reservation\n```\n\n### Running\n\n```\n$ ncdmv-driver-license-office-availability | jq | tee ncdmv.json\n[\n {\n \"is_reservable\": true,\n \"office_name\": \"Aberdeen\",\n \"street_address\": \"521 S. Sandhills Blvd., Aberdeen, NC\",\n \"zip_code\": \"28315\"\n },\n {\n \"is_reservable\": true,\n \"office_name\": \"Ahoskie\",\n \"street_address\": \"242 N.C. 42 W., Ahoskie, NC\",\n \"zip_code\": \"27910\"\n },\n {\n \"is_reservable\": true,\n \"office_name\": \"Albemarle\",\n \"street_address\": \"611 Concord Road, Albemarle, NC\",\n \"zip_code\": \"28001\"\n },\n {\n \"is_reservable\": true,\n \"office_name\": \"Andrews\",\n \"street_address\": \"1440 Main St., Andrews, NC\",\n \"zip_code\": \"28901\"\n },\n {\n \"is_reservable\": true,\n \"office_name\": \"Asheboro\",\n \"street_address\": \"2754 U.S. 220 Business South, Asheboro, NC\",\n \"zip_code\": \"27205\"\n },\n ...\n]\n```\n\nFiltering for the DMV office you're interested in with `jq`:\n\n```\n$ <ncdmv.json jq '.[] | select(.office_name == \"Raleigh West\") | .is_reservable' -r\nfalse\n# so it's completely booked (the `Raleigh West` office)\n```\n\n\n\n## How it works\n\n`ncdmv-driver-license-office-availability` spins up a chrome instance to click through the very user friendly DMV site, scrap the page, and convert it to structured JSON.\n\nUse the `-H, --no-headless` option to see the chrome instance in action.\n\n\n## Continuous Monitoring\n\n### On your local machine\n\nI found this approach more convenient for me.\n\n```bash\ndmv () {\n\tncdmv-driver-license-office-availability | jq '.[] | select(.office_name == \"Raleigh West\") | .is_reservable' -r\n\n}\n\n# replace `say` if you're not on macOS\n# you can change the frequency of the check by changing the `sleep` duration\ndmv_monitor() {\n\t(while :; do [[ $(dmv) == true ]] && say 'go to dmv and reserve now'; sleep 60; done)&\n}\n\n# start monitoring every 60s, in the background\n# don't close your terminal tab :)\ndmv_monitor\n\n# to stop it, run\n# kill %1\n# or just close the terminal tab. :)\n```\n\n### GitHub Actions\n\nEmail notification via sendgrid if the DMV office of your choice is reservable.\n\n[The workflow file](https://gist.github.com/tddschn/a3da8a200f3599b29533e02945264d3f)\n\n\n\n\n## Thoughts\n\nAfter I wrote this I remembered that I should check GitHub first to see if someone else has already done it. \n\nFortunately, their solutions are outdated, and I did not reinvent the wheel. :)\n\n\n## Develop\n\n```\n$ git clone https://github.com/tddschn/ncdmv-reservation.git\n$ cd ncdmv-reservation\n$ poetry install\n```\n\n## Links\n\n- Blog post: https://teddysc.me/blog/ncdmv-reservation\n- Source code: https://github.com/tddschn/ncdmv-reservation\n- PyPI: https://pypi.org/project/ncdmv-reservation/\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "",
"version": "0.1.8",
"project_urls": {
"Bug Tracker": "https://github.com/tddschn/ncdmv-reservation/issues",
"Homepage": "https://github.com/tddschn/ncdmv-reservation",
"Repository": "https://github.com/tddschn/ncdmv-reservation"
},
"split_keywords": [
"ncdmv"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "d898459c308d2028ec3a2986845382ad7a23a2ddfdc70b0bb3e2c0d6c28585d9",
"md5": "6c1bfca6bd8c131c4bfd88eefcc99eea",
"sha256": "bd081dbe5ec5c1c1dfda292346ef34a96d80c123436794cb89b45897e6201b45"
},
"downloads": -1,
"filename": "ncdmv_reservation-0.1.8-py3-none-any.whl",
"has_sig": false,
"md5_digest": "6c1bfca6bd8c131c4bfd88eefcc99eea",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.12,<4.0",
"size": 5505,
"upload_time": "2024-01-05T18:41:36",
"upload_time_iso_8601": "2024-01-05T18:41:36.160613Z",
"url": "https://files.pythonhosted.org/packages/d8/98/459c308d2028ec3a2986845382ad7a23a2ddfdc70b0bb3e2c0d6c28585d9/ncdmv_reservation-0.1.8-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "8c646add9af1fbb65b65f531d3e69d8db99c51c2b61e3757ec0f44032e766afe",
"md5": "2712146244f5a899eecd4c89bee95530",
"sha256": "4e733bedfec5104a6396c39e2b453cb3a3799a64566763b7fda65441f916139b"
},
"downloads": -1,
"filename": "ncdmv_reservation-0.1.8.tar.gz",
"has_sig": false,
"md5_digest": "2712146244f5a899eecd4c89bee95530",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.12,<4.0",
"size": 4639,
"upload_time": "2024-01-05T18:41:37",
"upload_time_iso_8601": "2024-01-05T18:41:37.064022Z",
"url": "https://files.pythonhosted.org/packages/8c/64/6add9af1fbb65b65f531d3e69d8db99c51c2b61e3757ec0f44032e766afe/ncdmv_reservation-0.1.8.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-01-05 18:41:37",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "tddschn",
"github_project": "ncdmv-reservation",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "ncdmv-reservation"
}