Class Specifications

This section is generated with the Sphinx autodoc extension.

PolrApi

This file defines the main component of the Mypolr package: the PolrApi class.

class mypolr.polr_api.PolrApi(api_server, api_key, api_root='/api/v2/')[source]

Url shorter instance that stores server and API key

Parameters:
  • api_server (str) – The url to your server with Polr Project installed.
  • api_key (str) – The API key associated with a user on the server.
  • api_root (str) – API root endpoint.
lookup(lookup_url, url_key=None)[source]

Looks up the url_ending to obtain information about the short url.

If it exists, the API will return a dictionary with information, including the long_url that is the destination of the given short url URL.

The lookup object looks like something like this:

{
    'clicks': 42,
    'created_at':
        {
            'date': '2017-12-03 00:40:45.000000',
            'timezone': 'UTC',
            'timezone_type': 3
        },
    'long_url': 'https://stackoverflow.com/questions/tagged/python',
    'updated_at':
        {
            'date': '2017-12-24 13:37:00.000000',
            'timezone': 'UTC',
            'timezone_type': 3
        }
}
Parameters:
  • lookup_url (str) – An url ending or full short url address
  • url_key (str or None) – optional URL ending key for lookups against secret URLs
Returns:

Lookup dictionary containing, among others things, the long url; or None if not existing

Return type:

dict or None

lookup_no_raise(*args, **kwargs)[source]

Calls PolrApi.lookup(*args, **kwargs) but returns None instead of raising module errors.

shorten(long_url, custom_ending=None, is_secret=False)[source]

Creates a short url if valid, else returns None

Parameters:
  • long_url (str) – The url to shorten.
  • custom_ending (str or None) – The custom url to create if available.
  • is_secret (bool) – if not public, it’s secret
Returns:

a short link

Return type:

str

shorten_no_raise(*args, **kwargs)[source]

Calls PolrApi.shorten(*args, **kwargs) but returns None instead of raising module errors.

Exceptions

All Mypolr exceptions are inherited from MypolrError and are defined in this file.

exception mypolr.exceptions.BadApiRequest[source]

Raised when a request is malformed or otherwise is not understandable by server.

exception mypolr.exceptions.BadApiResponse(msg='Cannot interpret API response: invalid JSON.')[source]

Raised when a response is malformed and cannot be interpreted as valid JSON.

exception mypolr.exceptions.CustomEndingUnavailable(custom_ending)[source]

Raised when a custom ending is in use and therefore cannot be created.

Parameters:custom_ending (str) – the custom ending that was unavailable
exception mypolr.exceptions.DebugTempWarning[source]

Temporary Warning that should be removed

exception mypolr.exceptions.MypolrError[source]

Base class for all module exceptions

exception mypolr.exceptions.QuotaExceededError[source]

Admins may assign quotas to users, and this is raised when it’s exceeded and service stopped.

exception mypolr.exceptions.ServerOrConnectionError(caused=None)[source]

Raised when there is a timeout, internal server error, or any other connection error.

exception mypolr.exceptions.UnauthorizedKeyError(msg=None)[source]

Raised when an invalid key has been used in a request.

This refers either to: the API_KEY used in all endpoints, or the URL_KEY optionally used at the lookup endpoint.

Parameters:msg
mypolr.exceptions.no_raise(f)[source]

Decorator/wrapper function to force return None instead of raising module exceptions.

Exceptions that can be ignored are found in mypolr.exceptions.

Testing

Use tox with conda

See: Working with Windows, conda, tox.

ResponseErrorMap

Eases the burden of making repeated calls to the same url for testing when using pytest and responses.

class test_mypolr.ResponseErrorMap(endpoint, response_args=None, errors=None, common_kwargs=None)[source]

Maps sets of responses.add()-arguments to expected exceptions.

This works with pytest and responses.

Either pass mappings to initializer, or add them as pairs with add(response_args, errors):

response_args = [
    dict(status=401, json=dict(error='please authorize')),
    dict(status=500, json=dict(error='internal error')),
    dict(body=requests.RequestException()),
    dict(body=ValueError())
]

errors = [
    UnauthorizedKeyError,
    ServerOrConnectionError,
    ServerOrConnectionError,
    BadApiResponse,
]

rmap = ResponseErrorMap(response_args, errors)

which is the equivalent of doing this:

rmap = ResponseErrorMap()
rmap.add(dict(status=401, json=dict(error='please authorize')), UnauthorizedKeyError)
rmap.add(dict(status=500, json=dict(error='internal error')), ServerOrConnectionError)
rmap.add(dict(body=requests.RequestException()), ServerOrConnectionError)
rmap.add(dict(body=ValueError()), BadApiResponse)

After (and only after) mappings have been added, the make_error_tests() can be called. E.g.:

rmap.make_error_tests(my_api.action, 'foo', 42, dict(user='Alice', pass='pass123'))

This will:

  • add all response_args entries with responses.add(*args), and then
  • call the my_api.action()-method with given arguments for each entry in the ResponseErrorMap, but in a pytest.raises()-context, like so:
for error in self.errors:
    with pytest.raises(error):
        my_api.action('foo', 42, dict(user='Alice', pass='pass123'))
Parameters:
  • response_args (list of dictionaries or None) – list of dictionaries that will be the arguments for the given test
  • errors (list or None) – list of exceptions that should be raised given when the corresponding response from response_args is used.
  • common_kwargs (dict or None) –
add(response_kwargs, error)[source]
Parameters:
  • response_kwargs (dict or None) – a dictionary of arguments to response.add()
  • error (type(Exception)) – the error that pytest should expect with pytest.raises(error).
Returns:

None