The message ID necessarily has to be an integer, and if no casting is
made it was being considered a string, causing problems when running
the example.
There were some issues running bots due to SSL issues.
Adding the extra_require requests[security] adds 3
additional packages that deal with these issues.
The root issue here is that we had been using `None` as a way of
encoding `event_types` as being an argument to not pass to the server
in the API codebase, but the marshalling to send this over the wire
didn't handle that possibility correctly.
This was incorrectly "fixed" in
409bb587429ec4dcb1220a8ed85ec1618ffde0ed; the root cause of the issue
was the refactor to the new approach for registering API endpoints.
This commit makes a bunch of improvements:
1. Use format() for string formatting instead of the old style.
2. Stop returning stuff where we don't have to.
3. URL generation should not be done by the script, especially
since our eventual goal is for the Zulip server to automatically
generate a webhook URL. So the user should be able to supply
the URL in the config file. Plus, this makes it easier to test
the script with non-Zulip URLs (such as RequestBin).
4. Removed unnecessary arguments.
Having a default parameter as '[]' may not be an issue with the current
implementation, but general practice is to default to None and assign
a default list subsequently.
This removes the use of RuntimeError, and replaces it with a custom
error class called ZulipError. In a few places, we use a subclass to
make it easier for code to interact with the error type.
Previously, remove_subscriptions called the
PATCH /api/v1/users/me/subscriptions endpoint, which is more like
an ad-hoc endpoint for bulk adding/removing subscriptions for the
user that makes the request. However, making a DELETE request
allows an admin to pass in the `principals` argument to unsubscribe
other users from streams as well, which is more consistent with how
add_subscriptions works.
The zulip and zulip_botserver packages specify mock as a runtime
dependency, which is only needed for testing during development.
So, it made more sense to move it to requirements.txt so that
it can be installed by ./tools/provision during development.
mypy with strict-optional led to examination of res.get('result')
calls potentially raising TypeError ('error' in None).
Server code indicates this is safe, and other nearby code assumes
presence of fields in 'res' also.
Rename the function channelmessage2zerver_message to channelmessage2zerver_message_for_one_stream.
Compress the converted data with tar instead of zip.
Add changes in zerver_userprofile mapping and zerver_realm mappings.
Do the manage.py import from a directory instead.
The API has aggressive retry logic for connecting to a
server, which may make sense for situation where you have
connection blips or server restarts.
When you're first connecting to the API, however, connection
failures are almost certainly a sign of misconfiguration, so
now we fail fast.
The bot lib takes advantage of this API change by catching the
ZulipError exception and exiting gracefully.
When invoked with search terms, twitter bot looks for these terms
in the content of a message to find out if they match. However,
Twitter can return messages that don't directly contain a search term.
This commit adds the tweeter user handle and expanded urls to the
places to look for a search term.
This parameter was intended to control whether we give a long timeout
and related behavior, but it was accidentally not being passed into
the second layer of the library from the first.
While we're fixing it, make it actually limit the length of a timeout
to something reasonable.
The only problem with this resulting code is that setup_path_on_import
only works if the Python versions are the same, so you need to run
this with Python 3 in that case.
We try to resolve that for use on Zulip servers with
zulip/zulip:47c5aae5b242fb6d2f5e860602e0fc0af68419bb; since that's the
main case where the code path runs, that should be good enough.
These were quite messy code, and now that almost nobody is running
their own zephyr mirroring script (vs. using webathena), making the
zephyr mirroring script deployable outside the package isn't super
valuable.
It is not guaranteed that the integration scripts in
the Zulip repository even specify a `provision` option.
Therefore, checking the value of this option would fail.
Updating this with getattr and a default value.
To do so, we need to import all required internal modules after the
script had the option to provision. The provisioning itself is then
done by zulip.init_from_options().
As the first unittest, this creates a test directory and
abnd adds it tho the excluded pip package files.
There are two `tests` directories now, one in zulip_botserver and one in
zulip. This confuses the unittest runner, leading to failed test imports.
Therefore, we need to tell the package importer that there are multiple
tests directories, all of which should be considered for a search.
I'm not thrilled with the `replace` error handler losing information
if the logfile contains invalid UTF-8 for some reason; but that sure
beats a UnicodeDecodeError, and for this script I can't quite be
bothered to run the rather tricky riddle trail that Python 3 makes it
to pass arbitrary byte data through layers of ordinary text processing.
Previously, if you didn't specify a list of `event_types` in either `register` or `call_on_each_event`, you'd get an exception due to the invalid event format.
This fixes#86.
With the new repo, doing a `pip install -e ./zulip` will be a part
of the core workflow. This mitigates the risk of developers
accidentally testing their changes against an installed copy of the
zulip package rather than the copy in their checkout. Therefore,
we can now get rid of the various `sys.path.inserts` in the examples.
In order to keep all three packages (zulip, zulip_bots,
zulip_botserver) in the same repo, all package files must now
be nested one level deeper.
For instance, python-zulip-api/zulip_bots/zulip_bots/bots/, instead
of python-zulip-api/zulip_bots/bots/.
Apparently, PyPI is very strict about package file names. Once you
upload files for 0.3.0, and only wish to make minor changes and
re-release it as the same version, it doesn't let you and complains
about identical file names.
Instead of using the `scripts` keyword, we now use the
`console_scripts` entry point to point to the zulip-send script
to be installed. This is what the Python Packaging User Guide
recommends for better cross-platform compatibility.
This adds support for controlling the basic configuration (user, API
key, etc.) of the Zulip API bindings via environment variables.
Fixes#3364.
Tweaked by tabbott to update variable names and document in README.md.
- Change `stream_name` into `stream_id` on some API endpoints that use
`stream_name` in their URLs to prevent confusion of `views` selection.
For example:
If the stream name is "foo/members", the URL would be trigger
"^streams/(?P<stream_name>.*)/members$" and it would be confusing because
we intend to use the endpoint with "^streams/(?P<stream_name>.*)$" regex.
All stream-related endpoints now use stream id instead of stream name,
except for a single endpoint that lets you convert stream names to stream ids.
See https://github.com/zulip/zulip/issues/2930#issuecomment-269576231
- Add `get_stream_id()` method to Zulip API client, and change
`get_subscribers()` method to comply with the new stream API
(replace `stream_name` with `stream_id`).
Fixes#2930.
Now, the `Client.do_api_query()` method supports sending files to the
API.
This has allowed the implementation of a new method,
`Client.upload_file(file)`. It simply uploads the file set in the
parameter, and returns the API's response (that includes the URI).
Despite the fact that `do_api_query()` supports multiple files as
parameters, `upload_file()` doesn't, because right now the API isn't
capable of managing more than a file in the same request.
We used to create endpoints with Client._register.
Now we now have explicit methods for the endpoints.
This allows us to add docstrings and stricter mypy annotations.
This fix also introduces a call_endpoint() method that avoids
the need for manually building urls with API_VERSTRING when you
know the URL pattern of the endpoint you want to hit (and when
the API doesn't have a convenient wrapper).
I fixed a bug with create_users where it now uses PUT instead
of POST.
I also removed client.export(), which was just broken.
I had to change recent-messages and zulip-export, which were
using client.do_api_query and Client._register.
Now it's easier to just call client.call_endpoint() for
situations where our API doesn't have convenient wrappers,
so that's what I did with those scripts.
Note that we still can't run mypy against this file and other files,
because of how the interface is dynamically created via _register. We
will need to change that or use a stub file to make it possible to
annotate this.
This was tweaked by tabbott to fix some bugs.
Add default "http://" to site argument locally if it is not specified
in an api call.
This fixes a problem where if you didn't manually specify `http://`
when connecting to a development server, the API bindings would hang
trying to connect using HTTPS.
Stops defaulting the site parameter to the now-nonexistent
https://zulip.com, and ask the user to enter the site via --site or
~/.zuliprc if not provided.
Fixes#2039.