{"id":24,"library":"grabfood-api-sdk-python","title":"GrabFood Partner API Python SDK","description":"Official Python SDK for the GrabFood Partner API — enables food delivery merchants and platform partners in Southeast Asia to manage orders, store hours, menus, and campaigns programmatically. Auto-generated from Grab's OpenAPI spec using OpenAPITools PythonClientCodegen. IMPORTANT: This SDK covers GrabFood only (merchant/food delivery). Grab rides/mobility has no official Python SDK. The SDK is not published on PyPI — install via GitHub only.","status":"active","version":"latest (no versioned releases — install from main branch)","language":"python","source_language":"en","source_url":"https://github.com/grab/grabfood-api-sdk-python","tags":["grab","grabfood","southeast-asia","sea","food-delivery","partner-api","singapore","indonesia","thailand","payments","merchant-api"],"install":[{"cmd":"pip install git+https://github.com/grab/grabfood-api-sdk-python.git","lang":"bash","label":"Install from GitHub (only available install method — not on PyPI)"}],"dependencies":[{"reason":"Required. Used for HTTP transport.","package":"urllib3","optional":false},{"reason":"Required. Used for date/time parsing in API responses.","package":"python-dateutil","optional":false},{"reason":"Required. Request and response models.","package":"pydantic","optional":false}],"imports":[{"note":"'grab' on PyPI is a completely unrelated web scraping framework (lorien/grab). pip install grab installs the wrong package entirely.","wrong":"import grab","symbol":"grabfood","correct":"import grabfood"}],"quickstart":{"code":"import grabfood\nfrom grabfood.configs.config import STG_ENV, PRD_ENV, STG_AUTH_ENV, PRD_AUTH_ENV\nfrom grabfood.rest import ApiException\n\n# Step 1: Get OAuth token (client credentials flow)\n# Credentials obtained from Grab Developer Portal\nCLIENT_ID = 'your_client_id'\nCLIENT_SECRET = 'your_client_secret'\n\n# Auth configuration — use STG_AUTH_ENV for staging, PRD_AUTH_ENV for production\nauth_config = grabfood.Configuration(host=STG_AUTH_ENV)\n\nwith grabfood.ApiClient(auth_config) as auth_client:\n    auth_api = grabfood.GetOauthGrabApi(auth_client)\n    oauth_request = grabfood.GrabOauthRequest(\n        client_id=CLIENT_ID,\n        client_secret=CLIENT_SECRET,\n        grant_type='client_credentials',\n        scope='food.partner_api'\n    )\n    token_response = auth_api.get_oauth_grab('application/json', oauth_request)\n    ACCESS_TOKEN = 'Bearer ' + token_response.access_token\n    # Store token_response.expires_in to know when to refresh\n\n# Step 2: Use token against GrabFood API\n# IMPORTANT: Default host is STG_ENV (sandbox). Switch to PRD_ENV for production.\nconfiguration = grabfood.Configuration(host=PRD_ENV)  # or STG_ENV for testing\n\nMERCHANT_ID = 'your_merchant_id'\n\nwith grabfood.ApiClient(configuration) as api_client:\n    # Get store hours\n    store_api = grabfood.GetStoreHourApi(api_client)\n    try:\n        response = store_api.get_store_hour(\n            authorization=ACCESS_TOKEN,\n            merchant_id=MERCHANT_ID\n        )\n        print(response)\n    except ApiException as e:\n        print(f'API error: {e}')\n\n    # Accept an order\n    order_api = grabfood.AcceptRejectOrderApi(api_client)\n    try:\n        order_api.accept_reject_order(\n            authorization=ACCESS_TOKEN,\n            content_type='application/json',\n            accept_order_request=grabfood.AcceptOrderRequest()\n        )\n    except ApiException as e:\n        print(f'Order error: {e}')","lang":"python","description":"Authentication is a two-step process: obtain an OAuth token from the auth endpoint, then use it as a Bearer token against the GrabFood partner API. The token must be refreshed manually using the expires_in value from the token response — the SDK does not handle token refresh automatically."},"warnings":[{"fix":"Apply for partner access at developer.grab.com before starting integration.","message":"GrabFood Partner API access requires a signed partnership agreement with Grab. It is not self-serve — you must apply via the Grab Developer Portal and be approved as a merchant or technology partner. Without approval, API credentials are not issued.","severity":"breaking","affected_versions":"all"},{"fix":"Install only via GitHub: pip install git+https://github.com/grab/grabfood-api-sdk-python.git","message":"'grab' on PyPI is a completely unrelated Python web scraping framework (github.com/lorien/grab). pip install grab installs the wrong package. The GrabFood SDK is not on PyPI at all.","severity":"gotcha","affected_versions":"all"},{"fix":"Always explicitly set host=PRD_ENV in production: grabfood.Configuration(host=PRD_ENV). Import PRD_ENV from grabfood.configs.config.","message":"The SDK default host is STG_ENV (sandbox/staging). Forgetting to switch to PRD_ENV means all production calls hit the sandbox silently — no error is thrown.","severity":"gotcha","affected_versions":"all"},{"fix":"Implement token refresh logic using expires_in: store the token issue time, check expiry before each request, and re-authenticate when expired.","message":"OAuth tokens are not auto-refreshed. The SDK returns expires_in in the token response but does not implement token refresh logic. In long-running services, tokens expire and API calls begin returning 401 errors.","severity":"gotcha","affected_versions":"all"},{"fix":"For non-GrabFood Grab APIs, use direct HTTP requests against the Grab Partner API with manual OAuth handling.","message":"This SDK covers GrabFood (food delivery merchant API) only. There is no official Python SDK for Grab rides, GrabPay, or GrabExpress. Attempting to call non-GrabFood endpoints with this SDK will fail.","severity":"gotcha","affected_versions":"all"},{"fix":"Verify merchant country scope with Grab during onboarding. Staging environment covers all markets.","message":"SDK is auto-generated from OpenAPI spec (PythonClientCodegen). The SDK is geographically scoped — GrabFood operates in Singapore, Malaysia, Indonesia, Thailand, Vietnam, Philippines, Cambodia, and Myanmar. Merchant IDs and API behavior may vary by country.","severity":"gotcha","affected_versions":"all"}],"env_vars":null,"last_verified":"2026-05-12T04:41:13.350Z","next_check":"2026-05-28T00:00:00.000Z","problems":[{"fix":"Install the SDK directly from GitHub using `pip install git+https://github.com/grab/grabfood-api-sdk-python.git`. Ensure your import statement is `import grabfood`.","cause":"The Python SDK was not installed correctly from its GitHub repository, or the `import` statement uses an incorrect package name.","error":"ModuleNotFoundError: No module named 'grabfood'"},{"fix":"Obtain a fresh and valid OAuth access token through the GrabFood Partner API's OAuth flow and include it in your API requests with the `Authorization: Bearer <your_access_token>` header.","cause":"The API request was made without a valid or correctly formatted OAuth bearer token in the `Authorization` header, or the token has expired.","error":"Unauthorized. The access token is invalid."},{"fix":"Inspect the `ApiException` object's attributes (e.g., `e.status`, `e.reason`, `e.body`) to retrieve detailed error messages from the GrabFood API, then correct your API call's parameters or payload.","cause":"A general API call failure occurred, often due to invalid request parameters, incorrect data format, or missing required fields in the API request body.","error":"grabfood.rest.ApiException: (400) Bad Request"}],"ecosystem":"pypi","meta_description":null,"install_score":0,"install_tag":"stale","quickstart_score":0,"quickstart_tag":"stale","pypi_latest":null,"install_checks":{"last_tested":"2026-05-12","tag":"stale","tag_description":"widespread failures or data too old to trust","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null}]},"quickstart_checks":{"last_tested":"2026-05-11","tag":"stale","tag_description":"widespread failures or data too old to trust","results":[{"runtime":"python:3.10-alpine","exit_code":1},{"runtime":"python:3.10-slim","exit_code":1},{"runtime":"python:3.11-alpine","exit_code":1},{"runtime":"python:3.11-slim","exit_code":1},{"runtime":"python:3.12-alpine","exit_code":1},{"runtime":"python:3.12-slim","exit_code":1},{"runtime":"python:3.13-alpine","exit_code":1},{"runtime":"python:3.13-slim","exit_code":1},{"runtime":"python:3.9-alpine","exit_code":1},{"runtime":"python:3.9-slim","exit_code":1}]}}