Šaltinių konfigūravimas

Tam, kad Agentas galėtų pasiekti duomenis ir teikti juos UDTS formatu, reikia nurodyti, kokie duomenys bus teikiami ir kaip juos pasiekti. Tai daroma naudojantis duomenų struktūros aprašais (DSA). Šiuo atveju, mums reikės Šaltinio duomenų struktūros aprašų (ŠDSA).

Kaip nurodyta konfigūracijos faile, turite pateikti duomenų struktūros aprašą, kurio pagrindu veiks agentas.

Spinta palaikomi šaltiniai:

  • SQL

  • WSDL/SOAP

  • XML

  • JSON

Manifest konfigūravimas

Manifest — tai CSV formato failas, kuriame aprašyta, kokius duomenis agentas teiks ir kaip juos pasiekti. Jis atitinka DSA 1.1 specifikaciją.

Prisijungimo duomenys saugomi config.yml, ne manifest faile

Prisijungimo duomenys (DSN su slaptažodžiu) niekada nerašomi į manifest.csv. Manifest faile nurodomas tik backend’o pavadinimas — nuoroda į config.yml, kurį mato tik sistemos administratorius.

config.yml ir manifest.csv ryšys — slaptažodžiai atskirti nuo DSA struktūros

config.yml ir manifest.csv ryšys (spustelėkite norėdami padidinti)

config.yml (tik administratorius):

backends:
  myapp_db:
    type: sql
    dsn: postgresql+psycopg2://user:slaptazodis@localhost:5432/myapp
  products_db:
    type: sql
    dsn: postgresql+psycopg2://user:slaptazodis@localhost:5433/products

manifests:
  default:
    type: csv
    path: /opt/spinta/manifest.csv
    backend: myapp_db
    mode: external

manifest.csv (veiklos žmonės gali matyti ir redaguoti — jokių slaptažodžių):

id,dataset,...,type,ref,...
,datasets/gov/lt/myapp,,,,,,,,,,,,,,,,,,,,  ← vardų erdvė [dataset stulpelis]
,,saltinis_1,,,,sql,myapp_db,,,,,,,,,,,,,  ← resource eilutė: resource = šaltinio pavadinimas, ref = backend iš config.yml

Keli duomenų šaltiniai viename manifest faile

Vienas agentas gali teikti duomenis iš kelių šaltinių — jų skaičius neribojamas. Kiekvienas šaltinis aprašomas atskira resource eilute su savo backend’o pavadinimu. Visi backend’ų pavadinimai ir jų DSN yra config.yml faile.

manifest.csv su dviem backend'ais — eilučių struktūra

manifest.csv su dviem šaltiniais viename faile (spustelėkite norėdami padidinti)

Manifest faile kiekvienas šaltinis turi savo blokų seką:

dataset eilutė   → vardų erdvė (pvz. datasets/gov/lt/myapp)       [dataset stulpelis]
resource eilutė  → šaltinio pavadinimas (jūsų pasirinktas)        [resource stulpelis]
                   duomenų šaltinio tipas (sql/wsdl/xml/json)      [type stulpelis]
                   backend pavadinimas iš config.yml               [ref stulpelis]
(tuščia eilutė)  → vizualinis atskyriklis
model eilutė     → duomenų objektas (lentelė/klasė)
property eilutės → laukai (stulpeliai)

ref stulpelio reikšmė skiriasi priklausomai nuo eilutės lygio — tas pats stulpelis reiškia skirtingus dalykus:

Eilutės tipas

ref reikšmė

resource eilutė

backend pavadinimas iš config.yml (pvz. myapp_db)

model eilutė

pirminio rakto laukų sąrašas (pvz. id arba id,code)

property eilutė

nurodomos modelio arba enum pavadinimas (ref tipo laukams)

Tą patį principą taiko ir kiti stulpeliai (source, prepare ir kt.) — jų prasmė priklauso nuo eilutės tipo (dataset / resource / model / property).

Jei norite pridėti antrą šaltinį — tiesiog tęskite tą patį failą nauju dataset/resource bloku.

Manifest CSV stulpelių struktūra

Manifest CSV turi tiksliai 21 stulpelį pagal DSA 1.1 specifikaciją:

id, dataset, resource, base, model, property, type, ref, source, source.type,
prepare, origin, count, level, status, visibility, access, uri, eli, title, description

Stulpelių eilės tvarka — nesvarbi. Spinta skaito pagal stulpelio pavadinimą, ne poziciją.

