How to create custom field via API? - python-3.x

This is the Question/Answer case, so here you wont find any details.
After Googling within few hours I found solution that you can find below.

simple_salesforce
from simple_salesforce import Salesforce
def custom_field_create:
"""
Based on https://salesforce.stackexchange.com/a/212747/65221
Examples of field types you can find in the column "Data Type" of the salesforce front end,
on the page where you can create/edit/delete fields for your selected object.
NOTE: case of "type" is important. For example the type "DateTime"
must be exactly "DateTime" and not like "datetime".
"""
email = 'your_email'
password = 'your_password'
security_token = 'your_token'
object_api_name = 'contact' # replace with your object name
field_api_name = 'Activity_Time' # replace with your field name
field_label = 'Activity Time' # replace with your field label
sf = Salesforce(username=email, password=password, security_token=security_token)
url = 'tooling/sobjects/CustomField/'
payload = {
"Metadata":
{"type": "Text", "inlineHelpText": "", "precision": None, "label": f"{field_label}", "length": 90, "required": False},
"FullName": f"{object_api_name}.{field_api_name}__c"
}
result = sf.restful(url, method='POST', json=payload)
print('result:', result)

Related

DRF Serializer not displaying fields (Foreign Key and many2many) in default HTML form page API. Field is available in GET

DRF Serializer contains a group and inventory field which are many2many and foreign key. It is missing in default DRF HTML Form but available in GET view. currently, the depth field is enabled in Serializer. If i am removing depth then Foreign key is available in default HTML form, but still group many2many field is missing. I need both the fields for POST call or in DRF HTML Form.
Do i have to write some create method, but I do not want to create new record for Foreign key and many2many just want to utilize the existing field.
My Serializer class.
class MainHostSerializer(serializers.ModelSerializer):
class Meta:
model = MainHost
fields = (
'host_id',
'host_name',
'inventory',
'group'
)
# depth = 2
Raw view for default DRF HTML Form
{
"host_id": null,
"host_name": ""
}
Model Class
class MainHost(models.Model):
host_id = models.IntegerField(verbose_name='HOST ID', primary_key=True)
host_name = models.CharField(verbose_name='HOST NAME', max_length=512)
inventory = models.ForeignKey(related_name='inv_ins', on_delete=models.SET_NULL, to='hosts.MainInventory', blank=True, null=True)
group = models.ManyToManyField(MainGroup, related_name='hostgroups', through ='HostGroup')
Create Method for MainHost Serializer
def create(self, validated_data):
inv_data = validated_data.pop('inventory')
inv_res = MainInventory.objects.create(**inv_data)
group_data = validated_data.pop('group')
host_data = MainHost.objects.create(inventory = inv_res, **validated_data)
for g_data in group_data:
inv_data = g_data.pop('inv_id')
inv = MainInventory.objects.create(**inv_data)
group_res = MainGroup.objects.create(inv_id = inv, **g_data)
print(validated_data)
HostGroup.objects.create(host = host_data, group = group_res)
This was sample JSON
{
"count": 1692,
"next": "http://127.0.0.1:8000/api/mainhost/?page=2",
"previous": null,
"results": [
{
"host_id": 4087,
"host_name": "10.240.144.2",
"inventory": {
"inv_id": 91,
"inv_name": "GNS Switches (TestNet)",
"total_hosts": 539,
"total_groups": 1,
"org_name": "ABC_TestNet",
"description": "Inventory of ABC switches on Testnet",
"inv_variables": "environ: testnet"
},
"group": [
{
"group_id": 280,
"group_name": "aruba",
"total_hosts": 539,
"total_groups": 0,
"inv_id": {
"inv_id": 91,
"inv_name": "ABC Switches (TestNet)",
"total_hosts": 539,
"total_groups": 1,
"org_name": "ABC_TestNet",
"description": "Inventory of ABC switches on Testnet",
"inv_variables": "environ: testnet"
},
"description": "imported",
"group_variables": "{}",
"groupinv_name": "ABC Switches (TestNet)",
"groupinv_description": "",
"groupinv_source": "scm",
"groupinv_path": "TEC/GNS/Switches/testnet.ini"
}
],
"description": "imported",
"foreman_group": "[{'id': 280, 'name': 'aruba'}]",
"host_variables": "{}",
"ansible_facts": "{}"
}
]
}

Creating a 'SS' item in DynamoDB using boto3

