streetview downloads current and historical Google Street View panoramas
Python package for retrieving current and historical photos from Google Street View
At a glance
- What is it?
- streetview is a small Python package that turns GPS coordinates into panorama IDs and then downloads the current view, the full equirectangular panorama, or the metadata including capture date, including historical imagery the official Google API does not expose. It suits research and mapping experiments, and it depends on undocumented Google endpoints that can change without notice.
- Who is it for?
- Adopt streetview if you need historical Street View imagery or full panoramas from Python, because that is the capability the official Google API does not offer and this package provides in a handful of functions.
- Can I use it commercially?
- Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
- Is it still maintained?
- Activity is slowing. The repository last received commits 6 months ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The gap the official API leaves open
streetview is a light module for downloading photos from Google Street View, and the functions allow you to retrieve current and old photos. The README explains why that needs a third party package. Google does have an API for accessing Street View, but it does not allow you to access old photos, and the JavaScript API allows you to download segments of current photos rather than each full panorama as you see it on Google Street View. Both of those gaps matter. Historical imagery is the whole point of studying how a street changed, and a stitched panorama rather than a segment is what you need for anything that samples the full field of view. The package therefore sits in a slightly awkward position that the README acknowledges directly: it is described as a light module and, in the maintainer's own words, a hack, with the warning that Google does not maintain the access points used by this API for public use, so the hack may break if Google makes changes to how Street View works. Any adoption decision should start from that sentence.
Installing the package and the first search
The package is on PyPI and installs with pip.
pip install streetviewThe repository itself expects a newer toolchain than a bare pip environment, since the build backend is uv_build and the tree carries a uv.lock file, so working from a clone means using uv rather than pip to resolve the dev group. Once installed, the smallest useful call is the panorama search, which needs nothing but coordinates.
from streetview import search_panoramas
panos = search_panoramas(lat=41.8982208, lon=12.4764804)
first = panos[0]You should get a result carrying a pano_id and the capture coordinates. If the list comes back empty, the coordinate is the first thing to check, since the search works by finding the closest panoramas to a point and a point in the middle of nowhere has none nearby.
Two steps: coordinates to panorama IDs, then IDs to images
The design is a two step process, and the README explains it directly. The photos on Google Street View are panoramas, and each panorama has its own unique ID, so retrieving photos means first translating GPS coordinates into panorama IDs. The search function returns a list of the closest panoramas.
from streetview import search_panoramas
panos = search_panoramas(lat=41.8982208, lon=12.4764804)
first = panos[0]
print(first)
# pano_id='_R1mwpMkiqa2p0zp48EBJg' lat=41.89820676786453 lon=12.47644220919742 heading=0.8815613985061646 pitch=89.001953125 roll=0.1744659692049026 date='2019-08'The printed object is a pydantic model, and the field set is what you would want: the panorama ID, the exact latitude and longitude of the capture point, the heading, pitch and roll of the camera, and a date field when one is known. That geometry is the part most home grown scripts get wrong, because the coordinates you searched with and the coordinates the camera was actually at are different numbers, and for anything that plots a marker on a map the difference matters. The package is MIT licensed per its pyproject.toml, requires Python 3.10 or newer, and depends on httpx, pillow, pydantic and requests, with the request library doing the plain HTTP work and pydantic giving the results a typed shape.
Fetching a capture date from the metadata API
The date is not always in the search results, and the README is clear about that: not all panoramas will have a date field in the search results, and you can fetch a date for any valid panorama from the metadata API. That call needs an API key.
from streetview import get_panorama_meta
meta = get_panorama_meta(pano_id='_R1mwpMkiqa2p0zp48EBJg', api_key=GOOGLE_MAPS_API_KEY)
print(meta)
# date='2019-08' location=Location(lat=41.89820659475458, lng=12.47644649615282) pano_id='_R1mwpMkiqa2p0zp48EBJg'The metadata object carries the date, a Location value with latitude and longitude, and the panorama ID. The date is a year and month rather than a full timestamp, so it is good enough to say when a street was captured and not good enough to order two captures within the same month. The API key is a real Google Maps key, so this part of the package is covered by the official API and its billing, while the panorama search and download calls are the ones that ride on undocumented behaviour.
Downloading a street view image and a full panorama
With an ID in hand there are two download paths, and the difference is what you get. The street view image call returns a single view at the panorama's heading, pitch and roll, which is the frame a user would see on Street View, and it takes an API key.
from streetview import get_streetview
image = get_streetview(
pano_id="z80QZ1_QgCbYwj7RrmlS0Q",
api_key=GOOGLE_MAPS_API_KEY,
)
image.save("image.jpg", "jpeg")The panorama call returns the whole equirectangular image, the same asset the JavaScript API stitches for the viewer, and it does not take an API key.
from streetview import get_panorama
image = get_panorama(pano_id="z80QZ1_QgCbYwj7RrmlS0Q")
image.save("image.jpg", "jpeg")Both return a Pillow image object, since Pillow is a dependency and the save call takes a path and a format. That the key is only needed for the single view and the metadata is a small but real detail for anyone thinking about billing, since the panorama download path is the one that does not bill against a key.
The async variant and the dev workflow
There is an asynchronous entry point for the panorama download, which matters if you are pulling many panoramas.
from streetview import get_panorama_async
image = await get_panorama_async(pano_id="z80QZ1_QgCbYwj7RrmlS0Q")
image.save("image.jpg", "jpeg")The repository itself is set up as a modern Python project. The build backend is uv_build with a pinned version range, and the tree carries a uv.lock file, a .devcontainer/ directory, a .vscode/ directory, an .env-example file, an examples/ directory with a notebook, and a tests/ directory. The dev dependency group is the interesting part: pytest with pytest-asyncio and pytest-cov for the test run, pytest-vcr for recording HTTP interactions so tests do not hit Google every time, pyright for type checking, ruff for linting with a rule set that includes the pycodestyle, pyflakes, pyupgrade, isort, bugbear, quotes, simplify, flynt and perflint families, poethepoet as a task runner, and twine for publishing. The uv.lock file and the pinned build backend mean the project expects uv as its toolchain rather than a bare pip environment.
Licence, releases and where streetview is the wrong tool
Three things to be careful about. The first is the licence position. GitHub does not classify the licence for this repository, while the pyproject.toml declares MIT and the pyproject.toml also names Adrian Letchford as the author, so the package as distributed on PyPI claims MIT but the repository page does not show a recognised licence, and that gap is worth resolving with the maintainer if you intend to vendor the code rather than depend on it. The second is the release history. The tags run v0.1.0 on 2026-04-15, v0.0.16 and v0.0.15 both in August 2025, and the version field in pyproject.toml is still 0.0.0, so the version metadata on PyPI and in the repository does not match the tagged releases. The last push to the repository was on 2026-04-15, so the project is not archived but it is not moving quickly either. The third is the wrong-tool case. If you only need current Street View imagery within Google's terms, the official Street View Static API and the Maps JavaScript API are the supported route, they will not break without notice, and the metadata you need, including dates, is available through the official API for panoramas it recognises. This package earns its place only where the official API stops, which is the historical imagery and the full panorama. A second sensible alternative for historical imagery is to keep your own archive as you capture imagery over time, since a dependency on undocumented endpoints is a poor long term plan for a pipeline that has to keep running.
Editorial conclusion
Adopt streetview if you need historical Street View imagery or full panoramas from Python, because that is the capability the official Google API does not offer and this package provides in a handful of functions. Do not adopt it for anything that must keep working indefinitely without maintenance, because the README is explicit that Google does not maintain the access points the package uses and the change may break at any time, and do not adopt it for bulk imagery collection without checking the API terms yourself. Verify two things before you build on it: that your Google Maps API key has the Street View API enabled for the metadata call, and that your project can tolerate a breaking change, since the first release is 0.1.0 and the version in pyproject.toml is still 0.0.0. The practical first step is to pip install streetview, call search_panoramas with a latitude and longitude, and confirm you get a pano_id back before writing any download logic.
Frequently asked questions
What is the streetview Python package?
It is a light Python module for downloading photos from Google Street View, with functions that retrieve both current and historical photos. It is published on PyPI as streetview and its pyproject.toml declares an MIT licence and Python 3.10 as the minimum version.
How do I install the streetview package?
Install it from pip with pip install streetview. The project itself is built with uv, since the build backend is uv_build and the repository carries a uv.lock file, and the runtime dependencies are httpx, jupyter, pillow, pydantic and requests.
How do I find the panorama ID for a location with streetview?
Call search_panoramas with a latitude and longitude, for example search_panoramas(lat=41.8982208, lon=12.4764804), and take the pano_id from the first result. Each result carries the panorama ID, the capture coordinates and the heading, pitch and roll, and a date field when it is known.
Can streetview download historical Google Street View images?
Yes, and that is the main reason the package exists, because the official Google API does not allow access to old photos. You can also fetch a capture date for any valid panorama from the metadata API with get_panorama_meta, which requires a Google Maps API key.
What is the risk of using the streetview package long term?
The README states that Google does not maintain the access points used by this API for public use, so the hack may break if Google makes changes to how Street View works. The search and panorama download calls rely on that undocumented behaviour, while the metadata and single view calls use the official API with your key.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/robolyst-streetview)Was this useful?