PyVK

PyVK is a Python client to VK API. It can be used in server or client applications, scripts, or interactively for data retrieval and analysis, social media integration, automation, and fun.

Features

  • Authorisation: PyVK assists both client- and server-side authorisation. It ensures that your password is not stored anywhere in plain-text. It also supports 2FA and captcha/mobile phone login confirmation.

  • Error handling: PyVK wraps API errors into exceptions and can recover from certain kinds of those, such as expired autorisation, temporal ban, or captcha request.

  • Pagination: PyVK can join paginated API responses into a single result.

  • Media upload: PyVK wraps it into a single method call and makes it easy to use those files as attachments in other API calls.

  • Python 2 and 3 : PyVK is tested for CPython 2.7 and 3.5-3.8

Example

>>> from pyvk import ClientAuth

>>> auth = ClientAuth(app_id=<...>, username=<...>)
>>> auth.auth()
Password: <...>
>>> api = auth.api(version='5.21', lang='en')

>>> # Call API methods
>>> api.users.get(user_ids=[210700286], fields=['bdate'])
[{'id': 210700286,
  'first_name': 'Lindsey',
  'last_name': 'Stirling',
  'bdate': '21.9.1986'}]

Authorisation

PyVK supports two types of authorisation:

  • Client-Side (so-called "Implicit") flow is suitable for interactive sessions and applications with a user interface. In this mode a user provides their login/password directly to PyVK:

  • Server-Side (so-called "Authorisation code") flow is intended for long-running server scripts, web-services, and other applications where there is no or limited user interaction.

Client-Side

class pyvk.ClientAuth(app_id=None, username=None[, **options])

Client-side auth object. In this mode a user provides their login/password directly to PyVK.

>>> auth = ClientAuth(app_id=<...>, username=<...>)
>>> auth.auth()
Password: <...>

The password is requested only once and not stored anywhere. PyVK remembers the access token and session cookies so that next time the authorisation will succeed immediately.

Apart from password PyVK may also request 2FA code, mobile number, and captcha depending on the situation and your profile settings. By default the input is read from stdin. One can also implement other ways of getting the input if the application is not supposed to have a shell session. Refer to input and User Input for more details.

Parameters
  • app_id – VK application identifier. Will be requested via an interactive session if not specified.

  • username – VK login (email, username, or mobile phone). Will be requested via an interactive session if not specified.

  • [options] – custom values for Global and ClientAuth configuration options. The latter ones are applied automatically to API objects spawned by api().

token

VK API token. Initialised only if authorisation is complete.

scope

Bitmask of access rights. Initialised only if authorisation is complete.

auth()

Starts authorisation. Initialises token and scope attributes if successful.

Raises

AuthError – if authorisation is unsuccessful.

api([**options])

Returns an API object if authorised.

Parameters

[options] – custom values for Global and API configuration options. The latter ones given to auth objects apply automatically.

Raises

AuthError – if not authorised

Returns

API object

Server-Side

In this mode a user should be redirected to VK login page:

>>> from pyvk import ServerAuth, p_photos, p_audio
>>> auth = ServerAuth(app_id=<...>,
                      redirect_uri='https://<example-server>/vkauth')
>>> auth.auth_url
'https://oauth.vk.com/authorize?client_id=[...]&response_type=code'

Once the user granted permissions to your application, VK API sends a unique code to the callback URL to complete the authorisation:

>>> # App Server
>>> # GET /vkauth?code=<...>
>>> auth = ServerAuth(<...>)  # (same as at the first step)
>>> auth.auth(
...     code=<...>,           # `code' from the query string
...     client_secret=<...>   # from VK application settings
... )
class pyvk.ServerAuth(app_id, redirect_uri[, **options])

Server-side auth helper. It is intended for long-running server scripts, web-services, and other applications where there is no or limited user interaction. See official VK documentation on Authorisation Code Flow for low-level details.

Intended workflow:

  • Redirect user to login page URL given by auth_url

  • If user confirms access for application, they will be redirected to redirect_uri

  • Pass code (from query string) and client_secret (from application settings) values to auth()

  • Authorisation is complete. Now you can put token into persistent storage and use it to create API objects if needed.