I'm trying to create an item in AWS DynamoDB using boto3 and regardless what I try I can't manage to get an item of type 'SS' created. Here's my code:
client = boto3.resource('dynamodb', region_name=region)
table = client.Table(config[region]['table'])
sched = {
"begintime": begintime,
"description": description,
"endtime": endtime,
"name": name,
"type": "period",
"weekdays": [weekdays]
}
table.put_item(Item=sched)
The other columns work fine but regardless what I try, weekdays always ends up as a 'S' type. For reference, this is what one of the other items look like from the same table:
{'begintime': '09:00', 'endtime': '18:00', 'description': 'Office hours', 'weekdays': {'mon-fri'}, 'name': 'office-hours', 'type': 'period'}
Trying to convert this to a Python structure obviously fails so I'm not sure how it's possible to insert a new item.
To indicate an attribute of type SS (String Set) using the boto3 DynamoDB resource-level methods, you need to supply a set rather than a simple list. For example:
import boto3
res = boto3.resource('dynamodb', region_name=region)
table = res.Table(config[region]['table'])
sched = {
"begintime": '09:00',
"description": 'Hello there',
"endtime": '14:00',
"name": 'james',
"type": "period",
"weekdays": set(['mon', 'wed', 'fri'])
}
table.put_item(Item=sched)
As follow up on #jarmod's answer:
If you want to call update_item with a String Set, then you'll insert a set via ExpressionAttributeValues property like shown below:
entry = table.put_item(
ExpressionAttributeNames={
"#begintime": "begintime",
"#description": "description",
"#endtime": "endtime",
"#name": "name",
"#type": "type",
"#weekdays": "weekdays"
},
ExpressionAttributeValues={
":begintime": '09:00',
":description": 'Hello there',
":endtime": '14:00',
":name": 'james',
":type": "period",
":weekdays": set(['mon', 'wed', 'fri'])
},
UpdateExpression="""
SET #begintime= :begintime,
#description = :description,
#endtime = :endtime,
#name = :name,
#type = :type,
#weekdays = :weekdays
"""
)
(Hint: Usage of AttributeUpdates (related Items equivalent for put_item calls) is deprecated, therefore I recommend using ExpressionAttributeNames, ExpressionAttributeValues and UpdateExpression).

