PyPNM FastAPI - PNM Capture cURL Examples¶
This guide shows how to invoke PyPNM PNM capture endpoints using curl. Each example
sends a POST request with a JSON body that mirrors the common FastAPI request models.
Table Of Contents¶
Downstream OFDM Capture Endpoints
- Downstream OFDM RxMER
- Downstream OFDM Channel Estimation
- Downstream OFDM FEC Summary
- Downstream OFDM Modulation Profile
- Downstream OFDM Constellation Display
- Downstream Spectrum Analysis
Upstream OFDMA Capture Endpoints
Overview¶
PNM capture endpoints in PyPNM are all POST operations that accept a JSON body based
on a shared request model (for example, CommonRequest / PnmSingleCaptureRequest).
Representative routers and services:
CmDsOfdmRxMerServiceCmDsOfdmChanEstimateCoefCmDsOfdmFecSummaryCmDsOfdmModulationProfileCmSpectrumAnalysisCmUsOfdmaPreEq
The examples focus on how to structure the JSON and how to invoke the endpoints
with curl. Response payloads are typically JSON containing PNM metadata and capture
file information. Archive/plot outputs follow the same request shape but use a different
analysis.output.type value.
For all examples below, generic addresses are used:
- Example CM MAC address:
aa:bb:cc:dd:ee:ff - Example CM IP address:
192.168.0.100 - Example TFTP server (IPv4):
192.168.0.200 - Example TFTP server (IPv6):
::1(dummy placeholder)
Common Request Template¶
Most PNM capture endpoints accept a request with this common structure (simplified).
Key details for the current implementation:
analysis.output.typeuses lowercase strings ("json","archive", etc.).analysis.plotis required for single-capture analysis routes; RxMER needs at leastplot.ui.theme.pnm_parameters.tftp.ipv6can safely use a dummy address::1if IPv6 is not otherwise used.
curl -X POST "http://127.0.0.1:8000/<endpoint>" -H "Content-Type: application/json" -d @- << 'JSON'
{
"cable_modem": {
"mac_address": "aa:bb:cc:dd:ee:ff",
"ip_address": "192.168.0.100",
"snmp": {
"snmp_v2c": {
"community": "private"
}
},
"pnm_parameters": {
"tftp": {
"ipv4": "192.168.0.200",
"ipv6": "::1",
"dest_dir": ""
},
"capture": {
"channel_ids": []
}
}
},
"analysis": {
"output": {
"type": "json"
},
"plot": {
"ui": {
"theme": "dark"
}
}
}
}
JSON
You can reuse this block and only change the <endpoint> path for each PNM capture.
Downstream OFDM Capture Endpoints¶
Downstream OFDM RxMER¶
Endpoint:
POST /docs/pnm/ds/ofdm/rxMer/getCapture
This is a validated RxMER pattern using the generic MAC/IP/TFTP and the required
analysis.plot.ui.theme field:
curl -X POST "http://127.0.0.1:8000/docs/pnm/ds/ofdm/rxMer/getCapture" -H "Content-Type: application/json" -d @- << 'JSON'
{
"cable_modem": {
"mac_address": "aa:bb:cc:dd:ee:ff",
"ip_address": "192.168.0.100",
"snmp": {
"snmp_v2c": {
"community": "private"
}
},
"pnm_parameters": {
"tftp": {
"ipv4": "192.168.0.200",
"ipv6": "::1",
"dest_dir": ""
},
"capture": {
"channel_ids": []
}
}
},
"analysis": {
"output": {
"type": "json"
},
"plot": {
"ui": {
"theme": "dark"
}
}
}
}
JSON
The response payload corresponds to the RxMER analysis model returned by your
Analysis(AnalysisType.BASIC, msg_rsp) path, combined with RxMER measurement stats.
Downstream OFDM Channel Estimation¶
Endpoint:
POST /docs/pnm/ds/ofdm/chanEstimate/getCapture
Channel estimation uses the same overall request shape. If the underlying route uses the
same CommonAnalysisRequest, this template should validate:
curl -X POST "http://127.0.0.1:8000/docs/pnm/ds/ofdm/chanEstimate/getCapture" -H "Content-Type: application/json" -d @- << 'JSON'
{
"cable_modem": {
"mac_address": "aa:bb:cc:dd:ee:ff",
"ip_address": "192.168.0.100",
"snmp": {
"snmp_v2c": {
"community": "private"
}
},
"pnm_parameters": {
"tftp": {
"ipv4": "192.168.0.200",
"ipv6": "::1",
"dest_dir": ""
},
"capture": {
"channel_ids": []
}
}
},
"analysis": {
"output": {
"type": "json"
},
"plot": {
"ui": {
"theme": "dark"
}
}
}
}
JSON
The JSON response will contain channel-estimation taps and related metadata, aligned with
your CmDsOfdmChanEstimateCoef / analysis models.
Downstream OFDM FEC Summary¶
Endpoint:
POST /docs/pnm/ds/ofdm/fecSummary/getCapture
Example:
curl -X POST "http://127.0.0.1:8000/docs/pnm/ds/ofdm/fecSummary/getCapture" -H "Content-Type: application/json" -d @- << 'JSON'
{
"cable_modem": {
"mac_address": "aa:bb:cc:dd:ee:ff",
"ip_address": "192.168.0.100",
"snmp": {
"snmp_v2c": {
"community": "private"
}
},
"pnm_parameters": {
"tftp": {
"ipv4": "192.168.0.200",
"ipv6": "::1",
"dest_dir": ""
},
"capture": {
"channel_ids": []
}
}
},
"analysis": {
"output": {
"type": "json"
},
"plot": {
"ui": {
"theme": "dark"
}
}
}
}
JSON
The response payload typically includes per-profile and per-subcarrier summary counters (total codewords, corrected, uncorrectable, etc.).
Downstream OFDM Modulation Profile¶
Endpoint:
POST /docs/pnm/ds/ofdm/modulationProfile/getCapture
Example:
curl -X POST "http://127.0.0.1:8000/docs/pnm/ds/ofdm/modulationProfile/getCapture" -H "Content-Type: application/json" -d @- << 'JSON'
{
"cable_modem": {
"mac_address": "aa:bb:cc:dd:ee:ff",
"ip_address": "192.168.0.100",
"snmp": {
"snmp_v2c": {
"community": "private"
}
},
"pnm_parameters": {
"tftp": {
"ipv4": "192.168.0.200",
"ipv6": "::1",
"dest_dir": ""
}
}
},
"analysis": {
"output": {
"type": "json"
},
"plot": {
"ui": {
"theme": "dark"
}
}
}
}
JSON
Downstream OFDM Constellation Display¶
Endpoint:
POST /docs/pnm/ds/ofdm/constellationDisplay/getCapture
Constellation Display extends the same analysis block with additional plot options
(such as display_cross_hair). The example below matches your UI fields:
curl -X POST "http://127.0.0.1:8000/docs/pnm/ds/ofdm/constellationDisplay/getCapture" -H "Content-Type: application/json" -d @- << 'JSON'
{
"cable_modem": {
"mac_address": "aa:bb:cc:dd:ee:ff",
"ip_address": "192.168.0.100",
"snmp": {
"snmp_v2c": {
"community": "private"
}
},
"pnm_parameters": {
"tftp": {
"ipv4": "192.168.0.200",
"ipv6": "::1",
"dest_dir": ""
}
}
},
"analysis": {
"type": "basic",
"output": {
"type": "json"
},
"plot": {
"ui": {
"theme": "dark"
},
"options": {
"display_cross_hair": true
}
}
},
"capture_settings": {
"modulation_order_offset": 0,
"number_sample_symbol": 8192
}
}
JSON
If you switch the output type to a plot/archive-oriented value in your OutputType enum,
you can have this endpoint generate MatPlot reports instead of pure JSON.
Downstream Spectrum Analysis¶
Endpoint:
POST /docs/pnm/ds/spectrumAnalysis/getCapture
Example:
curl -X POST "http://127.0.0.1:8000/docs/pnm/ds/spectrumAnalysis/getCapture" -H "Content-Type: application/json" -d @- << 'JSON'
{
"cable_modem": {
"mac_address": "aa:bb:cc:dd:ee:ff",
"ip_address": "192.168.0.100",
"snmp": {
"snmp_v2c": {
"community": "private"
}
},
"pnm_parameters": {
"tftp": {
"ipv4": "192.168.0.200",
"ipv6": "::1",
"dest_dir": ""
}
}
},
"analysis": {
"type": "basic",
"output": {
"type": "json"
},
"plot": {
"ui": {
"theme": "dark"
}
},
"spectrum_analysis": {
"moving_average": {
"points": 10
}
}
},
"capture_parameters": {
"inactivity_timeout": 60,
"first_segment_center_freq": 300000000,
"last_segment_center_freq": 900000000,
"segment_freq_span": 1000000,
"num_bins_per_segment": 256,
"noise_bw": 150,
"window_function": 1,
"num_averages": 1,
"spectrum_retrieval_type": 1
}
}
JSON
The JSON response will contain spectrum sweep configuration and amplitude bins that map
directly onto the CmSpectrumAnalysis / CmSpectrumAnalysisSnmp models.
Upstream OFDMA Capture Endpoints¶
Upstream OFDMA Pre-Equalization¶
Endpoint:
POST /docs/pnm/us/ofdma/preEqualization/getCapture
Example:
curl -X POST "http://127.0.0.1:8000/docs/pnm/us/ofdma/preEqualization/getCapture" -H "Content-Type: application/json" -d @- << 'JSON'
{
"cable_modem": {
"mac_address": "aa:bb:cc:dd:ee:ff",
"ip_address": "192.168.0.100",
"snmp": {
"snmp_v2c": {
"community": "private"
}
},
"pnm_parameters": {
"tftp": {
"ipv4": "192.168.0.200",
"ipv6": "::1",
"dest_dir": ""
}
}
},
"analysis": {
"output": {
"type": "json"
},
"plot": {
"ui": {
"theme": "dark"
}
}
}
}
JSON
The response will include decoded upstream pre-equalizer taps which correspond to the
CmUsOfdmaPreEqModel used by the parser examples.
Programming Notes¶
- When scripting against these endpoints, it is often convenient to template the common request body and just substitute MAC/IP/TFTP values.
- The same JSON payloads shown here can be used directly in Postman, Python
requests, or any other HTTP client. - For automation, you can combine these
curlinvocations with the parser examples insrc/pypnm/examples/python/parsers/to build end-to-end workflows: - Trigger capture via FastAPI.
- Download or reference the PNM binary.
- Parse with a
Cm*parser and feed into additional analysis utilities.