Parameters
  • app_id – VK application identifier.

  • redirect_uri – callback URL that is requested by VK API to send a secret code which is then used by the sever to request an access token.

  • [options] – custom values for Global and ServerAuth configuration options. The latter ones are applied automatically to API objects spawned by api().

token

VK API token. Initialised only if authorisation is complete.

scope

Bitmask of access rights. Ditto.

auth_url

URL for the first step of authorisation

auth(code, client_secret)

Completes authorisation with code and client_secret provided by VK via GET request to redirect_uri. Initialises token and scope attributes if successful.

Parameters
  • code – parameter from GET request sent to redirect_uri

  • client_secret – secret key from VK application settings

Raises

AuthError – if authorisation is unsuccessful.

api([**options])

Returns an API object if authorised.

Parameters

[options] – custom values for Global and API configuration options. The latter ones given to auth objects apply automatically.

Raises

AuthError – if not authorised

Returns

API object

Usage

VK API is accessible via API object. There are three ways to get one:

  • From an auth object. This is particulary handy for client applications:

    >>> auth = ClientAuth(app_id=<...>, username=<...>)
    >>> auth.auth()
    Password: <...>
    >>> api = auth.api()
    

    Keyword parameters given to api() will be passed to the API constructor. Global parameters will be inherited from the auth object (if not shadowed).

  • In server applications an auth object may not be around when it feels like an API call. In this case one can store an access token persistently and then use it create an API object manually:

    >>> auth = ServerAuth(<...>)
    >>> auth.auth(code=<...>, client_secret=<...>)
    >>> db['token'] = auth.token
    
    >>> # Elsewhere, elsewhen:
    >>> from pyvk import API
    >>> api = API(token=db['token'])
    
  • While it is not really common in practice, one can use a handful of API methods without an access token at all:

    >>> api = API()
    >>> api.users.getFollowers(user_id=1, count=1)
    {'count': 5985409, 'items': [354451485]}
    
class pyvk.API([token][, **parameters])
Parameters

token (str) – authorisation token. If None, only a small part of VK API methods is available.)

If you have obtained an API token elsewhere, you can use it directly:

>>> from pyvk import API
>>> api = API(token=<...>)

API Calls

Let’s call a couple of VK API methods:

>>> api.users.get(user_ids=[210700286], fields=['bdate'])
[{'bdate': '21.9.1986',
  'first_name': 'Lindsey',
  'id': 210700286,
  'last_name': 'Stirling'}]

Or, without fancy attribute-chaining:

>>> vk.call('account.getInfo')
{'2fa_required': 0,
 'country': 'RU',
 'https_required': 0,
 'intro': 0,
 'lang': 0,
 'no_wall_replies': 0,
 'own_posts_default': 0}

Note that pythonic integers and lists can be used where the official API documentation specifies numbers (including negative) and comma-separated lists.

Error Handling

VK API errors can be catched as exceptions:

>>> from pyvk.exceptions import APIError
>>> try:
...     api.docs.get()
... except APIError as exc:
...     print('Error %d: %s' % (exc.error_code, exc.error_msg))

Error 15: Access denied: no access to call this method

However, PyVK can handle some recoverable errors (“too many requests per second”, “captcha needed”, and the like) by its own:

>>> for i in range(1, 100000):
...     api.users.get(user_ids=[i])
...     print(i, end=' ')
...     sys.stdout.flush()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <...> pyvk.request INFO: Too many requests per second. Wait 0.3 sec and retry.
<...> pyvk.request INFO: Too many requests per second. Wait 0.6 sec and retry.
<...> pyvk.request INFO: Too many requests per second. Wait 1.2 sec and retry.
15 16 17 18 19 20 <...>

If that is not what you want, just make your request handler a bit dumber:

>>> api = auth.api(auto_delay=False, validation=False)

Or pass raw=True to work with JSON responses directly:

>>> api = auth.api(raw=True)
>>> api.docs.get()
{'error': {'error_code': 15, 'error_msg': 'Access denied: no access to call this method', <...>}}

Configuration

Access Rights

VK API requires an access control bitmask passed during authorisation. PyVK provides bitmasks for individual access rights as package-level constants. They can be combined by bitwise-or operator and passed into ClientAuth or ServerAuth with scope argument:

