Giter VIP home page Giter VIP logo

bugsy's Introduction

Bugsy

Build Status Coverage Status

Bugsy is a library for interacting with the native REST API for Bugzilla.

Documentation can be found on Read The Docs

bugsy's People

Contributors

automatedtester avatar dylanwh avatar indygreg avatar luser avatar parkouss avatar pyoor avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

bugsy's Issues

Add error handling

At the moment if we get something unexpected from Bugzilla we throw an exception which is bad! We need to guide users to what the problem is (and probably tell them to raise a bug here)

JSONDecodeError

Hi....any activity around here? I could use some help.

import bugsy
bugzilla = bugsy.Bugsy(
...         bugzilla_url='https://my.bugzilla.instance.com/bugzilla/rest',
...         api_key='my-key')
>>> bugzilla.authenticated
True
>>> bugzilla.get(22789)
requests.exceptions.JSONDecodeError: Expecting value: line 3 column 1 (char 4)

Only PUT fields that have changed

Due to the fact that Bugzilla's REST API isn't actually very RESTful, you can't directly update some fields by just setting the value in the PUT data. For example, when GETing a bug, the field "groups" contains a list of group names the bug is in. But to change the bug's groups, you have to pass in an object that contains "add" and/or "remove" keys. This means we either need to track it separately, or else the "groups" object in the _bug dictionary will have a different format depending on whether it is to be updated or not.

Furthermore, this would reduce both the transmission size and the time to process it.

I would suggest, rather than using a lot of @Property and @Setter decorators, overriding getattr and setattr, and, in the latter, building up a new dictionary of values to be updated, and using that in Bugsy.put().

HTTPErrors when making Bugzilla API requests result in a ValueError

There are three main buckets of errors that Bugsy could experience when interacting with Bugzilla's REST API:

  1. Network problem (e.g. DNS failure, refused connection, timeout etc)
  2. A non-200 HTTP response that is valid JSON and has "error" and "message" keys (eg Bugzilla responding saying a required field was omitted when creating a bug).
  3. A non-200 HTTP response that is not valid JSON (eg server HTTP 500, 404 page, maintenance page, load balancer error page etc)

Currently (1) is handled fine, since requests raises the correct exception itself - eg:

bz = bugsy.Bugsy(bugzilla_url="http://invalid-url")
bz.get(123456)
Traceback (most recent call last):
    ...
    raise ConnectionError(err, request=request)
requests.exceptions.ConnectionError: ('Connection aborted.', gaierror(8, 'Name or service not known'))

And as of #24 and #25, Bugsy also handles (2) fine, since it now returns a BugsyException with relevant message from the JSON error response "message" key.

However (3) still results in unexpected behaviour - ie for all of the following:

  • Requests to verify login
  • Creating/updating a bug
  • Fetching a bug
  • Adding a comment to a bug

...if an HTTP 500 is experienced for the request, then Bugsy currently returns ValueError: No JSON object could be decoded, since it doesn't use .json() within a try-except. This means the user doesn't see the original cause, which was an HTTPError.

Also for the add_comment() case, if the HTTP response happened to be something that the JSON parser would accept (eg body='"Foo"'), then the request fails silently even though it wasn't an HTTP 200 response.

