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.
Metadata
Release files for appning-api-python-client 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| appning_api_python_client-1.0.0.tar.gz | 14.2 MB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| appning_api_python_client-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 29.0 MB
Release files / appning_api_python_client-1.0.0.tar.gz
| Download URL | appning_api_python_client-1.0.0.tar.gz |
|---|---|
| Size | 14.2 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
4f48ea155b1de89db117bb9cea580d6d3867451dfe24a45fc09eb4c57edc757c
|
|
BLAKE2b-256 checksum How to use checksums |
ac7cb8e24b22861becbab111ef37613584ef3a23da08473bf61106bc75b63150
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.1
|
Release files / appning_api_python_client-1.0.0-py3-none-any.whl
| Download URL | appning_api_python_client-1.0.0-py3-none-any.whl |
|---|---|
| Size | 14.8 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ef7766baf0f2424e100b2c9211fbe31596d0c99b04ec99f9964df034d8cc97a8
|
|
BLAKE2b-256 checksum How to use checksums |
6554455a2c7ea71b42ff573356219e496f4a8f671abb56210cd8705b198b60cf
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.1
|
Security for appning-api-python-client 1.0.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.