Giter Site home page Giter Site logo

python-mattermost-driver's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

python-mattermost-driver's Issues

Configurable timeouts

Hi,

thanks for this awesome package!

My network isn't very reliable so I'd love to be able to set sensible timeouts for the requests made using requests.get (to be used in the client for example).

Thanks and best regards!

Passing a SSL Cert to the requests library

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.

Possible API improvements

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?

examples for various usage and add them in documentation

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.

Getting invalid URL error

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!

Driver provides SSL context to ws:// URI scheme

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.)

Driver cannot update channel if user is not in this channel

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

Compliance.Create_Report Method Doesn't Take Data Variables

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.

Please don't use `basicConfig`.

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!

Update Configuration API

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 ??

def update_configuration(self):
return self.client.put(
'/config'
)

Thank you.

Asyncio Support

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?

Improve logging

  • Add a debug option to activate debug messages
  • Actually add a few more useful log messages

Client._auth() -> TypeError: 'NoneType' object is not callable

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...

Setting debug to true sometimes causes hanging with issuing commands

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.

I'ts not posible add users with python driver when channel it's created from python driver

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

upload a file to a webhook incoming channel

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.

Generate api endpoints from mattermost openapi doc

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.

Python 2.7 support

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?

get_channel_by_name_and_team_name permission problem

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.

Get posts around oldest unread

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

JSON parsing works only on errors returned by mattermost

		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

Upload_file doesn`t work for image files?

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

Docker environment to run tests

I really want to have tests in this project.

What I am thinking of is something simple for the start.

  • Mattermost docker instance
  • A test file that tests the basic things
    • Does it even start
    • Does the login work
    • Does the websocket work
    • Can I make successful post/put/get/delete request

This probably shouldn't test every api endpoint...

make port as optional when making the requests

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

Gitlab LDAP login

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.

Create User Access Token

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...

Unable to create customer emojis

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 uploaded
  • emoji string Required
    A JSON object containing a name field with the name of the emoji and a creator_id field with the id of the authenticated user.

The driver only provide a name for the emoji object:

data={'emoji': {'name': emoji_name}},

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.

exception translation results in confusing backtraces

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.

Support bot tokens

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 ?

errors are unconditionally logged to terminal

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.

Very first websockets.pong() call seems to fail

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?

Support Python 3.8

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
Full output
/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.

`websocksets.ConnectionClosedError` may be raised in keepalive situations

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_

Add proxy support

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

Not able to authenticate while using Personal Access Token

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.")

SSLError: ssl3_get_record - wrong version number

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

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.