underground


Nameunderground JSON
Version 0.4.0 PyPI version JSON
download
home_pagehttps://github.com/nolanbconaway/underground
SummaryUtilities for NYC's realtime MTA data feeds.
upload_time2023-11-21 03:18:56
maintainer
docs_urlNone
authorNolan Conaway
requires_python
licenseMIT
keywords nyc transit subway command-line cli
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Python MTA Utilities

[![badge](https://github.com/nolanbconaway/underground/workflows/Push/badge.svg)](https://github.com/nolanbconaway/underground/actions)
[![codecov](https://codecov.io/gh/nolanbconaway/underground/branch/main/graph/badge.svg)](https://codecov.io/gh/nolanbconaway/underground)
[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/underground)](https://pypi.org/project/underground/)
[![PyPI](https://img.shields.io/pypi/v/underground)](https://pypi.org/project/underground/)

This is a set of Python utilities that I use to deal with [real-time NYC subway data](https://datamine.mta.info/).

I 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.

## Install

``` sh
pip install underground
```

Or if you'd like to live dangerously:

``` sh
pip install git+https://github.com/nolanbconaway/underground.git#egg=underground
```

To request data from the MTA, you'll also need a free API key.
[Register here](https://api.mta.info/).

## Python API

Once you have your API key, use the Python API like:

``` python
import os

from underground import metadata, SubwayFeed

API_KEY = os.getenv('MTA_API_KEY')
ROUTE = 'Q'
feed = SubwayFeed.get(ROUTE, api_key=API_KEY)

# request will read from $MTA_API_KEY if a key is not provided
feed = SubwayFeed.get(ROUTE)

# under the hood, the Q route is mapped to a URL. This call is equivalent:
URL = 'https://api-endpoint.mta.info/Dataservice/mtagtfsfeeds/nyct%2Fgtfs-nqrw'
feed = SubwayFeed.get(URL)

# or
URL = metadata.resolve_url(ROUTE)
feed = SubwayFeed.get(URL)
```

### List train stops on each line

`feed.extract_stop_dict` will return a dictionary of dictionaries, like:

```python
>>> feed.extract_stop_dict()

{

  "route_1": {
    "stop_1": [datetime.datetime(...), datetime.datetime(...)], 
    "stop_2": [datetime.datetime(...), datetime.datetime(...)], 
    ...
  }, 
  "route_2": {
    "stop_1": [datetime.datetime(...), datetime.datetime(...)], 
    "stop_2": [datetime.datetime(...), datetime.datetime(...)], 
    ...
  }

}
```

## CLI

The `underground` command line tool is also installed with the package.

### `feed` 
```
$ underground feed --help
Usage: underground feed [OPTIONS] ROUTE_OR_URL

  Request an MTA feed via a route or URL.

  ROUTE_OR_URL may be either a feed URL or a route (which will be used to
  look up the feed url).

  Examples (both access the same feed):

      underground feed Q --json > feed_nrqw.json

      URL='https://api-endpoint.mta.info/Dataservice/mtagtfsfeeds/nyct%2Fgtfs-nqrw' &&
      underground feed $URL --json > feed_nrqw.json

Options:
  --api-key TEXT         MTA API key. Will be read from $MTA_API_KEY if not
                         provided.

  --json                 Option to output the feed data as JSON. Otherwise
                         output will be bytes.

  -r, --retries INTEGER  Retry attempts in case of API connection failure.
                         Default 100.

  --help                 Show this message and exit.
```

### `stops` 

```
$ underground stops --help
Usage: underground stops [OPTIONS] [H|M|D|1|Z|A|N|GS|SI|J|G|Q|L|B|R|F|E|2|7|W|
                          6|4|C|5|FS]
    
  Print out train departure times for all stops on a subway line.

Options:

  -f, --format TEXT      strftime format for stop times. Use `epoch` for a
                          unix timestamp.
  -r, --retries INTEGER  Retry attempts in case of API connection failure.
                          Default 100.
  --api-key TEXT         MTA API key. Will be read from $MTA_API_KEY if not
                          provided.
  -t, --timezone TEXT    Output timezone. Ignored if --epoch. Default to NYC
                          time.
  -s, --stalled-timeout INTEGER  Number of seconds between the last movement
                                 of a train and the API update before
                                 considering a train stalled. Default is 90 as
                                 recommended by the MTA. Numbers less than 1
                                 disable this check.
  --help                 Show this message and exit.
```

Stops are printed to stdout in the format `stop_id t1 t2 ... tn` .

``` sh
$ export MTA_API_KEY='...'
$ underground stops Q | tail -2
Q05S 19:01 19:09 19:16 19:25 19:34 19:44 19:51 19:58
Q04S 19:03 19:11 19:18 19:27 19:36 19:46 19:53 20:00
```

If 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:

``` sh
$ underground stops Q | grep Q05S
Q05S 19:09 19:16 19:25 19:34 19:44 19:51 19:58
```

If you don't know your stop, see below for a handy tool!

### `findstops` 

```
$ underground findstops --help
Usage: underground findstops [OPTIONS] QUERY...

  Find your stop ID.

  Query a location and look for your stop ID, like:

  $ underground findstops parkside av

Options:

  --json  Option to output the data as JSON. Otherwise will be human readable
          table.

  --help  Show this message and exit.
```

Enter the name of your stop and a table of stops with matching names will be returned.

```
$ underground findstops parkside
ID: D27N    Direction: NORTH    Lat/Lon: 40.655292, -73.961495    Name: PARKSIDE AV
ID: D27S    Direction: SOUTH    Lat/Lon: 40.655292, -73.961495    Name: PARKSIDE AV
```

Some 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.

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/nolanbconaway/underground",
    "name": "underground",
    "maintainer": "",
    "docs_url": null,
    "requires_python": "",
    "maintainer_email": "",
    "keywords": "nyc,transit,subway,command-line,cli",
    "author": "Nolan Conaway",
    "author_email": "nolanbconaway@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/2f/73/00b0f3297b2b5d797d162c82d487b1d5af22225922f54edc132fdefcee9f/underground-0.4.0.tar.gz",
    "platform": null,
    "description": "# Python MTA Utilities\n\n[![badge](https://github.com/nolanbconaway/underground/workflows/Push/badge.svg)](https://github.com/nolanbconaway/underground/actions)\n[![codecov](https://codecov.io/gh/nolanbconaway/underground/branch/main/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://api.mta.info/).\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'\nfeed = SubwayFeed.get(ROUTE, api_key=API_KEY)\n\n# request will read from $MTA_API_KEY if a key is not provided\nfeed = SubwayFeed.get(ROUTE)\n\n# under the hood, the Q route is mapped to a URL. This call is equivalent:\nURL = 'https://api-endpoint.mta.info/Dataservice/mtagtfsfeeds/nyct%2Fgtfs-nqrw'\nfeed = SubwayFeed.get(URL)\n\n# or\nURL = metadata.resolve_url(ROUTE)\nfeed = SubwayFeed.get(URL)\n```\n\n### List train stops on each line\n\n`feed.extract_stop_dict` will return a dictionary of dictionaries, like:\n\n```python\n>>> feed.extract_stop_dict()\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\n## CLI\n\nThe `underground` command line tool is also installed with the package.\n\n### `feed` \n```\n$ underground feed --help\nUsage: underground feed [OPTIONS] ROUTE_OR_URL\n\n  Request an MTA feed via a route or URL.\n\n  ROUTE_OR_URL may be either a feed URL or a route (which will be used to\n  look up the feed url).\n\n  Examples (both access the same feed):\n\n      underground feed Q --json > feed_nrqw.json\n\n      URL='https://api-endpoint.mta.info/Dataservice/mtagtfsfeeds/nyct%2Fgtfs-nqrw' &&\n      underground feed $URL --json > feed_nrqw.json\n\nOptions:\n  --api-key TEXT         MTA API key. Will be read from $MTA_API_KEY if not\n                         provided.\n\n  --json                 Option to output the feed data as JSON. Otherwise\n                         output will be bytes.\n\n  -r, --retries INTEGER  Retry attempts in case of API connection failure.\n                         Default 100.\n\n  --help                 Show this message and exit.\n```\n\n### `stops` \n\n```\n$ underground stops --help\nUsage: 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\nOptions:\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  -s, --stalled-timeout INTEGER  Number of seconds between the last movement\n                                 of a train and the API update before\n                                 considering a train stalled. Default is 90 as\n                                 recommended by the MTA. Numbers less than 1\n                                 disable this check.\n  --help                 Show this message and exit.\n```\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```\n$ underground findstops --help\nUsage: 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\nOptions:\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```\n\nEnter the name of your stop and a table of stops with matching names will be returned.\n\n```\n$ underground findstops parkside\nID: D27N    Direction: NORTH    Lat/Lon: 40.655292, -73.961495    Name: PARKSIDE AV\nID: D27S    Direction: SOUTH    Lat/Lon: 40.655292, -73.961495    Name: PARKSIDE AV\n```\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",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Utilities for NYC's realtime MTA data feeds.",
    "version": "0.4.0",
    "project_urls": {
        "Homepage": "https://github.com/nolanbconaway/underground"
    },
    "split_keywords": [
        "nyc",
        "transit",
        "subway",
        "command-line",
        "cli"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "ef6a532438e3b88bc1a5543bbf6ff03c0a971fc7a6f8fc3f4c318e0d775ef2f7",
                "md5": "64b26610669a902113e21bc4bcc50cd2",
                "sha256": "45fd0792654112a650fa460c2d0cfcc06d68d0e744f9f393eb870b48aa5f763b"
            },
            "downloads": -1,
            "filename": "underground-0.4.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "64b26610669a902113e21bc4bcc50cd2",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": null,
            "size": 16943,
            "upload_time": "2023-11-21T03:18:54",
            "upload_time_iso_8601": "2023-11-21T03:18:54.296734Z",
            "url": "https://files.pythonhosted.org/packages/ef/6a/532438e3b88bc1a5543bbf6ff03c0a971fc7a6f8fc3f4c318e0d775ef2f7/underground-0.4.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "2f7300b0f3297b2b5d797d162c82d487b1d5af22225922f54edc132fdefcee9f",
                "md5": "87f5096ea7c4909461c169480fcb1b86",
                "sha256": "2386d0153c2d76e24e44c5560f3c9e4c01e5bbab67115c3b5b6552ae208d0a78"
            },
            "downloads": -1,
            "filename": "underground-0.4.0.tar.gz",
            "has_sig": false,
            "md5_digest": "87f5096ea7c4909461c169480fcb1b86",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 16488,
            "upload_time": "2023-11-21T03:18:56",
            "upload_time_iso_8601": "2023-11-21T03:18:56.209194Z",
            "url": "https://files.pythonhosted.org/packages/2f/73/00b0f3297b2b5d797d162c82d487b1d5af22225922f54edc132fdefcee9f/underground-0.4.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-11-21 03:18:56",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "nolanbconaway",
    "github_project": "underground",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "tox": true,
    "lcname": "underground"
}
        
Elapsed time: 0.14302s