{"action":"created","issue":{"url":"https://api.github.com/repos/Yelp/swagger-py/issues/86","labels_url":"https://api.github.com/repos/Yelp/swagger-py/issues/86/labels{/name}","comments_url":"https://api.github.com/repos/Yelp/swagger-py/issues/86/comments","events_url":"https://api.github.com/repos/Yelp/swagger-py/issues/86/events","html_url":"https://github.com/Yelp/swagger-py/pull/86","id":52968066,"number":86,"title":"Cleanup swagger client","user":{"login":"dnephin","id":442180,"avatar_url":"https://avatars.githubusercontent.com/u/442180?v=3","gravatar_id":"","url":"https://api.github.com/users/dnephin","html_url":"https://github.com/dnephin","followers_url":"https://api.github.com/users/dnephin/followers","following_url":"https://api.github.com/users/dnephin/following{/other_user}","gists_url":"https://api.github.com/users/dnephin/gists{/gist_id}","starred_url":"https://api.github.com/users/dnephin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dnephin/subscriptions","organizations_url":"https://api.github.com/users/dnephin/orgs","repos_url":"https://api.github.com/users/dnephin/repos","events_url":"https://api.github.com/users/dnephin/events{/privacy}","received_events_url":"https://api.github.com/users/dnephin/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2014-12-27T22:59:09Z","updated_at":"2015-01-07T01:02:01Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/Yelp/swagger-py/pulls/86","html_url":"https://github.com/Yelp/swagger-py/pull/86","diff_url":"https://github.com/Yelp/swagger-py/pull/86.diff","patch_url":"https://github.com/Yelp/swagger-py/pull/86.patch"},"body":"Previously the entire process of fetching the api docs, validating the api docs, and building `Resources`/`Operations` was done as part of the constructor of `SwaggerClient`.  Constructors should never do anything more than assignment to fields.  Complex constructors are difficult to test, and make re-use more difficult. \r\n\r\nThis branch splits the constructor into two factory methods `from_url()`, and `from_resource_listing()`.  This allows consumers to create a `SwaggerClient` from just a list of resources, which also removes the branch logic from the constructor. This is still backwards compatible because the only documented interface is the `get_client()` call. \r\n\r\nSome other things:\r\n* use `simplejson` if it's available (since it's much faster, and this is very slow)\r\n* completely removed the need for `ClientProcessor` (yay less inheritance!). This subclass was only being used for the single method that it implemented. All other operations are already done by default by the `Loader`. That method was extracted to `append_name_to_api()`.\r\n* change the kwarg for the client cache to be `ttl` instead of `timeout` (`timeout` is still supported for backwards compatibility), and some other renames around the cache\r\n* cache clients based on all args + kwargs, not just the first argument. All the arguments change the behaviour of the client, so they all need to be part of the key. Uses `repr()` instead of `json.dumps()`.\r\n* `SwaggerClient` and `Resource` now support `dir()` (and tab completion in ipython) without `setattr` (which was duplicating the `__getattr__`).\r\n\r\n\r\nResolves #80. Remove special case for `datetime` in `stringify_body`. This should be totally unnecessary. The `swagger_model` should already convert this datetime into the proper format.\r\n\r\nResolves #76. Previously `api_base_path` was being used for two different things: overriding the default url that was specified in the swagger api doc, and also as a base url for swagger api docs that use relative urls.  I've split this into two params. `api_base_path` is now only an override, `base_url` is now the base url to append to relatives `basePath` urls.\r\n\r\nResolves #83. `raise_with` is unnecessary, and makes the interface for `swagger-py` more verbose than it needs to be.\r\n\r\n\r\nSorry this is so big. Most of this had to be changed all at once, so I wasn't able to break it into smaller parts. I did pull out a couple isolated commits, and a lot of this is just simple replacement (json imports, and test changes to use the new factories)."},"comment":{"url":"https://api.github.com/repos/Yelp/swagger-py/issues/comments/68962985","html_url":"https://github.com/Yelp/swagger-py/pull/86#issuecomment-68962985","issue_url":"https://api.github.com/repos/Yelp/swagger-py/issues/86","id":68962985,"user":{"login":"analogue","id":26757,"avatar_url":"https://avatars.githubusercontent.com/u/26757?v=3","gravatar_id":"","url":"https://api.github.com/users/analogue","html_url":"https://github.com/analogue","followers_url":"https://api.github.com/users/analogue/followers","following_url":"https://api.github.com/users/analogue/following{/other_user}","gists_url":"https://api.github.com/users/analogue/gists{/gist_id}","starred_url":"https://api.github.com/users/analogue/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/analogue/subscriptions","organizations_url":"https://api.github.com/users/analogue/orgs","repos_url":"https://api.github.com/users/analogue/repos","events_url":"https://api.github.com/users/analogue/events{/privacy}","received_events_url":"https://api.github.com/users/analogue/received_events","type":"User","site_admin":false},"created_at":"2015-01-07T01:02:01Z","updated_at":"2015-01-07T01:02:01Z","body":"Looks good to merge even though large refactors like this scare me and turn my brain to swiss cheese. Definitely understand why this was not able to be split up into smaller pieces."}}