oracle/oci-python-sdk

resource name not getting cost analysis (Usageapi cllent)

Gopichand-Heeddata opened this issue · 13 comments

In the usage API call, many values return as "none". In the JSON response, the "resource name" key is present but its value is null. Could you assist me in making the correct API call to retrieve these values? @adizohar, for your help

  "compartment_id": null,
  "compartment_name": null,
  "compartment_path": null,
  "computed_amount": null,
  "computed_quantity": 0.0,
  "currency": " ",
  "discount": null,
  "is_forecast": false,
  "list_rate": null,
  "overage": null,
  "overages_flag": null,
  "platform": null,
 **"resource_name": null,**
  "service": "Virtual Cloud Network",
  "shape": null,
 "tenant_id": null,
  "tenant_name": null,
  "time_usage_ended": "2023-05-14T00:00:00+00:00",
  "time_usage_started": "2023-05-01T00:00:00+00:00",
  "unit": null,
  **"unit_price": null,**
  "weight": null

UsageAPI aggregate the data based on grouping, those fields only be populated if you group by them, please read the documentation for the usage_api

If you want the resource_name, try to use group_by the resource_name

@adizohar Okay but I am getting errors like unsupported key

Traceback (most recent call last):
 File "/home/ubuntu/Desktop/oci-api-tests/API/CostApI/costAnalayis.py", line 29, in <module>
   request_summarized_usages = usage_client.request_summarized_usages(
 File "/home/ubuntu/.local/lib/python3.8/site-packages/oci/usage_api/usageapi_client.py", line 2448, in request_summarized_usages
   return retry_strategy.make_retrying_call(
 File "/home/ubuntu/.local/lib/python3.8/site-packages/oci/retry/retry.py", line 308, in make_retrying_call
   response = func_ref(*func_args, **func_kwargs)
 File "/home/ubuntu/.local/lib/python3.8/site-packages/oci/base_client.py", line 535, in call_api
   response = self.request(request, allow_control_chars, operation_name, api_reference_link)
 File "/home/ubuntu/.local/lib/python3.8/site-packages/circuitbreaker.py", line 159, in wrapper
   return call(function, *args, **kwargs)
 File "/home/ubuntu/.local/lib/python3.8/site-packages/circuitbreaker.py", line 170, in call
   return func(*args, **kwargs)
 File "/home/ubuntu/.local/lib/python3.8/site-packages/oci/base_client.py", line 726, in request
   self.raise_service_error(request, response, service_code, message, operation_name, api_reference_link, target_service, request_endpoint, client_version, timestamp, deserialized_data)
 File "/home/ubuntu/.local/lib/python3.8/site-packages/oci/base_client.py", line 891, in raise_service_error
   raise exceptions.ServiceError(
oci.exceptions.ServiceError: {'target_service': 'usageapi', 'status': 400, 'code': 'InvalidParameter', 'opc-request-id': '91FDD27733B4484CADB85ACD14C0FB86/AB885EC69788B8BFF01FB5013CF79CBD/1B0E35632ED41672CE641373EFEE0B59', 'message': 'UnsupportedKey resource_name is in groupBy', 'operation_name': 'request_summarized_usages', 'timestamp': '2024-04-04T18:25:11.063243+00:00', 'client_version': 'Oracle-PythonSDK/2.125.0', 'request_endpoint': 'POST https://usageapi.ap-mumbai-1.oci.oraclecloud.com/20200107/usage', 'logging_tips': 'To get more info on the failing request, refer to https://docs.oracle.com/en-us/iaas/tools/python/latest/logging.html for ways to log the request/response details.', 'troubleshooting_tips': "See https://docs.oracle.com/iaas/Content/API/References/apierrors.htm#apierrors_400__400_invalidparameter for more information about resolving this error. Also see https://docs.oracle.com/iaas/api/#/en/usage/20200107/UsageSummary/RequestSummarizedUsages for details on this operation's requirements. If you are unable to resolve this usageapi issue, please contact Oracle support and provide them this full error message."}

import oci


config = oci.config.from_file("~/.oci/config", "DEFAULT")
tenant_id = config['tenancy']
time_usage_started = "2023-02-14T00:00:00Z"
time_usage_ended = "2023-05-14T00:00:00Z"

unique_combinations={}  
print("Tenant Name  : " + str(tenant_id))

usage_client = oci.usage_api.UsageapiClient(config)
requestSummarizedUsagesDetails = oci.usage_api.models.RequestSummarizedUsagesDetails(
    tenant_id=tenant_id,
    granularity='DAILY',
    query_type='COST',
    group_by=['region', 'service','resource_name','resourceId'],
    time_usage_started=time_usage_started,
    time_usage_ended=time_usage_ended,
    compartment_depth=2
)

request_summarized_usages = usage_client.request_summarized_usages(
    requestSummarizedUsagesDetails,
    retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY
)
# Create an empty dictionary to store the unique combinations and their sum
unique_combinations = {}



for item in request_summarized_usages.data.items:
 print(item)

Indeed, resource_name is not supported key, it is not in the documentation, it was added for future functionality

https://docs.oracle.com/en-us/iaas/tools/python/2.125.1/api/usage_api/models/oci.usage_api.models.RequestSummarizedUsagesDetails.html

Currently Supported - “compartmentName”, “compartmentPath”, “compartmentId”, “platform”, “region”, “logicalAd”, “resourceId”, “tenantId”, “tenantName”]`

Currently Supported - “compartmentName”, “compartmentPath”, “compartmentId”, “platform”, “region”, “logicalAd”, “resourceId”, “tenantId”, “tenantName”]`

Okay thankyou for confirming @adizohar, when we able to get resource_name in usageapi.
is there any way to get the cost by resource name ?

It was requested by many customers, metering team is working on it., I don't have any timeline or info, but will let you know once I have

Hi, @adizohar ,

how can I get the resource name other than the usage API call is there any other API call available or any other search options available
if any other approaches are there, let me know.

The easiest way is to use the search api:

#################################################################################
# search.py
# https://docs.oracle.com/en-us/iaas/Content/Search/Concepts/queryoverview.htm
#################################################################################
import oci

config_file = "~/.oci/config"
config = oci.config.from_file(config_file, "DEFAULT")
resource_ocid = "ocid1.instance.oc1.iad.xxxxxxxxxxx"
query = "query all resources where identifier == '" + resource_ocid + "'"

search_client = oci.resource_search.ResourceSearchClient(config)
reponse_data = search_client.search_resources(
    search_details=oci.resource_search.models.StructuredSearchDetails(query=query)
).data

name = reponse_data.items[0].display_name if reponse_data.items else ""
print(name)

Thanks @adizohar

in the above api call I need to do an individual search for every resource I need.
in this approach if i need 100 resources details, then it is not a better approach or if we need more resources like more than 100 like wise.
is there any better approach.
what do you suggest?

For now, Search is the best option
You can also run showoci
Produce CSV files, there is one CSV all_resources.csv which has most of the resources

hi, @adizohar

does we have any limitations to the api call we made using search api, like the number of api calls can be made to that particular tenancy.

as per my knowledge we can made only 1000 api calls for a particular tenancy. is it correct?

I am not aware of any API limitation, if you call too quickly, the service limits you and the retry option will work
Please check - https://docs.oracle.com/en-us/iaas/tools/python/2.125.2/sdk_behaviors/retries.html