fprimex / zdesk Goto Github PK
View Code? Open in Web Editor NEWZendesk API for Python generated from developer.zendesk.com
License: MIT License
Zendesk API for Python generated from developer.zendesk.com
License: MIT License
I've been trying to use the organizations_destroy_many() call by passing in a list of organization ids as a list to the argument 'ids', and have observed that only the last id in the list gets deleted from Zendesk.
I wonder if there is some issue with the use of requests.Session.request?
Hi,
I am trying to read some tickets from zendesk, but I am unable to read all the tickets. Probably it is because tickets are stored in multiple pages. I went through documentation and noticed that there is something like get_all_pages
. How can I use it to fetch all the tickets? Please help me with the syntax for it.
Hello, anyone who is following this repo. Zdesk has been in sore need of an updated release and I am ready to release a 2.5.0. Please try an install from master and give me some feedback, either here for via other channels. Thanks!
I've been looking through this project trying to determine if this action is supported?
Create Or Update User
POST /api/v2/users/create_or_update.json
Creates a user if the user does not already exist, or updates an existing user identified by e-mail address or external ID.
https://developer.zendesk.com/rest_api/docs/core/users#create-or-update-user
Add support for the Zopim (chat) api. https://developer.zendesk.com/rest_api/docs/zopim/introduction
The main ticket incremental export supports sideloading; however, the ticket events incremental endpoint in the API does not. Would we also be able to pass on incremental for ticket events (goal is comment contents)
def incremental_ticket_events_list(self, start_time=None, **kwargs):
"https://developer.zendesk.com/rest_api/docs/core/incremental_export#incremental-ticket-export"
api_path = "/api/v2/incremental/ticket_events.json"
api_query = {}
if "query" in kwargs.keys():
api_query.update(kwargs["query"])
del kwargs["query"]
if start_time:
api_query.update({
"start_time": start_time,
})
return self.call(api_path, query=api_query, **kwargs)
def incremental_tickets_list(self, include=None, start_time=None, **kwargs):
"https://developer.zendesk.com/rest_api/docs/core/incremental_export#start-time"
api_path = "/api/v2/incremental/tickets.json"
api_query = {}
if "query" in kwargs.keys():
api_query.update(kwargs["query"])
del kwargs["query"]
if include:
api_query.update({
"include": include,
})
if start_time:
api_query.update({
"start_time": start_time,
})
return self.call(api_path, query=api_query, **kwargs)
The API call expects two creation times but only one can be passed through zdesk.
A couple of examples and their thrown errors:
zendesk.audit_logs_list(filter_created_at='2016-01-01T08:00:00Z')
zdesk.zdesk.ZendeskError: '400: {"error":"InvalidValue","description":"Invalid filter[created_at] specified; format is ?filter[created_at][]=YYYY-MM-DDTHH:MM:SSZ&filter[created_at][]=YYYY-MM-DDTHH:MM:SSZ"} <Response [400]>'
zendesk.audit_logs_list(filter_created_at='2016-01-01T08:00:00Z', filter_created_at='2016-01-01T18:00:00Z')
SyntaxError: keyword argument repeated
The zdesk definition lives here:
Line 284 in 9f55892
Attempt to run in Visual Studio 2019.
I'm getting the error - " Message=attempted relative import with no known parent package" on the following lline at line 17 of zdesk.py
from .zdesk_api import ZendeskAPI
I got a new request from Zendesk team to upgrade client API to support their new DDoS protection system. Currently, I'm using version 2.6.0. Do we need to upgrade to the newest version for this?
The announcement is here:
https://support.zendesk.com/hc/en-us/articles/360001781967-Zendesk-rolls-out-new-DDoS-protection-and-abuse-prevention-system
In the call function we're setting the response code to 200...
https://github.com/fprimex/zdesk/blob/master/zdesk/zdesk.py#L109
And then we check to see if the response code is equal to 200, handles a few special cases and raises an error for all other codes....
https://github.com/fprimex/zdesk/blob/master/zdesk/zdesk.py#L178
But whenever you create a resource, for instance a macro, it will return a 201 response. This indicates that the response was valid and a resource was created. This should handle a 201 code as a valid response instead of throwing an error. Hoping this could be fixed and then released to PYPI.
In a web application, it is common to instanciate API client at import time:
# global variable
zendesk = Zendesk(...)
In that case, if a multi-threaded web application server is used, zendesk.session
can be shared across threads. (Most Python web application servers are multi-threaded to use more CPU and less RAM.)
Unfortunately https://github.com/kennethreitz/requests/issues/1871 suggests that this isn't safe.
You could work around this issue as follows:
import threading
class Zendesk:
def __init__(...):
# ...
self.thread_local = threading.local()
def call(...):
# In the light of https://github.com/kennethreitz/requests/issues/1871,
# it's safer to initialize a fresh requests.Session in each thread.
if not hasattr(self.thread_local, 'session'):
self.thread_local.session = requests.Session()
self.session = self.thread_local.session
# In case authentication information changed in another thread,
# reflect it in our thread local session.
self._update_auth()
Alternatively you could document that the Zendesk
class isn't thread safe. But that would put the burden of implementing that workaround on your users.
PS: I brought up the same argument on the requests
library, because I don't think it's a good idea for every API client based on requests
to implement that boilerplate. Unfortunately, it seems that making Session
thread-safe is a difficult endeavour for them.
As of June 27, 2016, Zendesk is changing their API to require a locale in the URL, from:
/api/v2/help_center/resource/{{resource_id}}
to:
/api/v2/help_center/en-us/resource/{{resource_id}}
(I'd add a link to Zendesk's site documenting this, but I can't find one...)
Helps to have a 2.1.0
git tag to match the Python repo's 2.1.0
version.
I"m trying to migrate macros from one Zendesk instance to another. I can retrieve macros from either instance without problem, but cannot seem to create them. Here's the script:
#!/usr/bin/env python3
from zdesk import Zendesk
from zdeskcfg import get_ini_config
import json
def retrieve_macros(config='REDACTED', write=True):
zendesk = Zendesk(**get_ini_config(section=config))
macros = zendesk.macros_list(get_all_pages=True)
if write:
with open(config + '_macros.json', 'w') as macrodump:
json.dump(macros, macrodump)
return macros['macros']
def add_macro(macro, config='REDACTED', group_id=REDACTED):
for attr in ['id', 'url', 'created_at', 'position', 'updated_at', 'restriction']:
macro.pop(attr)
if group_id:
macro['restriction'] = {'type': 'Group', 'id': group_id}
zendesk = Zendesk(**get_ini_config(section=config))
print('Adding macro:', macro)
r = zendesk.macro_create(macro)
return r
if __name__ == '__main__':
REDACTED_macros = retrieve_macros()
for macro in REDACTED_macros:
print('response:', add_macro(macro))
input('Hit return to continue, Ctrl-C to abort')
And here's the output:
Adding macro: {'active': True, 'title': 'REDACTED', 'actions': [{'value': 'solved', 'field': 'status'}, {'value': 'question', 'field': 'type'}, {'value': 'REDACTED', 'field': 'set_tags'}, {'value': ['channel:all', "REDACTED"], 'field': 'comment_value'}], 'restriction': {'type': 'Group', 'id': REDACTED}}
Traceback (most recent call last):
File "./migrate_macros.py", line 31, in <module>
print('response:', add_macro(macro))
File "./migrate_macros.py", line 24, in add_macro
r = zendesk.macro_create(macro)
File ".../zendesk_migration/venv/lib/python3.5/site-packages/zdesk/zdesk_api.py", line 1926, in macro_create
return self.call(api_path, method="POST", data=data, **kwargs)
File ".../zendesk_migration/venv/lib/python3.5/site-packages/zdesk/zdesk.py", line 229, in call
response.content, response.status_code, response)
zdesk.zdesk.ZendeskError: '500: b\'<!DOCTYPE html>\\n<html lang="en">\\n\\n<head>\\n <meta http-equiv="content-type" content="text/html; charset=UTF-8" />\\n <title>We\\\'re sorry, but something went wrong</title>\\n <link href="/external/error_pages.css" media="all" rel="stylesheet" type="text/css" />\\n <meta name = "viewport" content = "width=device-width">\\n</head>\\n\\n<body>\\n <!-- This file lives in public/500.html -->\\n <div class="dialog">\\n <div id="contents">\\n <h1>Oh no.<br/>Something went wrong.</h1>\\n <div class="box home">\\n <p>We\\\'ve been notified about this issue and we\\\'ll take a look at it ASAP.</p>\\n <ul><li><a href="/">Take me back to the home page \\xc2\\xbb</a></li></ul>\\n </div>\\n <br clear="both">\\n <div class="box operations">\\n <p>\\n This site is a <a href="http://www.zendesk.com" style="color:#FFF; font-weight:normal;">Zendesk</a> based help desk.\\n If you see this page frequently, you might want to check the Zendesk operational status:\\n <ul>\\n <li><a href="http://twitter.com/zendeskops">Zendesk operations on Twitter</a></li>\\n </ul>\\n </p>\\n </div>\\n </div>\\n </div>\\n</body>\\n</html>\\n\' <Response [500]>'
One should be able to set the number of times or a total amount of time to retry an operation if the API rate limit is hit.
When I try to connect to Zendesk I am getting the error
"zdesk.zdesk.AuthenticationError: '401: b'{"error":"invalid_token","error_description":"The access token provided is expired, revoked, malformed or invalid for other reasons."}' <Response [401]>' "
A few weeks ago the script was working smoothly. Any idea?
Thanks!
While the code generation appeared to be completed correctly, the diff to store the change to the documentation that was made was done in the wrong direction. The purpose of this patch was to fix the repeated {id} in the URL. The line that should be present after patching is this one:
DELETE /api/v2/help_center/articles/{article_id}/comments/{id}.json
instead of this one:
DELETE /api/v2/help_center/articles/{id}/comments/{id}.json
Just started using this API today due to issues with deprecated one and finding this one quite easy to use, but I'm wondering if this is a logic error on my part, issue with zdesk, or Zendesk itself.
`
current_day = datetime.date.today()
search_begin = current_day - relativedelta(days=15)
query = 'type:ticket,organization:%s,status:closed,created>%s' % (org_id, search_begin)
tickets = zendesk.search(query=query)
print 'created within the last 15 days and closed: %s' % tickets['count']
query = 'type:ticket,organization:%s,status:closed,sort_by:created_at' % (org_id)
tickets = zendesk.search(query=query)
print 'closed organization sort_by created: %s' % tickets['count']
`
I received the following output.
created within the last 15 days and closed: 9
closed organization sort_by created: 4
MacOs High Sierra, python 2.7.14 and also 3.6.3 <- the same issue.
After installation of all required modules, on first run this comes up:
"ImportError: cannot import name Zendesk"
Any idea ?
Thanks
Because kwargs
still contains the start_time parameter, it ends up doing the following:
DEBUG:requests.packages.urllib3.connectionpool:"GET /api/v2/incremental/tickets.json?start_time=1478649600 HTTP/1.1" 200 None
DEBUG:requests.packages.urllib3.connectionpool:"GET /api/v2/incremental/tickets.json?start_time=1478725380&start_time=1478649600 HTTP/1.1" 200 None
DEBUG:requests.packages.urllib3.connectionpool:"GET /api/v2/incremental/tickets.json?start_time=1478725380&start_time=1478649600 HTTP/1.1" 200 None
DEBUG:requests.packages.urllib3.connectionpool:"GET /api/v2/incremental/tickets.json?start_time=1478725380&start_time=1478649600 HTTP/1.1" 200 None
A possible fix could be to unset start_time
from kwargs
after assigning next_page
from the response to url
Hi
I am looking to filter what is returned when using the tickets_list function, can you provide some examples of using the query parameter.
I was hoping to get all tickets in the last 7 days similar too:
last_7_days = datetime.datetime.now() - datetime.timedelta(days=7)
zdesk_client.tickets_list(query={start_time=last_7_days})
The only testing that is done each release is the execution of the shipped examples. This ensures very, very basic functionality. I would like to provide better testing via py.test, and already have a functional branch for this that needs completing.
I am trying to test my zendesk connection with this code:
log.info("Initializing Zendesk...")
zendesk = Zendesk(
zdesk_url=config['zendesk']['url'],
zdesk_email=config['zendesk']['email'],
zdesk_password=config['zendesk']['password'],
zdesk_token=config['zendesk']['password-is-token'])
if args.debug:
log.debug("Testing Zendesk (Listing Tickets)...")
log.debug(str(zendesk.tickets_list()))
But it results in this traceback:
2016-01-20 08:29:20,949:zendesk-to-trello:INFO:<module>(102):Initializing Zendesk...
2016-01-20 08:29:20,951:zendesk-to-trello:DEBUG:<module>(109):Testing Zendesk (Listing Tickets)...
Traceback (most recent call last):
File "./zendesk-to-trello", line 110, in <module>
log.debug(str(zendesk.tickets_list()))
File "/usr/local/lib/python2.7/dist-packages/zdesk/zdesk_api.py", line 2891, in tickets_list
return self.call(api_path, query=api_query, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/zdesk/zdesk.py", line 215, in call
**self.client_args
TypeError: request() got an unexpected keyword argument 'json'
I also get the same error when trying to load a single ticket. I tried to update the zdesk_api.py from #21 just in case that would help, but it didn't.
The API generator code is a bit hard to follow. If there are going to be any improvements there by other people it needs to be easier to follow and use.
zdesk/zdesk.py
272: if isinstance(value, collections.Iterable):
For example this call:
zendesk.upload_create(somefile.read(),query=dict(file_name='myfile.pdf'), mime_type='application/binary', complete_response=True)
Would result in:
UnboundLocalError
local variable 'body' referenced before assignment
local/lib/python2.7/site-packages/zdesk/zdesk.py in call:169
urlencode is causing problems when using the search query method.
The query can not be coded:
type%3Aticket%2Borganization_id%3A22293406
I'm trying to parse your response file into a dataframe and all the documentation given doesn't work (from zendesk's documentation or provided here on github)?
from zdesk import Zendesk
import json
zendesk = Zendesk('https://prosper.zendesk.com', '@prosper.com', '')
response = zendesk.search(query='type:ticket status:open created>2015-12-04', page=1)
data = response.json()
for row in data['results']:
print(row)
Is there a timeline to update the version of pypi? The current version of 2.4.0 does not contain the max_retries feature.
upload_create()
corrupts the attachment created if you don't set mime_type
parameter to something else than application/json
.
mime_type
should have a default parameter value application/binary
for this method. How can this be achieved? If I understand correctly, the API itself is auto-generated from some API description. I want to create pull request for the fix, but don't know where to fix :)
Currently the 'include' parameter, which is used for sideloading (https://developer.zendesk.com/rest_api/docs/core/side_loading) is not accepted by zdesk for most endpoints listed in the sideloading doc. I added 'include' to the common_params locally and it seemed to work fine. (mjaskula@4649975) Before submitting that trivial PR, I'm wondering if this would be better handled in the api generator. I haven't gotten a good grasp on that code yet.
Also, I'm curious as to the reasoning behind validating common_params at all. It seems more flexible and pythonic to me to be able to pass on arbitrary parameters to zendesk. Maybe the solution to this is to just remove that check.
Thanks
Im having trouble finding any documentation on how to find the tag of a specific ticket rather than the most common tags as a whole.
Any ideas?
In https://github.com/fprimex/zdesk/blob/master/zdesk/zdesk_api.py#L3856
Say I'm paging through my it myself because I want to work over the results rather than waiting for all results at once. So I need to provide my own page param.
api_query = {}
if kwargs['query']:
api_query.update(kwargs['query'])
Including the above code should fix the issue
Hi,
The current version does not correctly support tokens.
I've logged the request and the authorization headers is as follows:
Authorization: Basic **Token**
where it should be:
Authorization: Bearer **Token**
I've temporary circumvented the problem by using a custom session:
zen = Zendesk(...)
session = requests.Session()
session.headers.update({'authorization': 'Bearer {}'.format(token)})
zen.client = session
It's very hard to handle multipart file uploads, which some endpoints require for their POST payloads, however the requests module can handle this kind of encoding easily. There is probably no downside to switching from httplib2 to requests, although it would be a breaking change for anyone using the complete_response
parameter, as we would start sending back requests responses rather than httplib2 responses.
Using requests would allow zdesk to better handle, and perhaps automatically handle, any complex encoding requirements.
from zdesk import Zendesk
fails and when run with python 3.7
====
Traceback (most recent call last):
File "/usr/local/lib/python3.7/site-packages/IPython/core/interactiveshell.py", line 2961, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "", line 1, in
from zdesk import Zendesk
File "/usr/local/lib/python3.7/site-packages/zdesk/init.py", line 1, in
from .zdesk import Zendesk, get_id_from_url
File "/usr/local/lib/python3.7/site-packages/zdesk/zdesk.py", line 17, in
from .zdesk_api import ZendeskAPI
File "/usr/local/lib/python3.7/site-packages/zdesk/zdesk_api.py", line 3053
def ticket_create(self, data, async=None, **kwargs):
^
SyntaxError: invalid syntax
====
But when run under python 3.6 it works
docker run --rm -it --entrypoint /bin/sh python:3.6-alpine
/ # which python
/usr/local/bin/python
/ # python --version
Python 3.6.6
/ # pip install zdesk
/ # pip install ipython
/ # ipython
Python 3.6.6 (default, Aug 22 2018, 20:48:31)
Type 'copyright', 'credits' or 'license' for more information
IPython 6.5.0 -- An enhanced Interactive Python. Type '?' for help.
In [1]: from zdesk import Zendesk
In [2]:
Hi, zdesk has been a massive help to me in the past few months! I have a script adding users to a series of Zendesk groups and then removing from a training group. However, the group removal part is not working. Can someone test and confirm if this is a Zendesk API issue or if maybe I'm just mixing something up?
My syntax looks like the following. user_id
and training_group
are defined earlier and I've verified that the values are being set correctly. I've also tried to hardcode the values for one agent for testing.
zendesk.user_group_membership_delete(user_id=user_id, id=training_group)
The traceback looks like this:
File "/Library/Python/2.7/site-packages/zdesk/zdesk_api.py", line 3320, in user_group_membership_delete
return self.call(api_path, method="DELETE", **kwargs)
File "/Library/Python/2.7/site-packages/zdesk/zdesk.py", line 229, in call
response.content, response.status_code, response)
zdesk.zdesk.ZendeskError: '404: {"error":"RecordNotFound","description":"Not found"} <Response [404]>'
Thanks for any help!
Hi I have some tickets and I would like to get the user information for said tickets. In the ticket result are requester_id
and submitter_id
. I've used both of these as input for calling the Zendesk.search
method with query set to "type:user USER_ID_HERE"
and calling Zendesk.end_user_show
with the ids as well. Both are returning:
*** zdesk.zdesk.ZendeskError: '404: b\'{"error":"RecordNotFound","description":"Not found"}\' <Response [404]>'
Is that the correct behavior?
Problem
Behavior of the users_search()
method appears to have suffered a regression in version 2.8.0, where it produces malformed requests to the Zendesk API.
Repro
Execute the following code in 2.8.0 and 2.7.1:
email = '[email protected]'
users = client.users_search(query=f'email:{email} -role:end-user')
Actual Result
2.8.0 produces the following GET request:
https://example.zendesk.com/api/v2/users/search?email:[email protected]%20-role:end-user
Note the lack of the query=
key in the URL.
As a result, Zendesk's API does not recognize this as a valid query, and produces a list of all users in the instance.
Expected Result
In version 2.7.1, the same code produces a correctly composed query string:
https://example.zendesk.com/api/v2/users/search.json?query=email%3Aauser%40example.com+-role%3Aend-user
Notes
Do a text find for "users_search" in this diff to see the change in implementation: 2.7.1...2.8.0#diff-a33b1f21ed323bc997b02c3cfafbd76572bfffa8afd954c202da7c3be8f0da41L4263 (Load the large diff of zdesk_api.py)
It appears that removing the manual extraction of query parameters from kwargs that was present in 2.7.1 has resulted in the URL being rendered differently, though I'm basing that on a cursory review of the diff.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.