import requests
import json Introduction to API Querying
In today’s digital world, being able to access and work with online data is a valuable skill, even in the Humanities and Social Sciences. This session is all about getting comfortable with APIs (Application Programming Interfaces) and understanding why they’re useful for research. You’ll learn how APIs compare to other ways of getting data, like text mining and web scraping, and how to tell if a website has an API you can use. We’ll walk through how to make a request to an API, use parameters to get the exact data you want, and understand the responses you get back (usually in JSON format). By the end, you’ll have hands-on experience using APIs to gather and explore data for your own projects.
Let’s get started by importing the libraries that we will be using:
Let’s explore the requests and json libraries using the Help function:
help(requests)Help on package requests:
NAME
requests
DESCRIPTION
Requests HTTP Library
~~~~~~~~~~~~~~~~~~~~~
Requests is an HTTP library, written in Python, for human beings.
Basic GET usage:
>>> import requests
>>> r = requests.get('https://www.python.org')
>>> r.status_code
200
>>> b'Python is a programming language' in r.content
True
... or POST:
>>> payload = dict(key1='value1', key2='value2')
>>> r = requests.post('https://httpbin.org/post', data=payload)
>>> print(r.text)
{
...
"form": {
"key1": "value1",
"key2": "value2"
},
...
}
The other HTTP methods are supported - see `requests.api`. Full documentation
is at <https://requests.readthedocs.io>.
:copyright: (c) 2017 by Kenneth Reitz.
:license: Apache 2.0, see LICENSE for more details.
PACKAGE CONTENTS
__version__
_internal_utils
_types
adapters
api
auth
certs
compat
cookies
exceptions
help
hooks
models
packages
sessions
status_codes
structures
utils
CLASSES
builtins.OSError(builtins.Exception)
requests.exceptions.RequestException
requests.exceptions.ConnectionError
requests.exceptions.ConnectTimeout(requests.exceptions.ConnectionError, requests.exceptions.Timeout)
requests.exceptions.HTTPError
requests.exceptions.Timeout
requests.exceptions.ReadTimeout
requests.exceptions.TooManyRedirects
requests.exceptions.URLRequired
builtins.object
requests.models.Response
json.decoder.JSONDecodeError(builtins.ValueError)
requests.exceptions.JSONDecodeError(requests.exceptions.InvalidJSONError, json.decoder.JSONDecodeError)
requests.exceptions.InvalidJSONError(requests.exceptions.RequestException)
requests.exceptions.JSONDecodeError(requests.exceptions.InvalidJSONError, json.decoder.JSONDecodeError)
requests.models.RequestEncodingMixin(builtins.object)
requests.models.PreparedRequest(requests.models.RequestEncodingMixin, requests.models.RequestHooksMixin)
requests.models.RequestHooksMixin(builtins.object)
requests.models.PreparedRequest(requests.models.RequestEncodingMixin, requests.models.RequestHooksMixin)
requests.models.Request
requests.sessions.SessionRedirectMixin(builtins.object)
requests.sessions.Session
class ConnectTimeout(ConnectionError, Timeout)
| ConnectTimeout(*args: Any, **kwargs: Any) -> None
|
| The request timed out while trying to connect to the remote server.
|
| Requests that produced this error are safe to retry.
|
| Method resolution order:
| ConnectTimeout
| ConnectionError
| Timeout
| RequestException
| builtins.OSError
| builtins.Exception
| builtins.BaseException
| builtins.object
|
| Methods inherited from RequestException:
|
| __init__(self, *args: Any, **kwargs: Any) -> None
| Initialize RequestException with `request` and `response` objects.
|
| ----------------------------------------------------------------------
| Data descriptors inherited from RequestException:
|
| __weakref__
| list of weak references to the object
|
| ----------------------------------------------------------------------
| Data and other attributes inherited from RequestException:
|
| __annotations__ = {}
|
| ----------------------------------------------------------------------
| Methods inherited from builtins.OSError:
|
| __reduce__(self, /)
| Helper for pickle.
|
| __str__(self, /)
| Return str(self).
|
| ----------------------------------------------------------------------
| Static methods inherited from builtins.OSError:
|
| __new__(*args, **kwargs) class method of builtins.OSError
| Create and return a new object. See help(type) for accurate signature.
|
| ----------------------------------------------------------------------
| Data descriptors inherited from builtins.OSError:
|
| characters_written
|
| errno
| POSIX exception code
|
| filename
| exception filename
|
| filename2
| second exception filename
|
| strerror
| exception strerror
|
| ----------------------------------------------------------------------
| Methods inherited from builtins.BaseException:
|
| __repr__(self, /)
| Return repr(self).
|
| __setstate__(self, state, /)
|
| add_note(self, note, /)
| Add a note to the exception
|
| with_traceback(self, tb, /)
| Set self.__traceback__ to tb and return self.
|
| ----------------------------------------------------------------------
| Data descriptors inherited from builtins.BaseException:
|
| __cause__
|
| __context__
|
| __dict__
|
| __suppress_context__
|
| __traceback__
|
| args
class ConnectionError(RequestException)
| ConnectionError(*args: Any, **kwargs: Any) -> None
|
| A Connection error occurred.
|
| Method resolution order:
| ConnectionError
| RequestException
| builtins.OSError
| builtins.Exception
| builtins.BaseException
| builtins.object
|
| Methods inherited from RequestException:
|
| __init__(self, *args: Any, **kwargs: Any) -> None
| Initialize RequestException with `request` and `response` objects.
|
| ----------------------------------------------------------------------
| Data descriptors inherited from RequestException:
|
| __weakref__
| list of weak references to the object
|
| ----------------------------------------------------------------------
| Data and other attributes inherited from RequestException:
|
| __annotations__ = {}
|
| ----------------------------------------------------------------------
| Methods inherited from builtins.OSError:
|
| __reduce__(self, /)
| Helper for pickle.
|
| __str__(self, /)
| Return str(self).
|
| ----------------------------------------------------------------------
| Static methods inherited from builtins.OSError:
|
| __new__(*args, **kwargs) class method of builtins.OSError
| Create and return a new object. See help(type) for accurate signature.
|
| ----------------------------------------------------------------------
| Data descriptors inherited from builtins.OSError:
|
| characters_written
|
| errno
| POSIX exception code
|
| filename
| exception filename
|
| filename2
| second exception filename
|
| strerror
| exception strerror
|
| ----------------------------------------------------------------------
| Methods inherited from builtins.BaseException:
|
| __repr__(self, /)
| Return repr(self).
|
| __setstate__(self, state, /)
|
| add_note(self, note, /)
| Add a note to the exception
|
| with_traceback(self, tb, /)
| Set self.__traceback__ to tb and return self.
|
| ----------------------------------------------------------------------
| Data descriptors inherited from builtins.BaseException:
|
| __cause__
|
| __context__
|
| __dict__
|
| __suppress_context__
|
| __traceback__
|
| args
class HTTPError(RequestException)
| HTTPError(*args: Any, **kwargs: Any) -> None
|
| An HTTP error occurred.
|
| Method resolution order:
| HTTPError
| RequestException
| builtins.OSError
| builtins.Exception
| builtins.BaseException
| builtins.object
|
| Methods inherited from RequestException:
|
| __init__(self, *args: Any, **kwargs: Any) -> None
| Initialize RequestException with `request` and `response` objects.
|
| ----------------------------------------------------------------------
| Data descriptors inherited from RequestException:
|
| __weakref__
| list of weak references to the object
|
| ----------------------------------------------------------------------
| Data and other attributes inherited from RequestException:
|
| __annotations__ = {}
|
| ----------------------------------------------------------------------
| Methods inherited from builtins.OSError:
|
| __reduce__(self, /)
| Helper for pickle.
|
| __str__(self, /)
| Return str(self).
|
| ----------------------------------------------------------------------
| Static methods inherited from builtins.OSError:
|
| __new__(*args, **kwargs) class method of builtins.OSError
| Create and return a new object. See help(type) for accurate signature.
|
| ----------------------------------------------------------------------
| Data descriptors inherited from builtins.OSError:
|
| characters_written
|
| errno
| POSIX exception code
|
| filename
| exception filename
|
| filename2
| second exception filename
|
| strerror
| exception strerror
|
| ----------------------------------------------------------------------
| Methods inherited from builtins.BaseException:
|
| __repr__(self, /)
| Return repr(self).
|
| __setstate__(self, state, /)
|
| add_note(self, note, /)
| Add a note to the exception
|
| with_traceback(self, tb, /)
| Set self.__traceback__ to tb and return self.
|
| ----------------------------------------------------------------------
| Data descriptors inherited from builtins.BaseException:
|
| __cause__
|
| __context__
|
| __dict__
|
| __suppress_context__
|
| __traceback__
|
| args
class JSONDecodeError(InvalidJSONError, json.decoder.JSONDecodeError)
| JSONDecodeError(*args: Any, **kwargs: Any) -> None
|
| Couldn't decode the text into json
|
| Method resolution order:
| JSONDecodeError
| InvalidJSONError
| RequestException
| builtins.OSError
| json.decoder.JSONDecodeError
| builtins.ValueError
| builtins.Exception
| builtins.BaseException
| builtins.object
|
| Methods defined here:
|
| __init__(self, *args: Any, **kwargs: Any) -> None
| Construct the JSONDecodeError instance first with all
| args. Then use it's args to construct the IOError so that
| the json specific args aren't used as IOError specific args
| and the error message from JSONDecodeError is preserved.
|
| __reduce__(self) -> tuple[Any, ...] | str
| The __reduce__ method called when pickling the object must
| be the one from the JSONDecodeError (be it json/simplejson)
| as it expects all the arguments for instantiation, not just
| one like the IOError, and the MRO would by default call the
| __reduce__ method from the IOError due to the inheritance order.
|
| ----------------------------------------------------------------------
| Data descriptors inherited from RequestException:
|
| __weakref__
| list of weak references to the object
|
| ----------------------------------------------------------------------
| Data and other attributes inherited from RequestException:
|
| __annotations__ = {}
|
| ----------------------------------------------------------------------
| Methods inherited from builtins.OSError:
|
| __str__(self, /)
| Return str(self).
|
| ----------------------------------------------------------------------
| Static methods inherited from builtins.OSError:
|
| __new__(*args, **kwargs) class method of builtins.OSError
| Create and return a new object. See help(type) for accurate signature.
|
| ----------------------------------------------------------------------
| Data descriptors inherited from builtins.OSError:
|
| characters_written
|
| errno
| POSIX exception code
|
| filename
| exception filename
|
| filename2
| second exception filename
|
| strerror
| exception strerror
|
| ----------------------------------------------------------------------
| Methods inherited from builtins.BaseException:
|
| __repr__(self, /)
| Return repr(self).
|
| __setstate__(self, state, /)
|
| add_note(self, note, /)
| Add a note to the exception
|
| with_traceback(self, tb, /)
| Set self.__traceback__ to tb and return self.
|
| ----------------------------------------------------------------------
| Data descriptors inherited from builtins.BaseException:
|
| __cause__
|
| __context__
|
| __dict__
|
| __suppress_context__
|
| __traceback__
|
| args
class PreparedRequest(RequestEncodingMixin, RequestHooksMixin)
| PreparedRequest() -> None
|
| The fully mutable :class:`PreparedRequest <PreparedRequest>` object,
| containing the exact bytes that will be sent to the server.
|
| Instances are generated from a :class:`Request <Request>` object, and
| should not be instantiated manually; doing so may produce undesirable
| effects.
|
| Usage::
|
| >>> import requests
| >>> req = requests.Request('GET', 'https://httpbin.org/get')
| >>> r = req.prepare()
| >>> r
| <PreparedRequest [GET]>
|
| >>> s = requests.Session()
| >>> s.send(r)
| <Response [200]>
|
| Method resolution order:
| PreparedRequest
| RequestEncodingMixin
| RequestHooksMixin
| builtins.object
|
| Methods defined here:
|
| __init__(self) -> None
| Initialize self. See help(type(self)) for accurate signature.
|
| __repr__(self) -> str
| Return repr(self).
|
| copy(self) -> PreparedRequest
|
| prepare(
| self,
| method: str | None = None,
| url: _t.UriType | None = None,
| headers: Mapping[str, str | bytes] | None = None,
| files: _t.FilesType = None,
| data: _t.DataType = None,
| params: _t.ParamsType = None,
| auth: _t.AuthType = None,
| cookies: RequestsCookieJar | CookieJar | dict[str, str] | None = None,
| hooks: _t.HooksInputType | None = None,
| json: _t.JsonType = None
| ) -> None
| Prepares the entire request with the given parameters.
|
| prepare_auth(self, auth: _t.AuthType, url: _t.UriType = '') -> None
| Prepares the given HTTP auth data.
|
| prepare_body(
| self,
| data: _t.DataType,
| files: _t.FilesType,
| json: _t.JsonType = None
| ) -> None
| Prepares the given HTTP body data.
|
| prepare_content_length(self, body: _t.BodyType) -> None
| Prepare Content-Length header based on request method and body
|
| prepare_cookies(
| self,
| cookies: RequestsCookieJar | CookieJar | dict[str, str] | None
| ) -> None
| Prepares the given HTTP cookie data.
|
| This function eventually generates a ``Cookie`` header from the
| given cookies using cookielib. Due to cookielib's design, the header
| will not be regenerated if it already exists, meaning this function
| can only be called once for the life of the
| :class:`PreparedRequest <PreparedRequest>` object. Any subsequent calls
| to ``prepare_cookies`` will have no actual effect, unless the "Cookie"
| header is removed beforehand.
|
| prepare_headers(self, headers: Mapping[str, str | bytes] | None) -> None
| Prepares the given HTTP headers.
|
| prepare_hooks(self, hooks: _t.HooksInputType | None) -> None
| Prepares the given hooks.
|
| prepare_method(self, method: str | None) -> None
| Prepares the given HTTP method.
|
| prepare_url(self, url: _t.UriType, params: _t.ParamsType) -> None
| Prepares the given HTTP URL.
|
| ----------------------------------------------------------------------
| Data and other attributes defined here:
|
| __annotations__ = {'_body_position': 'int | object | None', '_cookies'...
|
| ----------------------------------------------------------------------
| Readonly properties inherited from RequestEncodingMixin:
|
| path_url
| Build the path URL to use.
|
| ----------------------------------------------------------------------
| Data descriptors inherited from RequestEncodingMixin:
|
| __dict__
| dictionary for instance variables
|
| __weakref__
| list of weak references to the object
|
| ----------------------------------------------------------------------
| Methods inherited from RequestHooksMixin:
|
| deregister_hook(self, event: str, hook: _t.HookType) -> bool
| Deregister a previously registered hook.
| Returns True if the hook existed, False if not.
|
| register_hook(self, event: str, hook: Iterable[_t.HookType] | _t.HookType) -> None
| Properly register a hook.
class ReadTimeout(Timeout)
| ReadTimeout(*args: Any, **kwargs: Any) -> None
|
| The server did not send any data in the allotted amount of time.
|
| Method resolution order:
| ReadTimeout
| Timeout
| RequestException
| builtins.OSError
| builtins.Exception
| builtins.BaseException
| builtins.object
|
| Methods inherited from RequestException:
|
| __init__(self, *args: Any, **kwargs: Any) -> None
| Initialize RequestException with `request` and `response` objects.
|
| ----------------------------------------------------------------------
| Data descriptors inherited from RequestException:
|
| __weakref__
| list of weak references to the object
|
| ----------------------------------------------------------------------
| Data and other attributes inherited from RequestException:
|
| __annotations__ = {}
|
| ----------------------------------------------------------------------
| Methods inherited from builtins.OSError:
|
| __reduce__(self, /)
| Helper for pickle.
|
| __str__(self, /)
| Return str(self).
|
| ----------------------------------------------------------------------
| Static methods inherited from builtins.OSError:
|
| __new__(*args, **kwargs) class method of builtins.OSError
| Create and return a new object. See help(type) for accurate signature.
|
| ----------------------------------------------------------------------
| Data descriptors inherited from builtins.OSError:
|
| characters_written
|
| errno
| POSIX exception code
|
| filename
| exception filename
|
| filename2
| second exception filename
|
| strerror
| exception strerror
|
| ----------------------------------------------------------------------
| Methods inherited from builtins.BaseException:
|
| __repr__(self, /)
| Return repr(self).
|
| __setstate__(self, state, /)
|
| add_note(self, note, /)
| Add a note to the exception
|
| with_traceback(self, tb, /)
| Set self.__traceback__ to tb and return self.
|
| ----------------------------------------------------------------------
| Data descriptors inherited from builtins.BaseException:
|
| __cause__
|
| __context__
|
| __dict__
|
| __suppress_context__
|
| __traceback__
|
| args
class Request(RequestHooksMixin)
| Request(
| method: str | None = None,
| url: _t.UriType | None = None,
| headers: _t.HeadersType = None,
| files: _t.FilesType = None,
| data: _t.DataType = None,
| params: _t.ParamsType = None,
| auth: _t.AuthType = None,
| cookies: RequestsCookieJar | CookieJar | dict[str, str] | None = None,
| hooks: _t.HooksInputType | None = None,
| json: _t.JsonType = None
| ) -> None
|
| A user-created :class:`Request <Request>` object.
|
| Used to prepare a :class:`PreparedRequest <PreparedRequest>`, which is sent to the server.
|
| :param method: HTTP method to use.
| :param url: URL to send.
| :param headers: dictionary of headers to send.
| :param files: dictionary of {filename: fileobject} files to multipart upload.
| :param data: the body to attach to the request. If a dictionary or
| list of tuples ``[(key, value)]`` is provided, form-encoding will
| take place.
| :param json: json for the body to attach to the request (if files or data is not specified).
| :param params: URL parameters to append to the URL. If a dictionary or
| list of tuples ``[(key, value)]`` is provided, form-encoding will
| take place.
| :param auth: Auth handler or (user, pass) tuple.
| :param cookies: dictionary or CookieJar of cookies to attach to this request.
| :param hooks: dictionary of callback hooks, for internal usage.
|
| Usage::
|
| >>> import requests
| >>> req = requests.Request('GET', 'https://httpbin.org/get')
| >>> req.prepare()
| <PreparedRequest [GET]>
|
| Method resolution order:
| Request
| RequestHooksMixin
| builtins.object
|
| Methods defined here:
|
| __init__(
| self,
| method: str | None = None,
| url: _t.UriType | None = None,
| headers: _t.HeadersType = None,
| files: _t.FilesType = None,
| data: _t.DataType = None,
| params: _t.ParamsType = None,
| auth: _t.AuthType = None,
| cookies: RequestsCookieJar | CookieJar | dict[str, str] | None = None,
| hooks: _t.HooksInputType | None = None,
| json: _t.JsonType = None
| ) -> None
| Initialize self. See help(type(self)) for accurate signature.
|
| __repr__(self) -> str
| Return repr(self).
|
| prepare(self) -> PreparedRequest
| Constructs a :class:`PreparedRequest <PreparedRequest>` for transmission and returns it.
|
| ----------------------------------------------------------------------
| Data and other attributes defined here:
|
| __annotations__ = {'auth': '_t.AuthType', 'cookies': 'RequestsCookieJa...
|
| ----------------------------------------------------------------------
| Methods inherited from RequestHooksMixin:
|
| deregister_hook(self, event: str, hook: _t.HookType) -> bool
| Deregister a previously registered hook.
| Returns True if the hook existed, False if not.
|
| register_hook(self, event: str, hook: Iterable[_t.HookType] | _t.HookType) -> None
| Properly register a hook.
|
| ----------------------------------------------------------------------
| Data descriptors inherited from RequestHooksMixin:
|
| __dict__
| dictionary for instance variables
|
| __weakref__
| list of weak references to the object
class RequestException(builtins.OSError)
| RequestException(*args: Any, **kwargs: Any) -> None
|
| There was an ambiguous exception that occurred while handling your
| request.
|
| Method resolution order:
| RequestException
| builtins.OSError
| builtins.Exception
| builtins.BaseException
| builtins.object
|
| Methods defined here:
|
| __init__(self, *args: Any, **kwargs: Any) -> None
| Initialize RequestException with `request` and `response` objects.
|
| ----------------------------------------------------------------------
| Data descriptors defined here:
|
| __weakref__
| list of weak references to the object
|
| ----------------------------------------------------------------------
| Data and other attributes defined here:
|
| __annotations__ = {'request': 'Request | PreparedRequest | None', 'res...
|
| ----------------------------------------------------------------------
| Methods inherited from builtins.OSError:
|
| __reduce__(self, /)
| Helper for pickle.
|
| __str__(self, /)
| Return str(self).
|
| ----------------------------------------------------------------------
| Static methods inherited from builtins.OSError:
|
| __new__(*args, **kwargs) class method of builtins.OSError
| Create and return a new object. See help(type) for accurate signature.
|
| ----------------------------------------------------------------------
| Data descriptors inherited from builtins.OSError:
|
| characters_written
|
| errno
| POSIX exception code
|
| filename
| exception filename
|
| filename2
| second exception filename
|
| strerror
| exception strerror
|
| ----------------------------------------------------------------------
| Methods inherited from builtins.BaseException:
|
| __repr__(self, /)
| Return repr(self).
|
| __setstate__(self, state, /)
|
| add_note(self, note, /)
| Add a note to the exception
|
| with_traceback(self, tb, /)
| Set self.__traceback__ to tb and return self.
|
| ----------------------------------------------------------------------
| Data descriptors inherited from builtins.BaseException:
|
| __cause__
|
| __context__
|
| __dict__
|
| __suppress_context__
|
| __traceback__
|
| args
class Response(builtins.object)
| Response() -> None
|
| The :class:`Response <Response>` object, which contains a
| server's response to an HTTP request.
|
| Methods defined here:
|
| __bool__(self) -> bool
| Returns True if :attr:`status_code` is less than 400.
|
| This attribute checks if the status code of the response is between
| 400 and 600 to see if there was a client error or a server error. If
| the status code, is between 200 and 400, this will return True. This
| is **not** a check to see if the response code is ``200 OK``.
|
| __enter__(self) -> Self
|
| __exit__(self, *args: Any) -> None
|
| __getstate__(self) -> dict[str, Any]
| Helper for pickle.
|
| __init__(self) -> None
| Initialize self. See help(type(self)) for accurate signature.
|
| __iter__(self) -> Iterator[bytes]
| Allows you to use a response as an iterator.
|
| __nonzero__(self) -> bool
| Returns True if :attr:`status_code` is less than 400.
|
| This attribute checks if the status code of the response is between
| 400 and 600 to see if there was a client error or a server error. If
| the status code, is between 200 and 400, this will return True. This
| is **not** a check to see if the response code is ``200 OK``.
|
| __repr__(self) -> str
| Return repr(self).
|
| __setstate__(self, state: dict[str, Any]) -> None
|
| close(self) -> None
| Releases the connection back to the pool. Once this method has been
| called the underlying ``raw`` object must not be accessed again.
|
| *Note: Should not normally need to be called explicitly.*
|
| iter_content(self, chunk_size: int | None = 1, decode_unicode: bool = False) -> Iterator[str | bytes]
| Iterates over the response data. When stream=True is set on the
| request, this avoids reading the content at once into memory for
| large responses. The chunk size is the number of bytes it should
| read into memory. This is not necessarily the length of each item
| returned as decoding can take place.
|
| chunk_size must be of type int or None. A value of None will
| function differently depending on the value of `stream`.
| stream=True will read data as it arrives in whatever size the
| chunks are received. If stream=False, data is returned as
| a single chunk.
|
| If decode_unicode is True, content will be decoded using encoding
| information from the response. If no encoding information is available,
| bytes will be returned. This can be bypassed by manually setting
| `encoding` on the response.
|
| iter_lines(
| self,
| chunk_size: int = 512,
| decode_unicode: bool = False,
| delimiter: str | bytes | None = None
| ) -> Iterator[str | bytes]
| Iterates over the response data, one line at a time. When
| stream=True is set on the request, this avoids reading the
| content at once into memory for large responses.
|
| The decode_unicode param works the same as in `iter_content`, with the
| same caveats.
|
| .. note:: This method is not reentrant safe.
|
| json(self, **kwargs: Any) -> Any
| Decodes the JSON response body (if any) as a Python object.
|
| This may return a dictionary, list, etc. depending on what is in the response.
|
| :param \*\*kwargs: Optional arguments that ``json.loads`` takes.
| :raises requests.exceptions.JSONDecodeError: If the response body does not
| contain valid json.
|
| raise_for_status(self) -> None
| Raises :class:`HTTPError`, if one occurred.
|
| ----------------------------------------------------------------------
| Readonly properties defined here:
|
| apparent_encoding
| The apparent encoding, provided by the charset_normalizer or chardet libraries.
|
| content
| Content of the response, in bytes.
|
| is_permanent_redirect
| True if this Response one of the permanent versions of redirect.
|
| is_redirect
| True if this Response is a well-formed HTTP redirect that could have
| been processed automatically (by :meth:`Session.resolve_redirects`).
|
| links
| Returns the parsed header links of the response, if any.
|
| next
| Returns a PreparedRequest for the next request in a redirect chain, if there is one.
|
| ok
| Returns True if :attr:`status_code` is less than 400, False if not.
|
| This attribute checks if the status code of the response is between
| 400 and 600 to see if there was a client error or a server error. If
| the status code is between 200 and 400, this will return True. This
| is **not** a check to see if the response code is ``200 OK``.
|
| text
| Content of the response, in unicode.
|
| If Response.encoding is None, encoding will be guessed using
| ``charset_normalizer`` or ``chardet``.
|
| The encoding of the response content is determined based solely on HTTP
| headers, following RFC 2616 to the letter. If you can take advantage of
| non-HTTP knowledge to make a better guess at the encoding, you should
| set ``r.encoding`` appropriately before accessing this property.
|
| ----------------------------------------------------------------------
| Data descriptors defined here:
|
| __dict__
| dictionary for instance variables
|
| __weakref__
| list of weak references to the object
|
| ----------------------------------------------------------------------
| Data and other attributes defined here:
|
| __annotations__ = {'__attrs__': 'list[str]', '_content': 'bytes | Lite...
|
| __attrs__ = ['_content', 'status_code', 'headers', 'url', 'history', '...
class Session(SessionRedirectMixin)
| Session() -> None
|
| A Requests session.
|
| Provides cookie persistence, connection-pooling, and configuration.
|
| Basic Usage::
|
| >>> import requests
| >>> s = requests.Session()
| >>> s.get('https://httpbin.org/get')
| <Response [200]>
|
| Or as a context manager::
|
| >>> with requests.Session() as s:
| ... s.get('https://httpbin.org/get')
| <Response [200]>
|
| Method resolution order:
| Session
| SessionRedirectMixin
| builtins.object
|
| Methods defined here:
|
| __enter__(self) -> Self
|
| __exit__(self, *args: Any) -> None
|
| __getstate__(self) -> dict[str, Any]
| Helper for pickle.
|
| __init__(self) -> None
| Initialize self. See help(type(self)) for accurate signature.
|
| __setstate__(self, state: dict[str, Any]) -> None
|
| close(self) -> None
| Closes all adapters and as such the session
|
| delete(self, url: _t.UriType, **kwargs: Unpack[_t.RequestKwargs]) -> Response
| Sends a DELETE request. Returns :class:`Response` object.
|
| :param url: URL for the new :class:`Request` object.
| :param \*\*kwargs: Optional arguments that ``request`` takes.
| :rtype: requests.Response
|
| get(
| self,
| url: _t.UriType,
| params: _t.ParamsType = None,
| **kwargs: Unpack[_t.GetKwargs]
| ) -> Response
| Sends a GET request. Returns :class:`Response` object.
|
| :param url: URL for the new :class:`Request` object.
| :param params: (optional) Dictionary, list of tuples or bytes to send
| in the query string for the :class:`Request`.
| :param \*\*kwargs: Optional arguments that ``request`` takes.
| :rtype: requests.Response
|
| get_adapter(self, url: str) -> BaseAdapter
| Returns the appropriate connection adapter for the given URL.
|
| :rtype: requests.adapters.BaseAdapter
|
| head(self, url: _t.UriType, **kwargs: Unpack[_t.RequestKwargs]) -> Response
| Sends a HEAD request. Returns :class:`Response` object.
|
| :param url: URL for the new :class:`Request` object.
| :param \*\*kwargs: Optional arguments that ``request`` takes.
| :rtype: requests.Response
|
| merge_environment_settings(
| self,
| url: str,
| proxies: dict[str, str] | None,
| stream: bool | None,
| verify: _t.VerifyType | None,
| cert: _t.CertType
| ) -> dict[str, Any]
| Check the environment and merge it with some settings.
|
| :rtype: dict
|
| mount(self, prefix: str, adapter: BaseAdapter) -> None
| Registers a connection adapter to a prefix.
|
| Adapters are sorted in descending order by prefix length.
|
| options(self, url: _t.UriType, **kwargs: Unpack[_t.RequestKwargs]) -> Response
| Sends a OPTIONS request. Returns :class:`Response` object.
|
| :param url: URL for the new :class:`Request` object.
| :param \*\*kwargs: Optional arguments that ``request`` takes.
| :rtype: requests.Response
|
| patch(
| self,
| url: _t.UriType,
| data: _t.DataType = None,
| **kwargs: Unpack[_t.DataKwargs]
| ) -> Response
| Sends a PATCH request. Returns :class:`Response` object.
|
| :param url: URL for the new :class:`Request` object.
| :param data: (optional) Dictionary, list of tuples, bytes, or file-like
| object to send in the body of the :class:`Request`.
| :param \*\*kwargs: Optional arguments that ``request`` takes.
| :rtype: requests.Response
|
| post(
| self,
| url: _t.UriType,
| data: _t.DataType = None,
| json: _t.JsonType = None,
| **kwargs: Unpack[_t.PostKwargs]
| ) -> Response
| Sends a POST request. Returns :class:`Response` object.
|
| :param url: URL for the new :class:`Request` object.
| :param data: (optional) Dictionary, list of tuples, bytes, or file-like
| object to send in the body of the :class:`Request`.
| :param json: (optional) json to send in the body of the :class:`Request`.
| :param \*\*kwargs: Optional arguments that ``request`` takes.
| :rtype: requests.Response
|
| prepare_request(self, request: Request) -> PreparedRequest
| Constructs a :class:`PreparedRequest <PreparedRequest>` for
| transmission and returns it. The :class:`PreparedRequest` has settings
| merged from the :class:`Request <Request>` instance and those of the
| :class:`Session`.
|
| :param request: :class:`Request` instance to prepare with this
| session's settings.
| :rtype: requests.PreparedRequest
|
| put(
| self,
| url: _t.UriType,
| data: _t.DataType = None,
| **kwargs: Unpack[_t.DataKwargs]
| ) -> Response
| Sends a PUT request. Returns :class:`Response` object.
|
| :param url: URL for the new :class:`Request` object.
| :param data: (optional) Dictionary, list of tuples, bytes, or file-like
| object to send in the body of the :class:`Request`.
| :param \*\*kwargs: Optional arguments that ``request`` takes.
| :rtype: requests.Response
|
| request(
| self,
| method: str,
| url: _t.UriType,
| params: _t.ParamsType = None,
| data: _t.DataType = None,
| headers: _t.HeadersType = None,
| cookies: RequestsCookieJar | CookieJar | dict[str, str] | None = None,
| files: _t.FilesType = None,
| auth: _t.AuthType = None,
| timeout: _t.TimeoutType = None,
| allow_redirects: bool = True,
| proxies: dict[str, str] | None = None,
| hooks: _t.HooksInputType | None = None,
| stream: bool | None = None,
| verify: _t.VerifyType | None = None,
| cert: _t.CertType = None,
| json: _t.JsonType = None
| ) -> Response
| Constructs a :class:`Request <Request>`, prepares it and sends it.
| Returns :class:`Response <Response>` object.
|
| :param method: method for the new :class:`Request` object.
| :param url: URL for the new :class:`Request` object.
| :param params: (optional) Dictionary or bytes to be sent in the query
| string for the :class:`Request`.
| :param data: (optional) Dictionary, list of tuples, bytes, or file-like
| object to send in the body of the :class:`Request`.
| :param json: (optional) json to send in the body of the
| :class:`Request`.
| :param headers: (optional) Dictionary of HTTP Headers to send with the
| :class:`Request`.
| :param cookies: (optional) Dict or CookieJar object to send with the
| :class:`Request`.
| :param files: (optional) Dictionary of ``'filename': file-like-objects``
| for multipart encoding upload.
| :param auth: (optional) Auth tuple or callable to enable
| Basic/Digest/Custom HTTP Auth.
| :param timeout: (optional) How many seconds to wait for the server to send
| data before giving up, as a float, or a :ref:`(connect timeout,
| read timeout) <timeouts>` tuple.
| :type timeout: float or tuple
| :param allow_redirects: (optional) Set to True by default.
| :type allow_redirects: bool
| :param proxies: (optional) Dictionary mapping protocol or protocol and
| hostname to the URL of the proxy.
| :param hooks: (optional) Dictionary mapping hook name to one event or
| list of events, event must be callable.
| :param stream: (optional) whether to immediately download the response
| content. Defaults to ``False``.
| :param verify: (optional) Either a boolean, in which case it controls whether we verify
| the server's TLS certificate, or a string, in which case it must be a path
| to a CA bundle to use. Defaults to ``True``. When set to
| ``False``, requests will accept any TLS certificate presented by
| the server, and will ignore hostname mismatches and/or expired
| certificates, which will make your application vulnerable to
| man-in-the-middle (MitM) attacks. Setting verify to ``False``
| may be useful during local development or testing.
| :param cert: (optional) if String, path to ssl client cert file (.pem).
| If Tuple, ('cert', 'key') pair.
| :rtype: requests.Response
|
| send(self, request: PreparedRequest, **kwargs: Any) -> Response
| Send a given PreparedRequest.
|
| :rtype: requests.Response
|
| ----------------------------------------------------------------------
| Data and other attributes defined here:
|
| __annotations__ = {'__attrs__': 'list[str]', 'adapters': 'MutableMappi...
|
| __attrs__ = ['headers', 'cookies', 'auth', 'proxies', 'hooks', 'params...
|
| ----------------------------------------------------------------------
| Methods inherited from SessionRedirectMixin:
|
| get_redirect_target(self, resp: Response) -> str | None
| Receives a Response. Returns a redirect URI or ``None``
|
| rebuild_auth(self, prepared_request: PreparedRequest, response: Response) -> None
| When being redirected we may want to strip authentication from the
| request to avoid leaking credentials. This method intelligently removes
| and reapplies authentication where possible to avoid credential loss.
|
| rebuild_method(self, prepared_request: PreparedRequest, response: Response) -> None
| When being redirected we may want to change the method of the request
| based on certain specs or browser behavior.
|
| rebuild_proxies(
| self,
| prepared_request: PreparedRequest,
| proxies: dict[str, str] | None
| ) -> dict[str, str]
| This method re-evaluates the proxy configuration by considering the
| environment variables. If we are redirected to a URL covered by
| NO_PROXY, we strip the proxy configuration. Otherwise, we set missing
| proxy keys for this URL (in case they were stripped by a previous
| redirect).
|
| This method also replaces the Proxy-Authorization header where
| necessary.
|
| :rtype: dict
|
| resolve_redirects(
| self,
| resp: Response,
| req: PreparedRequest,
| stream: bool = False,
| timeout: _t.TimeoutType = None,
| verify: _t.VerifyType = True,
| cert: _t.CertType = None,
| proxies: dict[str, str] | None = None,
| yield_requests: bool = False,
| **adapter_kwargs: Any
| ) -> Generator[Response, None, None]
| Receives a Response. Returns a generator of Responses or Requests.
|
| should_strip_auth(self, old_url: str, new_url: str) -> bool
| Decide whether Authorization header should be removed when redirecting
|
| ----------------------------------------------------------------------
| Data descriptors inherited from SessionRedirectMixin:
|
| __dict__
| dictionary for instance variables
|
| __weakref__
| list of weak references to the object
class Timeout(RequestException)
| Timeout(*args: Any, **kwargs: Any) -> None
|
| The request timed out.
|
| Catching this error will catch both
| :exc:`~requests.exceptions.ConnectTimeout` and
| :exc:`~requests.exceptions.ReadTimeout` errors.
|
| Method resolution order:
| Timeout
| RequestException
| builtins.OSError
| builtins.Exception
| builtins.BaseException
| builtins.object
|
| Methods inherited from RequestException:
|
| __init__(self, *args: Any, **kwargs: Any) -> None
| Initialize RequestException with `request` and `response` objects.
|
| ----------------------------------------------------------------------
| Data descriptors inherited from RequestException:
|
| __weakref__
| list of weak references to the object
|
| ----------------------------------------------------------------------
| Data and other attributes inherited from RequestException:
|
| __annotations__ = {}
|
| ----------------------------------------------------------------------
| Methods inherited from builtins.OSError:
|
| __reduce__(self, /)
| Helper for pickle.
|
| __str__(self, /)
| Return str(self).
|
| ----------------------------------------------------------------------
| Static methods inherited from builtins.OSError:
|
| __new__(*args, **kwargs) class method of builtins.OSError
| Create and return a new object. See help(type) for accurate signature.
|
| ----------------------------------------------------------------------
| Data descriptors inherited from builtins.OSError:
|
| characters_written
|
| errno
| POSIX exception code
|
| filename
| exception filename
|
| filename2
| second exception filename
|
| strerror
| exception strerror
|
| ----------------------------------------------------------------------
| Methods inherited from builtins.BaseException:
|
| __repr__(self, /)
| Return repr(self).
|
| __setstate__(self, state, /)
|
| add_note(self, note, /)
| Add a note to the exception
|
| with_traceback(self, tb, /)
| Set self.__traceback__ to tb and return self.
|
| ----------------------------------------------------------------------
| Data descriptors inherited from builtins.BaseException:
|
| __cause__
|
| __context__
|
| __dict__
|
| __suppress_context__
|
| __traceback__
|
| args
class TooManyRedirects(RequestException)
| TooManyRedirects(*args: Any, **kwargs: Any) -> None
|
| Too many redirects.
|
| Method resolution order:
| TooManyRedirects
| RequestException
| builtins.OSError
| builtins.Exception
| builtins.BaseException
| builtins.object
|
| Methods inherited from RequestException:
|
| __init__(self, *args: Any, **kwargs: Any) -> None
| Initialize RequestException with `request` and `response` objects.
|
| ----------------------------------------------------------------------
| Data descriptors inherited from RequestException:
|
| __weakref__
| list of weak references to the object
|
| ----------------------------------------------------------------------
| Data and other attributes inherited from RequestException:
|
| __annotations__ = {}
|
| ----------------------------------------------------------------------
| Methods inherited from builtins.OSError:
|
| __reduce__(self, /)
| Helper for pickle.
|
| __str__(self, /)
| Return str(self).
|
| ----------------------------------------------------------------------
| Static methods inherited from builtins.OSError:
|
| __new__(*args, **kwargs) class method of builtins.OSError
| Create and return a new object. See help(type) for accurate signature.
|
| ----------------------------------------------------------------------
| Data descriptors inherited from builtins.OSError:
|
| characters_written
|
| errno
| POSIX exception code
|
| filename
| exception filename
|
| filename2
| second exception filename
|
| strerror
| exception strerror
|
| ----------------------------------------------------------------------
| Methods inherited from builtins.BaseException:
|
| __repr__(self, /)
| Return repr(self).
|
| __setstate__(self, state, /)
|
| add_note(self, note, /)
| Add a note to the exception
|
| with_traceback(self, tb, /)
| Set self.__traceback__ to tb and return self.
|
| ----------------------------------------------------------------------
| Data descriptors inherited from builtins.BaseException:
|
| __cause__
|
| __context__
|
| __dict__
|
| __suppress_context__
|
| __traceback__
|
| args
class URLRequired(RequestException)
| URLRequired(*args: Any, **kwargs: Any) -> None
|
| A valid URL is required to make a request.
|
| Method resolution order:
| URLRequired
| RequestException
| builtins.OSError
| builtins.Exception
| builtins.BaseException
| builtins.object
|
| Methods inherited from RequestException:
|
| __init__(self, *args: Any, **kwargs: Any) -> None
| Initialize RequestException with `request` and `response` objects.
|
| ----------------------------------------------------------------------
| Data descriptors inherited from RequestException:
|
| __weakref__
| list of weak references to the object
|
| ----------------------------------------------------------------------
| Data and other attributes inherited from RequestException:
|
| __annotations__ = {}
|
| ----------------------------------------------------------------------
| Methods inherited from builtins.OSError:
|
| __reduce__(self, /)
| Helper for pickle.
|
| __str__(self, /)
| Return str(self).
|
| ----------------------------------------------------------------------
| Static methods inherited from builtins.OSError:
|
| __new__(*args, **kwargs) class method of builtins.OSError
| Create and return a new object. See help(type) for accurate signature.
|
| ----------------------------------------------------------------------
| Data descriptors inherited from builtins.OSError:
|
| characters_written
|
| errno
| POSIX exception code
|
| filename
| exception filename
|
| filename2
| second exception filename
|
| strerror
| exception strerror
|
| ----------------------------------------------------------------------
| Methods inherited from builtins.BaseException:
|
| __repr__(self, /)
| Return repr(self).
|
| __setstate__(self, state, /)
|
| add_note(self, note, /)
| Add a note to the exception
|
| with_traceback(self, tb, /)
| Set self.__traceback__ to tb and return self.
|
| ----------------------------------------------------------------------
| Data descriptors inherited from builtins.BaseException:
|
| __cause__
|
| __context__
|
| __dict__
|
| __suppress_context__
|
| __traceback__
|
| args
FUNCTIONS
delete(url: _t.UriType, **kwargs: Unpack[_t.RequestKwargs]) -> Response
Sends a DELETE request.
:param url: URL for the new :class:`Request` object.
:param \*\*kwargs: Optional arguments that ``request`` takes.
:return: :class:`Response <Response>` object
:rtype: requests.Response
get(
url: _t.UriType,
params: _t.ParamsType = None,
**kwargs: Unpack[_t.GetKwargs]
) -> Response
Sends a GET request.
:param url: URL for the new :class:`Request` object.
:param params: (optional) Dictionary, list of tuples or bytes to send
in the query string for the :class:`Request`.
:param \*\*kwargs: Optional arguments that ``request`` takes.
:return: :class:`Response <Response>` object
:rtype: requests.Response
head(url: _t.UriType, **kwargs: Unpack[_t.RequestKwargs]) -> Response
Sends a HEAD request.
:param url: URL for the new :class:`Request` object.
:param \*\*kwargs: Optional arguments that ``request`` takes. If
`allow_redirects` is not provided, it will be set to `False` (as
opposed to the default :meth:`request` behavior).
:return: :class:`Response <Response>` object
:rtype: requests.Response
options(url: _t.UriType, **kwargs: Unpack[_t.RequestKwargs]) -> Response
Sends an OPTIONS request.
:param url: URL for the new :class:`Request` object.
:param \*\*kwargs: Optional arguments that ``request`` takes.
:return: :class:`Response <Response>` object
:rtype: requests.Response
patch(
url: _t.UriType,
data: _t.DataType = None,
**kwargs: Unpack[_t.DataKwargs]
) -> Response
Sends a PATCH request.
:param url: URL for the new :class:`Request` object.
:param data: (optional) Dictionary, list of tuples, bytes, or file-like
object to send in the body of the :class:`Request`.
:param json: (optional) A JSON serializable Python object to send in the body of the :class:`Request`.
:param \*\*kwargs: Optional arguments that ``request`` takes.
:return: :class:`Response <Response>` object
:rtype: requests.Response
post(
url: _t.UriType,
data: _t.DataType = None,
json: _t.JsonType = None,
**kwargs: Unpack[_t.PostKwargs]
) -> Response
Sends a POST request.
:param url: URL for the new :class:`Request` object.
:param data: (optional) Dictionary, list of tuples, bytes, or file-like
object to send in the body of the :class:`Request`.
:param json: (optional) A JSON serializable Python object to send in the body of the :class:`Request`.
:param \*\*kwargs: Optional arguments that ``request`` takes.
:return: :class:`Response <Response>` object
:rtype: requests.Response
put(url: _t.UriType, data: _t.DataType = None, **kwargs: Unpack[_t.DataKwargs]) -> Response
Sends a PUT request.
:param url: URL for the new :class:`Request` object.
:param data: (optional) Dictionary, list of tuples, bytes, or file-like
object to send in the body of the :class:`Request`.
:param json: (optional) A JSON serializable Python object to send in the body of the :class:`Request`.
:param \*\*kwargs: Optional arguments that ``request`` takes.
:return: :class:`Response <Response>` object
:rtype: requests.Response
request(method: str, url: _t.UriType, **kwargs: Unpack[_t.RequestKwargs]) -> Response
Constructs and sends a :class:`Request <Request>`.
:param method: method for the new :class:`Request` object: ``GET``, ``OPTIONS``, ``HEAD``, ``POST``, ``PUT``, ``PATCH``, or ``DELETE``.
:param url: URL for the new :class:`Request` object.
:param params: (optional) Dictionary, list of tuples or bytes to send
in the query string for the :class:`Request`.
:param data: (optional) Dictionary, list of tuples, bytes, or file-like
object to send in the body of the :class:`Request`.
:param json: (optional) A JSON serializable Python object to send in the body of the :class:`Request`.
:param headers: (optional) Dictionary of HTTP Headers to send with the :class:`Request`.
:param cookies: (optional) Dict or CookieJar object to send with the :class:`Request`.
:param files: (optional) Dictionary of ``'name': file-like-objects`` (or ``{'name': file-tuple}``) for multipart encoding upload.
``file-tuple`` can be a 2-tuple ``('filename', fileobj)``, 3-tuple ``('filename', fileobj, 'content_type')``
or a 4-tuple ``('filename', fileobj, 'content_type', custom_headers)``, where ``'content_type'`` is a string
defining the content type of the given file and ``custom_headers`` a dict-like object containing additional headers
to add for the file.
:param auth: (optional) Auth tuple to enable Basic/Digest/Custom HTTP Auth.
:param timeout: (optional) How many seconds to wait for the server to send data
before giving up, as a float, or a :ref:`(connect timeout, read
timeout) <timeouts>` tuple.
:type timeout: float or tuple
:param allow_redirects: (optional) Boolean. Enable/disable GET/OPTIONS/POST/PUT/PATCH/DELETE/HEAD redirection. Defaults to ``True``.
:type allow_redirects: bool
:param proxies: (optional) Dictionary mapping protocol to the URL of the proxy.
:param verify: (optional) Either a boolean, in which case it controls whether we verify
the server's TLS certificate, or a string, in which case it must be a path
to a CA bundle to use. Defaults to ``True``.
:param stream: (optional) if ``False``, the response content will be immediately downloaded.
:param cert: (optional) if String, path to ssl client cert file (.pem). If Tuple, ('cert', 'key') pair.
:return: :class:`Response <Response>` object
:rtype: requests.Response
Usage::
>>> import requests
>>> req = requests.request('GET', 'https://httpbin.org/get')
>>> req
<Response [200]>
session() -> Session
Returns a :class:`Session` for context-management.
.. deprecated:: 1.0.0
This method has been deprecated since version 1.0.0 and is only kept for
backwards compatibility. New code should use :class:`~requests.sessions.Session`
to create a session. This may be removed at a future date.
:rtype: Session
DATA
__all__ = ('ConnectionError', 'ConnectTimeout', 'HTTPError', 'JSONDeco...
__author_email__ = 'me@kennethreitz.org'
__build__ = 144386
__cake__ = '✨ 🍰 ✨'
__copyright__ = 'Copyright Kenneth Reitz'
__description__ = 'Python HTTP for Humans.'
__license__ = 'Apache-2.0'
__title__ = 'requests'
__url__ = 'https://requests.readthedocs.io'
codes = <lookup 'status_codes'>
VERSION
2.34.2
AUTHOR
Kenneth Reitz
FILE
/usr/lib/python3.14/site-packages/requests/__init__.py
help(json)Help on package json:
NAME
json
MODULE REFERENCE
https://docs.python.org/3.14/library/json#module-json
The following documentation is automatically generated from the Python
source files. It may be incomplete, incorrect or include features that
are considered implementation detail and may vary between Python
implementations. When in doubt, consult the module reference at the
location listed above.
DESCRIPTION
JSON (JavaScript Object Notation) <https://json.org> is a subset of
JavaScript syntax (ECMA-262 3rd edition) used as a lightweight data
interchange format.
:mod:`json` exposes an API familiar to users of the standard library
:mod:`marshal` and :mod:`pickle` modules. It is derived from a
version of the externally maintained simplejson library.
Encoding basic Python object hierarchies::
>>> import json
>>> json.dumps(['foo', {'bar': ('baz', None, 1.0, 2)}])
'["foo", {"bar": ["baz", null, 1.0, 2]}]'
>>> print(json.dumps("\"foo\bar"))
"\"foo\bar"
>>> print(json.dumps('\u1234'))
"\u1234"
>>> print(json.dumps('\\'))
"\\"
>>> print(json.dumps({"c": 0, "b": 0, "a": 0}, sort_keys=True))
{"a": 0, "b": 0, "c": 0}
>>> from io import StringIO
>>> io = StringIO()
>>> json.dump(['streaming API'], io)
>>> io.getvalue()
'["streaming API"]'
Compact encoding::
>>> import json
>>> mydict = {'4': 5, '6': 7}
>>> json.dumps([1,2,3,mydict], separators=(',', ':'))
'[1,2,3,{"4":5,"6":7}]'
Pretty printing::
>>> import json
>>> print(json.dumps({'4': 5, '6': 7}, sort_keys=True, indent=4))
{
"4": 5,
"6": 7
}
Decoding JSON::
>>> import json
>>> obj = ['foo', {'bar': ['baz', None, 1.0, 2]}]
>>> json.loads('["foo", {"bar":["baz", null, 1.0, 2]}]') == obj
True
>>> json.loads('"\\"foo\\bar"') == '"foo\x08ar'
True
>>> from io import StringIO
>>> io = StringIO('["streaming API"]')
>>> json.load(io)[0] == 'streaming API'
True
Specializing JSON object decoding::
>>> import json
>>> def as_complex(dct):
... if '__complex__' in dct:
... return complex(dct['real'], dct['imag'])
... return dct
...
>>> json.loads('{"__complex__": true, "real": 1, "imag": 2}',
... object_hook=as_complex)
(1+2j)
>>> from decimal import Decimal
>>> json.loads('1.1', parse_float=Decimal) == Decimal('1.1')
True
Specializing JSON object encoding::
>>> import json
>>> def encode_complex(obj):
... if isinstance(obj, complex):
... return [obj.real, obj.imag]
... raise TypeError(f'Object of type {obj.__class__.__name__} '
... f'is not JSON serializable')
...
>>> json.dumps(2 + 1j, default=encode_complex)
'[2.0, 1.0]'
>>> json.JSONEncoder(default=encode_complex).encode(2 + 1j)
'[2.0, 1.0]'
>>> ''.join(json.JSONEncoder(default=encode_complex).iterencode(2 + 1j))
'[2.0, 1.0]'
Using json from the shell to validate and pretty-print::
$ echo '{"json":"obj"}' | python -m json
{
"json": "obj"
}
$ echo '{ 1.2:3.4}' | python -m json
Expecting property name enclosed in double quotes: line 1 column 3 (char 2)
PACKAGE CONTENTS
__main__
decoder
encoder
scanner
tool
CLASSES
builtins.ValueError(builtins.Exception)
json.decoder.JSONDecodeError
builtins.object
json.decoder.JSONDecoder
json.encoder.JSONEncoder
class JSONDecodeError(builtins.ValueError)
| JSONDecodeError(msg, doc, pos)
|
| Subclass of ValueError with the following additional properties:
|
| msg: The unformatted error message
| doc: The JSON document being parsed
| pos: The start index of doc where parsing failed
| lineno: The line corresponding to pos
| colno: The column corresponding to pos
|
| Method resolution order:
| JSONDecodeError
| builtins.ValueError
| builtins.Exception
| builtins.BaseException
| builtins.object
|
| Methods defined here:
|
| __init__(self, msg, doc, pos)
| Initialize self. See help(type(self)) for accurate signature.
|
| __reduce__(self)
| Helper for pickle.
|
| ----------------------------------------------------------------------
| Data descriptors defined here:
|
| __weakref__
| list of weak references to the object
|
| ----------------------------------------------------------------------
| Static methods inherited from builtins.ValueError:
|
| __new__(*args, **kwargs) class method of builtins.ValueError
| Create and return a new object. See help(type) for accurate signature.
|
| ----------------------------------------------------------------------
| Methods inherited from builtins.BaseException:
|
| __repr__(self, /)
| Return repr(self).
|
| __setstate__(self, state, /)
|
| __str__(self, /)
| Return str(self).
|
| add_note(self, note, /)
| Add a note to the exception
|
| with_traceback(self, tb, /)
| Set self.__traceback__ to tb and return self.
|
| ----------------------------------------------------------------------
| Data descriptors inherited from builtins.BaseException:
|
| __cause__
|
| __context__
|
| __dict__
|
| __suppress_context__
|
| __traceback__
|
| args
class JSONDecoder(builtins.object)
| JSONDecoder(
| *,
| object_hook=None,
| parse_float=None,
| parse_int=None,
| parse_constant=None,
| strict=True,
| object_pairs_hook=None
| )
|
| Simple JSON <https://json.org> decoder
|
| Performs the following translations in decoding by default:
|
| +---------------+-------------------+
| | JSON | Python |
| +===============+===================+
| | object | dict |
| +---------------+-------------------+
| | array | list |
| +---------------+-------------------+
| | string | str |
| +---------------+-------------------+
| | number (int) | int |
| +---------------+-------------------+
| | number (real) | float |
| +---------------+-------------------+
| | true | True |
| +---------------+-------------------+
| | false | False |
| +---------------+-------------------+
| | null | None |
| +---------------+-------------------+
|
| It also understands ``NaN``, ``Infinity``, and ``-Infinity`` as
| their corresponding ``float`` values, which is outside the JSON spec.
|
| Methods defined here:
|
| __init__(
| self,
| *,
| object_hook=None,
| parse_float=None,
| parse_int=None,
| parse_constant=None,
| strict=True,
| object_pairs_hook=None
| )
| ``object_hook``, if specified, will be called with the result
| of every JSON object decoded and its return value will be used in
| place of the given ``dict``. This can be used to provide custom
| deserializations (e.g. to support JSON-RPC class hinting).
|
| ``object_pairs_hook``, if specified will be called with the result
| of every JSON object decoded with an ordered list of pairs. The
| return value of ``object_pairs_hook`` will be used instead of the
| ``dict``. This feature can be used to implement custom decoders.
| If ``object_hook`` is also defined, the ``object_pairs_hook`` takes
| priority.
|
| ``parse_float``, if specified, will be called with the string
| of every JSON float to be decoded. By default this is equivalent to
| float(num_str). This can be used to use another datatype or parser
| for JSON floats (e.g. decimal.Decimal).
|
| ``parse_int``, if specified, will be called with the string
| of every JSON int to be decoded. By default this is equivalent to
| int(num_str). This can be used to use another datatype or parser
| for JSON integers (e.g. float).
|
| ``parse_constant``, if specified, will be called with one of the
| following strings: -Infinity, Infinity, NaN.
| This can be used to raise an exception if invalid JSON numbers
| are encountered.
|
| If ``strict`` is false (true is the default), then control
| characters will be allowed inside strings. Control characters in
| this context are those with character codes in the 0-31 range,
| including ``'\t'`` (tab), ``'\n'``, ``'\r'`` and ``'\0'``.
|
| decode(
| self,
| s,
| _w=<built-in method match of re.Pattern object at 0x7ff4dbddca00>
| )
| Return the Python representation of ``s`` (a ``str`` instance
| containing a JSON document).
|
| raw_decode(self, s, idx=0)
| Decode a JSON document from ``s`` (a ``str`` beginning with
| a JSON document) and return a 2-tuple of the Python
| representation and the index in ``s`` where the document ended.
|
| This can be used to decode a JSON document from a string that may
| have extraneous data at the end.
|
| ----------------------------------------------------------------------
| Data descriptors defined here:
|
| __dict__
| dictionary for instance variables
|
| __weakref__
| list of weak references to the object
class JSONEncoder(builtins.object)
| JSONEncoder(
| *,
| skipkeys=False,
| ensure_ascii=True,
| check_circular=True,
| allow_nan=True,
| sort_keys=False,
| indent=None,
| separators=None,
| default=None
| )
|
| Extensible JSON <https://json.org> encoder for Python data structures.
|
| Supports the following objects and types by default:
|
| +-------------------+---------------+
| | Python | JSON |
| +===================+===============+
| | dict | object |
| +-------------------+---------------+
| | list, tuple | array |
| +-------------------+---------------+
| | str | string |
| +-------------------+---------------+
| | int, float | number |
| +-------------------+---------------+
| | True | true |
| +-------------------+---------------+
| | False | false |
| +-------------------+---------------+
| | None | null |
| +-------------------+---------------+
|
| To extend this to recognize other objects, subclass and implement a
| ``.default()`` method with another method that returns a serializable
| object for ``o`` if possible, otherwise it should call the superclass
| implementation (to raise ``TypeError``).
|
| Methods defined here:
|
| __init__(
| self,
| *,
| skipkeys=False,
| ensure_ascii=True,
| check_circular=True,
| allow_nan=True,
| sort_keys=False,
| indent=None,
| separators=None,
| default=None
| )
| Constructor for JSONEncoder, with sensible defaults.
|
| If skipkeys is false, then it is a TypeError to attempt
| encoding of keys that are not str, int, float, bool or None.
| If skipkeys is True, such items are simply skipped.
|
| If ensure_ascii is true, the output is guaranteed to be str objects
| with all incoming non-ASCII and non-printable characters escaped.
| If ensure_ascii is false, the output can contain non-ASCII and
| non-printable characters.
|
| If check_circular is true, then lists, dicts, and custom encoded
| objects will be checked for circular references during encoding to
| prevent an infinite recursion (which would cause an RecursionError).
| Otherwise, no such check takes place.
|
| If allow_nan is true, then NaN, Infinity, and -Infinity will be
| encoded as such. This behavior is not JSON specification compliant,
| but is consistent with most JavaScript based encoders and decoders.
| Otherwise, it will be a ValueError to encode such floats.
|
| If sort_keys is true, then the output of dictionaries will be
| sorted by key; this is useful for regression tests to ensure
| that JSON serializations can be compared on a day-to-day basis.
|
| If indent is a non-negative integer, then JSON array
| elements and object members will be pretty-printed with that
| indent level. An indent level of 0 will only insert newlines.
| None is the most compact representation.
|
| If specified, separators should be an (item_separator,
| key_separator) tuple. The default is (', ', ': ') if *indent* is
| ``None`` and (',', ': ') otherwise. To get the most compact JSON
| representation, you should specify (',', ':') to eliminate
| whitespace.
|
| If specified, default is a function that gets called for objects
| that can't otherwise be serialized. It should return a JSON
| encodable version of the object or raise a ``TypeError``.
|
| default(self, o)
| Implement this method in a subclass such that it returns
| a serializable object for ``o``, or calls the base implementation
| (to raise a ``TypeError``).
|
| For example, to support arbitrary iterators, you could
| implement default like this::
|
| def default(self, o):
| try:
| iterable = iter(o)
| except TypeError:
| pass
| else:
| return list(iterable)
| # Let the base class default method raise the TypeError
| return super().default(o)
|
| encode(self, o)
| Return a JSON string representation of a Python data structure.
|
| >>> from json.encoder import JSONEncoder
| >>> JSONEncoder().encode({"foo": ["bar", "baz"]})
| '{"foo": ["bar", "baz"]}'
|
| iterencode(self, o, _one_shot=False)
| Encode the given object and yield each string
| representation as available.
|
| For example::
|
| for chunk in JSONEncoder().iterencode(bigobject):
| mysocket.write(chunk)
|
| ----------------------------------------------------------------------
| Data descriptors defined here:
|
| __dict__
| dictionary for instance variables
|
| __weakref__
| list of weak references to the object
|
| ----------------------------------------------------------------------
| Data and other attributes defined here:
|
| item_separator = ', '
|
| key_separator = ': '
FUNCTIONS
dump(
obj,
fp,
*,
skipkeys=False,
ensure_ascii=True,
check_circular=True,
allow_nan=True,
cls=None,
indent=None,
separators=None,
default=None,
sort_keys=False,
**kw
)
Serialize ``obj`` as a JSON formatted stream to ``fp`` (a
``.write()``-supporting file-like object).
If ``skipkeys`` is true then ``dict`` keys that are not basic types
(``str``, ``int``, ``float``, ``bool``, ``None``) will be skipped
instead of raising a ``TypeError``.
If ``ensure_ascii`` is false, then the strings written to ``fp`` can
contain non-ASCII and non-printable characters if they appear in strings
contained in ``obj``. Otherwise, all such characters are escaped in JSON
strings.
If ``check_circular`` is false, then the circular reference check
for container types will be skipped and a circular reference will
result in an ``RecursionError`` (or worse).
If ``allow_nan`` is false, then it will be a ``ValueError`` to
serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``)
in strict compliance of the JSON specification, instead of using the
JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``).
If ``indent`` is a non-negative integer, then JSON array elements and
object members will be pretty-printed with that indent level. An indent
level of 0 will only insert newlines. ``None`` is the most compact
representation.
If specified, ``separators`` should be an ``(item_separator,
key_separator)`` tuple. The default is ``(', ', ': ')`` if *indent* is
``None`` and ``(',', ': ')`` otherwise. To get the most compact JSON
representation, you should specify ``(',', ':')`` to eliminate
whitespace.
``default(obj)`` is a function that should return a serializable version
of obj or raise TypeError. The default simply raises TypeError.
If *sort_keys* is true (default: ``False``), then the output of
dictionaries will be sorted by key.
To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the
``.default()`` method to serialize additional types), specify it with
the ``cls`` kwarg; otherwise ``JSONEncoder`` is used.
dumps(
obj,
*,
skipkeys=False,
ensure_ascii=True,
check_circular=True,
allow_nan=True,
cls=None,
indent=None,
separators=None,
default=None,
sort_keys=False,
**kw
)
Serialize ``obj`` to a JSON formatted ``str``.
If ``skipkeys`` is true then ``dict`` keys that are not basic types
(``str``, ``int``, ``float``, ``bool``, ``None``) will be skipped
instead of raising a ``TypeError``.
If ``ensure_ascii`` is false, then the return value can contain
non-ASCII and non-printable characters if they appear in strings
contained in ``obj``. Otherwise, all such characters are escaped in
JSON strings.
If ``check_circular`` is false, then the circular reference check
for container types will be skipped and a circular reference will
result in an ``RecursionError`` (or worse).
If ``allow_nan`` is false, then it will be a ``ValueError`` to
serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``) in
strict compliance of the JSON specification, instead of using the
JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``).
If ``indent`` is a non-negative integer, then JSON array elements and
object members will be pretty-printed with that indent level. An indent
level of 0 will only insert newlines. ``None`` is the most compact
representation.
If specified, ``separators`` should be an ``(item_separator,
key_separator)`` tuple. The default is ``(', ', ': ')`` if *indent* is
``None`` and ``(',', ': ')`` otherwise. To get the most compact JSON
representation, you should specify ``(',', ':')`` to eliminate
whitespace.
``default(obj)`` is a function that should return a serializable version
of obj or raise TypeError. The default simply raises TypeError.
If *sort_keys* is true (default: ``False``), then the output of
dictionaries will be sorted by key.
To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the
``.default()`` method to serialize additional types), specify it with
the ``cls`` kwarg; otherwise ``JSONEncoder`` is used.
load(
fp,
*,
cls=None,
object_hook=None,
parse_float=None,
parse_int=None,
parse_constant=None,
object_pairs_hook=None,
**kw
)
Deserialize ``fp`` (a ``.read()``-supporting file-like object containing
a JSON document) to a Python object.
``object_hook`` is an optional function that will be called with the
result of any object literal decode (a ``dict``). The return value of
``object_hook`` will be used instead of the ``dict``. This feature
can be used to implement custom decoders (e.g. JSON-RPC class hinting).
``object_pairs_hook`` is an optional function that will be called with
the result of any object literal decoded with an ordered list of pairs.
The return value of ``object_pairs_hook`` will be used instead of the
``dict``. This feature can be used to implement custom decoders. If
``object_hook`` is also defined, the ``object_pairs_hook`` takes
priority.
To use a custom ``JSONDecoder`` subclass, specify it with the ``cls``
kwarg; otherwise ``JSONDecoder`` is used.
loads(
s,
*,
cls=None,
object_hook=None,
parse_float=None,
parse_int=None,
parse_constant=None,
object_pairs_hook=None,
**kw
)
Deserialize ``s`` (a ``str``, ``bytes`` or ``bytearray`` instance
containing a JSON document) to a Python object.
``object_hook`` is an optional function that will be called with the
result of any object literal decode (a ``dict``). The return value of
``object_hook`` will be used instead of the ``dict``. This feature
can be used to implement custom decoders (e.g. JSON-RPC class hinting).
``object_pairs_hook`` is an optional function that will be called with
the result of any object literal decoded with an ordered list of pairs.
The return value of ``object_pairs_hook`` will be used instead of the
``dict``. This feature can be used to implement custom decoders. If
``object_hook`` is also defined, the ``object_pairs_hook`` takes
priority.
``parse_float``, if specified, will be called with the string
of every JSON float to be decoded. By default this is equivalent to
float(num_str). This can be used to use another datatype or parser
for JSON floats (e.g. decimal.Decimal).
``parse_int``, if specified, will be called with the string
of every JSON int to be decoded. By default this is equivalent to
int(num_str). This can be used to use another datatype or parser
for JSON integers (e.g. float).
``parse_constant``, if specified, will be called with one of the
following strings: -Infinity, Infinity, NaN.
This can be used to raise an exception if invalid JSON numbers
are encountered.
To use a custom ``JSONDecoder`` subclass, specify it with the ``cls``
kwarg; otherwise ``JSONDecoder`` is used.
DATA
__all__ = ['dump', 'dumps', 'load', 'loads', 'JSONDecoder', 'JSONDecod...
VERSION
2.0.9
AUTHOR
Bob Ippolito <bob@redivi.com>
FILE
/usr/lib/python3.14/json/__init__.py
Let’s get started with some hands-on API querying!
For our first example, we’ll use an easy-to-understand API from catfact.ninja, a site that serves up random cat facts, perfect for learning the basics in a fun way.
1. Create a variable for base URL
Let’s do a simple request and see what we get:
base_url = 'https://catfact.ninja/facts'
requests.get(base_url)<Response [200]>
2. Create a variable for the cat facts response
cat_facts = requests.get(base_url)Let’s explore the ‘responses’ library:
cat_facts.status_code200
cat_facts.text'{"current_page":1,"data":[{"fact":"Unlike dogs, cats do not have a sweet tooth. Scientists believe this is due to a mutation in a key taste receptor.","length":114},{"fact":"When a cat chases its prey, it keeps its head level. Dogs and humans bob their heads up and down.","length":97},{"fact":"The technical term for a cat\\u2019s hairball is a \\u201cbezoar.\\u201d","length":54},{"fact":"A group of cats is called a \\u201cclowder.\\u201d","length":38},{"fact":"A cat can\\u2019t climb head first down a tree because every claw on a cat\\u2019s paw points the same way. To get down from a tree, a cat must back down.","length":142},{"fact":"Cats make about 100 different sounds. Dogs make only about 10.","length":62},{"fact":"Every year, nearly four million cats are eaten in Asia.","length":55},{"fact":"There are more than 500 million domestic cats in the world, with approximately 40 recognized breeds.","length":100},{"fact":"Approximately 24 cat skins can make a coat.","length":43},{"fact":"While it is commonly thought that the ancient Egyptians were the first to domesticate cats, the oldest known pet cat was recently found in a 9,500-year-old grave on the Mediterranean island of Cyprus. This grave predates early Egyptian art depicting cats by 4,000 years or more.","length":278}],"first_page_url":"https:\\/\\/catfact.ninja\\/facts?page=1","from":1,"last_page":34,"last_page_url":"https:\\/\\/catfact.ninja\\/facts?page=34","links":[{"url":null,"label":"Previous","active":false},{"url":"https:\\/\\/catfact.ninja\\/facts?page=1","label":"1","active":true},{"url":"https:\\/\\/catfact.ninja\\/facts?page=2","label":"2","active":false},{"url":"https:\\/\\/catfact.ninja\\/facts?page=3","label":"3","active":false},{"url":"https:\\/\\/catfact.ninja\\/facts?page=4","label":"4","active":false},{"url":"https:\\/\\/catfact.ninja\\/facts?page=5","label":"5","active":false},{"url":"https:\\/\\/catfact.ninja\\/facts?page=6","label":"6","active":false},{"url":"https:\\/\\/catfact.ninja\\/facts?page=7","label":"7","active":false},{"url":"https:\\/\\/catfact.ninja\\/facts?page=8","label":"8","active":false},{"url":"https:\\/\\/catfact.ninja\\/facts?page=9","label":"9","active":false},{"url":"https:\\/\\/catfact.ninja\\/facts?page=10","label":"10","active":false},{"url":null,"label":"...","active":false},{"url":"https:\\/\\/catfact.ninja\\/facts?page=33","label":"33","active":false},{"url":"https:\\/\\/catfact.ninja\\/facts?page=34","label":"34","active":false},{"url":"https:\\/\\/catfact.ninja\\/facts?page=2","label":"Next","active":false}],"next_page_url":"https:\\/\\/catfact.ninja\\/facts?page=2","path":"https:\\/\\/catfact.ninja\\/facts","per_page":10,"prev_page_url":null,"to":10,"total":332}'
The output for the .text function is actually JSON (Javascript object notation). If we apply a JSON method we can export this as a dictionary, which will be much easier for us to work with:
cat_facts.json(){'current_page': 1,
'data': [{'fact': 'Unlike dogs, cats do not have a sweet tooth. Scientists believe this is due to a mutation in a key taste receptor.',
'length': 114},
{'fact': 'When a cat chases its prey, it keeps its head level. Dogs and humans bob their heads up and down.',
'length': 97},
{'fact': 'The technical term for a cat’s hairball is a “bezoar.”',
'length': 54},
{'fact': 'A group of cats is called a “clowder.”', 'length': 38},
{'fact': 'A cat can’t climb head first down a tree because every claw on a cat’s paw points the same way. To get down from a tree, a cat must back down.',
'length': 142},
{'fact': 'Cats make about 100 different sounds. Dogs make only about 10.',
'length': 62},
{'fact': 'Every year, nearly four million cats are eaten in Asia.',
'length': 55},
{'fact': 'There are more than 500 million domestic cats in the world, with approximately 40 recognized breeds.',
'length': 100},
{'fact': 'Approximately 24 cat skins can make a coat.', 'length': 43},
{'fact': 'While it is commonly thought that the ancient Egyptians were the first to domesticate cats, the oldest known pet cat was recently found in a 9,500-year-old grave on the Mediterranean island of Cyprus. This grave predates early Egyptian art depicting cats by 4,000 years or more.',
'length': 278}],
'first_page_url': 'https://catfact.ninja/facts?page=1',
'from': 1,
'last_page': 34,
'last_page_url': 'https://catfact.ninja/facts?page=34',
'links': [{'url': None, 'label': 'Previous', 'active': False},
{'url': 'https://catfact.ninja/facts?page=1', 'label': '1', 'active': True},
{'url': 'https://catfact.ninja/facts?page=2', 'label': '2', 'active': False},
{'url': 'https://catfact.ninja/facts?page=3', 'label': '3', 'active': False},
{'url': 'https://catfact.ninja/facts?page=4', 'label': '4', 'active': False},
{'url': 'https://catfact.ninja/facts?page=5', 'label': '5', 'active': False},
{'url': 'https://catfact.ninja/facts?page=6', 'label': '6', 'active': False},
{'url': 'https://catfact.ninja/facts?page=7', 'label': '7', 'active': False},
{'url': 'https://catfact.ninja/facts?page=8', 'label': '8', 'active': False},
{'url': 'https://catfact.ninja/facts?page=9', 'label': '9', 'active': False},
{'url': 'https://catfact.ninja/facts?page=10',
'label': '10',
'active': False},
{'url': None, 'label': '...', 'active': False},
{'url': 'https://catfact.ninja/facts?page=33',
'label': '33',
'active': False},
{'url': 'https://catfact.ninja/facts?page=34',
'label': '34',
'active': False},
{'url': 'https://catfact.ninja/facts?page=2',
'label': 'Next',
'active': False}],
'next_page_url': 'https://catfact.ninja/facts?page=2',
'path': 'https://catfact.ninja/facts',
'per_page': 10,
'prev_page_url': None,
'to': 10,
'total': 332}
3. Querying parameters
requests.get(base_url+"?limit=50")<Response [200]>
Let’s create a variable to save this parameter:
many_cat_facts = requests.get(base_url+"?limit=5")
many_cat_facts.json(){'current_page': 1,
'data': [{'fact': 'Unlike dogs, cats do not have a sweet tooth. Scientists believe this is due to a mutation in a key taste receptor.',
'length': 114},
{'fact': 'When a cat chases its prey, it keeps its head level. Dogs and humans bob their heads up and down.',
'length': 97},
{'fact': 'The technical term for a cat’s hairball is a “bezoar.”',
'length': 54},
{'fact': 'A group of cats is called a “clowder.”', 'length': 38},
{'fact': 'A cat can’t climb head first down a tree because every claw on a cat’s paw points the same way. To get down from a tree, a cat must back down.',
'length': 142}],
'first_page_url': 'https://catfact.ninja/facts?page=1',
'from': 1,
'last_page': 67,
'last_page_url': 'https://catfact.ninja/facts?page=67',
'links': [{'url': None, 'label': 'Previous', 'active': False},
{'url': 'https://catfact.ninja/facts?page=1', 'label': '1', 'active': True},
{'url': 'https://catfact.ninja/facts?page=2', 'label': '2', 'active': False},
{'url': 'https://catfact.ninja/facts?page=3', 'label': '3', 'active': False},
{'url': 'https://catfact.ninja/facts?page=4', 'label': '4', 'active': False},
{'url': 'https://catfact.ninja/facts?page=5', 'label': '5', 'active': False},
{'url': 'https://catfact.ninja/facts?page=6', 'label': '6', 'active': False},
{'url': 'https://catfact.ninja/facts?page=7', 'label': '7', 'active': False},
{'url': 'https://catfact.ninja/facts?page=8', 'label': '8', 'active': False},
{'url': 'https://catfact.ninja/facts?page=9', 'label': '9', 'active': False},
{'url': 'https://catfact.ninja/facts?page=10',
'label': '10',
'active': False},
{'url': None, 'label': '...', 'active': False},
{'url': 'https://catfact.ninja/facts?page=66',
'label': '66',
'active': False},
{'url': 'https://catfact.ninja/facts?page=67',
'label': '67',
'active': False},
{'url': 'https://catfact.ninja/facts?page=2',
'label': 'Next',
'active': False}],
'next_page_url': 'https://catfact.ninja/facts?page=2',
'path': 'https://catfact.ninja/facts',
'per_page': 5,
'prev_page_url': None,
'to': 5,
'total': 332}
Exercise 1:
Query the /breeds attribute and limit our results to 10.
base_url_breeds = "https://catfact.ninja/breeds"
cat_breeds = requests.get(base_url_breeds)
cat_breeds<Response [200]>
cat_breeds_limit = requests.get(base_url_breeds+"?limit=1")
cat_breeds_limit.json(){'current_page': 1,
'data': [{'breed': 'Abyssinian',
'country': 'Ethiopia',
'origin': 'Natural/Standard',
'coat': 'Short',
'pattern': 'Ticked'}],
'first_page_url': 'https://catfact.ninja/breeds?page=1',
'from': 1,
'last_page': 98,
'last_page_url': 'https://catfact.ninja/breeds?page=98',
'links': [{'url': None, 'label': 'Previous', 'active': False},
{'url': 'https://catfact.ninja/breeds?page=1', 'label': '1', 'active': True},
{'url': 'https://catfact.ninja/breeds?page=2',
'label': '2',
'active': False},
{'url': 'https://catfact.ninja/breeds?page=3',
'label': '3',
'active': False},
{'url': 'https://catfact.ninja/breeds?page=4',
'label': '4',
'active': False},
{'url': 'https://catfact.ninja/breeds?page=5',
'label': '5',
'active': False},
{'url': 'https://catfact.ninja/breeds?page=6',
'label': '6',
'active': False},
{'url': 'https://catfact.ninja/breeds?page=7',
'label': '7',
'active': False},
{'url': 'https://catfact.ninja/breeds?page=8',
'label': '8',
'active': False},
{'url': 'https://catfact.ninja/breeds?page=9',
'label': '9',
'active': False},
{'url': 'https://catfact.ninja/breeds?page=10',
'label': '10',
'active': False},
{'url': None, 'label': '...', 'active': False},
{'url': 'https://catfact.ninja/breeds?page=97',
'label': '97',
'active': False},
{'url': 'https://catfact.ninja/breeds?page=98',
'label': '98',
'active': False},
{'url': 'https://catfact.ninja/breeds?page=2',
'label': 'Next',
'active': False}],
'next_page_url': 'https://catfact.ninja/breeds?page=2',
'path': 'https://catfact.ninja/breeds',
'per_page': 1,
'prev_page_url': None,
'to': 1,
'total': 98}
Let’s try another example of API querying—this time with a sci-fi twist!
We’ll be using swapi.info, an API built specifically for exploring data from the Star Wars universe. It’s a great way to practice working with structured data while having a bit of fun with characters, planets, and starships.
Let’s create a variable for the people attributes URL and do a simple request to it:
people_url = "https://swapi.info/api/people"
all_people_api = requests.get(people_url)
all_people_api.json()[{'name': 'Luke Skywalker',
'height': '172',
'mass': '77',
'hair_color': 'blond',
'skin_color': 'fair',
'eye_color': 'blue',
'birth_year': '19BBY',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/1',
'films': ['https://swapi.info/api/films/1',
'https://swapi.info/api/films/2',
'https://swapi.info/api/films/3',
'https://swapi.info/api/films/6'],
'species': [],
'vehicles': ['https://swapi.info/api/vehicles/14',
'https://swapi.info/api/vehicles/30'],
'starships': ['https://swapi.info/api/starships/12',
'https://swapi.info/api/starships/22'],
'created': '2014-12-09T13:50:51.644000Z',
'edited': '2014-12-20T21:17:56.891000Z',
'url': 'https://swapi.info/api/people/1'},
{'name': 'C-3PO',
'height': '167',
'mass': '75',
'hair_color': 'n/a',
'skin_color': 'gold',
'eye_color': 'yellow',
'birth_year': '112BBY',
'gender': 'n/a',
'homeworld': 'https://swapi.info/api/planets/1',
'films': ['https://swapi.info/api/films/1',
'https://swapi.info/api/films/2',
'https://swapi.info/api/films/3',
'https://swapi.info/api/films/4',
'https://swapi.info/api/films/5',
'https://swapi.info/api/films/6'],
'species': ['https://swapi.info/api/species/2'],
'vehicles': [],
'starships': [],
'created': '2014-12-10T15:10:51.357000Z',
'edited': '2014-12-20T21:17:50.309000Z',
'url': 'https://swapi.info/api/people/2'},
{'name': 'R2-D2',
'height': '96',
'mass': '32',
'hair_color': 'n/a',
'skin_color': 'white, blue',
'eye_color': 'red',
'birth_year': '33BBY',
'gender': 'n/a',
'homeworld': 'https://swapi.info/api/planets/8',
'films': ['https://swapi.info/api/films/1',
'https://swapi.info/api/films/2',
'https://swapi.info/api/films/3',
'https://swapi.info/api/films/4',
'https://swapi.info/api/films/5',
'https://swapi.info/api/films/6'],
'species': ['https://swapi.info/api/species/2'],
'vehicles': [],
'starships': [],
'created': '2014-12-10T15:11:50.376000Z',
'edited': '2014-12-20T21:17:50.311000Z',
'url': 'https://swapi.info/api/people/3'},
{'name': 'Darth Vader',
'height': '202',
'mass': '136',
'hair_color': 'none',
'skin_color': 'white',
'eye_color': 'yellow',
'birth_year': '41.9BBY',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/1',
'films': ['https://swapi.info/api/films/1',
'https://swapi.info/api/films/2',
'https://swapi.info/api/films/3',
'https://swapi.info/api/films/6'],
'species': [],
'vehicles': [],
'starships': ['https://swapi.info/api/starships/13'],
'created': '2014-12-10T15:18:20.704000Z',
'edited': '2014-12-20T21:17:50.313000Z',
'url': 'https://swapi.info/api/people/4'},
{'name': 'Leia Organa',
'height': '150',
'mass': '49',
'hair_color': 'brown',
'skin_color': 'light',
'eye_color': 'brown',
'birth_year': '19BBY',
'gender': 'female',
'homeworld': 'https://swapi.info/api/planets/2',
'films': ['https://swapi.info/api/films/1',
'https://swapi.info/api/films/2',
'https://swapi.info/api/films/3',
'https://swapi.info/api/films/6'],
'species': [],
'vehicles': ['https://swapi.info/api/vehicles/30'],
'starships': [],
'created': '2014-12-10T15:20:09.791000Z',
'edited': '2014-12-20T21:17:50.315000Z',
'url': 'https://swapi.info/api/people/5'},
{'name': 'Owen Lars',
'height': '178',
'mass': '120',
'hair_color': 'brown, grey',
'skin_color': 'light',
'eye_color': 'blue',
'birth_year': '52BBY',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/1',
'films': ['https://swapi.info/api/films/1',
'https://swapi.info/api/films/5',
'https://swapi.info/api/films/6'],
'species': [],
'vehicles': [],
'starships': [],
'created': '2014-12-10T15:52:14.024000Z',
'edited': '2014-12-20T21:17:50.317000Z',
'url': 'https://swapi.info/api/people/6'},
{'name': 'Beru Whitesun lars',
'height': '165',
'mass': '75',
'hair_color': 'brown',
'skin_color': 'light',
'eye_color': 'blue',
'birth_year': '47BBY',
'gender': 'female',
'homeworld': 'https://swapi.info/api/planets/1',
'films': ['https://swapi.info/api/films/1',
'https://swapi.info/api/films/5',
'https://swapi.info/api/films/6'],
'species': [],
'vehicles': [],
'starships': [],
'created': '2014-12-10T15:53:41.121000Z',
'edited': '2014-12-20T21:17:50.319000Z',
'url': 'https://swapi.info/api/people/7'},
{'name': 'R5-D4',
'height': '97',
'mass': '32',
'hair_color': 'n/a',
'skin_color': 'white, red',
'eye_color': 'red',
'birth_year': 'unknown',
'gender': 'n/a',
'homeworld': 'https://swapi.info/api/planets/1',
'films': ['https://swapi.info/api/films/1'],
'species': ['https://swapi.info/api/species/2'],
'vehicles': [],
'starships': [],
'created': '2014-12-10T15:57:50.959000Z',
'edited': '2014-12-20T21:17:50.321000Z',
'url': 'https://swapi.info/api/people/8'},
{'name': 'Biggs Darklighter',
'height': '183',
'mass': '84',
'hair_color': 'black',
'skin_color': 'light',
'eye_color': 'brown',
'birth_year': '24BBY',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/1',
'films': ['https://swapi.info/api/films/1'],
'species': [],
'vehicles': [],
'starships': ['https://swapi.info/api/starships/12'],
'created': '2014-12-10T15:59:50.509000Z',
'edited': '2014-12-20T21:17:50.323000Z',
'url': 'https://swapi.info/api/people/9'},
{'name': 'Obi-Wan Kenobi',
'height': '182',
'mass': '77',
'hair_color': 'auburn, white',
'skin_color': 'fair',
'eye_color': 'blue-gray',
'birth_year': '57BBY',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/20',
'films': ['https://swapi.info/api/films/1',
'https://swapi.info/api/films/2',
'https://swapi.info/api/films/3',
'https://swapi.info/api/films/4',
'https://swapi.info/api/films/5',
'https://swapi.info/api/films/6'],
'species': [],
'vehicles': ['https://swapi.info/api/vehicles/38'],
'starships': ['https://swapi.info/api/starships/48',
'https://swapi.info/api/starships/59',
'https://swapi.info/api/starships/64',
'https://swapi.info/api/starships/65',
'https://swapi.info/api/starships/74'],
'created': '2014-12-10T16:16:29.192000Z',
'edited': '2014-12-20T21:17:50.325000Z',
'url': 'https://swapi.info/api/people/10'},
{'name': 'Anakin Skywalker',
'height': '188',
'mass': '84',
'hair_color': 'blond',
'skin_color': 'fair',
'eye_color': 'blue',
'birth_year': '41.9BBY',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/1',
'films': ['https://swapi.info/api/films/4',
'https://swapi.info/api/films/5',
'https://swapi.info/api/films/6'],
'species': [],
'vehicles': ['https://swapi.info/api/vehicles/44',
'https://swapi.info/api/vehicles/46'],
'starships': ['https://swapi.info/api/starships/39',
'https://swapi.info/api/starships/59',
'https://swapi.info/api/starships/65'],
'created': '2014-12-10T16:20:44.310000Z',
'edited': '2014-12-20T21:17:50.327000Z',
'url': 'https://swapi.info/api/people/11'},
{'name': 'Wilhuff Tarkin',
'height': '180',
'mass': 'unknown',
'hair_color': 'auburn, grey',
'skin_color': 'fair',
'eye_color': 'blue',
'birth_year': '64BBY',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/21',
'films': ['https://swapi.info/api/films/1',
'https://swapi.info/api/films/6'],
'species': [],
'vehicles': [],
'starships': [],
'created': '2014-12-10T16:26:56.138000Z',
'edited': '2014-12-20T21:17:50.330000Z',
'url': 'https://swapi.info/api/people/12'},
{'name': 'Chewbacca',
'height': '228',
'mass': '112',
'hair_color': 'brown',
'skin_color': 'unknown',
'eye_color': 'blue',
'birth_year': '200BBY',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/14',
'films': ['https://swapi.info/api/films/1',
'https://swapi.info/api/films/2',
'https://swapi.info/api/films/3',
'https://swapi.info/api/films/6'],
'species': ['https://swapi.info/api/species/3'],
'vehicles': ['https://swapi.info/api/vehicles/19'],
'starships': ['https://swapi.info/api/starships/10',
'https://swapi.info/api/starships/22'],
'created': '2014-12-10T16:42:45.066000Z',
'edited': '2014-12-20T21:17:50.332000Z',
'url': 'https://swapi.info/api/people/13'},
{'name': 'Han Solo',
'height': '180',
'mass': '80',
'hair_color': 'brown',
'skin_color': 'fair',
'eye_color': 'brown',
'birth_year': '29BBY',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/22',
'films': ['https://swapi.info/api/films/1',
'https://swapi.info/api/films/2',
'https://swapi.info/api/films/3'],
'species': [],
'vehicles': [],
'starships': ['https://swapi.info/api/starships/10',
'https://swapi.info/api/starships/22'],
'created': '2014-12-10T16:49:14.582000Z',
'edited': '2014-12-20T21:17:50.334000Z',
'url': 'https://swapi.info/api/people/14'},
{'name': 'Greedo',
'height': '173',
'mass': '74',
'hair_color': 'n/a',
'skin_color': 'green',
'eye_color': 'black',
'birth_year': '44BBY',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/23',
'films': ['https://swapi.info/api/films/1'],
'species': ['https://swapi.info/api/species/4'],
'vehicles': [],
'starships': [],
'created': '2014-12-10T17:03:30.334000Z',
'edited': '2014-12-20T21:17:50.336000Z',
'url': 'https://swapi.info/api/people/15'},
{'name': 'Jabba Desilijic Tiure',
'height': '175',
'mass': '1,358',
'hair_color': 'n/a',
'skin_color': 'green-tan, brown',
'eye_color': 'orange',
'birth_year': '600BBY',
'gender': 'hermaphrodite',
'homeworld': 'https://swapi.info/api/planets/24',
'films': ['https://swapi.info/api/films/1',
'https://swapi.info/api/films/3',
'https://swapi.info/api/films/4'],
'species': ['https://swapi.info/api/species/5'],
'vehicles': [],
'starships': [],
'created': '2014-12-10T17:11:31.638000Z',
'edited': '2014-12-20T21:17:50.338000Z',
'url': 'https://swapi.info/api/people/16'},
{'name': 'Wedge Antilles',
'height': '170',
'mass': '77',
'hair_color': 'brown',
'skin_color': 'fair',
'eye_color': 'hazel',
'birth_year': '21BBY',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/22',
'films': ['https://swapi.info/api/films/1',
'https://swapi.info/api/films/2',
'https://swapi.info/api/films/3'],
'species': [],
'vehicles': ['https://swapi.info/api/vehicles/14'],
'starships': ['https://swapi.info/api/starships/12'],
'created': '2014-12-12T11:08:06.469000Z',
'edited': '2014-12-20T21:17:50.341000Z',
'url': 'https://swapi.info/api/people/18'},
{'name': 'Jek Tono Porkins',
'height': '180',
'mass': '110',
'hair_color': 'brown',
'skin_color': 'fair',
'eye_color': 'blue',
'birth_year': 'unknown',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/26',
'films': ['https://swapi.info/api/films/1'],
'species': [],
'vehicles': [],
'starships': ['https://swapi.info/api/starships/12'],
'created': '2014-12-12T11:16:56.569000Z',
'edited': '2014-12-20T21:17:50.343000Z',
'url': 'https://swapi.info/api/people/19'},
{'name': 'Yoda',
'height': '66',
'mass': '17',
'hair_color': 'white',
'skin_color': 'green',
'eye_color': 'brown',
'birth_year': '896BBY',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/28',
'films': ['https://swapi.info/api/films/2',
'https://swapi.info/api/films/3',
'https://swapi.info/api/films/4',
'https://swapi.info/api/films/5',
'https://swapi.info/api/films/6'],
'species': ['https://swapi.info/api/species/6'],
'vehicles': [],
'starships': [],
'created': '2014-12-15T12:26:01.042000Z',
'edited': '2014-12-20T21:17:50.345000Z',
'url': 'https://swapi.info/api/people/20'},
{'name': 'Palpatine',
'height': '170',
'mass': '75',
'hair_color': 'grey',
'skin_color': 'pale',
'eye_color': 'yellow',
'birth_year': '82BBY',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/8',
'films': ['https://swapi.info/api/films/2',
'https://swapi.info/api/films/3',
'https://swapi.info/api/films/4',
'https://swapi.info/api/films/5',
'https://swapi.info/api/films/6'],
'species': [],
'vehicles': [],
'starships': [],
'created': '2014-12-15T12:48:05.971000Z',
'edited': '2014-12-20T21:17:50.347000Z',
'url': 'https://swapi.info/api/people/21'},
{'name': 'Boba Fett',
'height': '183',
'mass': '78.2',
'hair_color': 'black',
'skin_color': 'fair',
'eye_color': 'brown',
'birth_year': '31.5BBY',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/10',
'films': ['https://swapi.info/api/films/2',
'https://swapi.info/api/films/3',
'https://swapi.info/api/films/5'],
'species': [],
'vehicles': [],
'starships': ['https://swapi.info/api/starships/21'],
'created': '2014-12-15T12:49:32.457000Z',
'edited': '2014-12-20T21:17:50.349000Z',
'url': 'https://swapi.info/api/people/22'},
{'name': 'IG-88',
'height': '200',
'mass': '140',
'hair_color': 'none',
'skin_color': 'metal',
'eye_color': 'red',
'birth_year': '15BBY',
'gender': 'none',
'homeworld': 'https://swapi.info/api/planets/28',
'films': ['https://swapi.info/api/films/2'],
'species': ['https://swapi.info/api/species/2'],
'vehicles': [],
'starships': [],
'created': '2014-12-15T12:51:10.076000Z',
'edited': '2014-12-20T21:17:50.351000Z',
'url': 'https://swapi.info/api/people/23'},
{'name': 'Bossk',
'height': '190',
'mass': '113',
'hair_color': 'none',
'skin_color': 'green',
'eye_color': 'red',
'birth_year': '53BBY',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/29',
'films': ['https://swapi.info/api/films/2'],
'species': ['https://swapi.info/api/species/7'],
'vehicles': [],
'starships': [],
'created': '2014-12-15T12:53:49.297000Z',
'edited': '2014-12-20T21:17:50.355000Z',
'url': 'https://swapi.info/api/people/24'},
{'name': 'Lando Calrissian',
'height': '177',
'mass': '79',
'hair_color': 'black',
'skin_color': 'dark',
'eye_color': 'brown',
'birth_year': '31BBY',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/30',
'films': ['https://swapi.info/api/films/2',
'https://swapi.info/api/films/3'],
'species': [],
'vehicles': [],
'starships': ['https://swapi.info/api/starships/10'],
'created': '2014-12-15T12:56:32.683000Z',
'edited': '2014-12-20T21:17:50.357000Z',
'url': 'https://swapi.info/api/people/25'},
{'name': 'Lobot',
'height': '175',
'mass': '79',
'hair_color': 'none',
'skin_color': 'light',
'eye_color': 'blue',
'birth_year': '37BBY',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/6',
'films': ['https://swapi.info/api/films/2'],
'species': [],
'vehicles': [],
'starships': [],
'created': '2014-12-15T13:01:57.178000Z',
'edited': '2014-12-20T21:17:50.359000Z',
'url': 'https://swapi.info/api/people/26'},
{'name': 'Ackbar',
'height': '180',
'mass': '83',
'hair_color': 'none',
'skin_color': 'brown mottle',
'eye_color': 'orange',
'birth_year': '41BBY',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/31',
'films': ['https://swapi.info/api/films/3'],
'species': ['https://swapi.info/api/species/8'],
'vehicles': [],
'starships': [],
'created': '2014-12-18T11:07:50.584000Z',
'edited': '2014-12-20T21:17:50.362000Z',
'url': 'https://swapi.info/api/people/27'},
{'name': 'Mon Mothma',
'height': '150',
'mass': 'unknown',
'hair_color': 'auburn',
'skin_color': 'fair',
'eye_color': 'blue',
'birth_year': '48BBY',
'gender': 'female',
'homeworld': 'https://swapi.info/api/planets/32',
'films': ['https://swapi.info/api/films/3'],
'species': [],
'vehicles': [],
'starships': [],
'created': '2014-12-18T11:12:38.895000Z',
'edited': '2014-12-20T21:17:50.364000Z',
'url': 'https://swapi.info/api/people/28'},
{'name': 'Arvel Crynyd',
'height': 'unknown',
'mass': 'unknown',
'hair_color': 'brown',
'skin_color': 'fair',
'eye_color': 'brown',
'birth_year': 'unknown',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/28',
'films': ['https://swapi.info/api/films/3'],
'species': [],
'vehicles': [],
'starships': ['https://swapi.info/api/starships/28'],
'created': '2014-12-18T11:16:33.020000Z',
'edited': '2014-12-20T21:17:50.367000Z',
'url': 'https://swapi.info/api/people/29'},
{'name': 'Wicket Systri Warrick',
'height': '88',
'mass': '20',
'hair_color': 'brown',
'skin_color': 'brown',
'eye_color': 'brown',
'birth_year': '8BBY',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/7',
'films': ['https://swapi.info/api/films/3'],
'species': ['https://swapi.info/api/species/9'],
'vehicles': [],
'starships': [],
'created': '2014-12-18T11:21:58.954000Z',
'edited': '2014-12-20T21:17:50.369000Z',
'url': 'https://swapi.info/api/people/30'},
{'name': 'Nien Nunb',
'height': '160',
'mass': '68',
'hair_color': 'none',
'skin_color': 'grey',
'eye_color': 'black',
'birth_year': 'unknown',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/33',
'films': ['https://swapi.info/api/films/3'],
'species': ['https://swapi.info/api/species/10'],
'vehicles': [],
'starships': ['https://swapi.info/api/starships/10'],
'created': '2014-12-18T11:26:18.541000Z',
'edited': '2014-12-20T21:17:50.371000Z',
'url': 'https://swapi.info/api/people/31'},
{'name': 'Qui-Gon Jinn',
'height': '193',
'mass': '89',
'hair_color': 'brown',
'skin_color': 'fair',
'eye_color': 'blue',
'birth_year': '92BBY',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/28',
'films': ['https://swapi.info/api/films/4'],
'species': [],
'vehicles': ['https://swapi.info/api/vehicles/38'],
'starships': [],
'created': '2014-12-19T16:54:53.618000Z',
'edited': '2014-12-20T21:17:50.375000Z',
'url': 'https://swapi.info/api/people/32'},
{'name': 'Nute Gunray',
'height': '191',
'mass': '90',
'hair_color': 'none',
'skin_color': 'mottled green',
'eye_color': 'red',
'birth_year': 'unknown',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/18',
'films': ['https://swapi.info/api/films/4',
'https://swapi.info/api/films/5',
'https://swapi.info/api/films/6'],
'species': ['https://swapi.info/api/species/11'],
'vehicles': [],
'starships': [],
'created': '2014-12-19T17:05:57.357000Z',
'edited': '2014-12-20T21:17:50.377000Z',
'url': 'https://swapi.info/api/people/33'},
{'name': 'Finis Valorum',
'height': '170',
'mass': 'unknown',
'hair_color': 'blond',
'skin_color': 'fair',
'eye_color': 'blue',
'birth_year': '91BBY',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/9',
'films': ['https://swapi.info/api/films/4'],
'species': [],
'vehicles': [],
'starships': [],
'created': '2014-12-19T17:21:45.915000Z',
'edited': '2014-12-20T21:17:50.379000Z',
'url': 'https://swapi.info/api/people/34'},
{'name': 'Padmé Amidala',
'height': '185',
'mass': '45',
'hair_color': 'brown',
'skin_color': 'light',
'eye_color': 'brown',
'birth_year': '46BBY',
'gender': 'female',
'homeworld': 'https://swapi.info/api/planets/8',
'films': ['https://swapi.info/api/films/4',
'https://swapi.info/api/films/5',
'https://swapi.info/api/films/6'],
'species': [],
'vehicles': [],
'starships': ['https://swapi.info/api/starships/39',
'https://swapi.info/api/starships/49',
'https://swapi.info/api/starships/64'],
'created': '2014-12-19T17:28:26.926000Z',
'edited': '2014-12-20T21:17:50.381000Z',
'url': 'https://swapi.info/api/people/35'},
{'name': 'Jar Jar Binks',
'height': '196',
'mass': '66',
'hair_color': 'none',
'skin_color': 'orange',
'eye_color': 'orange',
'birth_year': '52BBY',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/8',
'films': ['https://swapi.info/api/films/4',
'https://swapi.info/api/films/5'],
'species': ['https://swapi.info/api/species/12'],
'vehicles': [],
'starships': [],
'created': '2014-12-19T17:29:32.489000Z',
'edited': '2014-12-20T21:17:50.383000Z',
'url': 'https://swapi.info/api/people/36'},
{'name': 'Roos Tarpals',
'height': '224',
'mass': '82',
'hair_color': 'none',
'skin_color': 'grey',
'eye_color': 'orange',
'birth_year': 'unknown',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/8',
'films': ['https://swapi.info/api/films/4'],
'species': ['https://swapi.info/api/species/12'],
'vehicles': [],
'starships': [],
'created': '2014-12-19T17:32:56.741000Z',
'edited': '2014-12-20T21:17:50.385000Z',
'url': 'https://swapi.info/api/people/37'},
{'name': 'Rugor Nass',
'height': '206',
'mass': 'unknown',
'hair_color': 'none',
'skin_color': 'green',
'eye_color': 'orange',
'birth_year': 'unknown',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/8',
'films': ['https://swapi.info/api/films/4'],
'species': ['https://swapi.info/api/species/12'],
'vehicles': [],
'starships': [],
'created': '2014-12-19T17:33:38.909000Z',
'edited': '2014-12-20T21:17:50.388000Z',
'url': 'https://swapi.info/api/people/38'},
{'name': 'Ric Olié',
'height': '183',
'mass': 'unknown',
'hair_color': 'brown',
'skin_color': 'fair',
'eye_color': 'blue',
'birth_year': 'unknown',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/8',
'films': ['https://swapi.info/api/films/4'],
'species': [],
'vehicles': [],
'starships': ['https://swapi.info/api/starships/40'],
'created': '2014-12-19T17:45:01.522000Z',
'edited': '2014-12-20T21:17:50.392000Z',
'url': 'https://swapi.info/api/people/39'},
{'name': 'Watto',
'height': '137',
'mass': 'unknown',
'hair_color': 'black',
'skin_color': 'blue, grey',
'eye_color': 'yellow',
'birth_year': 'unknown',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/34',
'films': ['https://swapi.info/api/films/4',
'https://swapi.info/api/films/5'],
'species': ['https://swapi.info/api/species/13'],
'vehicles': [],
'starships': [],
'created': '2014-12-19T17:48:54.647000Z',
'edited': '2014-12-20T21:17:50.395000Z',
'url': 'https://swapi.info/api/people/40'},
{'name': 'Sebulba',
'height': '112',
'mass': '40',
'hair_color': 'none',
'skin_color': 'grey, red',
'eye_color': 'orange',
'birth_year': 'unknown',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/35',
'films': ['https://swapi.info/api/films/4'],
'species': ['https://swapi.info/api/species/14'],
'vehicles': [],
'starships': [],
'created': '2014-12-19T17:53:02.586000Z',
'edited': '2014-12-20T21:17:50.397000Z',
'url': 'https://swapi.info/api/people/41'},
{'name': 'Quarsh Panaka',
'height': '183',
'mass': 'unknown',
'hair_color': 'black',
'skin_color': 'dark',
'eye_color': 'brown',
'birth_year': '62BBY',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/8',
'films': ['https://swapi.info/api/films/4'],
'species': [],
'vehicles': [],
'starships': [],
'created': '2014-12-19T17:55:43.348000Z',
'edited': '2014-12-20T21:17:50.399000Z',
'url': 'https://swapi.info/api/people/42'},
{'name': 'Shmi Skywalker',
'height': '163',
'mass': 'unknown',
'hair_color': 'black',
'skin_color': 'fair',
'eye_color': 'brown',
'birth_year': '72BBY',
'gender': 'female',
'homeworld': 'https://swapi.info/api/planets/1',
'films': ['https://swapi.info/api/films/4',
'https://swapi.info/api/films/5'],
'species': [],
'vehicles': [],
'starships': [],
'created': '2014-12-19T17:57:41.191000Z',
'edited': '2014-12-20T21:17:50.401000Z',
'url': 'https://swapi.info/api/people/43'},
{'name': 'Darth Maul',
'height': '175',
'mass': '80',
'hair_color': 'none',
'skin_color': 'red',
'eye_color': 'yellow',
'birth_year': '54BBY',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/36',
'films': ['https://swapi.info/api/films/4'],
'species': ['https://swapi.info/api/species/22'],
'vehicles': ['https://swapi.info/api/vehicles/42'],
'starships': ['https://swapi.info/api/starships/41'],
'created': '2014-12-19T18:00:41.929000Z',
'edited': '2014-12-20T21:17:50.403000Z',
'url': 'https://swapi.info/api/people/44'},
{'name': 'Bib Fortuna',
'height': '180',
'mass': 'unknown',
'hair_color': 'none',
'skin_color': 'pale',
'eye_color': 'pink',
'birth_year': 'unknown',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/37',
'films': ['https://swapi.info/api/films/3'],
'species': ['https://swapi.info/api/species/15'],
'vehicles': [],
'starships': [],
'created': '2014-12-20T09:47:02.512000Z',
'edited': '2014-12-20T21:17:50.407000Z',
'url': 'https://swapi.info/api/people/45'},
{'name': 'Ayla Secura',
'height': '178',
'mass': '55',
'hair_color': 'none',
'skin_color': 'blue',
'eye_color': 'hazel',
'birth_year': '48BBY',
'gender': 'female',
'homeworld': 'https://swapi.info/api/planets/37',
'films': ['https://swapi.info/api/films/4',
'https://swapi.info/api/films/5',
'https://swapi.info/api/films/6'],
'species': ['https://swapi.info/api/species/15'],
'vehicles': [],
'starships': [],
'created': '2014-12-20T09:48:01.172000Z',
'edited': '2014-12-20T21:17:50.409000Z',
'url': 'https://swapi.info/api/people/46'},
{'name': 'Ratts Tyerel',
'height': '79',
'mass': '15',
'hair_color': 'none',
'skin_color': 'grey, blue',
'eye_color': 'unknown',
'birth_year': 'unknown',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/38',
'films': ['https://swapi.info/api/films/4'],
'species': ['https://swapi.info/api/species/16'],
'vehicles': [],
'starships': [],
'created': '2014-12-20T09:53:15.086000Z',
'edited': '2014-12-20T21:17:50.410000Z',
'url': 'https://swapi.info/api/people/47'},
{'name': 'Dud Bolt',
'height': '94',
'mass': '45',
'hair_color': 'none',
'skin_color': 'blue, grey',
'eye_color': 'yellow',
'birth_year': 'unknown',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/39',
'films': ['https://swapi.info/api/films/4'],
'species': ['https://swapi.info/api/species/17'],
'vehicles': [],
'starships': [],
'created': '2014-12-20T09:57:31.858000Z',
'edited': '2014-12-20T21:17:50.414000Z',
'url': 'https://swapi.info/api/people/48'},
{'name': 'Gasgano',
'height': '122',
'mass': 'unknown',
'hair_color': 'none',
'skin_color': 'white, blue',
'eye_color': 'black',
'birth_year': 'unknown',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/40',
'films': ['https://swapi.info/api/films/4'],
'species': ['https://swapi.info/api/species/18'],
'vehicles': [],
'starships': [],
'created': '2014-12-20T10:02:12.223000Z',
'edited': '2014-12-20T21:17:50.416000Z',
'url': 'https://swapi.info/api/people/49'},
{'name': 'Ben Quadinaros',
'height': '163',
'mass': '65',
'hair_color': 'none',
'skin_color': 'grey, green, yellow',
'eye_color': 'orange',
'birth_year': 'unknown',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/41',
'films': ['https://swapi.info/api/films/4'],
'species': ['https://swapi.info/api/species/19'],
'vehicles': [],
'starships': [],
'created': '2014-12-20T10:08:33.777000Z',
'edited': '2014-12-20T21:17:50.417000Z',
'url': 'https://swapi.info/api/people/50'},
{'name': 'Mace Windu',
'height': '188',
'mass': '84',
'hair_color': 'none',
'skin_color': 'dark',
'eye_color': 'brown',
'birth_year': '72BBY',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/42',
'films': ['https://swapi.info/api/films/4',
'https://swapi.info/api/films/5',
'https://swapi.info/api/films/6'],
'species': [],
'vehicles': [],
'starships': [],
'created': '2014-12-20T10:12:30.846000Z',
'edited': '2014-12-20T21:17:50.420000Z',
'url': 'https://swapi.info/api/people/51'},
{'name': 'Ki-Adi-Mundi',
'height': '198',
'mass': '82',
'hair_color': 'white',
'skin_color': 'pale',
'eye_color': 'yellow',
'birth_year': '92BBY',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/43',
'films': ['https://swapi.info/api/films/4',
'https://swapi.info/api/films/5',
'https://swapi.info/api/films/6'],
'species': ['https://swapi.info/api/species/20'],
'vehicles': [],
'starships': [],
'created': '2014-12-20T10:15:32.293000Z',
'edited': '2014-12-20T21:17:50.422000Z',
'url': 'https://swapi.info/api/people/52'},
{'name': 'Kit Fisto',
'height': '196',
'mass': '87',
'hair_color': 'none',
'skin_color': 'green',
'eye_color': 'black',
'birth_year': 'unknown',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/44',
'films': ['https://swapi.info/api/films/4',
'https://swapi.info/api/films/5',
'https://swapi.info/api/films/6'],
'species': ['https://swapi.info/api/species/21'],
'vehicles': [],
'starships': [],
'created': '2014-12-20T10:18:57.202000Z',
'edited': '2014-12-20T21:17:50.424000Z',
'url': 'https://swapi.info/api/people/53'},
{'name': 'Eeth Koth',
'height': '171',
'mass': 'unknown',
'hair_color': 'black',
'skin_color': 'brown',
'eye_color': 'brown',
'birth_year': 'unknown',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/45',
'films': ['https://swapi.info/api/films/4',
'https://swapi.info/api/films/6'],
'species': ['https://swapi.info/api/species/22'],
'vehicles': [],
'starships': [],
'created': '2014-12-20T10:26:47.902000Z',
'edited': '2014-12-20T21:17:50.427000Z',
'url': 'https://swapi.info/api/people/54'},
{'name': 'Adi Gallia',
'height': '184',
'mass': '50',
'hair_color': 'none',
'skin_color': 'dark',
'eye_color': 'blue',
'birth_year': 'unknown',
'gender': 'female',
'homeworld': 'https://swapi.info/api/planets/9',
'films': ['https://swapi.info/api/films/4',
'https://swapi.info/api/films/6'],
'species': ['https://swapi.info/api/species/23'],
'vehicles': [],
'starships': [],
'created': '2014-12-20T10:29:11.661000Z',
'edited': '2014-12-20T21:17:50.432000Z',
'url': 'https://swapi.info/api/people/55'},
{'name': 'Saesee Tiin',
'height': '188',
'mass': 'unknown',
'hair_color': 'none',
'skin_color': 'pale',
'eye_color': 'orange',
'birth_year': 'unknown',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/47',
'films': ['https://swapi.info/api/films/4',
'https://swapi.info/api/films/6'],
'species': ['https://swapi.info/api/species/24'],
'vehicles': [],
'starships': [],
'created': '2014-12-20T10:32:11.669000Z',
'edited': '2014-12-20T21:17:50.434000Z',
'url': 'https://swapi.info/api/people/56'},
{'name': 'Yarael Poof',
'height': '264',
'mass': 'unknown',
'hair_color': 'none',
'skin_color': 'white',
'eye_color': 'yellow',
'birth_year': 'unknown',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/48',
'films': ['https://swapi.info/api/films/4'],
'species': ['https://swapi.info/api/species/25'],
'vehicles': [],
'starships': [],
'created': '2014-12-20T10:34:48.725000Z',
'edited': '2014-12-20T21:17:50.437000Z',
'url': 'https://swapi.info/api/people/57'},
{'name': 'Plo Koon',
'height': '188',
'mass': '80',
'hair_color': 'none',
'skin_color': 'orange',
'eye_color': 'black',
'birth_year': '22BBY',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/49',
'films': ['https://swapi.info/api/films/4',
'https://swapi.info/api/films/5',
'https://swapi.info/api/films/6'],
'species': ['https://swapi.info/api/species/26'],
'vehicles': [],
'starships': ['https://swapi.info/api/starships/48'],
'created': '2014-12-20T10:49:19.859000Z',
'edited': '2014-12-20T21:17:50.439000Z',
'url': 'https://swapi.info/api/people/58'},
{'name': 'Mas Amedda',
'height': '196',
'mass': 'unknown',
'hair_color': 'none',
'skin_color': 'blue',
'eye_color': 'blue',
'birth_year': 'unknown',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/50',
'films': ['https://swapi.info/api/films/4',
'https://swapi.info/api/films/5'],
'species': ['https://swapi.info/api/species/27'],
'vehicles': [],
'starships': [],
'created': '2014-12-20T10:53:26.457000Z',
'edited': '2014-12-20T21:17:50.442000Z',
'url': 'https://swapi.info/api/people/59'},
{'name': 'Gregar Typho',
'height': '185',
'mass': '85',
'hair_color': 'black',
'skin_color': 'dark',
'eye_color': 'brown',
'birth_year': 'unknown',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/8',
'films': ['https://swapi.info/api/films/5'],
'species': [],
'vehicles': [],
'starships': ['https://swapi.info/api/starships/39'],
'created': '2014-12-20T11:10:10.381000Z',
'edited': '2014-12-20T21:17:50.445000Z',
'url': 'https://swapi.info/api/people/60'},
{'name': 'Cordé',
'height': '157',
'mass': 'unknown',
'hair_color': 'brown',
'skin_color': 'light',
'eye_color': 'brown',
'birth_year': 'unknown',
'gender': 'female',
'homeworld': 'https://swapi.info/api/planets/8',
'films': ['https://swapi.info/api/films/5'],
'species': [],
'vehicles': [],
'starships': [],
'created': '2014-12-20T11:11:39.630000Z',
'edited': '2014-12-20T21:17:50.449000Z',
'url': 'https://swapi.info/api/people/61'},
{'name': 'Cliegg Lars',
'height': '183',
'mass': 'unknown',
'hair_color': 'brown',
'skin_color': 'fair',
'eye_color': 'blue',
'birth_year': '82BBY',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/1',
'films': ['https://swapi.info/api/films/5'],
'species': [],
'vehicles': [],
'starships': [],
'created': '2014-12-20T15:59:03.958000Z',
'edited': '2014-12-20T21:17:50.451000Z',
'url': 'https://swapi.info/api/people/62'},
{'name': 'Poggle the Lesser',
'height': '183',
'mass': '80',
'hair_color': 'none',
'skin_color': 'green',
'eye_color': 'yellow',
'birth_year': 'unknown',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/11',
'films': ['https://swapi.info/api/films/5',
'https://swapi.info/api/films/6'],
'species': ['https://swapi.info/api/species/28'],
'vehicles': [],
'starships': [],
'created': '2014-12-20T16:40:43.977000Z',
'edited': '2014-12-20T21:17:50.453000Z',
'url': 'https://swapi.info/api/people/63'},
{'name': 'Luminara Unduli',
'height': '170',
'mass': '56.2',
'hair_color': 'black',
'skin_color': 'yellow',
'eye_color': 'blue',
'birth_year': '58BBY',
'gender': 'female',
'homeworld': 'https://swapi.info/api/planets/51',
'films': ['https://swapi.info/api/films/5',
'https://swapi.info/api/films/6'],
'species': ['https://swapi.info/api/species/29'],
'vehicles': [],
'starships': [],
'created': '2014-12-20T16:45:53.668000Z',
'edited': '2014-12-20T21:17:50.455000Z',
'url': 'https://swapi.info/api/people/64'},
{'name': 'Barriss Offee',
'height': '166',
'mass': '50',
'hair_color': 'black',
'skin_color': 'yellow',
'eye_color': 'blue',
'birth_year': '40BBY',
'gender': 'female',
'homeworld': 'https://swapi.info/api/planets/51',
'films': ['https://swapi.info/api/films/5'],
'species': ['https://swapi.info/api/species/29'],
'vehicles': [],
'starships': [],
'created': '2014-12-20T16:46:40.440000Z',
'edited': '2014-12-20T21:17:50.457000Z',
'url': 'https://swapi.info/api/people/65'},
{'name': 'Dormé',
'height': '165',
'mass': 'unknown',
'hair_color': 'brown',
'skin_color': 'light',
'eye_color': 'brown',
'birth_year': 'unknown',
'gender': 'female',
'homeworld': 'https://swapi.info/api/planets/8',
'films': ['https://swapi.info/api/films/5'],
'species': ['https://swapi.info/api/species/1'],
'vehicles': [],
'starships': [],
'created': '2014-12-20T16:49:14.640000Z',
'edited': '2014-12-20T21:17:50.460000Z',
'url': 'https://swapi.info/api/people/66'},
{'name': 'Dooku',
'height': '193',
'mass': '80',
'hair_color': 'white',
'skin_color': 'fair',
'eye_color': 'brown',
'birth_year': '102BBY',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/52',
'films': ['https://swapi.info/api/films/5',
'https://swapi.info/api/films/6'],
'species': ['https://swapi.info/api/species/1'],
'vehicles': ['https://swapi.info/api/vehicles/55'],
'starships': [],
'created': '2014-12-20T16:52:14.726000Z',
'edited': '2014-12-20T21:17:50.462000Z',
'url': 'https://swapi.info/api/people/67'},
{'name': 'Bail Prestor Organa',
'height': '191',
'mass': 'unknown',
'hair_color': 'black',
'skin_color': 'tan',
'eye_color': 'brown',
'birth_year': '67BBY',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/2',
'films': ['https://swapi.info/api/films/5',
'https://swapi.info/api/films/6'],
'species': ['https://swapi.info/api/species/1'],
'vehicles': [],
'starships': [],
'created': '2014-12-20T16:53:08.575000Z',
'edited': '2014-12-20T21:17:50.463000Z',
'url': 'https://swapi.info/api/people/68'},
{'name': 'Jango Fett',
'height': '183',
'mass': '79',
'hair_color': 'black',
'skin_color': 'tan',
'eye_color': 'brown',
'birth_year': '66BBY',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/53',
'films': ['https://swapi.info/api/films/5'],
'species': [],
'vehicles': [],
'starships': [],
'created': '2014-12-20T16:54:41.620000Z',
'edited': '2014-12-20T21:17:50.465000Z',
'url': 'https://swapi.info/api/people/69'},
{'name': 'Zam Wesell',
'height': '168',
'mass': '55',
'hair_color': 'blonde',
'skin_color': 'fair, green, yellow',
'eye_color': 'yellow',
'birth_year': 'unknown',
'gender': 'female',
'homeworld': 'https://swapi.info/api/planets/54',
'films': ['https://swapi.info/api/films/5'],
'species': ['https://swapi.info/api/species/30'],
'vehicles': ['https://swapi.info/api/vehicles/45'],
'starships': [],
'created': '2014-12-20T16:57:44.471000Z',
'edited': '2014-12-20T21:17:50.468000Z',
'url': 'https://swapi.info/api/people/70'},
{'name': 'Dexter Jettster',
'height': '198',
'mass': '102',
'hair_color': 'none',
'skin_color': 'brown',
'eye_color': 'yellow',
'birth_year': 'unknown',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/55',
'films': ['https://swapi.info/api/films/5'],
'species': ['https://swapi.info/api/species/31'],
'vehicles': [],
'starships': [],
'created': '2014-12-20T17:28:27.248000Z',
'edited': '2014-12-20T21:17:50.470000Z',
'url': 'https://swapi.info/api/people/71'},
{'name': 'Lama Su',
'height': '229',
'mass': '88',
'hair_color': 'none',
'skin_color': 'grey',
'eye_color': 'black',
'birth_year': 'unknown',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/10',
'films': ['https://swapi.info/api/films/5'],
'species': ['https://swapi.info/api/species/32'],
'vehicles': [],
'starships': [],
'created': '2014-12-20T17:30:50.416000Z',
'edited': '2014-12-20T21:17:50.473000Z',
'url': 'https://swapi.info/api/people/72'},
{'name': 'Taun We',
'height': '213',
'mass': 'unknown',
'hair_color': 'none',
'skin_color': 'grey',
'eye_color': 'black',
'birth_year': 'unknown',
'gender': 'female',
'homeworld': 'https://swapi.info/api/planets/10',
'films': ['https://swapi.info/api/films/5'],
'species': ['https://swapi.info/api/species/32'],
'vehicles': [],
'starships': [],
'created': '2014-12-20T17:31:21.195000Z',
'edited': '2014-12-20T21:17:50.474000Z',
'url': 'https://swapi.info/api/people/73'},
{'name': 'Jocasta Nu',
'height': '167',
'mass': 'unknown',
'hair_color': 'white',
'skin_color': 'fair',
'eye_color': 'blue',
'birth_year': 'unknown',
'gender': 'female',
'homeworld': 'https://swapi.info/api/planets/9',
'films': ['https://swapi.info/api/films/5'],
'species': ['https://swapi.info/api/species/1'],
'vehicles': [],
'starships': [],
'created': '2014-12-20T17:32:51.996000Z',
'edited': '2014-12-20T21:17:50.476000Z',
'url': 'https://swapi.info/api/people/74'},
{'name': 'R4-P17',
'height': '96',
'mass': 'unknown',
'hair_color': 'none',
'skin_color': 'silver, red',
'eye_color': 'red, blue',
'birth_year': 'unknown',
'gender': 'female',
'homeworld': 'https://swapi.info/api/planets/28',
'films': ['https://swapi.info/api/films/5',
'https://swapi.info/api/films/6'],
'species': [],
'vehicles': [],
'starships': [],
'created': '2014-12-20T17:43:36.409000Z',
'edited': '2014-12-20T21:17:50.478000Z',
'url': 'https://swapi.info/api/people/75'},
{'name': 'Wat Tambor',
'height': '193',
'mass': '48',
'hair_color': 'none',
'skin_color': 'green, grey',
'eye_color': 'unknown',
'birth_year': 'unknown',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/56',
'films': ['https://swapi.info/api/films/5'],
'species': ['https://swapi.info/api/species/33'],
'vehicles': [],
'starships': [],
'created': '2014-12-20T17:53:52.607000Z',
'edited': '2014-12-20T21:17:50.481000Z',
'url': 'https://swapi.info/api/people/76'},
{'name': 'San Hill',
'height': '191',
'mass': 'unknown',
'hair_color': 'none',
'skin_color': 'grey',
'eye_color': 'gold',
'birth_year': 'unknown',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/57',
'films': ['https://swapi.info/api/films/5'],
'species': ['https://swapi.info/api/species/34'],
'vehicles': [],
'starships': [],
'created': '2014-12-20T17:58:17.049000Z',
'edited': '2014-12-20T21:17:50.484000Z',
'url': 'https://swapi.info/api/people/77'},
{'name': 'Shaak Ti',
'height': '178',
'mass': '57',
'hair_color': 'none',
'skin_color': 'red, blue, white',
'eye_color': 'black',
'birth_year': 'unknown',
'gender': 'female',
'homeworld': 'https://swapi.info/api/planets/58',
'films': ['https://swapi.info/api/films/5',
'https://swapi.info/api/films/6'],
'species': ['https://swapi.info/api/species/35'],
'vehicles': [],
'starships': [],
'created': '2014-12-20T18:44:01.103000Z',
'edited': '2014-12-20T21:17:50.486000Z',
'url': 'https://swapi.info/api/people/78'},
{'name': 'Grievous',
'height': '216',
'mass': '159',
'hair_color': 'none',
'skin_color': 'brown, white',
'eye_color': 'green, yellow',
'birth_year': 'unknown',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/59',
'films': ['https://swapi.info/api/films/6'],
'species': ['https://swapi.info/api/species/36'],
'vehicles': ['https://swapi.info/api/vehicles/60'],
'starships': ['https://swapi.info/api/starships/74'],
'created': '2014-12-20T19:43:53.348000Z',
'edited': '2014-12-20T21:17:50.488000Z',
'url': 'https://swapi.info/api/people/79'},
{'name': 'Tarfful',
'height': '234',
'mass': '136',
'hair_color': 'brown',
'skin_color': 'brown',
'eye_color': 'blue',
'birth_year': 'unknown',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/14',
'films': ['https://swapi.info/api/films/6'],
'species': ['https://swapi.info/api/species/3'],
'vehicles': [],
'starships': [],
'created': '2014-12-20T19:46:34.209000Z',
'edited': '2014-12-20T21:17:50.491000Z',
'url': 'https://swapi.info/api/people/80'},
{'name': 'Raymus Antilles',
'height': '188',
'mass': '79',
'hair_color': 'brown',
'skin_color': 'light',
'eye_color': 'brown',
'birth_year': 'unknown',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/2',
'films': ['https://swapi.info/api/films/1',
'https://swapi.info/api/films/6'],
'species': [],
'vehicles': [],
'starships': [],
'created': '2014-12-20T19:49:35.583000Z',
'edited': '2014-12-20T21:17:50.493000Z',
'url': 'https://swapi.info/api/people/81'},
{'name': 'Sly Moore',
'height': '178',
'mass': '48',
'hair_color': 'none',
'skin_color': 'pale',
'eye_color': 'white',
'birth_year': 'unknown',
'gender': 'female',
'homeworld': 'https://swapi.info/api/planets/60',
'films': ['https://swapi.info/api/films/5',
'https://swapi.info/api/films/6'],
'species': [],
'vehicles': [],
'starships': [],
'created': '2014-12-20T20:18:37.619000Z',
'edited': '2014-12-20T21:17:50.496000Z',
'url': 'https://swapi.info/api/people/82'},
{'name': 'Tion Medon',
'height': '206',
'mass': '80',
'hair_color': 'none',
'skin_color': 'grey',
'eye_color': 'black',
'birth_year': 'unknown',
'gender': 'male',
'homeworld': 'https://swapi.info/api/planets/12',
'films': ['https://swapi.info/api/films/6'],
'species': ['https://swapi.info/api/species/37'],
'vehicles': [],
'starships': [],
'created': '2014-12-20T20:35:04.260000Z',
'edited': '2014-12-20T21:17:50.498000Z',
'url': 'https://swapi.info/api/people/83'}]
Let’s query the People attribute ID 1 by creating a variable
requests.get(people_url+"/1")<Response [200]>
first_person_url = "https://swapi.info/api/people/1"
requests.get(first_person_url)<Response [200]>
Let’s declare a second variable, called api_url_response:
first_person_response = requests.get(first_person_url)
first_person_info = first_person_response.json()JSON Format
JSON data is formatted in key-value pairs. If you refer to the JSON data, you’ll see that it’s actually a list of keys and their corresponding values. For example, there’s a “birth_year” key whose value is “19BBY” as well as an “eye_color” key whose value is “blue.”
We can refer to the JSON data by its key:
hair = first_person_info["hair_color"]
name = first_person_info["name"]
print(f"{name} \'s hair is: {hair}")Luke Skywalker 's hair is: blond
In the statement above, we are setting a new variable called hair. The variable is composed of the value of the hair_color key, as specified in the data you see in the previous cell.
We also set a variable called name, which is composed of the value of the name key. Then we tell the program to print those values
Exercise 2
Write some code that uses the API to tell us Luke Skywalker’s eye color.
eye_color = first_person_info["eye_color"]
print(f"{name}'s eye color is {eye_color}")Luke Skywalker's eye color is blue
Exercise 3
Let’s try a different attribute! Choose one from the documentation: swapi.info
Try choosing a specific endpoint associated with an attribute to create a full string.
films_url = "https://swapi.info/api/films"
films_response = requests.get(films_url)
films_response<Response [200]>
films--------------------------------------------------------------------------- NameError Traceback (most recent call last) Cell In[20], line 1 ----> 1 films NameError: name 'films' is not defined
films = films_response.json()
film_names = list()
for film in films:
title = film['title']
film_names.append(title)
print("The Star Wars films are:\n")
count = 0
for name in film_names:
count = count + 1
print(f"{count} {name}")The Star Wars films are:
1 A New Hope
2 The Empire Strikes Back
3 Return of the Jedi
4 The Phantom Menace
5 Attack of the Clones
6 Revenge of the Sith