Praleisti stulpeliai — leidžiama. Stulpeliai, kurių nėra antraštėje, automatiškai gauna tuščią reikšmę "". Jūs neprivalote įtraukti visų 21 stulpelio — tik tuos, kuriuos naudojate.

Papildomi (savi) stulpeliai pastaboms — leidžiama, bet tik jei antraštėje yra visi 21 standartiniai stulpeliai, o savas stulpelis eina 22 pozicijoje ar vėliau. Spinta tokį stulpelį ignoruos — jis skirtas tik žmonėms (pvz. audito žymoms, komentarams):

id,...,description,original_access  ← 22-as stulpelis, Spinta neskaitys

Svarbu

Kiekviena eilutė privalo turėti lygiai tiek reikšmių kiek yra antraštėje — net jei reikšmė tuščia. Jei antraštė turi 22 stulpelius, kiekvienoje eilutėje turi būti 22 kableliais atskirtos reikšmės.

Sutrumpinti stulpelių pavadinimai — Spinta priima trumpinius:

Trumpinys

Pilnas pavadinimas

d

dataset

r

resource

b

base

m

model

p

property

t

type


WSDL ir SOAP šaltiniai

WSDL ir SOAP šaltinio struktūros parengimas aprašytas čia:

Duomenų šaltiniai - DSA

Pastaba

Žemiau pateiktas manifest pavyzdys yra skirtas pradiniam testavimui — jis naudoja viešai prieinamą demo WSDL paslaugą, kurią galima pasiekti be kredencialų. Jis leidžia patikrinti ar agentas apskritai veikia teisingai dar prieš jungiantis prie realaus šaltinio.

Kai testavimas sėkmingas — šį manifestą reikia pakeisti savo institucijos realiuoju sDSA (sugeneruotu su spinta inspect iš jūsų šaltinio). Kaip tai padaryti aprašyta skyriuje Agento paruošimas.

Pasikeiskite aktyvų naudotoją ir katalogą:

sudo -Hsu spinta
cd

Struktūros aprašo, skirto WSDL duomenims gauti, sudarymo pavyzdys:

cat > manifest.csv << 'EOF'
id,dataset,resource,base,model,property,type,ref,source,prepare,level,status,visibility,access,uri,eli,title,description
,datasets/gov/vssa/demo/rctest,,,,,dataset,,,,,,,,,,,
,,rc_wsdl,,,,wsdl,,https://test-data.data.gov.lt/api/v1/rc/get-data/?wsdl,,,,,,,,,
,,get_data,,,,soap,,Get.GetPort.GetPort.GetData,wsdl(rc_wsdl),,,,,,,,
,,,,,,param,action_type,input/ActionType,input(),,,,,,,,
,,,,,,param,caller_code,input/CallerCode,input(),,,,,,,,
,,,,,,param,end_user_info,input/EndUserInfo,input(),,,,,,,,
,,,,,,param,parameters,input/Parameters,input(),,,,,,,,
,,,,,,param,time,input/Time,input(),,,,,,,,
,,,,,,param,signature,input/Signature,"creds(""sub"").input()",,,,,,,,
,,,,,,param,caller_signature,input/CallerSignature,input(),,,,,,,,
,,,,GetData,,,,/,,,,,,,,,
,,,,,response_code,string,,ResponseCode,,,,,,,,,
,,,,,response_data,string,,ResponseData,base64(),,,,,,,,
 ,,,,,decoded_parameters,string,,DecodedParameters,,,,,,,,,
 ,,,,,action_type,string,,,param(action_type),,,,,,,,
,,,,,end_user_info,string,,,param(end_user_info),,,,,,,,
,,,,,caller_code,string,,,param(caller_code),,,,,,,,
,,,,,parameters,string,,,param(parameters),,,,,,,,
,,,,,time,string,,,param(time),,,,,,,,
,,,,,signature,string,,,param(signature),,,,,,,,
,,,,,caller_signature,string,,,param(caller_signature),,,,,,,,
,,,,,,,,,,,,,,,,,
,,nested_read,,,,dask/xml,,,eval(param(nested_xml)),,,,,,,,
 ,,,,,,param,nested_xml,GetData,read().response_data,,,,,,,,
,,,,Country,,,,countries/countryData,,,,,,,,,
,,,,,id,string,,id,,,,,,,,,
,,,,,title,string,,title,,,,,,,,,
EOF

SOAP adapteriai

Kai kurių SOAP paslaugų užklausoms reikia laukų, kurių reikšmę galima apskaičiuoti tik tada, kai visi kiti užklausos laukai jau žinomi — pavyzdžiui, parašas (signature), kuris skaičiuojamas iš kelių kitų laukų reikšmių kartu.

