Softlayer API To get a particular Storage ID for a particular Order ID - api

After placing order for a storage in softlayer, I need to get that storage id for a particular order id.The api call i am using, is giving me a list of storage ID. But, if user orders for a storage, only one storage id the user should get right.
So, the api is not properly filtering and not getting a particularly storage id for a particular order id . The rest api, i am using is given below and please tell me what should be the proper filtering ,
"https://[username]:[apikey]#api.softlayer.com/rest/v3/SoftLayer_Account/getIscsiNetworkStorage.json?objectFilter={"networkStorage": {"billingItem": {"nasType": { "operation": "ISCSI"}, "orderItem": {"order": {"id":{"operation":"[orderID]"}}}}}} "
This api is provided by softlayer team
Regards,
Debartha

use this request:
GET https://api.softlayer.com/rest/v3/SoftLayer_Account/getIscsiNetworkStorage?objectMask=mask[billingItem[orderItem[order]]]&objectFilter={"iscsiNetworkStorage": {"billingItem": { "orderItem": {"order": {"id":{"operation":5208963}}}}}}
note: replace 5208963, with your orderID
Basically all the devices must have a billingItem and that billingItem should have orderItem.order.id property, so you can use this filter to get any device using the orderID property, you just to need to make sure that the "iscsiNetworkStorage" value, in the filter, has the same name as the method you are calling (in this case getIscsiNetworkStorage method ), but without the pre-fix "get" and it must start with lower case e.g.
getIscsiNetworkStorage -> iscsiNetworkStorage
Regards

Related

How can I create a device group in Cumulocity with REST

I am writing a service for forwarding our sensor data to Cumulocity platform. I designed the structure so that all the data is first sent to our main tenant and then device data for each customer is forwarded to corresponding tenants with Data Broker.
I can group devices manually and forward by group but I don't want to deal with it every time a new device is added.Sensor data contains customer name. Probably I can add customer name to device properties (like device_type) and use that as a filter but I want to avoid that if possible. So I thought, when a sensor data hits my endpoint, I do something like this:
Look if the device exists in the database.If it exists just publish measurement data.
If not look at the Group database(Just a key-value store containing customer names and managed Object Ids of the corresponding groups from Cumulocity) to see if there is entry for the customer.
If not add an entry and create a group with customer name.Then add the device to the group.
If it exists, just add the device to the group.
I tried adding devices to groups with REST and it works. The problem is I cannot create a device group with REST.
I looked at the Cumulocity API example requests and tried to tweak them a little.
I tried sending POST request to {{url}}/inventory/managedObjects as:
{
"name": "TestDeviceGroup",
"c8y_IsDeviceGroup": {}
}
It returns 201 created but I cannot see the group. When I try to get collection of groups I see it there as a managed object with a new Id.
I tried to add a new device to this object as a child asset.
{{url}}/inventory/managedObjects/{{GroupId}}/childAssets
{
"managedObject": "id:{{deviceId}}"
}
It returns 201 created but device GROUP is not updated.
If I recreate this scenario with a group created with UI and its Id everything works fine and device is added to the group.
As I understand what I create is not a legit device group and that is the main problem. So my question is How can I create device group with REST?
To create the group you were already on the right track you are just missing the correct type. Create your group like this:
POST /inventory/managedObjects
{
"name": "TestDeviceGroup",
"type": "c8y_DeviceGroup",
"c8y_IsDeviceGroup": {}
}
To assign your device to a particular group you can EITHER assign an existing device to an existing group like this (replace the placeholders in <> with your IDs):
POST /inventory/managedObjects/<groupId>/childAssets
{
"managedObject": {"id":"<deviceId>"}
}
Or you can directly create a new device into an existing group like this:
POST /inventory/managedObjects/<groupId>/childAssets
Content-Type: application/vnd.com.nsn.cumulocity.managedobject+json
{
"name": "my device",
"c8y_IsDevice": {}
}

How to get all Storage ID to Authorize with VM ID..?

