gRPC Introduktion
Avidentifiera API via gRPC erbjuder ett högpresterande, typsäkert alternativ till REST för server-till-server-kommunikation. API:et tar emot text, PDF eller DOCX och returnerar en avidentifierad version baserat på regelstyrd behandling av personuppgifter.
Tjänsten RedactionService har två huvudsakliga RPC-metoder:
-
RedactFile– tar emot en PDF eller DOCX (Word) som bytes eller Base64 och returnerar den avidentifierade filen på samma sätt. -
RedactText– tar en textsträng och returnerar den avidentifierade texten.
Endpoint (Native & Web):
https://api.avidentifiera.se:50051
Direkt in, direkt ut – inga känsliga dokument lagras
Precis som med vårt REST-API har vi valt en synkron modell för datasäkerhet och enkelhet. Dokumentet skickas i din begäran, bearbetas helt i minnet och det avidentifierade resultatet skickas tillbaka i samma anrop. Vi lagrar aldrig ditt originaldokument på våra servrar.
För verksamheter som hanterar sekretessreglerade handlingar betyder detta att du skickar ett dokument och får tillbaka en avidentifierad version direkt – utan att vi behöver spara ditt original.
Proto-definition
Du kan alltid hämta den senaste kontraktsdefinitionen (.proto) här:
Klient-setup
För att komma igång behöver du gRPC-verktyg för ditt språk för att generera klientkod från vår .proto-fil. Här är de vanligaste paketen och kommandona.
<!-- Lägg till i din .csproj-fil -->
<ItemGroup>
<PackageReference Include="Grpc.Net.Client" Version="2.62.0" />
<PackageReference Include="Grpc.Net.Client.Web" Version="2.62.0" />
<PackageReference Include="Google.Protobuf" Version="3.25.3" />
<PackageReference Include="Grpc.Tools" Version="2.62.0" PrivateAssets="All" />
</ItemGroup>
<ItemGroup>
<Protobuf Include="Protos\redaction.v1.proto" GrpcServices="Client" />
</ItemGroup>
# 1. Installera paket
pip install grpcio grpcio-tools
# 2. Ladda ner .proto-filen och generera kod
python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. redaction.v1.proto
# För native gRPC (backend)
npm install @grpc/grpc-js @grpc/proto-loader
# För gRPC-Web (webbläsare)
npm install grpc-web google-protobuf
Autentisering
Varje anrop måste innehålla en giltig API-nyckel som metadata med nyckeln
authorization och värdet Bearer <din-nyckel>.
Om nyckeln saknas eller är ogiltig returneras statuskoden UNAUTHENTICATED.
var metadata = new Grpc.Core.Metadata { { "Authorization", "Bearer live_xxx..." } };
var response = await client.RedactTextAsync(request, metadata);
metadata = [('authorization', 'Bearer live_xxx...')]
response = stub.RedactText(request, metadata=metadata)
const md = new grpc.Metadata();
md.set('authorization', 'Bearer live_xxx...');
client.RedactText(request, md, (err, resp) => { /* ... */ });
Avidentifiera fil
RPCRedactFile
Skicka en PDF eller DOCX och få tillbaka en avidentifierad version. Filen kan skickas som råa bytes eller som en Base64-kodad sträng.
Request: RedactFileRequest
| Fält | Beskrivning |
|---|---|
fileName |
Filnamn, t.ex. "dokument.pdf". Används för att avgöra filtyp. |
fileBytes |
Filens innehåll som en byte-array. Använd antingen detta fält eller fileBase64. |
fileBase64 |
Filens innehåll som en Base64-kodad sträng. Använd antingen detta fält eller fileBytes. |
options |
Valfri konfiguration. Se Regelkonfiguration. |
Response: RedactFileResponse
| Fält | Beskrivning |
|---|---|
took |
Total bearbetningstid på servern i millisekunder. |
result |
Innehåller den avidentifierade filen som redactedFileBytes eller redactedFileBase64 (beroende på request), samt funna entities.
|
using Google.Protobuf;
using Grpc.Core;
using Grpc.Net.Client;
using Grpc.Net.Client.Web;
using Grpc.Redaction.V1;
const string apiKey = "Bearer live_xxx...";
var metadata = new Metadata { { "Authorization", apiKey } };
var grpcWebHandler = new GrpcWebHandler(GrpcWebMode.GrpcWebText, new HttpClientHandler());
using var channel = GrpcChannel.ForAddress("https://api.avidentifiera.se:50051", new GrpcChannelOptions { HttpHandler = grpcWebHandler });
var client = new RedactionService.RedactionServiceClient(channel);
var fileBytes = await File.ReadAllBytesAsync("dokument.pdf");
var req = new RedactFileRequest
{
FileName = "dokument.pdf",
FileBytes = ByteString.CopyFrom(fileBytes),
Options = new Options { Entities = { EntityType.Name, EntityType.Address } }
};
var resp = await client.RedactFileAsync(req, metadata);
await File.WriteAllBytesAsync("redacted.pdf", resp.Result.RedactedFileBytes.ToByteArray());
using Google.Protobuf;
using Grpc.Core;
using Grpc.Net.Client;
using Grpc.Redaction.V1;
using System.Net;
const string apiKey = "Bearer live_xxx...";
var metadata = new Metadata { { "Authorization", apiKey } };
var socketsHandler = new SocketsHttpHandler { EnableMultipleHttp2Connections = true };
var httpClient = new HttpClient(socketsHandler) { DefaultRequestVersion = HttpVersion.Version20, DefaultVersionPolicy = HttpVersionPolicy.RequestVersionExact };
using var channel = GrpcChannel.ForAddress("https://api.avidentifiera.se:50051", new GrpcChannelOptions { HttpClient = httpClient });
var client = new RedactionService.RedactionServiceClient(channel);
var fileBytes = await File.ReadAllBytesAsync("dokument.pdf");
var req = new RedactFileRequest
{
FileName = "dokument.pdf",
FileBytes = ByteString.CopyFrom(fileBytes),
Options = new Options { Entities = { EntityType.Name, EntityType.Address } }
};
var resp = await client.RedactFileAsync(req, metadata);
await File.WriteAllBytesAsync("redacted.pdf", resp.Result.RedactedFileBytes.ToByteArray());
import { RedactionServiceClient } from './generated/RedactionServiceClientPb.js';
import { RedactFileRequest, Options, EntityType } from './generated/redaction_v1_pb.js';
const client = new RedactionServiceClient('https://api.avidentifiera.se:50051');
const req = new RedactFileRequest();
// I webbläsare är det vanligast att hantera filen som Base64
const base64String = "JVBERi0xLjQKJ..."; // Din Base64-kodade PDF/DOCX
req.setFileName("dokument.pdf");
req.setFilebase64(base64String);
const options = new Options();
options.addEntities(EntityType.NAME);
options.addEntities(EntityType.ADDRESS);
req.setOptions(options);
const metadata = { 'authorization': 'Bearer live_xxx...' };
client.redactFile(req, metadata, (err, resp) => {
if (err) return console.error(err);
// Svaret kommer som Base64, som kan användas för att skapa en nedladdningslänk
const redactedBase64 = resp.getResult().getRedactedfilebase64();
console.log('Mottog avidentifierad fil som Base64.');
});
import grpc from '@grpc/grpc-js';
import protoLoader from '@grpc/proto-loader';
import fs from 'fs';
const def = protoLoader.loadSync('./Protos/redaction.v1.proto', { keepCase: true, longs: String, enums: String, defaults: true, oneofs: true });
const proto = grpc.loadPackageDefinition(def).grpc.redaction.v1;
const client = new proto.RedactionService('api.avidentifiera.se:50051', grpc.credentials.createSsl());
const md = new grpc.Metadata();
md.set('authorization', 'Bearer live_xxx...');
const bytes = fs.readFileSync('dokument.pdf');
const req = {
fileName: 'dokument.pdf',
fileBytes: bytes,
options: { entities: ['name','address'] }
};
client.RedactFile(req, md, (err, resp) => {
if (err) return console.error(err);
fs.writeFileSync('redacted.pdf', resp.result.redactedFileBytes);
console.log('Avidentifierad fil sparad som redacted.pdf');
});
import grpc
import redaction_v1_pb2
import redaction_v1_pb2_grpc
API_KEY = "Bearer live_xxx..."
ADDRESS = "api.avidentifiera.se:50051"
def run():
creds = grpc.ssl_channel_credentials()
with grpc.secure_channel(ADDRESS, creds) as channel:
stub = redaction_v1_pb2_grpc.RedactionServiceStub(channel)
with open("dokument.pdf", "rb") as f:
file_bytes = f.read()
req = redaction_v1_pb2.RedactFileRequest(
fileName="dokument.pdf",
fileBytes=file_bytes,
options=redaction_v1_pb2.Options(entities=[redaction_v1_pb2.EntityType.name, redaction_v1_pb2.EntityType.address])
)
md = [('authorization', API_KEY)]
resp = stub.RedactFile(req, metadata=md)
with open("redacted.pdf", "wb") as out:
out.write(resp.result.redactedFileBytes)
print("Avidentifierad fil sparad som redacted.pdf")
if __name__ == "__main__":
run()
Avidentifiera text
RPCRedactText
Skicka en textsträng och få tillbaka en avidentifierad version. Lyckade anrop returnerar status OK.
Request: RedactTextRequest
| Fält | Beskrivning |
|---|---|
text |
Texten som ska avidentifieras. Max 1 000 000 tecken. |
options |
Valfri konfiguration som styr avidentifieringen. Om den utelämnas används standardprofilen (namn, adress, personnummer maskeras). Se Regelkonfiguration. |
Response: RedactTextResponse
| Fält | Beskrivning |
|---|---|
took |
Total bearbetningstid på servern i millisekunder. |
result |
Innehåller den avidentifierade texten (redactedText) och en lista över funna entiteter (entities).
|
using Grpc.Core;
using Grpc.Net.Client;
using Grpc.Net.Client.Web;
using Grpc.Redaction.V1;
const string apiKey = "Bearer live_xxx...";
var metadata = new Metadata { { "Authorization", apiKey } };
var grpcWebHandler = new GrpcWebHandler(GrpcWebMode.GrpcWebText, new HttpClientHandler());
using var channel = GrpcChannel.ForAddress("https://api.avidentifiera.se:50051", new GrpcChannelOptions { HttpHandler = grpcWebHandler });
var client = new RedactionService.RedactionServiceClient(channel);
var request = new RedactTextRequest
{
Text = "Mitt namn är Anna Andersson och mitt personnummer är 850612-1234.",
Options = new Options
{
Entities = { EntityType.Name, EntityType.PersonalNumber },
Rules = new Rules
{
Name = new NameRules { Method = Method.ReplaceWithInitials },
PersonalNumber = new PersonalNumberRules { Method = Method.Remove }
}
}
};
var response = await client.RedactTextAsync(request, metadata);
Console.WriteLine(response.Result.RedactedText); // "Mitt namn är A.A och mitt personnummer är ."
using Grpc.Core;
using Grpc.Net.Client;
using Grpc.Redaction.V1;
using System.Net;
const string apiKey = "Bearer live_xxx...";
var metadata = new Metadata { { "Authorization", apiKey } };
var socketsHandler = new SocketsHttpHandler { EnableMultipleHttp2Connections = true };
var httpClient = new HttpClient(socketsHandler) { DefaultRequestVersion = HttpVersion.Version20, DefaultVersionPolicy = HttpVersionPolicy.RequestVersionExact };
using var channel = GrpcChannel.ForAddress("https://api.avidentifiera.se:50051", new GrpcChannelOptions { HttpClient = httpClient });
var client = new RedactionService.RedactionServiceClient(channel);
var request = new RedactTextRequest
{
Text = "Mitt namn är Anna Andersson och mitt personnummer är 850612-1234.",
Options = new Options
{
Entities = { EntityType.Name, EntityType.PersonalNumber },
Rules = new Rules
{
Name = new NameRules { Method = Method.ReplaceWithInitials },
PersonalNumber = new PersonalNumberRules { Method = Method.Remove }
}
}
};
var response = await client.RedactTextAsync(request, metadata);
Console.WriteLine(response.Result.RedactedText); // "Mitt namn är A.A och mitt personnummer är ."
import { RedactionServiceClient } from './generated/RedactionServiceClientPb.js';
import { RedactTextRequest, Options, Rules, NameRules, PersonalNumberRules, Method, EntityType } from './generated/redaction_v1_pb.js';
const client = new RedactionServiceClient('https://api.avidentifiera.se:50051');
const req = new RedactTextRequest();
req.setText('Mitt namn är Anna Andersson och mitt personnummer är 850612-1234.');
const options = new Options();
options.addEntities(EntityType.NAME);
options.addEntities(EntityType.PERSONALNUMBER);
const rules = new Rules();
const nameRules = new NameRules();
nameRules.setMethod(Method.REPLACEWITHINITIALS);
rules.setName(nameRules);
const pnRules = new PersonalNumberRules();
pnRules.setMethod(Method.REMOVE);
rules.setPersonalnumber(pnRules);
options.setRules(rules);
req.setOptions(options);
const metadata = { 'authorization': 'Bearer live_xxx...' };
client.redactText(req, metadata, (err, resp) => {
if (err) return console.error(err);
console.log(resp.getResult().getRedactedText());
});
import grpc from '@grpc/grpc-js';
import protoLoader from '@grpc/proto-loader';
const def = protoLoader.loadSync('./Protos/redaction.v1.proto', { keepCase: true, longs: String, enums: String, defaults: true, oneofs: true });
const proto = grpc.loadPackageDefinition(def).grpc.redaction.v1;
const client = new proto.RedactionService('api.avidentifiera.se:50051', grpc.credentials.createSsl());
const md = new grpc.Metadata();
md.set('authorization', 'Bearer live_xxx...');
const request = {
text: 'Mitt namn är Anna Andersson och mitt personnummer är 850612-1234.',
options: {
entities: ['name', 'personalNumber'],
rules: {
name: { method: 'replaceWithInitials' },
personalNumber: { method: 'remove' }
}
}
};
client.RedactText(request, md, (err, resp) => {
if (err) return console.error(err);
console.log(resp.result.redactedText);
});
import grpc
import redaction_v1_pb2
import redaction_v1_pb2_grpc
API_KEY = "Bearer live_xxx..."
ADDRESS = "api.avidentifiera.se:50051"
def run():
creds = grpc.ssl_channel_credentials()
with grpc.secure_channel(ADDRESS, creds) as channel:
stub = redaction_v1_pb2_grpc.RedactionServiceStub(channel)
req = redaction_v1_pb2.RedactTextRequest(
text="Mitt namn är Anna Andersson och mitt personnummer är 850612-1234.",
options=redaction_v1_pb2.Options(
entities=[redaction_v1_pb2.EntityType.name, redaction_v1_pb2.EntityType.personalNumber],
rules=redaction_v1_pb2.Rules(
name=redaction_v1_pb2.NameRules(method=redaction_v1_pb2.Method.replaceWithInitials),
personalNumber=redaction_v1_pb2.PersonalNumberRules(method=redaction_v1_pb2.Method.remove)
)
)
)
md = [('authorization', API_KEY)]
resp = stub.RedactText(req, metadata=md)
print(resp.result.redactedText)
if __name__ == "__main__":
run()
Regelkonfiguration (Options)
Meddelandet Options är valfritt. Om du utelämnar det används standardläget: namn, adress och personnummer maskeras.
Strukturen består av två delar:
entities– en lista med deEntityTypesom API:t ska leta efter och behandla.rules– ett objekt där du kan specificera detaljerade regler för varje entitetstyp.
Övergripande struktur: Options
| Fält | Beskrivning |
|---|---|
entities |
Vilka entiteter som ska avidentifieras. Värden:
name,
address,
email,
phoneNumber,
personalNumber.
|
rules |
Ett objekt som innehåller en default-regel och specifika regler för varje entitetstyp (t.ex. name, address). Specifika regler ärver från och skriver över default-regeln.
|
Gemensamma regelfält (gäller alla entiteter)
| Fält | Beskrivning |
|---|---|
method | Hur värdet ska hanteras: mask, replaceWithInitials (endast för name), replaceWith, remove. |
replacementText | Krävs om method är replaceWith. |
maskingCharacter | Tecken som används vid textmaskering när method är mask. Standard är "█". |
fillColor / textColor | Hex-färger (#RRGGBB eller #RRGGBBAA) för visuell redigering i PDF/DOCX. |
findValues / ignoreValues | Listor med strängar för att tvinga fram eller ignorera specifika matchningar. |
Entitetsspecifika regelfält
| Fält | Gäller för | Beskrivning |
|---|---|---|
minNameParts | name | Minsta antal ord som ska betraktas som ett fullständigt namn (t.ex. 2 för "Anna Andersson"). |
redactPersonNamedCompanies | name | Om true, avidentifieras även företagsnamn som liknar personnamn (t.ex. "Eriksson AB"). |
mode | address | Typ av adress att matcha: "fullAddress", "anyAddress", "streetAddress". |
minConfidence | name, address | Tröskelvärde för konfidens (0.0–1.0) vid matchning. |
Idempotens
För att göra säkra retries utan att orsaka dubbeldebitering kan du skicka med metadata-headern
idempotency-key: <unik-nyckel>.
Detta är valfritt men rekommenderat för robusta integrationer.
Om ett anrop med en specifik nyckel lyckas, kommer efterföljande anrop med samma nyckel och identisk request-payload inom 15 minuter att returnera det cachade svaret istället för att utföra operationen på nytt.
Svaret innehåller två trailers (metadata som skickas efter responsen) för att bekräfta status:
idempotency-key: Ekar nyckeln som användes. Om du inte skickade en, innehåller den en server-genererad nyckel.idempotency-status: Antingencreated(första lyckade anropet) ellerreplayed(ett cachat svar returnerades).
Felhantering
API:t använder standardiserade gRPC-statuskoder för att signalera resultat. Vid valideringsfel (INVALID_ARGUMENT) skickas en mer detaljerad felbeskrivning enligt Google RPC Error Model i trailern grpc-status-details-bin.
| Statuskod | Betydelse |
|---|---|
OK | Anropet lyckades. |
INVALID_ARGUMENT | Ogiltig indata, t.ex. saknat fält eller felaktiga värden i Options. Detaljer finns i trailers. |
UNAUTHENTICATED | API-nyckel saknas eller är ogiltig. |
FAILED_PRECONDITION | En förutsättning är inte uppfylld, t.ex. filtypen som skickades stöds inte. |
RESOURCE_EXHAUSTED | Din dagliga sidkvot har överskridits. |
ALREADY_EXISTS | Idempotenskonflikt. Samma idempotency-key har använts med en annan request-payload. |
INTERNAL | Ett oväntat serverfel inträffade. |