vaelor / python-mattermost-driver Goto Github PK
View Code? Open in Web Editor NEWPython Mattermost Driver for APIv4
Home Page: https://vaelor.github.io/python-mattermost-driver/
License: MIT License
Python Mattermost Driver for APIv4
Home Page: https://vaelor.github.io/python-mattermost-driver/
License: MIT License
I believe this line:
Should be corrected to:
self.endpoint + '/name/' + role_name
The following code works just fine in Jupyter:
from mattermostdriver import Driver
from pprint import pprint
options = {}
options[ 'url' ] = '<url>'
options[ 'token' ] = '<your personal token here>'
options[ 'port' ] = 443
%env REQUESTS_CA_BUNDLE=/path/to/cert.pem
driver = Driver( options = options )
driver.login()
teamData = driver.teams.get_team_by_name( 'teamname' )
teamID = teamData[ 'id' ]
channelData = driver.channels.get_channel_by_name( teamID, 'roomname' )
postOptions = { 'channel_id': channelData[ 'id' ], 'message': 'mattermost test' }
driver.posts.create_post( options = postOptions )
The reason why it works is that I can specify in the environment that path to the .pem file for the requests library to use. It would be nice if there was some way to pass this path directly down to the requests library through login() or just adding stuff to the options variable, but that does not appear to be possible...unless I have missed something.
I like that you divided mm-driver’s functionality into several classes that we can compose and customize.
However, I think that the actual usage of the diver when calling the enpoint’s methods could be improved, so that instead of doing
mm = Driver(...)
mm.login()
mm.api['users'].get_user_by_username('another.name')
we can just do:
mm = MatterMost(...)
mm.login()
mm.users.get_user_by_username('another.name')
This is relatively easy to implement in another wrapper class (maybe it can even be merged into Driver
):
class MatterMost:
def __init__(self):
self._driver = Driver()
# self._driver.login()
@property
def userid(self):
return self._driver.client.userid
@property
def username(self):
return self._driver.client.username
def __getattr__(self, key):
try:
return self._driver.api[key]
except KeyError:
raise AttributeError(key) from None
@Vaelor What do you think about this?
how is it sound like to create the examples code for various usage and add those sample codes in the documentation.
it is just like my usage (posting files to channels) , there is less support in stackoverflow , and documentation will help for those who don't know how web/rest communication works in web development.
Hi,
Documentation: https://api.mattermost.com/#tag/users%2Fpaths%2F~1users~1usernames%2Fpost
expected: users/usernames
observed: users/username
Best regards
Rico
Hi,
I am getting the following error while launching errbot with backend set to a mattermost instance.
15:20:12 ERROR errbot.backends.base Exception occurred in serve_once:
Traceback (most recent call last):
File "/usr/local/lib/python3.6/site-packages/errbot/backends/base.py", line 861, in serve_forever
if self.serve_once():
File "/root/errbot-root/errbot-mattermost-backend/mattermost.py", line 311, in serve_once
self.driver.login()
File "/usr/local/lib/python3.6/site-packages/mattermostdriver/driver.py", line 171, in login
result = self.users.get_user('me')
File "/usr/local/lib/python3.6/site-packages/mattermostdriver/endpoints/users.py", line 45, in get_user
self.endpoint + '/' + user_id
File "/usr/local/lib/python3.6/site-packages/mattermostdriver/client.py", line 193, in get
response = self.make_request('get', endpoint, options=options, params=params)
File "/usr/local/lib/python3.6/site-packages/mattermostdriver/client.py", line 162, in make_request
response.raise_for_status()
File "/usr/local/lib/python3.6/site-packages/requests/models.py", line 943, in raise_for_status
raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 411 Client Error: Length Required for url: http://SERVER_IP_HERE:8065/mm:8065/api/v4/users/me
15:20:12 INFO errbot.backends.base Reconnecting in 1 seconds (0 attempted reconnections so far).
15:20:13 DEBUG urllib3.connectionpool Starting new HTTP connection (1): PROXY_IP_HERE
15:20:13 DEBUG urllib3.connectionpool http://PROXY_IP_HERE "GET http://SERVER_IP_HERE:8065/mm:8065/api/v4/users/me HTTP/1.1" 411 4390
15:20:13 ERROR mattermostdriver.websocke <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>ERROR: The requested URL could not be retrieved</title>
This is followed by html data of a webpage with the message "The requested URL could not be retrieved"
I have configured Mattermost such that the URL (http://SERVER_IP_HERE:8065/mm:8065/api/v4/users/me) automatically redirects on Mattermost login page (tested the same on another server).
There should not be any access related issue as Mattermost and Errbot are installed on the same server (represented here with SERVER_IP_HERE).
Let me know if any additional information is required.
Please Help!
Connecting to an HTTP endpoint correctly sets ws://
but incorrectly provides ssl=context
with context
being set on line 26 of websocket.py
context = ssl.create_default_context(purpose=ssl.Purpose.CLIENT_AUTH)
This is used on line 39, even if the URI scheme was set to ws://
on line 32.
Setting context=None
correctly resolves this.
(Before you ask why I'm using HTTP instead of HTTPS, I have the bot running within an overlay network under Rancher in AWS, so it communicates locally to Mattermost. If I provide the HTTPS URL for mattermost, it will exit the VPC and connect to the public IP for the load balancer, generating unnecessary usage charges. I terminate SSL on the load balancer, so I need internal communication to be unencrypted.)
This here is the wrong method:
Not worth doing a PR for?
Driver cannot update channel if user (whose token is used for authorization) is not in this channel. Server sends 404 status code for self.driver.channels.update_channel
method.
File "/usr/local/lib/python3.5/dist-packages/mattermostdriver/endpoints/channels.py", line 45, in update_channel
options=options
File "/usr/local/lib/python3.5/dist-packages/mattermostdriver/client.py", line 172, in put
return self.make_request('put', endpoint, options=options, params=params, data=data).json()
File "/usr/local/lib/python3.5/dist-packages/mattermostdriver/client.py", line 140, in make_request
response.raise_for_status()
File "/usr/local/lib/python3.5/dist-packages/requests/models.py", line 829, in raise_for_status
raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 404 Client Error: Not Found
This line
def get_channels_for_user(self, user_id, team_id):
.
It does not fetch a single channel but all channels for the user.
https://api.mattermost.com/#tag/channels%2Fpaths%2F~1users~1{user_id}~1teams~1{team_id}~1channels%2Fget
I am trying to create a compliance report via this project through compliance.py->create_report(). I have been able to create a Driver object, login, and run other commands in users.py and the get_reports method. Looking through the documentation here, mattermost is expecting data variables to specify how the report should be created such as time range of compliance report and description. However, the create_report method doesn't take any parameters and trying to pass any variables into it will throw a parameter error due to its method signature not allowing for them. Trying to run the method as is will raise InvalidOrMissingParameters(message):Invalid description.
I have tested that the endpoint works on my server, I ran curl commands as specified in the documentation above and was able to see new reports created when running the get_reports method.
I found bug.
Bug fixed code is as follows
disconnect_bug.txt
https://github.com/Vaelor/python-mattermost-driver/pull/92/files
Hello!
What?
Please change:
logging.basicConfig(level=logging.INFO)
log = logging.getLogger('mattermostdriver. ...')
to:
log = logging.getLogger('mattermostdriver. ...')
log.setLevel(logging.INFO)
i.e. do not configure the root logger, but only the current logger.
Why?
logging.basicConfig(**kwargs)
...
This function does nothing if the root logger already has handlers configured for it.
So this will not work as expected:
import logging
import mattermostdriver # calls logging.basicConfig
logging.basicConfig(level=logging.DEBUG) # does nothing
logging.debug("Test") # output suppressed
This would print the desired output but the import order is wrong:
import logging
logging.basicConfig(level=logging.DEBUG)
import mattermostdriver
logging.debug("Test")
Thank you for your work!
Thank you for helping me for creating access token.
By the way, I also want to use update configuration API like below.
https://api.mattermost.com/#tag/system%2Fpaths%2F~1config%2Fget
According to the documentation, update_conf API needs argument including new configuration(json type).
But, it looks like that your "update_configuration" fuction doesn't have any argument.
How to use it ??
python-mattermost-driver/src/mattermostdriver/endpoints/system.py
Lines 29 to 32 in a7628e8
Thank you.
I like your library, and I'm thinking about integrating it with my application, but it currently only supports asyncio for the websockets part of the library. I would like to extend this to the rest of the library. I would be willing to investigate migrating all of the HTTP calls from requests to aiohttp, is async something that you'd like to see integrated into the mainline?
There is a bug after last update. There is no way to use token auth.
In client.py:
def auth_header(self):
if self._auth: return None
...
then:
def make_request(self, method, endpoint, options=None, params=None, data=None, files=None, basepath=None):
...
response = request(
url + endpoint,
headers=self.auth_header(),
auth = self._auth(),
verify=self._verify,
json=options,
params=params,
data=data,
files=files,
timeout=self.request_timeout
)
So if you want use token self_auth should be None. But then None will call...
While searching for what is returned for each endpoint call, I'm finding myself constantly jumping between the driver endpoint docs the source links and https://api.mattermost.com/ often fumbling to find the correct API endpoint.
Would it be possible to generate a link back to the original documentation from every endpoint entry in the endpoint documentation?
Here is the code that I have:
# mattermost driver settings
driver = Driver({
'url': '<url>',
'login_id': '<email>',
'password': '<password>',
'port': <port>,
'debug': True,
})
# log into mattermost
driver.login()
# make a post in mattermost
driver.posts.create_post(options={
'channel_id': '<id>',
'message': '<message>'
})
When using this code, the driver.posts.create_post method sometimes hangs indefinitely without any debug output. It is seemingly random as to when this happens.
This package currently requires a password for login, it should instead allow for OAuth token to be provided.
See also https://docs.mattermost.com/developer/personal-access-tokens.html
Thank you for your excellent job.
There is a missing '/' in this line : https://github.com/Vaelor/python-mattermost-driver/blob/master/src/mattermostdriver/endpoints/users.py#L203 between self.endpoint
and user_id
.
Example in readme.
Must be foo.webhooks.
instead
when i create a new channel from function mattermost_connection.channels.create_channel in python driver, the channel it's create correcly, but qhen i add user from function mattermost_connection.channels.add_user, the user not add in channel (the user i'ts in the team previously)
when add a new user from mattermost web, the number of members counter plus the "gost user add from python driver", when refresh the page, the "gost user add from python driver" i'ts less
i try to set the mattermost_connection.channels.update_channel_roles, but not work.
when i talk about counter, i'ts the "members" counter in the top of chat
not exactly a issue (not fimiliar with web requests)
i am trying to upload a file to webhook , so thi s is my code
import requests, json
import base64
import os
URL = ""
file_path = r'C:\Users\prashra\PycharmProjects\personal_project\mattermost\requiremnets.txt'
form_data = {
"file": (os.path.basename(file_path),open(file_path, 'rb'))
}
payload = {"channel_id": "mattermost_test", "display_name": "i dont know", "text": "holy"}
headers = {"Content-Type": "application/json"}
r = requests.post(URL, data=json.dumps(payload),files = form_data)
this is giving me eror
ValueError: Data must not be a string.
can you help me how to uploada file to channel.
Instead of manually adding each endpoint, a script to generate all endpoints from the openapi documentation would be nice.
This could also add more infos to every endpoint instead of only a options
or params
parameter.
Same thing only different, the get_user_by_email
method should be using GET on the endpoint, see here:
https://api.mattermost.com/#tag/users%2Fpaths%2F~1users~1email~1%7Bemail%7D%2Fget
I'm getting this when trying to install it with pip on Python 2.7:
Collecting mattermostdriver
Using cached mattermostdriver-4.2.0.tar.gz
Complete output from command python setup.py egg_info:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/tmp/pip-build-hV1oTl/mattermostdriver/setup.py", line 11, in <module>
with open(readme_file, encoding='utf-8') as f:
TypeError: 'encoding' is an invalid keyword argument for this function
Will this library not support 2.7?
The following code works as expected within Jupiter lab.
from mattermostdriver import Driver
from pprint import pprint
options = {}
options['url'] = '<url>'
options['token'] = '<token>'
options['port'] = 443
%env REQUESTS_CA_BUNDLE=/CB64_CERTS.pem
driver = Driver(options=options)
driver.login()
teamData = driver.teams.get_team_by_name('team')
teamID = teamData['id']
channelData = driver.channels.get_channel_by_name(teamID, 'channel')
postOptions = {'channel_id': channelData['id'], 'message': 'mattermost test'}
driver.posts.create_post(options=postOptions)
However, if I try to call:
driver.channels.get_channel_by_name_and_team_name('team', 'channel')
I get the error:
NotEnoughPermissions: You do not have the appropriate permissions
which seems strange. As near as I can tell, all of the appropriate permissions are there as should be evidenced by the ability to call alternative functions to obtain the required information to post a message to a channel.
I am not sure if the bug is in the library or if this is a bug in mattermost itself.
I cant seem to find a function that does this API call.
https://api.mattermost.com/#tag/posts/paths/~1users~1{user_id}~1channels~1{channel_id}~1posts~1unread/get
looking at the source code something like the code below would work in mattermostdriver.endpoints.posts
def get_unread_posts_for_channel(self, user_id, channel_id, params=None):
return self.client.get(
Users.endpoint + '/' + user_id + '/' + Channels.endpoint + '/' + channel_id + '/posts/unread',
params=params
)
I can open a PR if needed, just wanted to post an issue first to see if maybe I am missing a function that already accomplishes this.
Cheers
try:
response.raise_for_status()
except requests.HTTPError as e:
data = e.response.json()
log.error(data['message'])
if data['status_code'] == 400:
raise InvalidOrMissingParameters(data['message'])
elif data['status_code'] == 401:
raise NoAccessTokenProvided(data['message'])
elif data['status_code'] == 403:
raise NotEnoughPermissions(data['message'])
elif data['status_code'] == 413:
raise ContentTooLarge(data['message'])
elif data['status_code'] == 501:
raise FeatureDisabled(data['message'])
else:
raise
The except block will throw if for example an 502 occurs, it shouldn't even try to parse json
This may be an API issue, but perhaps someone can help me:
I don' have no problem to upload quite any file type, but image files (jpg, png) are rejected:
Traceback (most recent call last):
File "d:\Users\Markus\Documents\python\imagequote\mmtest.py", line 60, in <module>
files={'files': (FILENAME, open(FILENAME))}
File "C:\Program Files (x86)\Python36-32\lib\site-packages\mattermostdriver\endpoints\files.py", line 11, in upload_file
files=files
File "C:\Program Files (x86)\Python36-32\lib\site-packages\mattermostdriver\client.py", line 135, in post
return self.make_request('post', endpoint, options=options, params=params, data=data, files=files).json()
File "C:\Program Files (x86)\Python36-32\lib\site-packages\mattermostdriver\client.py", line 109, in make_request
files=files
File "C:\Program Files (x86)\Python36-32\lib\site-packages\requests\api.py", line 112, in post
return request('post', url, data=data, json=json, **kwargs)
File "C:\Program Files (x86)\Python36-32\lib\site-packages\requests\api.py", line 58, in request
return session.request(method=method, url=url, **kwargs)
File "C:\Program Files (x86)\Python36-32\lib\site-packages\requests\sessions.py", line 494, in request
prep = self.prepare_request(req)
File "C:\Program Files (x86)\Python36-32\lib\site-packages\requests\sessions.py", line 437, in prepare_request
hooks=merge_hooks(request.hooks, self.hooks),
File "C:\Program Files (x86)\Python36-32\lib\site-packages\requests\models.py", line 308, in prepare
self.prepare_body(data, files, json)
File "C:\Program Files (x86)\Python36-32\lib\site-packages\requests\models.py", line 496, in prepare_body
(body, content_type) = self._encode_files(files, data)
File "C:\Program Files (x86)\Python36-32\lib\site-packages\requests\models.py", line 159, in _encode_files
fdata = fp.read()
File "C:\Program Files (x86)\Python36-32\lib\encodings\cp1252.py", line 23, in decode
return codecs.charmap_decode(input,self.errors,decoding_table)[0]
UnicodeDecodeError: 'charmap' codec can't decode byte 0x90 in position 172: character maps to <undefined>
I have no idea how to investigate the problem. Mattermost's API documentation doesn' t help either.
Thanks for help & for this project!
Markus
I really want to have tests in this project.
What I am thinking of is something simple for the start.
post
/put
/get
/delete
requestThis probably shouldn't test every api endpoint...
facing issue when i am trying to log in the mattermost using the package.
in package port is defined and is used in when making requests to the mattermost server.
ps . i dont know my port of server.
if i make the request satement to the server with out port i am able to login into the system
so i am proposing to make port optional in url
ie https://server_url:port/basepath/endpoint
to https://server_url/basepath/endpoint
hello
Thank you for your giving great useful OSS for mattermost.
I'm using mattermost with Gitlab-LDAP authentication.
I'd like to use this driver with Gitlab-LDAP account instead of mattermost standard account.
Is there somehow I can use this driver through Gitlab-LDAP login ?
I can get tokens & cookies from python requests module as below.
#######################################
session = requests.session()
get_auth_token = session.get(mm+'/oauth/gitlab/login')
pq_auth_token = pq(get_auth_token.content)
csrf_token = pq_auth_token('#new_ldap_user input[name="authenticity_token"]')[0].value
payload = {'authenticity_token': csrf_token, 'username': userid, 'password': password}
ldap_login = session.post(
gitlab + '/users/auth/ldapmain/callback',
data=payload,
)
for i,ldap_history in enumerate(ldap_login.history):
if i == 2:
authenticated_response = ldap_history
mm_cookie = authenticated_response.cookies
#######################################
Thank you.
The file is transferred as binary instead of json. (ofc)
Mattermost API has 'Create a user access token' POST request menu.
Would you update python-mattermost-driver for this function??
I'm trying to post "create user access token" request like below. But, it doesn't work.
Do you have any idea ?
My mattermost server is version 4.6 .
/* MY CODE FOR POST REQUEST */
payload={"description": "some message"}
requests(
'https://<my_mattermost_URL>/api/v4/users/UserID from API/tokens',
cookies = foo.client.cookise,
json = payload
)
/* END OF CODE */
If you know something about this problem, please help me...
It is probably a silly tasks but I try to upload emojis and I miserably fail. 😁
Here's my non-working code:
emoji_name = "test"
image_path = "test.gif"
with open(image_path, "rb") as image:
files = {"image": image}
mm.emoji.create_custom_emoji(emoji_name=emoji_name, files=files)
which gives me:
Invalid or missing emoji in request body
Traceback (most recent call last):
File "/Users/max/.pyenv/versions/mmemoji/lib/python3.7/site-packages/mattermostdriver/client.py", line 140, in make_request
response.raise_for_status()
File "/Users/max/.pyenv/versions/mmemoji/lib/python3.7/site-packages/requests/models.py", line 939, in raise_for_status
raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 400 Client Error: Bad Request for url: https://mattermost.example.org:443/api/v4/emoji
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "mmemoji_other.py", line 20, in <module>
mm.emoji.create_custom_emoji(emoji_name=emoji_name, files=files)
File "/Users/max/.pyenv/versions/mmemoji/lib/python3.7/site-packages/mattermostdriver/endpoints/emoji.py", line 11, in create_custom_emoji
files=files
File "/Users/max/.pyenv/versions/mmemoji/lib/python3.7/site-packages/mattermostdriver/client.py", line 174, in post
return self.make_request('post', endpoint, options=options, params=params, data=data, files=files).json()
File "/Users/max/.pyenv/versions/mmemoji/lib/python3.7/site-packages/mattermostdriver/client.py", line 145, in make_request
raise InvalidOrMissingParameters(data['message'])
mattermostdriver.exceptions.InvalidOrMissingParameters: Invalid or missing emoji in request body
According to the Mattermost API Reference, this endpoint needs:
FormData Parameters
image
file Required
A file to be uploadedemoji
string Required
A JSON object containing aname
field with the name of the emoji and acreator_id
field with the id of the authenticated user.
The driver only provide a name
for the emoji
object:
I also checked a few other drivers, use cases of them and the server side code which seem to confirm the need of a creator_id
(I can give details if it helps).
So I tried to work around it but I get the exact same error:
creator_id = mm.users.get_user(user_id="me")["id"]
with open(image_path, "rb") as image:
data = {"emoji": {"name": emoji_name, "creator_id": creator_id}}
files = {"image": image}
mm.client.post("/emoji", data=data, files=files)
What else do I miss?
The creation of the emoji with same file and name via the Web UI perfectly works.
For example, with bogus terms in search_criteria
:
>>> mm.users.search_users(search_criteria)
Invalid or missing term in request body.
Traceback (most recent call last):
File "/home/paul/.local/lib/python3.8/site-packages/mattermostdriver/client.py", line 162, in make_request
response.raise_for_status()
File "/usr/lib/python3/dist-packages/requests/models.py", line 940, in raise_for_status
raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 400 Client Error: Bad Request for url: https://chat.example.com:443/api/v4/users/search
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/paul/.local/lib/python3.8/site-packages/mattermostdriver/endpoints/users.py", line 32, in search_users
return self.client.post(
File "/home/paul/.local/lib/python3.8/site-packages/mattermostdriver/client.py", line 206, in post
return self.make_request('post', endpoint, options=options, params=params, data=data, files=files).json()
File "/home/paul/.local/lib/python3.8/site-packages/mattermostdriver/client.py", line 173, in make_request
raise InvalidOrMissingParameters(message)
mattermostdriver.exceptions.InvalidOrMissingParameters: Invalid or missing term in request body.
>>> _
This makes the traceback more difficult to read than necessary. I did a little research and it seems that translating exceptions as follows:
raise MyFriendlyException() from None
should suppress the original exception and yield a clean traceback.
HI @Vaelor,
Are bot tokens supported ?
https://docs.mattermost.com/developer/bot-accounts.html
Because I cannot get it work it seems.
Created a bot account in MT and then
import os, sys
import urllib3
import requests
urllib3.disable_warnings()
from mattermostdriver import Driver
mt = Driver(
{
"url": "on prem MT",
"token": "s1z1g6sqp...........w",
"verify": False,
"port": 443,
"debug": True,
}
)
mt.login()
# print(mt.users.get_user(user_id="me"))
mt.posts.create_post(
options={
"channel_id": "j9d13993o............mo",
"message": "This is the important file",
}
)
Then:
keep-alive\r\nAuthorization: Bearer s1xxxxxx7ahhmrw\r\nContent-Length: 2\r\nContent-Type: application/json\r\n\r\n'
send: b'{}'
reply: 'HTTP/1.1 401 Unauthorized\r\n'
header: Content-Length: 186
header: Content-Type: application/json
header: Date: Wed, 06 May 2020 12:34:05 GMT
header: Expires: 0
header: Set-Cookie: MMAUTHTOKEN=; Path=/; Max-Age=0; HttpOnly
header: Vary: Accept-Encoding
header: X-Request-Id: hw63wjjj7jyebf3m4zhrtsnssw
header: X-Version-Id: 5.22.0.5.22.1.
Invalid or expired session, please login again.
Traceback (most recent call last):
File "/usr/local/lib/python3.6/site-packages/mattermostdriver/client.py", line 162, in make_request
response.raise_for_status()
File "/home/xxxxxxxxxxxx/.local/lib/python3.6/site-packages/requests/models.py", line 940, in raise_for_status
raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 401 Client Error: Unauthorized for url: https://URL:443/api/v4/users/me
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "../update/mt.py", line 19, in <module>
mt.login()
File "/usr/local/lib/python3.6/site-packages/mattermostdriver/driver.py", line 162, in login
result = self.users.get_user('me')
File "/usr/local/lib/python3.6/site-packages/mattermostdriver/endpoints/users.py", line 45, in get_user
self.endpoint + '/' + user_id
File "/usr/local/lib/python3.6/site-packages/mattermostdriver/client.py", line 193, in get
response = self.make_request('get', endpoint, options=options, params=params)
File "/usr/local/lib/python3.6/site-packages/mattermostdriver/client.py", line 175, in make_request
raise NoAccessTokenProvided(message)
mattermostdriver.exceptions.NoAccessTokenProvided: Invalid or expired session, please login again.
Any tips ?
While writing some code against our Mattermost, I discovered that exceptions are being logged, even though my code is handling them. For example, ResourceNotFound
wrote the following to my terminal:
Unable to find an existing account matching your username for this team. This team may require an invite from the team owner to join.
My script dealt with the situation, and so this logging is unwanted noise.
Hi, we are using this driver for our bot code, and are seeing some weird behavior (See details here: attzonko/mmpy_bot#171)
On the Mattermost server side, I am seeing an invalid character error from the first websockets.pong()
future after the 20s timeout.
{"level":"debug","ts":1616195215.1219645,"caller":"app/web_conn.go:190","msg":"Error while reading message from websocket","error":"error during decoding websocket message: invalid character 'ð' looking for beginning of value","errorVerbose":"invalid character 'ð' looking for beginning of value\nerror during decoding websocket message\ngithub.com/mattermost/mattermost-server/v5/app.(*WebConn).ReadMsg\n\tgithub.com/mattermost/mattermost-server/v5/app/web_conn.go:257\ngithub.com/mattermost/mattermost-server/v5/app.(*WebConn).startPoller.func1.1\n\tgithub.com/mattermost/mattermost-server/v5/app/web_conn.go:188\nruntime.goexit\n\truntime/asm_amd64.s:1374"}
Any ideas on what we could be doing wrong? Or is this possibly a real issue?
Python 3.8.0 has been released on October 14, 2019:
https://www.python.org/downloads/release/python-380/
I have been testing my project against 3.8-dev for a few weeks and it has reported only 1 warning (4 occurrences):
DeprecationWarning: "@coroutine" decorator is deprecated since Python 3.8, use "async def" instead
/home/travis/virtualenv/python3.8-dev/lib/python3.8/site-packages/mattermostdriver/websocket.py:19
/home/travis/virtualenv/python3.8-dev/lib/python3.8/site-packages/mattermostdriver/websocket.py:19: DeprecationWarning: "@coroutine" decorator is deprecated since Python 3.8, use "async def" instead
def connect(self, event_handler):
/home/travis/virtualenv/python3.8-dev/lib/python3.8/site-packages/mattermostdriver/websocket.py:54
/home/travis/virtualenv/python3.8-dev/lib/python3.8/site-packages/mattermostdriver/websocket.py:54: DeprecationWarning: "@coroutine" decorator is deprecated since Python 3.8, use "async def" instead
def _start_loop(self, websocket, event_handler):
/home/travis/virtualenv/python3.8-dev/lib/python3.8/site-packages/mattermostdriver/websocket.py:73
/home/travis/virtualenv/python3.8-dev/lib/python3.8/site-packages/mattermostdriver/websocket.py:73: DeprecationWarning: "@coroutine" decorator is deprecated since Python 3.8, use "async def" instead
def _authenticate_websocket(self, websocket, event_handler):
/home/travis/virtualenv/python3.8-dev/lib/python3.8/site-packages/mattermostdriver/websocket.py:103
/home/travis/virtualenv/python3.8-dev/lib/python3.8/site-packages/mattermostdriver/websocket.py:103: DeprecationWarning: "@coroutine" decorator is deprecated since Python 3.8, use "async def" instead
def _wait_for_message(self, websocket, event_handler):
Documentation:
The new syntax async def
is new in Python 3.5, meaning Python 3.4 support would have to be dropped to fix these warnings. Python 3.4 having reached EOL on March 18, 2019 (https://python.org/downloads/release/python-3410), I think this should be acceptable.
See #86 (comment)
I believe websocksets.ConnectionClosedError
may be raised here in situations where one would want the keepalive to persist. For instance, if prototyping a bot on a laptop that suspends sometimes, you may get something like:
Traceback (most recent call last):
File "/usr/local/lib/python3.9/dist-packages/websockets-8.1-py3.9-linux-x86_64.egg/websockets/protocol.py", line 827, in transfer_data
message = await self.read_message()
File "/usr/local/lib/python3.9/dist-packages/websockets-8.1-py3.9-linux-x86_64.egg/websockets/protocol.py", line 895, in read_message
frame = await self.read_data_frame(max_size=self.max_size)
File "/usr/local/lib/python3.9/dist-packages/websockets-8.1-py3.9-linux-x86_64.egg/websockets/protocol.py", line 971, in read_data_frame
frame = await self.read_frame(max_size)
File "/usr/local/lib/python3.9/dist-packages/websockets-8.1-py3.9-linux-x86_64.egg/websockets/protocol.py", line 1047, in read_frame
frame = await Frame.read(
File "/usr/local/lib/python3.9/dist-packages/websockets-8.1-py3.9-linux-x86_64.egg/websockets/framing.py", line 105, in read
data = await reader(2)
File "/usr/lib/python3.9/asyncio/streams.py", line 723, in readexactly
await self._wait_for_data('readexactly')
File "/usr/lib/python3.9/asyncio/streams.py", line 517, in _wait_for_data
await self._waiter
File "/usr/lib/python3.9/asyncio/selector_events.py", line 856, in _read_ready__data_received
data = self._sock.recv(self.max_size)
ConnectionResetError: [Errno 104] Connection reset by peer
The above exception was the direct cause of the following exception:
File "/home/pde/src/mmpy_bot/mmpy_bot/bot.py", line 88, in run
self.event_handler.start()
File "/home/pde/src/mmpy_bot/mmpy_bot/event_handler.py", line 44, in start
self.driver.init_websocket(self._handle_event)
File "/usr/local/lib/python3.9/dist-packages/mattermostdriver-7.2.0-py3.9.egg/mattermostdriver/driver.py", line 148, in init_websocket
File "/usr/lib/python3.9/asyncio/base_events.py", line 642, in run_until_complete
return future.result()
File "/usr/local/lib/python3.9/dist-packages/mattermostdriver-7.2.0-py3.9.egg/mattermostdriver/websocket.py", line 51, in connect
File "/usr/local/lib/python3.9/dist-packages/mattermostdriver-7.2.0-py3.9.egg/mattermostdriver/websocket.py", line 63, in _start_loop
File "/usr/lib/python3.9/asyncio/tasks.py", line 481, in wait_for
return fut.result()
File "/usr/local/lib/python3.9/dist-packages/mattermostdriver-7.2.0-py3.9.egg/mattermostdriver/websocket.py", line 108, in _wait_for_message
File "/usr/local/lib/python3.9/dist-packages/websockets-8.1-py3.9-linux-x86_64.egg/websockets/protocol.py", line 509, in recv
await self.ensure_open()
File "/usr/local/lib/python3.9/dist-packages/websockets-8.1-py3.9-linux-x86_64.egg/websockets/protocol.py", line 803, in ensure_open
raise self.connection_closed_exc()
websockets.exceptions.ConnectionClosedError: code = 1006 (connection closed abnormally [internal]), no reason
_Originally posted by @pde in https://github.com/Vaelor/python-mattermost-driver/pull/86#discussion_r601958017_
Hello everyone,
I would like to add proxy support, as I have come across a case where I need to explicitly add the proxy to the client (requests and websocket) and more people may have the same problem.
In some cases, adding http_proxy and https_proxy to the environment may be enough, but in some cases it may be explicit for the connection with mattermost
I can open a PR if you think it's a good idea
The API endpoints documented here are not implemented (in version 7.0.1 at least).
I'll have a go at it if I figure out, how to use a forked package in my venv :)
Traceback (most recent call last):
File "C:\Users\ATHARVA\Anaconda3\lib\site-packages\urllib3\connection.py", line 141, in _new_conn
(self.host, self.port), self.timeout, **extra_kw)
File "C:\Users\ATHARVA\Anaconda3\lib\site-packages\urllib3\util\connection.py", line 60, in create_connection
for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM):
File "C:\Users\ATHARVA\Anaconda3\lib\socket.py", line 745, in getaddrinfo
for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
socket.gaierror: [Errno 11001] getaddrinfo failed
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\ATHARVA\Anaconda3\lib\site-packages\urllib3\connectionpool.py", line 600, in urlopen
chunked=chunked)
File "C:\Users\ATHARVA\Anaconda3\lib\site-packages\urllib3\connectionpool.py", line 345, in _make_request
self._validate_conn(conn)
File "C:\Users\ATHARVA\Anaconda3\lib\site-packages\urllib3\connectionpool.py", line 844, in _validate_conn
conn.connect()
File "C:\Users\ATHARVA\Anaconda3\lib\site-packages\urllib3\connection.py", line 284, in connect
conn = self._new_conn()
File "C:\Users\ATHARVA\Anaconda3\lib\site-packages\urllib3\connection.py", line 150, in _new_conn
self, "Failed to establish a new connection: %s" % e)
urllib3.exceptions.NewConnectionError: <urllib3.connection.VerifiedHTTPSConnection object at 0x000002C648DF85F8>: Failed to establish a new connection: [Errno 11001] getaddrinfo failed
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\ATHARVA\Anaconda3\lib\site-packages\requests\adapters.py", line 449, in send
timeout=timeout
File "C:\Users\ATHARVA\Anaconda3\lib\site-packages\urllib3\connectionpool.py", line 649, in urlopen
_stacktrace=sys.exc_info()[2])
File "C:\Users\ATHARVA\Anaconda3\lib\site-packages\urllib3\util\retry.py", line 388, in increment
raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='https', port=443): Max retries exceeded with url: //bot-dev-hackathon-iitbbs.herokuapp.com:8065/api/v4/users/me (Caused by NewConnectionError('<urllib3.connection.VerifiedHTTPSConnection object at 0x000002C648DF85F8>: Failed to establish a new connection: [Errno 11001] getaddrinfo failed',))
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "mattermostdevbot.py", line 14, in <module>
driver.login()
File "C:\Users\ATHARVA\Anaconda3\lib\site-packages\mattermostdriver\driver.py", line 162, in login
result = self.users.get_user('me')
File "C:\Users\ATHARVA\Anaconda3\lib\site-packages\mattermostdriver\endpoints\users.py", line 45, in get_user
self.endpoint + '/' + user_id
File "C:\Users\ATHARVA\Anaconda3\lib\site-packages\mattermostdriver\client.py", line 193, in get
response = self.make_request('get', endpoint, options=options, params=params)
File "C:\Users\ATHARVA\Anaconda3\lib\site-packages\mattermostdriver\client.py", line 159, in make_request
**request_params
File "C:\Users\ATHARVA\Anaconda3\lib\site-packages\requests\api.py", line 75, in get
return request('get', url, params=params, **kwargs)
File "C:\Users\ATHARVA\Anaconda3\lib\site-packages\requests\api.py", line 60, in request
return session.request(method=method, url=url, **kwargs)
File "C:\Users\ATHARVA\Anaconda3\lib\site-packages\requests\sessions.py", line 533, in request
resp = self.send(prep, **send_kwargs)
File "C:\Users\ATHARVA\Anaconda3\lib\site-packages\requests\sessions.py", line 646, in send
r = adapter.send(request, **kwargs)
File "C:\Users\ATHARVA\Anaconda3\lib\site-packages\requests\adapters.py", line 516, in send
raise ConnectionError(e, request=request)
requests.exceptions.ConnectionError: HTTPSConnectionPool(host='https', port=443): Max retries exceeded with url: //bot-dev-hackathon-iitbbs.herokuapp.com:8065/api/v4/users/me (Caused by NewConnectionError('<urllib3.connection.VerifiedHTTPSConnection object at 0x000002C648DF85F8>: Failed to establish a new connection: [Errno 11001] getaddrinfo failed',))
I am getting the above error whenever I am trying to authenticate my bot.
This is the code that I am running :
from mattermostdriver import Driver
driver_options = {
'url': "url",
'token':'token',
'scheme': 'https',
'port': 8065,
'basepath': '/api/v4',
'verify': True
}
driver = Driver(driver_options)
print("Authenticating...")
driver.login()
print("Successfully authenticated.")
Using with Python 3.6.1
When trying to execute the code, get this error:
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='domain.com', port=8065): Max retries exceeded with url: /api/v4/users/login (Caused by SSLError(SSLError("bad handshake: Error([('SSL routines', 'ssl3_get_record', 'wrong version number')],)",),))
Seems like this is related to:
https://stackoverflow.com/a/9963668/3090556
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.