{ "info": { "author": "Nolan Conaway", "author_email": "nolanbconaway@gmail.com", "bugtrack_url": null, "classifiers": [ "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7" ], "description": "# Python MTA Utilities\n\n[![GitHub Actions status](https://github.com/nolanbconaway/underground/workflows/Main%20Workflow/badge.svg)](https://github.com/nolanbconaway/underground/actions)\n[![codecov](https://codecov.io/gh/nolanbconaway/underground/branch/master/graph/badge.svg)](https://codecov.io/gh/nolanbconaway/underground)\n[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/underground)](https://pypi.org/project/underground/)\n[![PyPI](https://img.shields.io/pypi/v/underground)](https://pypi.org/project/underground/)\n\nThis is a set of Python utilities that I use to deal with [real-time NYC subway data](https://datamine.mta.info/).\n\nI usually want to know when trains are going to depart a specific stop along a specific train line, so right now the tools are mostly for that. But I tried to write them to support arbitrary functionality.\n\n## Install\n\n``` sh\npip install underground\n```\n\nOr if you'd like to live dangerously:\n\n``` sh\npip install git+https://github.com/nolanbconaway/underground.git#egg=underground\n```\n\nTo request data from the MTA, you'll also need a free API key.\n[Register here](https://datamine.mta.info/user/register).\n\n## Python API\n\nOnce you have your API key, use the Python API like:\n\n``` python\nimport os\n\nfrom underground import metadata, SubwayFeed\n\nAPI_KEY = os.getenv('MTA_API_KEY')\nROUTE = 'Q'\n\n# get feed id for the Q train route\nFEED_ID = metadata.get_feed_id(ROUTE)\n\n# request and serialize the feed data.\nfeed = SubwayFeed.get(FEED_ID, api_key=API_KEY)\n\n# request will automatically try to read from $MTA_API_KEY if a key is not provided,\n# so this also works:\nfeed = SubwayFeed.get(FEED_ID)\n\n# extract train stops on each line\nq_train_stops = feed.extract_stop_dict()[ROUTE]\n```\n\n`feed.extract_stop_dict` will return a dictionary of dictionaries, like:\n\n {\n\n \"route_1\": {\n \"stop_1\": [datetime.datetime(...), datetime.datetime(...)], \n \"stop_2\": [datetime.datetime(...), datetime.datetime(...)], \n ...\n }, \n \"route_2\": {\n \"stop_1\": [datetime.datetime(...), datetime.datetime(...)], \n \"stop_2\": [datetime.datetime(...), datetime.datetime(...)], \n ...\n }\n\n }\n\n> Note: future functionality to be written around the `SubwayFeed` class.\n\n## CLI\n\nThe `underground` command line tool is also installed with the package.\n\n $ underground --help\n Usage: underground [OPTIONS] COMMAND [ARGS]...\n\n Command line handlers for MTA realtime data.\n\n Options:\n\n --help Show this message and exit.\n\n feed Request an MTA feed.\n findstops Find your stop ID.\n stops Print out train departure times for all stops on a subway line.\n\n### `feed` \n\n $ underground feed --help\n Usage: underground feed [OPTIONS] [1|2|36|11|16|51|21|26|31]\n\n Request an MTA feed.\n\n Options:\n\n --api-key TEXT MTA API key. Will be read from $MTA_API_KEY if not\n provided.\n --json Option to output the feed data as JSON. Otherwise\n output will be bytes.\n -r, --retries INTEGER Retry attempts in case of API connection failure.\n Default 100.\n --help Show this message and exit.\n\nUse it like\n\n $ export MTA_API_KEY='...'\n $ underground feed 16 --json > feed_16.json\n\n### `stops` \n\n $ underground stops --help\n Usage: underground stops [OPTIONS] [H|M|D|1|Z|A|N|GS|SI|J|G|Q|L|B|R|F|E|2|7|W|\n 6|4|C|5|FS]\n \n Print out train departure times for all stops on a subway line.\n\n Options:\n\n -f, --format TEXT strftime format for stop times. Use `epoch` for a\n unix timestamp.\n -r, --retries INTEGER Retry attempts in case of API connection failure.\n Default 100.\n --api-key TEXT MTA API key. Will be read from $MTA_API_KEY if not\n provided.\n -t, --timezone TEXT Output timezone. Ignored if --epoch. Default to NYC\n time.\n --help Show this message and exit.\n\nStops are printed to stdout in the format `stop_id t1 t2 ... tn` .\n\n``` sh\n$ export MTA_API_KEY='...'\n$ underground stops Q | tail -2\nQ05S 19:01 19:09 19:16 19:25 19:34 19:44 19:51 19:58\nQ04S 19:03 19:11 19:18 19:27 19:36 19:46 19:53 20:00\n```\n\nIf you know your stop id (stop IDs can be found in [stops.txt](http://web.mta.info/developers/data/nyct/subway/google_transit.zip)), you can grep the results:\n\n``` sh\n$ underground stops Q | grep Q05S\nQ05S 19:09 19:16 19:25 19:34 19:44 19:51 19:58\n```\n\nIf you don't know your stop, see below for a handy tool!\n\n### `findstops` \n\n $ underground findstops --help\n Usage: underground findstops [OPTIONS] QUERY...\n\n Find your stop ID.\n\n Query a location and look for your stop ID, like:\n\n $ underground findstops parkside av\n\n Options:\n\n --json Option to output the data as JSON. Otherwise will be human readable\n table.\n\n --help Show this message and exit.\n\nEnter the name of your stop and a table of stops with matching names will be returned.\n\n $ underground findstops parkside\n ID: D27N Direction: NORTH Lat/Lon: 40.655292, -73.961495 Name: PARKSIDE AV\n ID: D27S Direction: SOUTH Lat/Lon: 40.655292, -73.961495 Name: PARKSIDE AV\n\nSome names are ambiguous (try \"fulton st\"), for these you'll have to dig into the [metadata](http://web.mta.info/developers/data/nyct/subway/google_transit.zip) more carefully.\n\n## Todo\n\nNone of this is particularly important, I am happy with the API at the moment.\n\n* [ ] Better exception printing from click.\n* [ ] Pypi?\n* [ ] Markdown auto format. Check as a part of the build process.\n* [x] Add some tooling to make finding your stop easier.\n* [ ] Add method to SubwayFeed which counts trains per line/direction.\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/nolanbconaway/underground", "keywords": "nyc,transit,subway,command-line", "license": "MIT", "maintainer": "Nolan Conaway", "maintainer_email": "nolanbconaway@gmail.com", "name": "underground", "package_url": "https://pypi.org/project/underground/", "platform": "", "project_url": "https://pypi.org/project/underground/", "project_urls": { "Homepage": "https://github.com/nolanbconaway/underground", "Repository": "https://github.com/nolanbconaway/underground" }, "release_url": "https://pypi.org/project/underground/0.2.7.3/", "requires_dist": [ "requests (>=2.22,<3.0)", "google (>=2.0,<3.0)", "gtfs-realtime-bindings (>=0.0.6,<0.0.7)", "protobuf3-to-dict (>=0.1.5,<0.2.0)", "click (>=7.0,<8.0)", "pydantic (>=0.31.1,<0.32.0)", "pytz (>=2019.2,<2020.0)" ], "requires_python": ">=3.6,<4.0", "summary": "Utilities for NYC's realtime MTA data feeds.", "version": "0.2.7.3" }, "last_serial": 5932848, "releases": { "0.2.7": [ { "comment_text": "", "digests": { "md5": "c4cf4ad0d57977c410afa8dad519d61b", "sha256": "f564980236c1a2b495dbb80426638b08ad7a2583a632593e23b65c771b21e500" }, "downloads": -1, "filename": "underground-0.2.7-py3-none-any.whl", "has_sig": false, "md5_digest": "c4cf4ad0d57977c410afa8dad519d61b", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6,<4.0", "size": 10623, "upload_time": "2019-10-05T17:42:04", "url": "https://files.pythonhosted.org/packages/69/60/dcd75ca299f4373d355c1dbee4fe24ea1d73270abc19c3ade9a1afec695f/underground-0.2.7-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "45fb09c2dd065c1e922cdc7504b26df5", "sha256": "d2f4fae66b33f6d37263684961afc6f50006f2fb2340219e82bf2531cec7a5b7" }, "downloads": -1, "filename": "underground-0.2.7.tar.gz", "has_sig": false, "md5_digest": "45fb09c2dd065c1e922cdc7504b26df5", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6,<4.0", "size": 7606, "upload_time": "2019-10-05T17:42:06", "url": "https://files.pythonhosted.org/packages/b2/76/b1cb972bca1080f383bc1ae9a28ae67d8ce38820071d7b48eeafb1e8d190/underground-0.2.7.tar.gz" } ], "0.2.7.1": [ { "comment_text": "", "digests": { "md5": "5dbdb0e1fc8b190428340e7be382b750", "sha256": "9626badcdb88bace22b6be14fa9f4ec7fa4669a106b90f98d4ae06f7b817d5fa" }, "downloads": -1, "filename": "underground-0.2.7.1-py3-none-any.whl", "has_sig": false, "md5_digest": "5dbdb0e1fc8b190428340e7be382b750", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6,<4.0", "size": 12913, "upload_time": "2019-10-05T18:01:59", "url": "https://files.pythonhosted.org/packages/0b/56/bc2423f9e379a94c16127a897dca586d5bd1ec85412e34f03435480d10ed/underground-0.2.7.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "f2269a031757445fd9451e9f717765c9", "sha256": "1f4c8f2889f1999aaf15b069078baa9ae1ac13ea2b170dbf2b82890a588d8c72" }, "downloads": -1, "filename": "underground-0.2.7.1.tar.gz", "has_sig": false, "md5_digest": "f2269a031757445fd9451e9f717765c9", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6,<4.0", "size": 11835, "upload_time": "2019-10-05T18:02:08", "url": "https://files.pythonhosted.org/packages/ab/bf/2fc5f2dff84e74893ccae4a4bca0e2cdcc7c1b52407c772b0f90fb6928c8/underground-0.2.7.1.tar.gz" } ], "0.2.7.2": [ { "comment_text": "", "digests": { "md5": "c1c0d83afdfc00b2a38424522e001c51", "sha256": "196299a9286c00d3b117997c6daa3ec50b7e5b19cceec2f5493636e3607bad84" }, "downloads": -1, "filename": "underground-0.2.7.2-py3-none-any.whl", "has_sig": false, "md5_digest": "c1c0d83afdfc00b2a38424522e001c51", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6,<4.0", "size": 12882, "upload_time": "2019-10-05T18:04:31", "url": "https://files.pythonhosted.org/packages/7f/38/582f61798a1531df38a10f5087872afe356d8b4e7f1482589ee50492ce80/underground-0.2.7.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "9d67ddc7d8b898b8451ba90d4f599cee", "sha256": "ac77214ae6defc1810cc34e165c59e3be5e9de610c33a423751727dc539b6478" }, "downloads": -1, "filename": "underground-0.2.7.2.tar.gz", "has_sig": false, "md5_digest": "9d67ddc7d8b898b8451ba90d4f599cee", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6,<4.0", "size": 11789, "upload_time": "2019-10-05T18:04:41", "url": "https://files.pythonhosted.org/packages/40/88/f4f0c05fc262ac92653aefa75faefb357c674a15244619f95e7d8c41c080/underground-0.2.7.2.tar.gz" } ], "0.2.7.3": [ { "comment_text": "", "digests": { "md5": "1a54009cb9692aeeff3cabc3fbb9ed36", "sha256": "bd89e062fd1d2be113da9d824e7293088ff4c41497c55b6f7cdb38f1ec25d5b4" }, "downloads": -1, "filename": "underground-0.2.7.3-py3-none-any.whl", "has_sig": false, "md5_digest": "1a54009cb9692aeeff3cabc3fbb9ed36", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6,<4.0", "size": 12942, "upload_time": "2019-10-05T18:51:28", "url": "https://files.pythonhosted.org/packages/c1/d1/a54b06d392a18a22e0836a488c8e776d521ebd4a36622845e76a368a0f8f/underground-0.2.7.3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "951ec712254039be669fa19dd1a4e6af", "sha256": "3771e918c68eca5665ed78b641f793fc457e4fa2843f282a3e32634744fe4154" }, "downloads": -1, "filename": "underground-0.2.7.3.tar.gz", "has_sig": false, "md5_digest": "951ec712254039be669fa19dd1a4e6af", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6,<4.0", "size": 11791, "upload_time": "2019-10-05T18:51:30", "url": "https://files.pythonhosted.org/packages/53/ae/330dd9279e087b3556a3da6b059ad03e5e61434fb4cb3fe58b421c2fe476/underground-0.2.7.3.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "1a54009cb9692aeeff3cabc3fbb9ed36", "sha256": "bd89e062fd1d2be113da9d824e7293088ff4c41497c55b6f7cdb38f1ec25d5b4" }, "downloads": -1, "filename": "underground-0.2.7.3-py3-none-any.whl", "has_sig": false, "md5_digest": "1a54009cb9692aeeff3cabc3fbb9ed36", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6,<4.0", "size": 12942, "upload_time": "2019-10-05T18:51:28", "url": "https://files.pythonhosted.org/packages/c1/d1/a54b06d392a18a22e0836a488c8e776d521ebd4a36622845e76a368a0f8f/underground-0.2.7.3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "951ec712254039be669fa19dd1a4e6af", "sha256": "3771e918c68eca5665ed78b641f793fc457e4fa2843f282a3e32634744fe4154" }, "downloads": -1, "filename": "underground-0.2.7.3.tar.gz", "has_sig": false, "md5_digest": "951ec712254039be669fa19dd1a4e6af", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6,<4.0", "size": 11791, "upload_time": "2019-10-05T18:51:30", "url": "https://files.pythonhosted.org/packages/53/ae/330dd9279e087b3556a3da6b059ad03e5e61434fb4cb3fe58b421c2fe476/underground-0.2.7.3.tar.gz" } ] }