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.
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
andscope
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.
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 theAPI
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.
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_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>')
-
static
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_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¶
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
-