I want to authorize a storage with VMs. For that I need to have all the VM ID's for a storage and those I get using the following call:
https://[username]:[apikey]#api.softlayer.com/rest/v3/SoftLayer_Network_Storage_Iscsi/9653497/getAllowableVirtualGuests?objectMask=mask[id,fullyQualifiedDomainName]
This gives me all the VM ID's corresponding to 9653497 (storage/order ID). However, I need to have all those storage ID's (like 9653497) which are not assigned to any of the VM's ID. I am using below call to get all storage ID:
https://[username]:[apikey]#api.softlayer.com/rest/v3/SoftLayer_Account/getNetworkStorage?objectMask=mask[id,username,nasType,storageType, billingItem[description,location[id,longName]]]&objectFilter={"networkStorage":{"nasType":{"operation":"ISCSI"},"billingItem":{"description":{"operation":"Endurance Storage"}}}}
the data that you are using for the filter probably are wrong, try to call the get object method GET /SoftLayer_Network_Storage/9653497/getObject?objectMask=mask[nasType,billingItem[description]] and see if the values of the request are the same as of your objectFilter
The filter in your request, gets Block Storage("nasType":{"operation":"ISCSI"}), maybe you need the File Storage. We can remove it to get more "Endurance" items (Block and File).
Please try the following removing some filters:
https://[username]:[apikey]#api.softlayer.com/rest/v3/SoftLayer_Account/getNetworkStorage?objectMask=mask[id,username,nasType,storageType, billingItem[description,location[id,longName]]]&objectFilter={ "networkStorage": { "billingItem": { "description": { "operation": "Endurance Storage" } } } }
Method: GET
if we don't want to get only Endurance, we can remove that filter too.
But when trying to add some properties using objectMasks to SoftLayer_Account::getNetworkStorage like allowableVirtualGuests, that property is not present in SoftLayer_Network_Storage.
For that reason the unique way to get “getAllowableVirtualGuests” is using SoftLayer_Network_Storage::getAllowableVirtualGuests

Instagram API error