>>> from pyvk import p_audio, p_offline
>>> auth = ClientAuth(app_id=<...>, username=<...>,
                      scope=p_audio | p_offline)

There are also predefined p_all and p_basic. The latter is used by default in ClientAuth and combines access rights commonly used used in scripts and interactive sessions. ServerAuth defaults to p_offline.

pyvk.p_basic

Combines p_friends, p_photos, p_audio, p_video, p_status, p_messages, p_wall, p_groups, p_offline.

pyvk.p_all

Combines all the access rights.

pyvk.p_notify

User allowed to send notifications to they (for Flash/iFrame apps)

pyvk.p_friends

Access to friends.

pyvk.p_photos

Access to photos.

pyvk.p_audio

Access to audio.

pyvk.p_video

Access to video.

pyvk.p_pages

Access to wiki pages.

pyvk.p_leftmenu

Addition of link to the application in the left menu.

pyvk.p_status

Access to user status.

pyvk.p_notes

Access to notes.

pyvk.p_messages

Access to advanced methods for messaging. Unavailable for server-side authorisation.

pyvk.p_wall

Access to standard and advanced methods for the wall. Ignored for server-side authorisation.

pyvk.p_ads

Access to advanced methods for Ads API.

pyvk.p_offline

Access to API at any time (non-expiring access token).

pyvk.p_docs

Access to docs.

pyvk.p_groups

Access to user communities.

pyvk.p_notifications

Access to notifications about answers to the user.

pyvk.p_stats

Access to statistics of user groups and applications where they is an administrator.

pyvk.p_email

Access to user email.

pyvk.p_market

Access to market.

User Input

class pyvk.Input

Interface for requesting input from user via stdin. One can subclass and override ask() in order to implement other ways of providing the input.

static ask(field, **kwargs)

Read certain type of input from stdin with a relevant prompt.

Parameters

field (str) – type of input

Returns

input string

Raises

ValueError if incorrect arguments are passed

Additional keyword arguments are needed in some cases.

Possible inputs:

  • ask('app_id')

  • ask('username')

  • ask('password')

  • ask('secret_code')

  • ask('phone', msg='...')

  • ask('captcha', img='<image URL>')

Options

The following are configuration options and their default value used by ClientAuth, ServerAuth, and API. Global options apply to all the classes, the others are specific to certain class. One can customise them by passing corresponding keyword arguments when constructing the objects in question, for example:

>>> auth = ClientAuth(app_id=<...>, username=<...>, timeout=20.05,
                      version='5.0', disable_cache=True)

>>> auth = ServerAuth(app_id=<...>, username=<...>,
                      log_file='/logs/auth.log',
                      scope=p_groups | p_notes)

>>> api = API(token=<...>, scope=p_docs, lang='ru', max_attempts=10)

Global

class pyvk.config.GlobalConfig(**params)
log_format = '%(asctime)s %(name)s %(levelname)s: %(message)s'

log messages format compatible with logging module

log_level = 20

log messages level compatible with logging module

log_file = None

optional log file. If not set, standard output is used

input

alias of pyvk.utils.Input

timeout = 6.05

time for waiting for a network response

version = '5.60'

VK API version. See version history for more information.

ClientAuth

class pyvk.config.ClientAuthConfig(**params)
scope = 341022

bitmask for access rights requested from VK API

disable_cache = False

controls authorisation cache. If set, login and password will be requested every time ClientAuth is called

ServerAuth

class pyvk.config.ServerAuthConfig(**params)
scope = 65536

bitmaks for access rights requested from VK API

display = 'page'

sets authorisation page appearance. See VK documentation for more details

state = None

an arbitrary string that will be returned together with the authorisation result

API

class pyvk.config.APIConfig(**params)
lang = 'en'

language of VK API responses

validation = True

if set, captcha requests will be handled via an interactive session.

auto_delay = True

when encounter a request frequency limit add delays of increasing lenghts and repeat the request max_attempts times.

max_attempts = 5

how many times to repeat a failed request if the failure is configured to be handled

raw = False

return raw response objects (converted from JSON) instead of unpacking and error handling. If set, validation and auto_delay will be ignored

response_type

alias of builtins.dict