How to find the value of a key in a dictionary that is part of a list with multiple dictionaries. (pulled from an api

I'm using an api to pull in this List.
I need the user to be able to enter in the 'name' of airline. Then, once the name is captured, match the 'name' to the 'icao' code within the same Dictionary.
My code
import requests
api-url= ("https://api.url")
class airlinenames(Component):
def start(self):
name = "Ali Airlines"
url = API_URL
data = requests.get(url).json()
icao = data['airlines'][0]['icao']
text = ( "this is your airline: {name} and this is the icao code: {icao}"
).format(
name=name,
icao=icao
)
message = self.create_message(text=text)
return self.respond(message=message, action="next"
My issue is, instead of pulling in the matching 'icao' from the same dictionary, it pulls in the very next one at the top.
So for example if user enters in "Ali Airline"
It should read " This is your airline: Ali Airline, your ICAO code is: ALI
Example list:
{
"airlines": [
{
"fs": "BS",
"iata": "BS",
"icao": "ALI",
"name": "Ali Airlines",
"active": true
},
{
"fs": "BS*",
"iata": "BS",
"icao": "BAL",
"name": "Bali Airline",
"active": true
},
{
"fs": "BSK",
"iata": "LL",
"icao": "GAL",
"name": "Gali airline",
"active": true
}
]
}
Currently, in the code you provided you are always getting the the very first airline (data['airlines'][0]).
Instead, you should probably convert your data into a dictionary keyed by airline name first, e.g.:
airlines = { a['name'] : a for a in data['airlines']}
Now, with that dictionary and the name variable, you can find the corresponding code:
icao = airlines[name]['icao'] # This will give you the code give a name.

How to filter SharePoint list items by Created by in Microsoft Graph?

I'm trying to get a collection of list items from a SharePoint through Microsoft Graph, which I want to filter by CreatedBy.
Requesting: https://graph.microsoft.com/v1.0/sites/{siteid}/lists/TeamRequests/items
Returns:
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#sites('{url}')/lists('TeamRequests')/items",
"value": [
{
"#odata.etag": "\"56ad787e-bd69-464a-b5da-dd953e40d7c4,13\"",
"createdDateTime": "2018-02-26T08:34:26Z",
"eTag": "\"56ad787e-bd69-464a-b5da-dd953e40d7c4,13\"",
"id": "11",
"lastModifiedDateTime": "2018-03-22T13:20:03Z",
"webUrl": "{url}/Lists/TeamRequests/11_.000",
"createdBy": {
"user": {
"email": "{email}",
"id": "9c9cbb67-c049-4a2d-845d-6c5ca2300041",
"displayName": "{Name}"
}
},
"lastModifiedBy": {
"user": {
"email": "{email}",
"id": "9c9cbb67-c049-4a2d-845d-6c5ca2300041",
"displayName": "{Name}"
}
},
"parentReference": {},
"contentType": {
"id": "0x01005F15F8133495554D834FF82F187AD0630002133A9CCDE4494D8CB2206D7D6453D6"
}
},
Now I'd like to filter this request for createdBy, either Id, displayName or email address. I tried ?$filter=createdBy/user/email eq '{email}' and similar requests for id or displayName. They all return
{
"error": {
"code": "generalException",
"message": "An unspecified error has occurred.",
"innerError": {
"request-id": "492e3bde-05fe-4484-a475-435ff0aa70b6",
"date": "2018-07-23T07:41:46"
}
}
}
So how to accomplish this filter? Is it even supported?
Even though it sounds like a straightforward query, i have not come up to anything more simple then the following solution:
It seems filtering by user field is not supported except the case when user id is provided, that's the reason why the solution consists of two steps:
1) First, we need to determine user Id by Email , for that purpose the following query could be utilized:
https://graph.microsoft.com/v1.0/sites/root/lists('User Information List')/items?expand=fields(select=Id,Email)
*where User Information List system list stores user properties including Id and Email properties *
2) Once the user Id is resolved, the final query to filter items by user id could be applied:
https://graph.microsoft.com/v1.0/sites/{site-id}/lists('list-name')/items?filter=fields/<user-field-name>LookupId eq '<user-id>'
where
<user-field-name>LookupId is a field which is getting exposed in addition to user field, in case of Created field the name should be AuthorLookupId
Example:
https://graph.microsoft.com/v1.0/sites/root/lists('TeamRequests')/items?filter=fields/AuthorLookupId eq '10'
Note
In some cases the following error is returned Field ''
cannot be referenced in filter or orderby as it is not indexed.
Provide the 'Prefer: HonorNonIndexedQueriesWarningMayFailRandomly'
header to allow this, but be warned that such queries may fail on
large lists.
In that case the following request header needs to be applied:
Prefer: HonorNonIndexedQueriesWarningMayFailRandomly
When I tried to access User Information List list. There is an error with list not found.
So since in my case, first I filtered list data based on status value and next step got the logged in user display name and filtered listitems based on display name.
I'm using #pnp/graph
Filter list data with status filter
let resultsList = await listItemsQuery.filter("fields/RequestStatus eq 'Approval Pending'").expand("fields").get<MicrosoftGraph.ListItem[]>();
Get Logged-In Profile:
const profileQueryEndPoint = new GraphQueryableCollection(graph.me, "/");
Select displayName property from above result
let profileData : User = await profileQueryEndPoint.select("displayName").get <User>();
console.log('displayName : ' + profileData['displayName']);
Filter ListItems with createdby Field by passing profileData['displayName']
let filterUserCreatedRequests: MicrosoftGraph.ListItem[] = resultsList.filter(ListItem => ListItem["createdBy"].user.displayName === profileData['displayName']);
Display filtered results
console.log('filterUserCreatedRequests : ' + JSON.stringify(filterUserCreatedRequests));
I'm giving all the steps for your reference. But above code can simplified more.
Hope this helps someone :)

How to get ALL likes for a given media-id

I am trying to iterate over the user ID of each like for a given {media_id}
https://api.instagram.com/v1/media/{media-id}/likes?access_token=ACCESS-TOKEN
is returning something like this (a data array of approx 300 likes)
{
"data": [{
"username": "jack",
"first_name": "Jack",
"last_name": "Dorsey",
"type": "user",
"id": "66"
},
{
"username": "sammyjack",
"first_name": "Sammy",
"last_name": "Jack",
"type": "user",
"id": "29648"
}]
}
The problem is that it does not return ALL the likes, or any pagination feature.
Is there any workaround to get ALL likes for a given {media_ID}?
You're using the correct API endpoint to get media likes, however this endpoint has a limitation. It only returns a maximum of 100-120 likes per media with no pagination.
Unfortunately there is no workaround!
The same limitation applies for the comments endpoint.
Check this Python library out.
Then you can use this sample code I made; however, It will only get 1000 of the most recent likes.
from InstagramAPI import InstagramAPI
likes_list = []
def get_likes_list(username):
API.searchUsername(username) #Gets most recent post from user
info = API.LastJson
username_id = info['user']['pk']
user_posts = API.getUserFeed(username_id)
info = API.LastJson
media_id = info['items'][0]['id']
API.getMediaLikers(media_id)
f = API.LastJson['users']
for x in f:
likes_list.append(x['username'])
get_likes_list("tailopez")
print(likes_list)

Resources