The best fix for this is likely to use raise_for_status() (as mentioned in #25) as a fallback after checking if an error/message key exists (ie to make sure we don't regress the (2) case above).

I have some tests that currently fail that demonstrate the issue - I'll open a PR to add them as expected fail, which will hopefully make this clearer :-) If I have time I'll also then open a PR to fix them (and remove the xfail annotation).

Support setting whiteboard

It would be nice if tools using bugsy could use the whiteboard. I guess the simplest API is just to manipulate it as a string, although maybe there are enough conventions to make it possible to provide a get/set/contains API.

Add ability to fetch a bug's attachments

I don't need this at the moment, but it would be nice to have the ability to fetch a list of attachments for a bug, and then get/set information about those attachments, like reviews or feedback flags, maybe be able to obsolete an attachment. Stretch goal of attaching an attachment to a bug, I guess.

Let `bug` set/get dependencies

I need to be able to set both the 'dependson' and 'blocks' values on bug creation, but that doesn't seem possible at the moment.

Can't log into bugzilla 5.0 dev server on landfill

I'm practising using Bugsy against the landfill 5.0 server at https://landfill.bugzilla.org/bugzilla-5.0-branch/

When I try to log in with an API key, I get:

<Response [200]>
{u'result': False}
Traceback (most recent call last):
  File "bin/create_release.py", line 46, in <module>
    main()
  File "bin/create_release.py", line 42, in main
    releaseStandalone(useDev=True)
  File "bin/create_release.py", line 19, in releaseStandalone
    bugzilla = bugsy.Bugsy(username=USERNAME, api_key=DEV_APIKEY, bugzilla_url=bugzillaUrl)
  File "/Users/mark/loop/loop/built/.venv/lib/python2.7/site-packages/bugsy/bugsy.py", line 72, in __init__
    raise LoginException(result['message'])
KeyError: 'message'

The first two lines are debug added by me. Trying to use this on production gives the result as True and everything is OK.

Creating bug fails due to `cc_detail` field

After upgrading to 0.12.0 from 0.10.1 creating bugs in bugzilla.mozilla.org failed. After some investigation it turned out that the difference is that bugsy now populates the POST request body with empty arrays for all the fields in bugsy.bug.ARRAY_TYPES. In particular this includes cc_detail which afaict isn't supported for bug creation.

Bugsy doesn't load depend_on list

If I called the BMO API directly, I can get a legit depends list...

api_key = getpass.getpass("Enter Bugzilla API Key: ")
resp = requests.get('https://bugzilla.mozilla.org/rest/bug', params={'id': 'BUG_ID_WITH_DEPENDS', 'api_key': api_key})

If I use bugsy to get this, I doesn't seem to populate depends on the bug object...

api_key = getpass.getpass("Enter Bugzilla API Key: ")
bugzilla = bugsy.Bugsy(api_key=api_key)
bug = bugzilla.get(BUG_ID_WITH_DEPENDS)

Feature request: Search-by-flag

It would be very, very helpful to allow Bugsy to search by flags. A lot of workflow-relevant information is tucked away in there.

Allow additional bug field filters

There is currently no way in Bugsy to request additional fields returned in Bug requests. This is due to changes from 4e62855. It would be helpful to allow an add_fields parameter to Bug.get() in order to append additional fields to the include_fields request parameter.

Add ability to check if bugsy is authenticated against the server

Currently a bugsy instance hold a _has_auth property that indicate if it is authenticated. It would be nice to have a public access for it - I propose an authenticated property.

This would allow to create bugsy (with or without auth), then later be able to check the auth state without going through the exceptions.

bugsy always requests all fields from bugs

because bugsy doesn't set "include_fields", it always requests all bug fields from bugzilla.

this is overly resource intensive in most cases.

it should default to a small set of fields, and all the caller to extend the default list when required.

Set and clear flags on attachments

I need to be able to alter flags on attachments. I imagine this will require fetching information on attachments as well, but for now I don't need to create nor update metadata on them.

Setting a cc on a new bug doesn't work

For a new bug, doing:

bug.summary = "test"
bug.cc = "myemail@..."
bugzilla.put(bug)

fails with bugsy.errors.BugsyException: Message: Not an ARRAY reference at /data/www/bugzilla-dev.allizom.org/Bugzilla/Bug.pm line 1613.

This is because bug.cc is putting the value into a dict with add/remove options, whereas bugzilla is expecting a simple array for the new bug case.

The workaround is to do:

bug.summary = "test"
bug._bug["cc"] = "myemail@..."
bugzilla.put(bug)

I'm not sure if its best to fix the code in _process_setter in bug.py or if this should just be document.

Let `bug` set/get keywords

I need to be able to set keywords on bug creation, and it'd be nice to be able up update them (and fetch them) after creation. The REST API differs for creation vs update in regards to how they get specified.

Add assigned to property to bugs

Afaik right now given a bug object one cannot query or change the user it has been assigned to with the api (one could probably tweak the underlying dict though)

BugsyException not raised when performing .get() on invalid/inaccesible bugs

eg:

import bugsy
bz = bugsy.Bugsy()
bz.get(111111111111111111)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/Ed/.virtualenvs/of/lib/python2.7/site-packages/bugsy/bugsy.py", line 138, in get
    return Bug(self, **bug['bugs'][0])
KeyError: 'bugs'

Expected:
Some instance of BugsyException, that surfaces the "message" attribute returned from https://bugzilla.mozilla.org/rest/bug/111111111111111111

This would also affect security bugs.

Adding new comments doesn't work

I attempted to add a new comment to a bug and Bugzilla responds with:

{"error":true,"code":32614,"message":"A REST API resource was not found for 'POST /bug/1030911'."}

No error from the Bugsy client, which means it isn't looking at responses to determine if an error occurred. Another good reason for wrapping requests (see my recent pull request).

We're going to have issues like this if we mock Bugzilla API responses. I'm very tempted to integrate an actual Bugzilla server into the test environment (as heavyweight as that will be).

add_comment() silently fails if posting to an invalid/inaccessible bug

eg:

import bugsy
bz = bugsy.Bugsy(username=REDACTED, api_key=REDACTED)
bug = bugsy.Bug(bugsy=bz, id=111111111111111111)
bug.add_comment("foo")
# No exception was generated

Expected:
Command doesn't silently fail. Instead some instance of BugsyException is raised.

Note that whilst this example manually generates the bug object, the same could happen if a bug was made private after the .get() but before the .add_comment(), or if say the bug comment was too long - which causes Bugzilla to return an error even though the .get() might have succeeded.

Support other status flags

Our bugzilla server have various other valid status which are not permitted by bugsy. Two that come to mind are review_requested and merge_requested.

Given that bugzilla supports having custom statuses, it would be nice if bugsy supported that too.

Use headers for authentication rather than URL parameters

Bugzilla supports using custom HTTP headers for the various authentication fields, instead of passing them as parameters in the request URL.

This prevents them from accidentally being included in logs.

The header key names can be found here:
https://github.com/mozilla/webtools-bmo-bugzilla/blob/f70d4ce7e0a94379bb901559109650874946c84b/Bugzilla/WebService/Constants.pm#L305-L310

use constant API_AUTH_HEADERS => {
    X_BUGZILLA_LOGIN    => 'Bugzilla_login',
    X_BUGZILLA_PASSWORD => 'Bugzilla_password',
    X_BUGZILLA_API_KEY  => 'Bugzilla_api_key',
    X_BUGZILLA_TOKEN    => 'Bugzilla_token',
};

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.