Zapier line item manipulation with python - python

My zap runs a GET from Intercom which places all messages in a convo into a line-item field.
I want to change the entire line item field into a string without all the commas that zapier puts in when it joins all the values. So I can write the conversation as a text note elsewhere.
Someone at zapier suggested I should use join in code to do this but ofcourse they aren't allowed to give me the actual code.
Input:
input_data = {
"values": "<p>Ok, I see your request. Give me just a minute to get it set up </p>,<p>ok</p>,<p>You should see the email shortly. When you get logged in, let me know if you have any other questions, I'm happy to help </p>,<p>cool</p>,<p>More Pipedrive testing</p>"
}
I tried the following code:
L = input_data['values']
return {" ".join(str(x) for x in L)}
But got the following errors:
TypeError(repr(o) + " is not JSON serializable")
TypeError: set(['< p > H i n e w b i e < / p >']) is not JSON serializable

Cool! So your issue is that you're returning a python set from your code step, which Zapier can't turn into json.
That's happening because you've got a string between curlies. See:
>>> {'asdf'}
set(['asdf'])
Your input is a big string with html in it. It seems like you could split on </p>,<p> and join on ' '.
In either case, you need to return your output as a value:
>>> {'result': " ".join(str(x) for x in L.split('</p>,<p>'))}
{'result': "<p>Ok, I see your request. Give me just a minute to get it set up ok You should see the email shortly. When you get logged in, let me know if you have any other questions, I'm happy to help cool More Pipedrive testing</p>"}
You could also pull of the leading and trailing <p> tags if you'd like.
Hope that helps!

Related

Creating a list holding JSON arrays from values in another list

