The preparation for creating an account in the AOS is minimal. It is only required that you are already registered in an AAI that is supported by the GfBio SSO Service, i.e. DFN AAI, Life Science Login (ELIXIR AAI) or GfBio Accounts. These are also the current options that are offered if you want to register or login via the official AOS demo website. If you want to register via the AOS API instead, you just have to put the OIDC token you received from one of the previously mentioned services into the user registration request header for authorization.
To create/modify resources within the given scope/permissions you have to generate API token(s) after you have been activated by an AOS instance administrator.
Please note that these following tutorials cover only the most basic operations but we do our best to make the as extensive as possible.
For a complete list of the public API endpoints, their matching requests and responses, please refer to our Aruna Object Storage REST API Swagger-UI.
Client Creation
If you plan to send your requests through gRPC the first step is to open a connection to the gRPC gateway of the server you want to send the requests to.
The presence of a client connection to the specific resource service is required for all further requests in this tutorial if the requests are send via gRPC.
Danger
These are minimal reproducible examples only for demonstration purposes which should not be used 'as-is' in a production environment!
To use the Rust API library you have to set it as dependency aruna-rust-api = "<Aruna-Rust-API-Version>" in the cargo.toml of your project.
usearuna_rust_api::api::aruna::api::storage::services::v1::{storage_info_service_client,user_service_client,project_service_client,collection_service_client,object_service_client,object_group_service_client,}usestd::sync::Arc;usetonic::codegen::InterceptedService;usetonic::metadata::{AsciiMetadataKey,AsciiMetadataValue};usetonic::transport::{Channel,ClientTlsConfig};// Create a client interceptor which always adds the specified api token to the request header#[derive(Clone)]pubstructClientInterceptor{api_token: String,}// Implement a request interceptor which always adds // the authorization header with a specific API token to all requestsimpltonic::service::InterceptorforClientInterceptor{fncall(&mutself,request: tonic::Request<()>)-> Result<tonic::Request<()>,tonic::Status>{letmutmut_req: tonic::Request<()>=request;letmetadata=mut_req.metadata_mut();metadata.append(AsciiMetadataKey::from_bytes("authorization".as_bytes()).unwrap(),AsciiMetadataValue::try_from(format!("Bearer {}",self.api_token.as_str())).unwrap(),);returnOk(mut_req);}}fnmain(){// Create connection to AOS instance gRPC gatewayletapi_token="MySecretArunaApiToken".to_string();lettls_config=ClientTlsConfig::new();letendpoint=Channel::from_shared("https://<URL-To-AOS-Instance-gRPC-Gateway>").unwrap().tls_config(tls_config).unwrap();letchannel=endpoint.connect().await.unwrap();letinterceptor=ClientInterceptor{api_token: api_token.clone()};// Create the individual client servicesletmutinfo_client=storage_info_service_client::StorageInfoServiceClient::new(channel.clone());letmutuser_client=user_service_client::UserServiceClient::with_interceptor(channel.clone(),interceptor.clone());letmutproject_client=project_service_client::ProjectServiceClient::with_interceptor(channel.clone(),interceptor.clone());letmutcollection_client=collection_service_client::CollectionServiceClient::with_interceptor(channel.clone(),interceptor.clone());letmutobject_client=object_service_client::ObjectServiceClient::with_interceptor(channel.clone(),interceptor.clone());letmutobject_group_client=object_group_service_client::ObjectGroupServiceClient::with_interceptor(channel.clone(),interceptor.clone());// Do something with the client services ...}
To use the Python API library in your Python project you have to install the PyPI package: pip install Aruna-Python-API.
Note
This example additionally implements an interceptor which adds the authorization token automatically to each request send by the service clients.
It is a little more complicated and extra work up front but offers the advantage of having to worry less about the correct API token request metadata later.
All Python examples in this documentation assume that the client services have been initialized with an interceptor.
importcollectionsimportgrpcfromaruna.api.storage.services.v1.collection_service_pb2_grpcimportCollectionServiceStubfromaruna.api.storage.services.v1.object_service_pb2_grpcimportObjectServiceStubfromaruna.api.storage.services.v1.objectgroup_service_pb2_grpcimportObjectGroupServiceStubfromaruna.api.storage.services.v1.project_service_pb2_grpcimportProjectServiceStubfromaruna.api.storage.services.v1.info_service_pb2_grpcimportStorageInfoServiceStubfromaruna.api.storage.services.v1.user_service_pb2_grpcimportUserServiceStub# Valid Aruna API token# In a production environment this should be stored in a more secure location ...API_TOKEN='MySecretArunaApiToken'# AOS instance gRPC gateway endpointAOS_HOST='<URL-To-AOS-Instance-gRPC-Gateway>'# Protocol (e.g. https://) has to be omittedAOS_PORT='443'class_MyAuthInterceptor(grpc.UnaryUnaryClientInterceptor):""" Implement abstract class grpc.UnaryUnaryClientInterceptor to extend request metadata. """defintercept_unary_unary(self,continuation,client_call_details,request):# Append authorization token to request metadatametadata=[]ifclient_call_details.metadataisnotNone:metadata=list(client_call_details.metadata)metadata.append(('authorization',f'Bearer {API_TOKEN}'))# Continue with new client call detailsrequest_iterator=iter((request,))updated_details=_ClientCallDetails(client_call_details.method,client_call_details.timeout,metadata,client_call_details.credentials)returncontinuation(updated_details,next(request_iterator))class_ClientCallDetails(collections.namedtuple('_ClientCallDetails',('method','timeout','metadata','credentials')),grpc.ClientCallDetails):""" Implement grpc.ClientCallDetails to pass modified request details in interceptor. """passclassAosClient(object):""" Class to contain the AOS gRPC client service stubs for easier usage. """def__init__(self,):ssl_credentials=grpc.ssl_channel_credentials()self.secure_channel=grpc.secure_channel("{}:{}".format(AOS_HOST,AOS_PORT),ssl_credentials)self.intercept_channel=grpc.intercept_channel(self.secure_channel,_MyAuthInterceptor())self.info_client=StorageInfoServiceStub(self.secure_channnel)self.user_client=UserServiceStub(self.intercept_channel)self.project_client=ProjectServiceStub(self.intercept_channel)self.collection_client=CollectionServiceStub(self.intercept_channel)self.object_client=ObjectServiceStub(self.intercept_channel)self.object_group_client=ObjectGroupServiceStub(self.intercept_channel)# Entry point of the scriptif__name__=='__main__':# Instantiate AosClientclient=AosClient()# Do something with the client services ...
To use the Python API library in your Python project you have to install the PyPI package: pip install Aruna-Python-API.
Note
This example does not consider adding the authorization token metadata to every request.
In this case you have to manually add the authorization token header by using the with_call(...) extension of the client service methods.
All Python examples in this documentation assume that the client services have been initialized with an interceptor.
importgrpcfromaruna.api.storage.services.v1.collection_service_pb2_grpcimportCollectionServiceStubfromaruna.api.storage.services.v1.object_service_pb2_grpcimportObjectServiceStubfromaruna.api.storage.services.v1.objectgroup_service_pb2_grpcimportObjectGroupServiceStubfromaruna.api.storage.services.v1.project_service_pb2_grpcimportProjectServiceStubfromaruna.api.storage.services.v1.info_service_pb2_grpcimportStorageInfoServiceStubfromaruna.api.storage.services.v1.user_service_pb2_grpcimportUserServiceStub# Valid Aruna API token# In a production environment this should be stored in a more secure location ...API_TOKEN='MySecretArunaApiToken'# AOS instance gRPC gateway endpointAOS_HOST='<URL-To-AOS-Instance-gRPC-Gateway>'# Protocol (e.g. https://) has to be omittedAOS_PORT='443'classAosClient(object):""" Class to contain the AOS gRPC client service stubs for easier usage. """def__init__(self):# Read TLS credentials from local trusted certificates and instantiate a channelssl_credentials=grpc.ssl_channel_credentials()self.channel=grpc.secure_channel("{}:{}".format(AOS_HOST,AOS_PORT),ssl_credentials)self.info_client=StorageInfoServiceStub(self.channnel)self.user_client=UserServiceStub(self.channel)self.project_client=ProjectServiceStub(self.channel)self.collection_client=CollectionServiceStub(self.channel)self.object_client=ObjectServiceStub(self.channel)self.object_group_client=ObjectGroupServiceStub(self.channel)# Entry point of the Python scriptif__name__=='__main__':# Instantiate AosClientclient=AosClient()# Do something with the client services ...
User registration
Users can register themselves with an individual display name in an AOS instance with their valid OIDC token received from the AAI login.
The email and project parameters are optional. If you provide an e-mail address during registration, you will receive system-relevant
notifications to this address e.g. advance notifications of maintenance. The project parameter is a hint for the administrators to associate
the newly registered user with a project for identification purposes.
// Create tonic/ArunaAPI request to register OIDC userletregister_request=RegisterUserRequest{display_name: "Forename Surname".to_string(),email: "forename.surname@example.com".to_string(),project: "Random Project".to_string(),};// Send the request to the AOS instance gRPC gatewayletresponse=user_client.register_user(register_request).await.unwrap().into_inner();// Do something with the responseprintln!("Registered user: {:#?}",response.user_id)
1 2 3 4 5 6 7 8 9101112131415
# Create tonic/ArunaAPI request to register OIDC userrequest=RegisterUserRequest(display_name="Forename Surname",email="forename.surname@example.com",project="Random Project")# Send the request to the AOS instance gRPC gatewayresponse=client.user_client.RegisterUser(request=request,metadata=(('authorization',f'Bearer {OIDC_TOKEN}'),))# Do something with the responseprint(f'{response}')
User activation
Note
Users can only be activated by AOS instance administrators.
After registration users additionally have to be activated in a second step.
1234
# For convenience, administrators can request info on all unactivated users at once
curl-H"Authorization: Bearer <API-Or-OIDC_TOKEN>"\-H"Content-Type: application/json"\-XGEThttps://<URL-to-AOS-instance-API-gateway>/v1/user/not_activated
1234
# Native JSON request to activate registered user
curl-H"Authorization: Bearer <API-Or-OIDC_TOKEN>"\-H"Content-Type: application/json"\-XPATCHhttps://<URL-to-AOS-instance-API-gateway>/v1/user/<user-id>/activate
1 2 3 4 5 6 7 8 91011
// Create tonic/ArunaAPI request to fetch all not activated usersletget_request=GetNotActivatedUsersRequest{};// Send the request to the AOS instance gRPC gatewayletunactivated=user_client.get_not_activated_users(request).await.unwrap().into_inner();// Do something with the responseprintln!("{:#?}",unactivated);
1 2 3 4 5 6 7 8 9101112131415
// Create tonic/ArunaAPI request for user activationletuser_id=uuid::Uuid::parse("12345678-1234-1234-1234-123456789999").unwrap();letactivate_request=ActivateUserRequest{user_id: user_id.to_string()};// Send the request to the AOS instance gRPC gatewayletactivate_response=user_client.activate_user(activate_request).await.unwrap().into_inner();// Do something with the responseprintln!("Activated user: {:#?}",activate_response.user_id)
12345678
# Create tonic/ArunaAPI request to fetch all not activated usersrequest=GetNotActivatedUsersRequest()# Send the request to the AOS instance gRPC gatewayresponse=client.user_client.GetNotActivatedUsers(request=request)# Do something with the responseprint(f'{response}')
1 2 3 4 5 6 7 8 910
# Create tonic/ArunaAPI request for user activationrequest=ActivateUserRequest(user_id="<user-id>"# Has to be a valid UUID v4 of a registered user)# Send the request to the AOS instance gRPC gatewayresponse=client.user_client.ActivateUser(request=request)# Do something with the responseprint(f'{response}')
Who Am I / What Am I
To check which user a token is associated with or get information about the current users permissions, you can use the UserService API.
Note
Only AOS instance administrators can request user information of other users.
1234
# Native JSON request to fetch user information associated with authorization token
curl-H"Authorization: Bearer <API-Or-OIDC_TOKEN>"\-H"Content-Type: application/json"\-XGEThttps://<URL-to-AOS-instance-API-gateway>/v1/user
1234
# Native JSON request to fetch user information associated with the provided user id
curl-H"Authorization: Bearer <API-Or-OIDC_TOKEN>"\-H"Content-Type: application/json"\-XGEThttps://<URL-to-AOS-instance-API-gateway>/v1/user?userId=<user-id>
1 2 3 4 5 6 7 8 91011121314151617
// Create tonic/ArunaAPI request to fetch user info of current userletget_request=GetUserRequest{user_id: "".to_string()};// Send the request to the AOS instance gRPC gatewayletresponse=user_client.get_user(get_request).await.unwrap().into_inner();// Do something with the responseprintln!("Received permission info for user: {:#?}",response.user);println!("Received project permissions:");forpermissioninresponse.project_permissions{println!("{:#?}",permission);}
12345678
# Create tonic/ArunaAPI request to fetch user info of current userrequest=GetUserRequest()# Send the request to the AOS instance gRPC gatewayresponse=client.user_client.GetUser(request=request)# Do something with the responseprint(f'{response}')