Appning API Client Library for Python (Android Publisher, JWT Bearer)
Project description
Appning API Client Library for Python
License: Apache 2.0
The Appning API enables developers to interact with Appning services from their own systems (server-to-server). This client library is focused on Android Publisher with custom endpoints.
All Appning endpoints are authenticated using JWT Bearer tokens signed locally with RS256. This library is based on the Google API Python Client and is adapted for use with Appning services.
This library is an unofficial fork of Google’s
google-api-python-clientlibrary and is maintained independently by Appning. It is not an official Google product and is provided under the same Apache License 2.0 terms as the upstream project.
Requirements
Installation
pip
The preferred method is via pip. From the project root:
python3 -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
pip install -e .
Or install the published package:
pip install appning-api-python-client
This library relies on google-auth and google-auth-httplib2 for authentication and HTTP transport. They are installed automatically as dependencies.
Authentication (JWT Bearer)
Obtain API access credentials
Obtain API access credentials from the Developer Portal:
From there you can download a credentials file (e.g. serviceAccount.json) with this structure:
{
"kid": "the-key-id",
"privateKeyPem": "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n",
"clientId": "the-client-id"
}
privateKeyPemis private and must remain local (never sent to the server).kididentifies the key used to sign the JWT.clientIdidentifies the client and must be used as the JWTissandsubclaims.
JWT requirements
- Required claims: The JWT must include
issandsub, both set to the client’sclientId. - Token validity: The server only accepts tokens with a maximum validity of 15 minutes (
exp - iat <= 900seconds). The JWT must includeiatandexp(Unix epoch seconds). The library handles this when you useJwtBearerCredentialswith the credentials file.
For full details (clock skew, error responses), see Service Account Authentication.
Basic Usage Example
See samples/androidpublisher/example_custom_endpoint.py for a complete example.
import json
import os
import time
import google_auth_httplib2
import httplib2
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError
from googleapiclient.http import set_user_agent
from googleapiclient.jwt_bearer_credentials import JwtBearerCredentials
service_account_file = 'serviceAccount.json'
package_name = "com.example.app"
if not os.path.exists(service_account_file):
raise FileNotFoundError("serviceAccount.json not found. Obtain credentials from the developer portal.")
with open(service_account_file, 'r') as f:
data = json.load(f)
cred_kwargs = {'kid': data['kid'], 'private_key_pem': data['privateKeyPem']}
if data.get('clientId'):
cred_kwargs['client_id'] = data['clientId']
credentials = JwtBearerCredentials(**cred_kwargs)
custom_endpoint = 'https://product.faa.faurecia-aptoide.com/api/8.20200601/'
base_http = set_user_agent(httplib2.Http(timeout=30), 'appning-api-python-client/androidpublisher')
authorized_http = google_auth_httplib2.AuthorizedHttp(credentials, http=base_http)
service = build('androidpublisher', 'v3', http=authorized_http, client_options={'api_endpoint': custom_endpoint})
batch_request_body = {
"requests": [
{
"oneTimeProduct": {
"packageName": package_name,
"productId": f"coin_pack_etc_{int(time.time())}",
"listings": [
{
"languageCode": "pt-BR",
"title": "300 Moedas",
"description": "Receba 300 moedas instantaneamente"
},
{
"languageCode": "en-US",
"title": "300 Coins",
"description": "Receive 300 coins instantly"
}
],
"purchaseOptions": [
{
"purchaseOptionId": "default",
"buyOption": {
"legacyCompatible": True,
"multiQuantityEnabled": False
},
"regionalPricingAndAvailabilityConfigs": [
{
"regionCode": "US",
"price": {
"currencyCode": "USD",
"units": "1",
"nanos": 880000000
},
"availability": "AVAILABLE"
}
]
}
]
},
"updateMask": "listings,purchaseOptions",
"allowMissing": True,
"latencyTolerance": "PRODUCT_UPDATE_LATENCY_TOLERANCE_LATENCY_TOLERANT",
"regionsVersion": {
"version": "2025/03"
}
}
]
}
response = service.monetization().onetimeproducts().batchUpdate(
packageName=package_name, body=batch_request_body
).execute()
Available endpoints
| Service | Method | Description |
|---|---|---|
| Android Publisher | POST | Batch create/update one-time products (monetization): applications/{packageName}/oneTimeProducts:batchUpdate |
The base URL for the Appning product API is typically https://product.faa.faurecia-aptoide.com/api/8.20240517 (or the version your account uses). Set it via client_options={'api_endpoint': '...'} when building the service.
Examples
- Android Publisher batch update: samples/androidpublisher/example_custom_endpoint.py — JWT Bearer auth and batch updates of one-time products (monetization).
Testing
How to run tests
-
Use a virtual environment (recommended):
python3 -m venv .venv source .venv/bin/activate # Windows: .venv\Scripts\activate
-
Install the package in editable mode and test dependencies:
The test suite requires several dependencies (e.g.
pytest,parameterized,mox,webtest). Install them all with:pip install -e . pip install -r dev-requirements.txt
Without
dev-requirements.txt, collection may fail withModuleNotFoundError(e.g.No module named 'parameterized'). -
Run the test suite:
From the project root:
pytest tests/Or with Python module (if
pytestis not on your PATH):python -m pytest tests/
Optional: run with coverage:
pytest tests/ --cov=googleapiclient --cov-report=term-missing
-
Run the Android Publisher sample (manual/integration):
Requires a valid
serviceAccount.jsonin the project root (or path used by the sample). This calls a real or custom endpoint:cd samples/androidpublisher python example_custom_endpoint.py
What is tested
- Unit tests (
tests/) — Core client library (discovery, HTTP, auth, mocks). No live API calls. - Android Publisher sample — Manual verification against a real or custom endpoint; not run in CI unless configured with credentials.
Credential-related deprecation warnings from dependencies (e.g. credentials_file) are suppressed in tests. For Appning, obtain credentials from the Developer Portal (JWT Bearer / serviceAccount.json), not via Application Default Credentials or credentials_file.
Code style
flake8 googleapiclient/ tests/
autopep8 --in-place --recursive googleapiclient/ tests/
API responses and troubleshooting
- 200 OK — Request processed successfully.
- 400 Bad Request — Invalid payload or validation failure (missing required fields, invalid types).
- 401 Unauthorized — Authentication failure: missing or malformed
Authorizationheader, malformed JWT, invalid signature, unknown/revokedkid, expired token, or token validity > 15 minutes. Ensureissandsubequal yourclientId. - 403 Forbidden — Token valid but caller lacks permission for this operation; check permissions for your
clientIdat developers.appning.com. - 404 Not Found — Resource not found (e.g. package not available for monetization or not under your account).
See Service Account Authentication for more detail.
Documentation
The docs/ folder contains Getting Started, Installation, Service Account Authentication.
Contributing
See CONTRIBUTING.md. Pull requests are welcome.
Support
For issues with the library, open an issue in the project’s issue tracker with a minimal example and error details. For API-specific questions, refer to the relevant API documentation.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file appning_api_python_client-1.0.0.tar.gz.
File metadata
- Download URL: appning_api_python_client-1.0.0.tar.gz
- Upload date:
- Size: 14.2 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4f48ea155b1de89db117bb9cea580d6d3867451dfe24a45fc09eb4c57edc757c
|
|
| MD5 |
8f10c24da07194eecdd35b5a184d0d22
|
|
| BLAKE2b-256 |
ac7cb8e24b22861becbab111ef37613584ef3a23da08473bf61106bc75b63150
|
File details
Details for the file appning_api_python_client-1.0.0-py3-none-any.whl.
File metadata
- Download URL: appning_api_python_client-1.0.0-py3-none-any.whl
- Upload date:
- Size: 14.8 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ef7766baf0f2424e100b2c9211fbe31596d0c99b04ec99f9964df034d8cc97a8
|
|
| MD5 |
3b96e2e1ef8202ff92037d1f24fa17ec
|
|
| BLAKE2b-256 |
6554455a2c7ea71b42ff573356219e496f4a8f671abb56210cd8705b198b60cf
|