Metadata-Version: 2.5
Name: random-streetview
Version: 0.2.0
Summary: One call, one random Street View panorama (Google, Naver, Kakao)
Project-URL: Homepage, https://github.com/AngLaboratory/random-streetview
Project-URL: Source, https://github.com/AngLaboratory/random-streetview
Project-URL: Issues, https://github.com/AngLaboratory/random-streetview/issues
Author-email: AngLaboratory <anglaboratory@gmail.com>
License-Expression: MIT
License-File: LICENSE
Keywords: geoguessr,google-street-view,panoid,panorama,random,street-view,streetview
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Multimedia :: Graphics
Classifier: Typing :: Typed
Requires-Python: >=3.9
Requires-Dist: requests>=2.25
Description-Content-Type: text/markdown

# random-streetview

[![PyPI](https://img.shields.io/pypi/v/random-streetview)](https://pypi.org/project/random-streetview/)
[![Python](https://img.shields.io/pypi/pyversions/random-streetview)](https://pypi.org/project/random-streetview/)

One call, one random Street View panorama. Google is worldwide and the
default; Naver and Kakao return road-view panoramas from South Korea.

```bash
pip install random-streetview
```

```python
from random_streetview import random_panorama

pano = random_panorama()

pano.id       # 'ptFCsB5aFyaWDDlpbCliVw'
pano.lon      # 2.2954822
pano.lat      # 48.8583758
pano.platform # 'google'
pano.url      # 'https://www.google.com/maps/@?api=1&map_action=pano&pano=...'
```

`Panorama` is a named tuple, so `panoid, lon, lat, platform = random_panorama()`
works too (`platform` defaults to `'google'` when constructed directly).

Nothing raises on a network or parsing failure — you get `None` once the
attempts are used up.

## Platforms

```python
random_panorama()                     # Google, worldwide (default)
random_panorama(platform="naver")     # Naver, South Korea
random_panorama(platform="kakao")     # Kakao, South Korea
```

`platform` is one of `"google"`, `"naver"`, `"kakao"`; anything else raises
`ValueError`. `pano.platform` records which one produced the result, and
`pano.url` builds the matching map link.

Naver and Kakao only cover South Korea, so their candidate coordinates are
drawn from inland Korea rather than the worldwide lists Google uses. Both hit
undocumented internal map endpoints — same no-key, no-guarantees caveat as
Google below — and return `None` rather than raising when they come up empty.

## Timeouts

```python
random_panorama(max_retry=10, timeout=3.0)   # the defaults
```

`timeout` is per request, in seconds, and is raised to **0.5** if you ask for
less. A single call budgets at most **30 seconds** of timeout across its
attempts, so `max_retry` is an upper bound rather than a promise: at
`timeout=10.0` you get 3 attempts, not 10. The default pairing is sized to
reach all 10. Time actually spent on the wire does not count against the
budget — only the timeouts do.

## How it works, and why it can break

Picking a coordinate at random mostly lands you in the ocean, so candidates
come from [randomstreetview.com][rsv] and [wandery.it][wandery], which keep
lists of places known to have coverage. Each candidate is then resolved to a
panorama id through `GeoPhotoService.SingleImageSearch`, an **undocumented
internal Google Maps endpoint**.

That means no API key — and no guarantees. The scraped sites will change their
HTML, and Google can alter or start refusing that endpoint at any time; when
that happens this library returns `None` rather than breaking your program. If
you need something dependable, use the official
[Street View Static API metadata endpoint][meta] with a key instead (metadata
requests are not billed).

Requests are not rate-limited for you. Space out your calls.

## Development

```bash
uv sync
uv run pytest    # fully offline; network calls are monkeypatched
```

## License

MIT

[rsv]: https://randomstreetview.com/
[wandery]: https://www.wandery.it/
[meta]: https://developers.google.com/maps/documentation/streetview/metadata