I have a python script that sends a JSON post. Part of the payload comes from a list in the following format
SERVICES = [{'id':'PZV8CL7', 'type':'service'}, {'id':'PYMOSPH', 'type':'service'}]
payload = {
'maintenance_window': {
'services': SERVICES,
}
The script works just fine when manually adding the services to the script, however I needed it to be able to work with a lot of them, so I added this:
code = ['PH6FKI0', 'PD1EK3Z', 'PSJR02A', 'PI8VRN1']
list = []
for c in code:
list.append("{'id':'%s', 'type':'service'}" % s)
print(list)
["{'id':'PH6FKI0', 'type':'service'}", "{'id':'PD1EK3Z', 'type':'service'}"
The problem here is that the quotation marks seem to interfere when sent in the the JSON post which returns an error.
['Services must be an object containing properties id and type.']
How can I make a list without the quotations mark being added to it? any other way to make this, would be awesome as well.
Thanks in advance
Insert objects, not strings:
for c in code:
list.append({'id':s, 'type':'service'})

Neatly Print Comments Through Python Reddit API

I am trying to do some text analysis with Reddit comments. The script I have currently prints out the body and upvote count all comments on a given subreddit's "hot" posts with more than 5 upvotes:
import praw
reddit = praw.Reddit(client_id=ID,
client_secret=SECRET, password=PWORD,
user_agent=UAGENT, username=UNAME)
subreddit = reddit.subreddit('cryptocurrency')
for submission in subreddit.hot(limit=10):
submission.comments.replace_more(limit=10)
for comment in submission.comments.list():
submission.comment_sort = 'top'
if comment.ups > 5:
print(comment.body, comment.ups)
However, the outputs look something like this:
(u'Just hodl and let the plebs lose money on scamcoin ICO\'s that don\'t even have a working product. I don\'t understand some of these "traders" and "investors".', 9)
(u"Good idea imho but it's gonna be abused af. Think about it. It will be the sexual go to app real soon. If they will 'ban' nudity on it, then you will simply get the instagram chicks on there with all the horny guys liking their photos and giving them free money. 'if this gets 1000 likes I will post a pic of me in bikini' ", 7)
(u"But but but, I just sold a kidney and bought in at the top, now I can't afford to get the stitches removed!\n\n/s just in case.", 7)
Two questions:
Is there any way to convert the outputs to JSON using python?
If not, how can I get rid of all of the excess characters other than the body and the upvote count?
My ultimate goal is to have this output neatly organized so that I can analyze keywords vs. upvote count (what keywords get the most upvotes, etc).
Thank you!
Answer to question 2: It looks like you are writing in Python 2, but are using Python 3 print syntax. To get rid of the tuple notation in your print call you need
from __future__ import print_function
at the top of your program.
1) Is there any way to convert the outputs to JSON using python?
It's almost as simple as this
output_string = json.dumps(comments)
Except a couple of keys cause the error TypeError: Object of type Foo is not JSON serializable
We can solve this. PRAW objects which are not serializable will work correctly when converted to a string.
def is_serializable(k, v):
try:
json.dumps({k: v})
except TypeError:
return False
return True
for comment in comments:
for k, v in comment.items():
if is_serializable(k, v):
comment[k] = v
else:
comment[k] = str(v)
Now saving works.
json.dumps(comments)
2) If not, how can I get rid of all of the excess characters other than the body and the upvote count?
I think you're asking how to remove keys you do not want. You can use:
save_keys = ['body', 'ups']
for k in list(comment):
if not k in save_keys:
del comment[k]
We use list(dict) to iterate over a copy of dict's keys. This prevents you from mutating the same thing you are iterating on.
list(dict) is the same as `list(dict.keys())

Django assert that response contains one of a list of possible strings

I'm writing tests for my Django app using the built-in testing tools. Right now I'm trying to write a test for a page that displays a list of a user's followers. When a user has no followers the page displays a message randomly picked from a list of strings. As an example:
NO_FOLLOWERS_MESSAGES = [
"You don't have any followers.",
"Sargent Dan, you ain't got no followers!"
]
So now I want to write a test that asserts that the response contains one of those strings. If I was only using one string, I could just use self.assertContains(request, "You don't have any followers.") but I'm stuck on how to write the test with multiple possible outcomes. Any help would be appreciated.
Try this:
if not any([x in response.content for x in NO_FOLLOWERS_MESSAGES]):
raise AssertionError("Did not match any of the messages in the request")
About any(): https://docs.python.org/2/library/functions.html#any
Would something like this work?
found_quip = [quip in response.content for quip in NO_FOLLOWERS_MESSAGES]
self.assertTrue(any(found_quip))
Internally assertContains(), uses the count from _assert_contains()
So if you want to preserve exactly the same behavior as assertContains(), and given that the implementation of _assert_contains() isn't a trivial one, you can get inspiration from the source code above and adapt one for your needs
Our assertContainsAny() inspired by assertContains()
def assertContainsAny(self, response, texts, status_code=200,
msg_prefix='', html=False):
total_count = 0
for text in texts:
text_repr, real_count, msg_prefix = self._assert_contains(response, text, status_code, msg_prefix, html)
total_count += real_count
self.assertTrue(total_count != 0, "None of the text options were found in the response")
Use by passing the argument texts as a list, e.g.
self.assertContainsAny(response, NO_FOLLOWERS_MESSAGES)

Syntax Error (FROM) in Python, I do not want to use it as function but rather use it as to print something

I am trying to print out usernames from Instagram. When I type in print i.from.username, there will be syntax error because Python thinks that I am using from function, which i actually not.
for i in a:
print i.from.username
Is there anyway to troubleshoot it? I tried using making a string but it is still wrong. What I try to did was:
for i in a:
print i+ ".from." +username
Base on the comments:
I'm not trying to put from as a key attribute. What I'm trying to do is collect data from Instagram API.
The a represents the comments, so basically I'm going into the comments to collect the usernames that commented.
"text": "This is #kimsoohyun 's "house" in The Producer!",
"from": {
"username": "lilingchen",
},
If I put i.text, it will print out every comments. Now, I wanted to print out the username that commented, so I tried using i.from.username.
print getattr(i, 'from').username

Python splitting values from urllib in string

I'm trying to get IP location and other stuff from ipinfodb.com, but I'm stuck.
I want to split all of the values into new strings that I can format how I want later. What I wrote so far is:
resp = urllib2.urlopen('http://api.ipinfodb.com/v3/ip-city/?key=mykey&ip=someip').read()
out = resp.replace(";", " ")
print out
Before I replaced the string into new one the output was:
OK;;someip;somecountry;somecountrycode;somecity;somecity;-;42.1975;23.3342;+05:00
So I made it show only
OK someip somecountry somecountrycode somecity somecity - 42.1975;23.3342 +05:00
But the problem is that this is pretty stupid, because I want to use them not in one string, but in more, because what I do now is print out and it outputs this, I want to change it like print country, print city and it outputs the country,city etc. I tried checking in their site, there's some class for that but it's for different api version so I can't use it (v2, mine is v3). Does anyone have an idea how to do that?
PS. Sorry if the answer is obvious or I'm mistaken, I'm new with Python :s
You need to split the resp text by ;:
out = resp.split(';')
Now out is a list of values instead, use indexes to access various items:
print 'Country: {}'.format(out[3])
Alternatively, add format=json to your query string and receive a JSON response from that API:
import json
resp = urllib2.urlopen('http://api.ipinfodb.com/v3/ip-city/?format=json&key=mykey&ip=someip')
data = json.load(resp)
print data['countryName']

Categories