@@ -62,6 +62,68 @@ To connect a node with MQTT support for streaming:
6262 app.add_node(node)
6363
6464
65+ Authentication
66+ --------------
67+ OSHConnect speaks **HTTP Basic Auth ** to OGC CS API servers. There is no
68+ bearer-token, OAuth, or API-key flow — the underlying ``requests ``
69+ library carries credentials as a ``(username, password) `` tuple.
70+
71+ For a secured server, pass ``username `` and ``password `` to ``Node ``:
72+
73+ .. code-block :: python
74+
75+ node = Node(protocol = ' https' , address = ' sensors.example.org' , port = 443 ,
76+ username = ' alice' , password = ' s3cret' )
77+
78+ Every HTTP call the node makes — discovery, resource creation, schema
79+ fetches — automatically carries those credentials. Internally, the node
80+ constructs an ``APIHelper `` that holds the credentials and reads them
81+ back via ``get_helper_auth() `` on each request. The same credentials
82+ also flow into the MQTT client when ``enable_mqtt=True ``.
83+
84+ For an unsecured server (e.g., a local OSH dev instance), simply omit
85+ ``username `` and ``password ``:
86+
87+ .. code-block :: python
88+
89+ node = Node(protocol = ' http' , address = ' localhost' , port = 8585 )
90+
91+ If the server has been secured but you forget to provide credentials,
92+ each request will return ``401 Unauthorized `` from the server — no
93+ exception is raised by the library; inspect the response status.
94+
95+ Lower-level usage (free helpers)
96+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
97+ For one-off scripts or when you don't want a full ``Node `` /
98+ ``OSHConnect `` setup, the module-level helpers in
99+ ``oshconnect.api_helpers `` mirror each CS API endpoint and accept an
100+ optional ``auth `` tuple plus optional ``headers `` dict. Every helper
101+ returns a ``requests.Response `` object:
102+
103+ .. code-block :: python
104+
105+ from oshconnect.api_helpers import list_all_systems, create_new_systems
106+
107+ resp = list_all_systems(
108+ ' http://sensors.example.org/sensorhub' ,
109+ auth = (' alice' , ' s3cret' ),
110+ )
111+ resp.raise_for_status()
112+ systems = resp.json()[' items' ]
113+
114+ created = create_new_systems(
115+ ' http://sensors.example.org/sensorhub' ,
116+ request_body = {' name' : ' Sensor #1' , ' uid' : ' urn:test:sensor:1' },
117+ auth = (' alice' , ' s3cret' ),
118+ headers = {' Content-Type' : ' application/sml+json' },
119+ )
120+ new_id = created.headers[' Location' ].rsplit(' /' , 1 )[- 1 ]
121+
122+ Omit ``auth `` to call an unsecured endpoint. For application code,
123+ prefer the ``Node `` / ``APIHelper `` path so credentials are configured
124+ once at the node boundary instead of threaded through every call site.
125+
126+
65127Discovery
66128---------
67129
0 commit comments