Wstęp
Interfejs API rejestracji typu zero-touch pomaga sprzedawcom urządzeń zautomatyzować integrację. Narzędzia sprzedażowe w Twojej organizacji mogą zostać zintegrowane z rejestracją typu zero-touch, zwiększając w ten sposób wydajność Twoich użytkowników i klientów. Używaj interfejsu API, aby pomagać użytkownikom:
- Przypisz kupione urządzenia do konta rejestracji typu zero-touch klienta.
- Utwórz konto rejestracji typu zero-touch dla klienta.
- Dołącz do urządzeń metadane dotyczące numerów telefonów i zamówień organizacji.
- Twórz raporty o urządzeniach przypisanych do klientów.
Ten dokument stanowi wprowadzenie do interfejsu API i wyjaśnia występujące w nim wzorce. Jeśli chcesz samodzielnie poznać interfejs API, skorzystaj z krótkiego wprowadzenia do Java, .NET lub Pythona.
Pojęcia związane z interfejsami API
Interfejs API to podstawowe zasoby obejmujące klientów i urządzenia. Aby utworzyć klientów, zadzwoń pod numer create
. Możesz tworzyć urządzenia za pomocą metod interfejsu API deklaracji (patrz niżej). Twoja organizacja może też tworzyć klientów i urządzenia za pomocą portalu do rejestracji typu zero-touch.
- Klient
- Firmy, którym Twoja organizacja sprzedaje urządzenia. Klienci mają właściwości
name
iID
. Użyj konta klienta, gdy chcesz zgłosić własność lub znaleźć jego urządzenia. Więcej informacji:Customer
. - Urządzenie
- urządzenie z Androidem lub ChromeOS sprzedawane przez Twoją organizację i obsługujące rejestrację typu zero-touch. Urządzenia mają identyfikatory sprzętu, metadane i roszczenia klientów. Urządzenia stanowią centralny element interfejsu API, więc można ich używać w niemal wszystkich metodach. Więcej informacji:
Device
. - DeviceIdentifier
- Zawiera identyfikatory sprzętowe (np. IMEI lub MEID), aby umożliwić identyfikację wyprodukowanego urządzenia. Użyj
DeviceIdentifier
, aby ustawić kierowanie na urządzenie, które chcesz znaleźć, zaktualizować lub zgłosić do niego prawa. Więcej informacji znajdziesz w artykule Identyfikatory. - DeviceMetadata
- Przechowuje pary klucz-wartość metadanych dla urządzenia. Przechowuj metadane organizacji w
DeviceMetadata
. Więcej informacji znajdziesz w artykule Metadane urządzenia.
Listę wszystkich metod i zasobów interfejsu API, z których może korzystać Twoja aplikacja, znajdziesz w dokumentacji interfejsu API.
Tworzenie klientów
W przypadku urządzeń z Androidem sprzedawca odpowiada za utworzenie konta klienta w imieniu klienta. Klient będzie używać tego konta, aby uzyskać dostęp do portalu rejestracji typu zero-touch, aby skonfigurować ustawienia obsługi administracyjnej urządzeń. Nie jest to konieczne w przypadku urządzeń z ChromeOS, które mają już konto Google Workspace, za pomocą którego będą konfigurować ustawienia obsługi administracyjnej.
Aby utworzyć konta klientów na potrzeby rejestracji typu zero-touch, możesz wywołać metodę interfejsu API create
. Klienci widzą nazwę firmy w portalu rejestracji typu zero-touch, więc użytkownik aplikacji powinien potwierdzić, że jest prawidłowa. Po utworzeniu klienta nie możesz już zmienić jego nazwy.
Aby zostać właścicielem, musisz podać co najmniej jeden firmowy adres e-mail powiązany z kontem Google. Przez interfejs API nie można używać osobistych kont Gmail. Jeśli klient potrzebuje pomocy w powiązaniu konta, wyślij instrukcje podane w artykule Przypisywanie konta Google.
Gdy utworzysz klienta za pomocą interfejsu API, będzie on zarządzać dostępem swoich pracowników do portalu – nie możesz edytować użytkowników klientów za pomocą interfejsu API. Fragment kodu poniżej pokazuje, jak możesz utworzyć klienta:
Java
// Provide the customer data as a Company type. // The API requires a name and owners. Company customer = new Company(); customer.setCompanyName("XYZ Corp"); customer.setOwnerEmails(Arrays.asList("liz@example.com", "darcy@example.com")); customer.setAdminEmails(Collections.singletonList("jane@example.com")); // Use our reseller ID for the parent resource name. String parentResource = String.format("partners/%d", PARTNER_ID); // Call the API to create the customer using the values in the company object. CreateCustomerRequest body = new CreateCustomerRequest(); body.setCustomer(customer); Company response = service.partners().customers().create(parentResource, body).execute();
.NET
// Provide the customer data as a Company type. // The API requires a name and owners. var customer = new Company { CompanyName = "XYZ Corp", OwnerEmails = new String[] { "liz@example.com", "darcy@example.com" }, AdminEmails = new String[] { "jane@example.com" } }; // Use our reseller ID for the parent resource name. var parentResource = String.Format("partners/{0}", PartnerId); // Call the API to create the customer using the values in the company object. var body = new CreateCustomerRequest { Customer = customer }; var request = service.Partners.Customers.Create(body, parentResource); var response = request.Execute();
Python
# Provide the customer data as a Company type. The API requires # a name and at least one owner. company = {'companyName':'XYZ Corp', \ 'ownerEmails':['liz@example.com', 'darcy@example.com'], \ 'adminEmails':['jane@example.com']} # Use our reseller ID for the parent resource name. parent_resource = 'partners/{0}'.format(PARTNER_ID) # Call the API to create the customer using the values in the company object. response = service.partners().customers().create(parent=parent_resource, body={'customer':company}).execute()
Więcej informacji o rolach właściciela i administratora pracowników klienta znajdziesz w artykule Użytkownicy portalu.
Zarezerwuj urządzenia dla klientów
Po zakupie urządzeń klienci powinni skonfigurować dla nich ustawienia obsługi administracyjnej na swoich kontach. Zarezerwowanie urządzenia powoduje dodanie go do rejestracji typu zero-touch i umożliwia klientowi skonfigurowanie ustawień obsługi administracyjnej.
Rekord obsługi administracyjnej urządzenia zawiera sekcję rejestracji typu zero-touch. Aby przypisać urządzenie, zarezerwuj dla klienta sekcję rejestracji typu zero-touch dla rekordu. Wywołaj metody partners.devices.claim
lub partners.devices.claimAsync
, podając klienta jako argument. Zawsze podawaj SECTION_TYPE_ZERO_TOUCH
jako wartość parametru sectionType
.
Aby móc zarezerwować to samo urządzenie dla innego klienta, musisz najpierw cofnąć rezerwację tego urządzenia (patrz poniżej). Podczas tworzenia nowego urządzenia podczas tworzenia nowego urządzenia validate pola DeviceIdentifier
, w tym numer IMEI lub MEID lub numer seryjny, nazwę producenta i model oraz poświadczony identyfikator urządzenia z ChromeOS.
Ten fragment kodu pokazuje, jak zgłosić własność urządzenia:
Java
// Identify the device to claim. DeviceIdentifier identifier = new DeviceIdentifier(); // The manufacturer value is optional but recommended for cellular devices identifier.setManufacturer("Google"); identifier.setImei("098765432109875"); // Create the body to connect the customer with the device. ClaimDeviceRequest body = new ClaimDeviceRequest(); body.setDeviceIdentifier(identifier); body.setCustomerId(customerId); body.setSectionType("SECTION_TYPE_ZERO_TOUCH"); // Claim the device. ClaimDeviceResponse response = service.partners().devices().claim(PARTNER_ID, body).execute();
.NET
// Identify the device to claim. var deviceIdentifier = new DeviceIdentifier { // The manufacturer value is optional but recommended for cellular devices Manufacturer = "Google", Imei = "098765432109875" }; // Create the body to connect the customer with the device. ClaimDeviceRequest body = new ClaimDeviceRequest { DeviceIdentifier = deviceIdentifier, CustomerId = CustomerId, SectionType = "SECTION_TYPE_ZERO_TOUCH" }; // Claim the device. var response = service.Partners.Devices.Claim(body, PartnerId).Execute();
Python
# Identify the device to claim. # The manufacturer value is optional but recommended for cellular devices device_identifier = {'manufacturer':'Google', 'imei':'098765432109875'} # Create the body to connect the customer with the device. request_body = {'deviceIdentifier':device_identifier, \ 'customerId':customer_id, \ 'sectionType':'SECTION_TYPE_ZERO_TOUCH'} # Claim the device. response = service.partners().devices().claim(partnerId=PARTNER_ID, body=request_body).execute()
Usuwanie rezerwacji urządzeń
Twoja organizacja może usunąć rezerwację urządzenia od klienta. Gdy cofniesz rezerwację urządzenia,
zostanie ono usunięte z rejestracji typu zero-touch. Sprzedawca może wycofać rezerwację urządzenia, które chce przenieść na inne konto, zwrócić lub zostało zgłoszone przez pomyłkę.
Wywołaj metodę partners.devices.unclaim
lub partners.devices.unclaimAsync
, aby wycofać rezerwację urządzenia od klienta.
Dostawcy
Możesz ich używać do reprezentowania partnerów sprzedawców w sieci salonów samochodowych, lokalnych operatorów w globalnej sieci sprzedawców lub dowolnej organizacji, która sprzedaje urządzenia w Twoim imieniu. Dostawcy pomagają rozdzielić użytkowników, klientów i urządzenia:
- Tworząc przez Ciebie dostawcy, nie widzą Twojego konta rejestracji typu zero-touch ani kont innych użytkowników.
- Możesz wyświetlać klientów i urządzenia dostawców oraz wyrejestrowywać urządzenia dostawców. Nie możesz jednak przypisywać urządzeń do klientów dostawców.
Na portalu możesz utworzyć dostawców dla swojej organizacji – nie możesz korzystać z interfejsu API. Aby można było utworzyć nowego dostawcę, musisz mieć na koncie rolę Właściciel. Jeśli Twoja organizacja ma dostawców, możesz wywołać metodę partners.vendors.list
, aby wyświetlić listę dostawców, oraz metodę partners.vendors.customers.list
, aby pozyskać klientów dostawcy. Poniższy przykład pokazuje wykorzystanie obu tych metod do wydrukowania raportu zawierającego stan Warunków korzystania z usługi dla klientów dostawców:
Java
// First, get the organization's vendors. String parentResource = String.format("partners/%d", PARTNER_ID); ListVendorsResponse results = service.partners().vendors().list(parentResource).execute(); if (results.getVendors() == null) { return; } // For each vendor, report the company name and a maximum 5 customers. for (Company vendor: results.getVendors()) { System.out.format("\n%s customers\n", vendor.getCompanyName()); System.out.println("---"); // Use the vendor's API resource name as the parent resource. AndroidProvisioningPartner.Partners.Vendors.Customers.List customerRequest = service.partners().vendors().customers().list(vendor.getName()); customerRequest.setPageSize(5); ListVendorCustomersResponse customerResponse = customerRequest.execute(); List<Company> customers = customerResponse.getCustomers(); if (customers == null) { System.out.println("No customers"); break; } else { for (Company customer: customers) { System.out.format("%s: %s\n", customer.getCompanyName(), customer.getTermsStatus()); } } }
.NET
// First, get the organization's vendors. var parentResource = String.Format("partners/{0}", PartnerId); var results = service.Partners.Vendors.List(parentResource).Execute(); if (results.Vendors == null) { return; } // For each vendor, report the company name and a maximum 5 customers. foreach (Company vendor in results.Vendors) { Console.WriteLine("\n{0} customers", vendor); Console.WriteLine("---"); // Use the vendor's API resource name as the parent resource. PartnersResource.VendorsResource.CustomersResource.ListRequest customerRequest = service.Partners.Vendors.Customers.List(vendor.Name); customerRequest.PageSize = 5; var customerResponse = customerRequest.Execute(); IList<Company> customers = customerResponse.Customers; if (customers == null) { Console.WriteLine("No customers"); break; } else { foreach (Company customer in customers) { Console.WriteLine("{0}: {1}", customer.Name, customer.TermsStatus); } } }
Python
# First, get the organization's vendors. parent_resource = 'partners/{0}'.format(PARTNER_ID) vendor_response = service.partners().vendors().list( parent=parent_resource).execute() if 'vendors' not in vendor_response: return # For each vendor, report the company name and a maximum 5 customers. for vendor in vendor_response['vendors']: print '\n{0} customers'.format(vendor['companyName']) print '---' # Use the vendor's API resource name as the parent resource. customer_response = service.partners().vendors().customers().list( parent=vendor['name'], pageSize=5).execute() if 'customers' not in customer_response: print 'No customers' break for customer in customer_response['customers']: print ' {0}: {1}'.format(customer['name'], customer['termsStatus'])
Jeśli masz kolekcję urządzeń, warto wiedzieć, który sprzedawca lub dostawca odebrał urządzenie. Aby uzyskać numeryczny identyfikator sprzedawcy, sprawdź wartość pola resellerId
w rejestrze roszczenia urządzenia.
Twoja organizacja może wycofać rezerwację urządzenia objętego roszczeniem przez dostawcę. W przypadku innych wywołań interfejsu API, które modyfikują urządzenia, przed wywołaniem metody interfejsu API sprawdź, czy organizacja zarezerwowała urządzenie. Aby to zrobić:
Java
// Get the devices claimed for two customers: one of our organization's // customers and one of our vendor's customers. FindDevicesByOwnerRequest body = new FindDevicesByOwnerRequest(); body.setSectionType("SECTION_TYPE_ZERO_TOUCH"); body.setCustomerId(Arrays.asList(resellerCustomerId, vendorCustomerId)); body.setLimit(MAX_PAGE_SIZE); FindDevicesByOwnerResponse response = service.partners().devices().findByOwner(PARTNER_ID, body).execute(); if (response.getDevices() == null) { return; } for (Device device: response.getDevices()) { // Confirm the device was claimed by our reseller and not a vendor before // updating metadata in another method. for (DeviceClaim claim: device.getClaims()) { if (claim.getResellerId() == PARTNER_ID) { updateDeviceMetadata(device.getDeviceId()); break; } } }
.NET
// Get the devices claimed for two customers: one of our organization's // customers and one of our vendor's customers. FindDevicesByOwnerRequest body = new FindDevicesByOwnerRequest { Limit = MaxPageSize, SectionType = "SECTION_TYPE_ZERO_TOUCH", CustomerId = new List<long?> { resellerCustomerId, vendorCustomerId } }; var response = service.Partners.Devices.FindByOwner(body, PartnerId).Execute(); if (response.Devices == null) { return; } foreach (Device device in response.Devices) { // Confirm the device was claimed by our reseller and not a vendor before // updating metadata in another method. foreach (DeviceClaim claim in device.Claims) { if (claim.ResellerId == PartnerId) { UpdateDeviceMetadata(device.DeviceId); break; } } }
Python
# Get the devices claimed for two customers: one of our organization's # customers and one of our vendor's customers. request_body = {'limit':MAX_PAGE_SIZE, \ 'pageToken':None, \ 'customerId':[reseller_customer_id, vendor_customer_id], \ 'sectionType':'SECTION_TYPE_ZERO_TOUCH'} response = service.partners().devices().findByOwner(partnerId=PARTNER_ID, body=request_body).execute() for device in response['devices']: # Confirm the device was claimed by our reseller and not a vendor before # updating metadata in another method. for claim in device['claims']: if claim['resellerId'] == PARTNER_ID: update_device_metadata(device['deviceId']) break
Długo trwające operacje wsadowe
Interfejs API zawiera asynchroniczne wersje metod urządzeń.
Metody te umożliwiają przetwarzanie wsadowe wielu urządzeń, a metody synchroniczne przetwarzają każde żądanie do interfejsu API po jednym urządzeniu. Nazwy metod asynchronicznych mają sufiks asynchroniczny, na przykład claimAsync
.
Asynchroniczne metody interfejsu API zwracają wynik przed zakończeniem przetwarzania. Metody asynchroniczne pomagają też aplikacji (lub narzędziu) zachować reagowanie na działania użytkowników w czasie, gdy oczekują na zakończenie długotrwałej operacji. Aplikacja powinna okresowo sprawdzać stan operacji.
Operacje
Operation
służy do śledzenia długo trwającej operacji zbiorczej. Skuteczne wywołanie metody asynchronicznej zwraca odwołanie do operacji w odpowiedzi. Poniższy fragment kodu JSON pokazuje typową odpowiedź po wywołaniu updateMetadataAsync
:
{
"name": "operations/apibatchoperation/1234567890123476789"
}
Każda operacja zawiera listę poszczególnych zadań. Wywołaj operations.get
, aby uzyskać informacje o stanie i wynikach zadań zawartych w operacji. Poniższy fragment kodu pokazuje,
jak to można zrobić. Wszystkie błędy musisz naprawić we własnej aplikacji.
Java
// Build out the request body to apply the same order number to a customer's // purchase of 2 devices. UpdateMetadataArguments firstUpdate = new UpdateMetadataArguments(); firstUpdate.setDeviceMetadata(metadata); firstUpdate.setDeviceId(firstTargetDeviceId); UpdateMetadataArguments secondUpdate = new UpdateMetadataArguments(); secondUpdate.setDeviceMetadata(metadata); secondUpdate.setDeviceId(firstTargetDeviceId); // Start the device metadata update. UpdateDeviceMetadataInBatchRequest body = new UpdateDeviceMetadataInBatchRequest(); body.setUpdates(Arrays.asList(firstUpdate, secondUpdate)); Operation response = service .partners() .devices() .updateMetadataAsync(PARTNER_ID, body) .execute(); // Assume the metadata update started, so get the Operation for the update. Operation operation = service.operations().get(response.getName()).execute();
.NET
// Build out the request body to apply the same order number to a customer's // purchase of 2 devices. var updates = new List<UpdateMetadataArguments> { new UpdateMetadataArguments { DeviceMetadata = metadata, DeviceId = firstTargetDeviceId }, new UpdateMetadataArguments { DeviceMetadata = metadata, DeviceId = secondTargetDeviceId } }; // Start the device metadata update. UpdateDeviceMetadataInBatchRequest body = new UpdateDeviceMetadataInBatchRequest { Updates = updates }; var response = service.Partners.Devices.UpdateMetadataAsync(body, PartnerId).Execute(); // Assume the metadata update started, so get the Operation for the update. Operation operation = service.Operations.Get(response.Name).Execute();
Python
# Build out the request body to apply the same order number to a customer's # purchase of 2 devices. updates = [{'deviceMetadata':metadata,'deviceId':first_target_device_id}, {'deviceMetadata':metadata,'deviceId':second_target_device_id}] # Start the device metadata update. response = service.partners().devices().updateMetadataAsync( partnerId=PARTNER_ID, body={'updates':updates}).execute() # Assume the metadata update started, so get the Operation for the update. operation = service.operations().get(name=response['name']).execute()
Aby dowiedzieć się, czy operacja została zakończona, sprawdź ją na polu done
z wartością true
. Jeśli brakuje done
lub false
, operacja jest nadal wykonywana.
Odpowiedzi
Po zakończeniu operacji interfejs API aktualizuje ją o jej wynik, nawet jeśli nie udało się wykonać wszystkich zadań lub nie wykonać żadnego działania. Pole response
jest obiektem DevicesLongRunningOperationResponse
, który określa przetwarzanie każdego urządzenia w ramach operacji.
Zbadaj pole successCount
, aby skutecznie sprawdzić, czy jakieś zadanie się nie udało, i uniknąć iteracji z użyciem obszernych list wyników. Pole perDeviceStatus
obiektu DevicesLongRunningOperationResponse
zawiera listę instancji OperationPerDevice
zawierających szczegółowe informacje o poszczególnych urządzeniach w ramach operacji. Kolejność na liście odpowiada zadaniom w pierwotnym żądaniu.
Każde zadanie OperationPerDevice
zawiera pole result
i przypomnienie z podsumowaniem żądania otrzymanego przez serwer. Sprawdź w polu result
, czy udało się wykonać zadanie.
Poniższy fragment kodu JSON pokazuje część typowej odpowiedzi z operacji po wywołaniu funkcji updateMetadataAsync
:
"response": {
"perDeviceStatus": [
{
"result": {
"deviceId": "12345678901234567",
"status": "SINGLE_DEVICE_STATUS_SUCCESS"
},
"updateMetadata": {
"deviceId": "12345678901234567",
"deviceMetadata": {
"entries": {
"phonenumber": "+1 (800) 555-0100"
}
}
}
}
],
"successCount": 1
}
Śledź postęp
Jeśli aplikacja musi śledzić postęp, należy co jakiś czas ponownie pobierać operację. Pole metadata
zawiera instancję DevicesLongRunningOperationMetadata
, która ułatwia aplikacji sprawdzanie najnowszego postępu uruchomionej operacji. Aby śledzić postęp operacji, użyj pól DevicesLongRunningOperationMetadata
wymienionych w tej tabeli:
Pole | Typowe zastosowanie |
---|---|
processingStatus
|
Zmienia się z BATCH_PROCESS_PENDING na BATCH_PROCESS_IN_PROGRESS , a w miarę postępów operacji na BATCH_PROCESS_PROCESSED . |
progress
|
Odsetek przetworzonych aktualizacji. Na podstawie tych informacji Twoja aplikacja może
oszacować czas zakończenia. Ze względu na to, że podczas kończenia operacji wartość progress może wynosić 100, dlatego sprawdź w polu done działanie, czy operacja została zakończona i przyniosła oczekiwany rezultat. |
devicesCount
|
Pokazuje liczbę aktualizacji w ramach operacji. Ta wartość może różnić się od liczby aktualizacji w żądaniu, jeśli interfejs API nie może przeanalizować niektórych aktualizacji. |
Poniżej znajdziesz uproszczony przykład pokazujący, jak aplikacja może używać metadanych postępu do ustawiania interwałów odpytywania. W aplikacji możesz potrzebować bardziej zaawansowanego mechanizmu uruchamiania zadań do odpytywania. Musisz też dodać obsługę błędów.
Java
// Milliseconds between polling the API. private static long MIN_INTERVAL = 2000; private static long MAX_INTERVAL = 10000; // ... // Start the device metadata update. Operation response = service .partners() .devices() .updateMetadataAsync(PARTNER_ID, body) .execute(); String operationName = response.getName(); // Start polling for completion. long startTime = new Date().getTime(); while (true) { // Get the latest update on the operation's progress using the API. Operation operation = service.operations().get(operationName).execute(); if (operation.get("done") != null && operation.getDone()) { // The operation is finished. Print the status. System.out.format("Operation complete: %s of %s successful device updates\n", operation.getResponse().get("successCount"), operation.getMetadata().get("devicesCount")); break; } else { // Estimate how long the operation *should* take - within min and max value. BigDecimal opProgress = (BigDecimal) operation.getMetadata().get("progress"); double progress = opProgress.longValue(); long interval = MAX_INTERVAL; if (progress > 0) { interval = (long) ((new Date().getTime() - startTime) * ((100.0 - progress) / progress)); } interval = Math.max(MIN_INTERVAL, Math.min(interval, MAX_INTERVAL)); // Sleep until the operation should be complete. Thread.sleep(interval); } }
.NET
// Milliseconds between polling the API. private static double MinInterval = 2000; private static double MaxInterval = 10000; // ... // Start the device metadata update. var response = service.Partners.Devices.UpdateMetadataAsync(body, PartnerId).Execute(); var operationName = response.Name; // Start polling for completion. var startTime = DateTime.Now; while (true) { // Get the latest update on the operation's progress using the API. Operation operation = service.Operations.Get(operationName).Execute(); if (operation.Done == true) { // The operation is finished. Print the status. Console.WriteLine("Operation complete: {0} of {1} successful device updates", operation.Response["successCount"], operation.Metadata["devicesCount"]); break; } else { // Estimate how long the operation *should* take - within min and max value. double progress = (double)(long)operation.Metadata["progress"]; double interval = MaxInterval; if (progress > 0) { interval = DateTime.Now.Subtract(startTime).TotalMilliseconds * ((100.0 - progress) / progress); } interval = Math.Max(MinInterval, Math.Min(interval, MaxInterval)); // Sleep until the operation should be complete. System.Threading.Thread.Sleep((int)interval); } }
Python
# Seconds between polling the API. MIN_INTERVAL = 2; MAX_INTERVAL = 10; # ... # Start the device metadata update response = service.partners().devices().updateMetadataAsync( partnerId=PARTNER_ID, body={'updates':updates}).execute() op_name = response['name'] start_time = time.time() # Start polling for completion while True: # Get the latest update on the operation's progress using the API op = service.operations().get(name=op_name).execute() if 'done' in op and op['done']: # The operation is finished. Print the status. print('Operation complete: {0} of {1} successful device updates'.format( op['response']['successCount'], op['metadata']['devicesCount'] )) break else: # Estimate how long the operation *should* take - within min and max. progress = op['metadata']['progress'] interval = MIN_INTERVAL if progress > 0: interval = (time.time() - start_time) * ((100.0 - progress) / progress) interval = max(MIN_INTERVAL, min(interval, MAX_INTERVAL)) # Sleep until the operation should be complete. time.sleep(interval)
Wybierz metodę ankietowania odpowiednią dla użytkowników Twojej aplikacji. Niektórzy użytkownicy aplikacji mogą korzystać z regularnych aktualizacji, gdy oczekują na zakończenie procesu.
Wyniki podzielone na strony
Metoda partners.devices.findByOwner
API może zwracać bardzo duże listy urządzeń. Aby zmniejszyć rozmiar odpowiedzi, ta i inne metody interfejsu API (np. partners.devices.findByIdentifier
) obsługują wyniki z podziałem na strony. Dzięki temu aplikacja może iteracyjnie prosić o duże listy i przetwarzać je pojedynczo.
Po wywołaniu metody interfejsu API sprawdź, czy odpowiedź zawiera wartość nextPageToken
. Jeśli nextPageToken
nie ma wartości null
, aplikacja może użyć jej do pobrania innej strony urządzeń, ponownie wywołując tę metodę. Musisz ustawić górny limit liczby urządzeń w parametrze limit
. Jeśli nextPageToken
to null
, aplikacja zażądała ostatniej strony.
W przykładowej metodzie poniżej pokazujemy, jak aplikacja może drukować listę urządzeń (po jednej stronie):
Java
private static long MAX_PAGE_SIZE = 10; // ... /** * Demonstrates how to loop through paginated lists of devices. * @param pageToken The token specifying which result page to return. * @throws IOException If the zero-touch API call fails. */ private void printDevices(String pageToken) throws IOException { // Create the request body to find the customer's devices. FindDevicesByOwnerRequest body = new FindDevicesByOwnerRequest(); body.setLimit(MAX_PAGE_SIZE); body.setSectionType("SECTION_TYPE_ZERO_TOUCH"); body.setCustomerId(Collections.singletonList(targetCustomerId)); // Call the API to get a page of Devices. Send a page token from the method // argument (might be None). If the page token is None, the API returns the first page. FindDevicesByOwnerResponse response = service.partners().devices().findByOwner(PARTNER_ID, body).execute(); if (response.getDevices() == null) { return; } // Print the devices included in this page of results. for (Device device: response.getDevices()) { System.out.format("Device %s\n", device.getName()); } System.out.println("---"); // Check to see if another page of devices is available. If yes, // fetch and print the devices. if (response.getNextPageToken() != null) { this.printDevices(response.getNextPageToken()); } } // ... // Pass null to start printing the first page of devices. printDevices(null);
.NET
private static int MaxPageSize = 10; // ... /// <summary>Demonstrates how to loop through paginated lists of devices.</summary> /// <param name="pageToken">The token specifying which result page to return.</param> private void PrintDevices(string pageToken) { // Create the request body to find the customer's devices. FindDevicesByOwnerRequest body = new FindDevicesByOwnerRequest { PageToken = pageToken, Limit = MaxPageSize, SectionType = "SECTION_TYPE_ZERO_TOUCH", CustomerId = new List<long?> { targetCustomerId } }; // Call the API to get a page of Devices. Send a page token from the method // argument (might be None). If the page token is None, the API returns the first page. var response = service.Partners.Devices.FindByOwner(body, PartnerId).Execute(); if (response.Devices == null) { return; } // Print the devices included in this page of results. foreach (Device device in response.Devices) { Console.WriteLine("Device: {0}", device.Name); } Console.WriteLine("---"); // Check to see if another page of devices is available. If yes, // fetch and print the devices. if (response.NextPageToken != null) { this.PrintDevices(response.NextPageToken); } } // ... // Pass null to start printing the first page of devices. PrintDevices(null);
Python
MAX_PAGE_SIZE = 10; # ... def print_devices(page_token): """Demonstrates how to loop through paginated lists of devices. Args: page_token: The token specifying which result page to return. """ # Create the body to find the customer's devices. request_body = {'limit':MAX_PAGE_SIZE, \ 'pageToken':page_token, \ 'customerId':[target_customer_id], \ 'sectionType':'SECTION_TYPE_ZERO_TOUCH'} # Call the API to get a page of Devices. Send a page token from the method # argument (might be None). If the page token is None, # the API returns the first page. response = service.partners().devices().findByOwner(partnerId=PARTNER_ID, body=request_body).execute() # Print the devices included in this page of results. for device in response['devices']: print 'Device: {0}'.format(device['name']) print '---' # Check to see if another page of devices is available. If yes, # fetch and print the devices. if 'nextPageToken' in response: print_devices(response['nextPageToken']) # ... # Pass None to start printing the first page of devices. print_devices(None);
Dalsze kroki
Skoro już wiesz, jak działa interfejs API, zapoznaj się z przykładami w krótkim wprowadzeniu do Java, .NET lub Pythona.