I using Instagram API to get user info
api = InstagramAPI(access_token=access_token)
profile = api.user(user_id="kallaucyahoocojp") # I try to put output data to profile variable here
And I get the below error:
DownloadError: Unable to fetch URL: https://api.instagram.com/v1/users/kallaucyahoocojp.json?access_token=(u'1191812153.f78cd79.d2d99595c79d4c23a7994d85ea0d412c', {u'username': u'kallaucyahoocojp', u'bio': u'\u30c4\u30a4\u30c3\u30bf\u30d5\u30a9\u30ed\u30ef\u30fc\u5897\u52a0\u30b5\u30fc\u30d3\u30b9', u'website': u'http://twitter\u30d5\u30a9\u30ed\u30ef\u30fc.jp', u'profile_picture': u'http://images.ak.instagram.com/profiles/anonymousUser.jpg', u'full_name': u'Kallauc', u'id': u'1191812153'})
Can anybody help me to fix it?
You need to pass the numeric-based user id, rather than the username. For example, instead of passing kallaucyahoocojp, you might pass 1234 if t
Here's how to get the ID if you don't have it:
Search for the instagram user id using this endpoint. In the python api:
api.user_search(q="kallaucyahoocojp", count=100)
Check the results for an exact string match on each user name while iterating through the results (calling .lower() to be sure to ignore potential case issues).
If you don't find the user in the first page of results, call to the next page using the max id returned.
Get the user id object from the returned from the matching users search result, then call your original function again with the numeric id.
A couple of very important notes:
Notice that I called the search function for users with a count of 100. You can pick any number, but contrary to other SO posts, the first user is not always the user you want in a search. The search can and will match partials, and not always according to an exact match first. How do I know? I have production instagram apps. I will qualify and say that usually the results are in the first 2-3 matches. Decide what is cheaper; repeated API calls that bring you closer to the limit, or 1 large bulk call where you are certain to get all the results.
The python Instagram API last I checked does a terrible job returning paging information. You actually get the paging URL which defeats the purpose of the python API itself to get additional pages. Your options are extract the next id parameter from the URL using urlparse or something similar, or fix the API to return the paging data as an object per the json (I've done both). What happens is the API itself is discarding part of the json and only giving you the URL which normally you don't want/need.
In your example, here's the search response:
{
"meta": {
"code": 200
},
"data": [
{
"username": "kallaucyahoocojp",
"bio": "ツイッタフォロワー増加サービス",
"website": "http://twitterフォロワー.jp",
"profile_picture": "http://images.ak.instagram.com/profiles/anonymousUser.jpg",
"full_name": "Kallauc",
"id": "1191812153"
}
]
}
Revising your call:
api = InstagramAPI(access_token=access_token)
profile = api.user(user_id="1191812153")
I should note that you may not need to call the user call if you did a search because you may simply have all the info you need. It will depend on what you are doing of course, so I am giving you the general method to use the rest of the user api.
For extracting profile info using Instagram API, userid is required.
The endpoint for extracting userID:
https://api.instagram.com/v1/users/search?q=[username]&access_token=[HERE]
The endpoint for extracting profile info:
https://api.instagram.com/v1/users/[userid]/?access_token=[HERE]
Note that before extracting information, check the login permissions for your access token.

Proper resource names of a REST API

Let's say we are making an invoice API. What is a more appropriate resource?
GET
paid_invoices
due_invoices
all_invoices
or
GET
invoices/all
invoices/due
invoices/paid
Additional question: If your API allows marking invoices as paid what's the proper resource?
PUT //where 3 is the id
invoices/3
or
PUT
pay_invoice/3
I would say:
GET /invoices returns all invoices;
A filter can return either paid or due invoices: GET /invoices?state=paid where state can be paid or due.
To mark an invoice as paid, you can either set the corresponding state to your resource, and then you just have to update (replace actually) it using PUT /invoices/<id>.
Alternatively, you can patch your resource: PATCH /invoices/<id>. This method requires a diff like state=paid for example.
It's just a matter of what you want to send to your API (a complete resource, or just the change to apply).
A non-REST solution could be to perform a PATCH request to /invoices/<id>/paid. It's not pure REST but it's ok.

RESTful API - How do I return different results for the same resource?

Question
How do I return different results for the same resource?
Details
I have been searching for some time now about the proper way to build a RESTful API. Tons of great information out there. Now I am actually trying to apply this to my website and have run into a few snags. I found a few suggestions that said to base the resources on your database as a starting point, considering your database should be structured decently. Here is my scenario:
My Site:
Here is a little information about my website and the purpose of the API
We are creating a site that allows people to play games. The API is supposed to allow other developers to build their own games and use our backend to collect user information and store it.
Scenario 1:
We have a players database that stores all player data. A developer needs to select this data based on either a user_id (person who owns the player data) or a game_id (the game that collected the data).
Resource
http://site.com/api/players
Issue:
If the developer calls my resource using GET they will receive a list of players. Since there are multiple developers using this system they must specify some ID by which to select all the players. This is where I find a problem. I want the developer to be able to specify two kinds of ID's. They can select all players by user_id or by game_id.
How do you handle this?
Do I need two separate resources?
Lets say you have a controller name 'Players', then you'll have 2 methods:
function user_get(){
//get id from request and do something
}
function game_get(){
//get id from request and do something
}
now the url will look like: http://site.com/api/players/user/333, http://site.com/api/players/game/333
player is the controller.
user/game are the action
If you use phil sturgeon's framework, you'll do that but the url will look like:
http://site.com/api/players/user/id/333, http://site.com/api/players/game/id/333
and then you get the id using : $this->get('id');
You can limit the results by specifying querystring parameters, i.e:
http://site.com/api/players?id=123
http://site.com/api/players?name=Paolo
use phil's REST Server library: https://github.com/philsturgeon/codeigniter-restserver
I use this library in a product environment using oauth, and api key generation. You would create a api controller, and define methods for each of the requests you want. In my case i created an entirely seperate codeigniter instance and just wrote my models as i needed them.
You can also use this REST library to insert data, its all in his documentation..
Here is a video Phil threw together on the basics back in 2011..
http://philsturgeon.co.uk/blog/2011/03/video-set-up-a-rest-api-with-codeigniter
It should go noted, that RESTful URLs mean using plural/singular wording e.g; player = singular, players = all or more than one, games|game etc..
this will allow you to do things like this in your controller
//users method_get is the http req type.. you could use post, or put as well.
public function players_get(){
//query db for players, pass back data
}
Your API Request URL would be something like:
http://api.example.com/players/format/[csv|json|xml|html|php]
this would return a json object of all the users based on your query in your model.
OR
public function player_get($id = false, $game = false){
//if $game_id isset, search by game_id
//query db for a specific player, pass back data
}
Your API Request URL would be something like:
http://api.example.com/player/game/1/format/[csv|json|xml|html|php]
OR
public function playerGames_get($id){
//query db for a specific players games based on $userid
}
Your API Request URL would be something like:
http://api.example.com/playerGames/1/format/[csv|json|xml|html|php]