Tokius atvejus galima išspręsti rašant pasirinktinį Python modulį (adapterį) ir nurodant jį config.yml. Spinta įkelia šį modulį paleidimo metu ir naudoja jį SOAP užklausos formavimo metu.

Kaip tai veikia

Įprasti prepare laukai manifest faile įvertinami iš karto, vienas po kito. Adapteris leidžia nurodyti, kad konkretus laukas turi būti įvertintas paskutinis — kai visi kiti laukai jau turi reikšmes.

Tai daroma dviem žingsniais:

  1. Manifest prepare stulpelyje naudojamas adapterio funkcijos pavadinimas (pvz. rc_signature()).

  2. Adapterio modulyje ta funkcija įregistruojama kaip „atidėta“ — Spinta ją įvertins tik po to, kai kiti laukai jau bus sudėti į užklausą.

config.yml

soap_adapter_modules:
  - /opt/spinta/adapters/my_adapter.py

Galima nurodyti kelis failus. Keliai turi būti absoliutūs.

Jei adapteriui reikia papildomų nustatymų, juos galima dėti config.yml šalia kitų raktų. Pavyzdžiui:

rc_signature:
  private_key_path: /opt/spinta/keys/private.pem

Manifest

SOAP resurso param eilutėse prepare stulpelyje naudojamas adapterio funkcijos pavadinimas:

property

source

prepare

signature

input/Signature

rc_signature()

Kad tai veiktų, adapterio modulyje rc_signature turi būti nurodytas ir kaip atidėtas pavadinimas, ir kaip funkcija, kuri grąžina galutinę reikšmę.

Adapterio modulis

Adapteris yra paprastas Python failas su dviem privalomomis funkcijomis:

Funkcija

Paskirtis

get_deferred_prepare_names()

Grąžina sąrašą pavadinimų, kurie turi būti įvertinti paskutiniai, pvz. ["rc_signature"].

get_body_resolvers()

Grąžina žodyną {"rc_signature": fn}, kur fn(env) apskaičiuoja ir grąžina lauko reikšmę.

Papildomai galima aprašyti validate_soap_adapter_config(raw_config) — ji bus iškviesta paleidimo metu ir leis pranešti apie konfigūracijos klaidas iš karto, o ne užklausos metu.

Funkcija fn(env) gauna SoapQueryBuilder objektą — per env.soap_request_body pasiekiami visi jau sudėti užklausos laukai.

Pavyzdinis adapteris Spinta kode: spinta/adapters/rc/signature_adapter.py.

Adapterio kūrimo pavyzdys

Žemiau pateiktas minimalus adapteris, kuris apskaičiuoja parašą iš jau sudėtų užklausos laukų:

# /opt/spinta/adapters/my_signature_adapter.py

def get_deferred_prepare_names():
    """Šie prepare pavadinimai manifest faile bus įvertinti paskutiniai."""
    return ["rc_signature"]


def get_body_resolvers():
    """Funkcijos, kurios apskaičiuoja atidėtų laukų reikšmes."""
    return {"rc_signature": compute_signature}


def compute_signature(env, expr=None):
    """
    env.soap_request_body — žodynas su visais jau sudėtais SOAP užklausos laukais.
    env.context — Spinta kontekstas, per kurį pasiekiama konfigūracija.
    """
    body = env.soap_request_body

    # Skaitome konfigūraciją iš config.yml
    config = env.context.get("config")
    key_path = config.rc_signature["private_key_path"]

    # Apskaičiuojame parašą iš laukų reikšmių
    data_to_sign = (
        str(body.get("input/CallerCode", "")) +
        str(body.get("input/Time", "")) +
        str(body.get("input/ActionType", ""))
    )

    return sign(data_to_sign, key_path)


def sign(data: str, key_path: str) -> str:
    """Parašo skaičiavimo logika — pakeiskite savo implementacija."""
    ...


def validate_soap_adapter_config(raw_config):
    """Tikrinama konfigūracija paleidimo metu — klaida pasirodys iš karto."""
    if "rc_signature" not in raw_config:
        raise ValueError("Trūksta 'rc_signature' skilties config.yml faile")
    if "private_key_path" not in raw_config["rc_signature"]:
        raise ValueError("Trūksta 'rc_signature.private_key_path' config.yml faile")

Pastaba

env.soap_request_body raktai atitinka manifest source stulpelio reikšmes (input/CallerCode, input/Time ir t.t.), o ne property pavadinimus.