Pointing a client at it - dubsector/meraki-api-emulator GitHub Wiki
Use http://localhost:8765/api/v1 wherever the client asks for the Meraki base URL, and any non-empty API key. The key goes in X-Cisco-Meraki-API-Key or Authorization: Bearer, the same as the real API. The official Python SDK needs a different setup, described below.
For the Cisco Meraki data source for Grafana, set Base URL in the data source settings. If Grafana runs in Docker and the emulator runs on the host, start the emulator with --host 0.0.0.0 and use http://host.docker.internal:8765/api/v1.
The official Python SDK
The Meraki Python SDK only follows Link URLs on meraki.com hosts. With base_url="http://localhost:8765/api/v1" the first page works, then the SDK glues the next page's URL onto its base URL and gets a 404. Give it a made-up meraki.com name instead and use the emulator as its proxy:
import meraki
dashboard = meraki.DashboardAPI(
"any-key",
base_url="http://emulator.meraki.com/api/v1",
requests_proxy="http://localhost:8765",
suppress_logging=True,
)
devices = dashboard.organizations.getOrganizationDevices(org_id, total_pages="all")
Every request goes to the emulator, and its Link headers keep the name you asked for, so paging, 429 and 5xx retries and writes behave as they do against the real API. Keep the base URL on http://, since the emulator doesn't do TLS. meraki.aio.AsyncDashboardAPI takes the same two options. Under Docker Compose with the network alias, base_url="http://emulator.meraki.com:8765/api/v1" works on its own, with no proxy.
Three things the SDK does that are easy to trip over:
- Walking the event log forward (
direction="next") stops once the next page starts within 5 minutes of your computer's clock. With--nowin the past that never happens, so passevent_log_end_timeor a number fortotal_pages. - With
use_iterator_for_get_pages=True, a forward event log walk loses its last page, because the SDK checks when to stop before handing over the page it just fetched. The default mode keeps it. - Paging the assurance alert overviews by network or by type across more than one page raises
TypeError. The SDK expectsmeta.counts.itemsto be an object withremaining, and the spec makes it a number. One page, the defaultperPageof 1000, works.
scripts/sdk-check.py runs the SDK against the emulator: paging, the event log, writes, rate limits, faults and the async client. CI runs it with the SDK version pinned in scripts/sdk-requirements.txt. To run it yourself:
python -m pip install --require-hashes -r scripts/sdk-requirements.txt
python scripts/sdk-check.py
The official Go SDK
dashboard-api-go builds its paths on /api/v1 itself, so give it the emulator's address without the path:
client, err := meraki.NewClientWithOptions("http://127.0.0.1:8765", "any-key", "false", "my-app")
The SDK ignores JSON it can't decode into its types, so a type mismatch shows up as empty fields rather than an error. Its types differ from the spec in a few places, for example VLAN IDs as integers, syslog ports as strings and the latency stats traffic classes as strings, so those fields stay empty whenever an answer follows the spec.
scripts/go-sdk-check creates the items that single-item reads need, such as a branding policy or a switch stack, then calls every GET in the SDK with the emulator's sample IDs and decodes each answer again into the SDK's type, reporting any mismatch. Known differences are listed in it with their reasons. CI runs it with the SDK version pinned in its go.mod. To run it yourself:
cd scripts/go-sdk-check
go run .
Add -fields to also list answer fields the SDK's types don't have yet.