1414
1515"""Low level HTTP interface to the RelationalAI REST API."""
1616
17- import ed25519
18- import base64
19- from datetime import datetime
20- import hashlib
2117import json
2218from os import path
2319from urllib .parse import urlencode , urlsplit , quote
2420from urllib .request import Request , urlopen
2521
2622from .__init__ import __version__
2723from .credentials import (
28- AccessKeyCredentials ,
2924 AccessToken ,
3025 Credentials ,
3126 ClientCredentials ,
4439SCOPE = "scope"
4540
4641
47- _empty = bytes ("" , encoding = "utf8" )
48-
49-
5042# Context contains the state required to make rAI REST API calls.
5143class Context (object ):
5244 def __init__ (self , region : str = None , credentials : Credentials = None ):
@@ -202,63 +194,6 @@ def _request_access_token(ctx: Context, url: str) -> AccessToken:
202194 raise Exception ("failed to get the access token" )
203195
204196
205- # Implement RAI API key authentication by signing the request and adding the
206- # required authorization header.
207- def _sign (ctx : Context , req : Request ) -> None :
208- assert isinstance (ctx .credentials , AccessKeyCredentials )
209-
210- ts = datetime .utcnow ()
211-
212- # ISO8601 date/time strings for time of request
213- signature_date = ts .strftime ("%Y%m%dT%H%M%SZ" )
214- scope_date = ts .strftime ("%Y%m%d" )
215-
216- # Authentication scope
217- scope = f"{ scope_date } /{ ctx .region } /{ ctx .service } /rai01_request"
218-
219- # SHA256 hash of content
220- content = req .data or _empty
221- content_hash = hashlib .sha256 (content ).hexdigest ()
222-
223- # Include "x-rai-date" in signed headers
224- req .headers ["x-rai-date" ] = signature_date
225-
226- # Sort and lowercase headers to produce a canonical form
227- canonical_headers = sorted (
228- [f"{ k .lower ()} :{ v .strip ()} " for k , v in req .headers .items ()]
229- )
230-
231- h_names = sorted ([k .lower () for k in req .headers ])
232- signed_headers = ";" .join (h_names )
233-
234- # Create hash of canonical request
235- split_result = urlsplit (req .full_url ) # was self.url
236- canonical_form = "{}\n {}\n {}\n {}\n \n {}\n {}" .format (
237- req .method ,
238- _encode_path (split_result .path ),
239- split_result .query ,
240- "\n " .join (canonical_headers ),
241- signed_headers ,
242- content_hash ,
243- )
244-
245- canonical_hash = hashlib .sha256 (canonical_form .encode ("utf-8" )).hexdigest ()
246- # Create and sign "String to sign"
247- string_to_sign = "RAI01-ED25519-SHA256\n {}\n {}\n {}" .format (
248- signature_date , scope , canonical_hash
249- )
250-
251- seed = base64 .b64decode (ctx .credentials .pkey )
252- signing_key = ed25519 .SigningKey (seed )
253- sig = signing_key .sign (string_to_sign .encode ("utf-8" )).hex ()
254-
255- req .headers ["authorization" ] = (
256- "RAI01-ED25519-SHA256 Credential={}/{},"
257- "SignedHeaders={},"
258- "Signature={}" .format (ctx .credentials .akey , scope , signed_headers , sig )
259- )
260-
261-
262197# Authenticate the request by signing or adding access token.
263198def _authenticate (ctx : Context , req : Request ) -> Request :
264199 creds = ctx .credentials
@@ -268,9 +203,6 @@ def _authenticate(ctx: Context, req: Request) -> Request:
268203 access_token = _get_access_token (ctx , req .full_url )
269204 req .headers ["authorization" ] = f"Bearer { access_token } "
270205 return req
271- if isinstance (creds , AccessKeyCredentials ):
272- _sign (ctx , req )
273- return req
274206 raise Exception ("unknown credential type" )
275207
276208
0 commit comments