{"id":50913002,"url":"https://github.com/datacore-vietnam/datacore-python","last_synced_at":"2026-06-16T12:01:19.848Z","repository":{"id":355958364,"uuid":"1219618612","full_name":"DataCore-VietNam/datacore-python","owner":"DataCore-VietNam","description":"Official Python client for the DataCore Gateway API — access Vietnam capital-markets datasets with demo + paid modes.","archived":false,"fork":false,"pushed_at":"2026-05-30T06:27:38.000Z","size":457,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-30T23:05:06.263Z","etag":null,"topics":["data-api","datasets","finance","financial-data","jupyter-notebook","market-data","python","python-sdk","sdk","vietnam"],"latest_commit_sha":null,"homepage":"https://datacore.vn","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DataCore-VietNam.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-24T03:52:56.000Z","updated_at":"2026-05-30T06:27:42.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/DataCore-VietNam/datacore-python","commit_stats":null,"previous_names":["datacore-vietnam/datacore","datacore-vietnam/datacore-python"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/DataCore-VietNam/datacore-python","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DataCore-VietNam%2Fdatacore-python","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DataCore-VietNam%2Fdatacore-python/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DataCore-VietNam%2Fdatacore-python/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DataCore-VietNam%2Fdatacore-python/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DataCore-VietNam","download_url":"https://codeload.github.com/DataCore-VietNam/datacore-python/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DataCore-VietNam%2Fdatacore-python/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34404748,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-16T02:00:06.860Z","response_time":126,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["data-api","datasets","finance","financial-data","jupyter-notebook","market-data","python","python-sdk","sdk","vietnam"],"created_at":"2026-06-16T12:01:18.646Z","updated_at":"2026-06-16T12:01:19.835Z","avatar_url":"https://github.com/DataCore-VietNam.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# datacore-python\n\n[![PyPI version](https://img.shields.io/pypi/v/datacore.svg)](https://pypi.org/project/datacore/)\n[![Python versions](https://img.shields.io/pypi/pyversions/datacore.svg)](https://pypi.org/project/datacore/)\n[![CI](https://github.com/DataCore-VietNam/datacore-python/actions/workflows/ci.yml/badge.svg)](https://github.com/DataCore-VietNam/datacore-python/actions/workflows/ci.yml)\n[![License: MIT](https://img.shields.io/pypi/l/datacore.svg)](https://github.com/DataCore-VietNam/datacore-python/blob/main/LICENSE)\n\nPython client library for the Datacore API — supports two access modes:\n\n- **Demo**: Preview datasets without an API key\n- **Paid**: Full access with an API key\n\n\n\n## Installation\n\nFrom PyPI:\n\n```bash\npip install datacore                # core (pandas-only)\npip install \"datacore[polars]\"      # also installs polars\npip install \"datacore[all]\"         # all optional extras\n```\n\nOr with `uv`:\n\n```bash\nuv add datacore\nuv add \"datacore[polars]\"\n```\n\nFrom GitHub directly:\n\n```bash\npip install git+https://github.com/DataCore-VietNam/datacore-python.git\npip install \"datacore[polars] @ git+https://github.com/DataCore-VietNam/datacore-python.git\"\n```\n\nFor contributors only (you do **not** need this to use the library — the\ncommands above are all an end user needs):\n\n```bash\ngit clone https://github.com/DataCore-VietNam/datacore-python.git\ncd datacore-python\npip install -e \".[dev]\"\n```\n\n## Configuration (`.env`, optional)\n\nCreate a `.env` file in your working directory (see `.env.example`):\n\n```env\nX_API_KEY=your-api-key-here\n```\n\n\u003e **Never commit your real API key.** `.env` is git-ignored. Use `.env.example` as a template.\n\n---\n\n## Usage\n\n### 1. Initialize the client\n\n```python\nfrom datacore import Datacore\n\n# Demo mode (no API key required)\nclient = Datacore()\n\n# Paid mode — pass the key explicitly...\nclient = Datacore(api_key=\"your-api-key\")\n\n# ...or rely on X_API_KEY from .env / environment\nclient = Datacore()\n\n# Enable request/response debug logging\nclient = Datacore(api_key=\"your-api-key\", debug=True)\n```\n\n---\n\n### 2. Preview a dataset (Demo mode)\n\nPreview data without an API key.\n\n```python\n# All columns\ndf = client.preview(\"dataset_historical_price\")\nprint(df.head())\n\n# Filter specific columns\ndf = client.preview(\"dataset_historical_price\", columns=[\"symbol\", \"date\", \"close_price\"])\nprint(df.head())\n```\n\n---\n\n### 3. Fetch data (Paid mode)\n\n```python\n# All columns — returns {\"data\": DataFrame, \"info\": str}\nresult = client.get_data(\"dataset_historical_price\")\nprint(result[\"data\"].head())\nprint(result[\"info\"])\n# num: 3760607, totalPage: 37607, currentPage: 1, queried_rows: 100\n\n# Filter specific columns\nresult = client.get_data(\n    \"dataset_historical_price\",\n    columns=[\"symbol\", \"date\", \"close_price\"],\n)\nprint(result[\"data\"].head())\n```\n\nFull parameters:\n\n```python\nresult = client.get_data(\n    dataset_code=\"dataset_historical_price\",\n    columns=[\"symbol\", \"date\", \"close_price\"],   # client-side column filter (optional)\n    conditions=None,         # EXPERIMENTAL server-side row filter -- see note below\n    select_fields=None,      # server-side field selection (optional)\n    page=1,\n    limit=100,               # max 100 server-side (HTTP 400 if higher)\n    return_type=\"dataframe\", # \"dataframe\" | \"polars\" | \"json\" | \"dict\"\n    include_info=True,       # True: returns {\"data\": ..., \"info\": ...} | False: data only\n)\n```\n\n\u003e **Page size**: the gateway currently caps `limit` at **100** rows per\n\u003e request. Passing a larger value returns `HTTP 400: Invalid request content`.\n\u003e For larger downloads, paginate with `download_data` or `paginate`.\n\n\u003e ⚠️ **`conditions` is experimental.** The server-side `conditions` row\n\u003e filter is forwarded to the gateway verbatim, but the accepted JSON shape\n\u003e is not yet finalised — every shape tried so far is rejected by\n\u003e `gateway.datacore.vn/data/ds/search` with `HTTP 400`. **Do not rely on\n\u003e `conditions` in production yet.** Until the gateway schema is confirmed,\n\u003e fetch unfiltered data and filter the returned DataFrame client-side. This\n\u003e parameter may change in a future release.\n\nA convenience wrapper that returns the DataFrame directly (no info dict):\n\n```python\ndf = client.get_dataframe(\"dataset_historical_price\", limit=100)\n```\n\n---\n\n### 3b. Polars output (optional)\n\nIf you installed with `pip install \"datacore[polars]\"`, you can ask for a\n[polars](https://pola.rs/) `DataFrame` instead of pandas:\n\n```python\n# Via return_type\nresult = client.get_data(\n    \"dataset_historical_price\",\n    columns=[\"symbol\", \"date\", \"close_price\"],\n    limit=100,\n    return_type=\"polars\",\n)\nprint(type(result[\"data\"]))     # \u003cclass 'polars.DataFrame'\u003e\nprint(result[\"data\"].head())\n\n# Convenience method (no info dict, just the polars frame)\ndf_pl = client.get_polars(\"dataset_historical_price\", limit=100)\n\n# Preview supports polars too\ndf_pl = client.preview(\"dataset_historical_price\", return_type=\"polars\")\n```\n\nPandas is the default for backwards compatibility; polars is purely opt-in.\nThe same `columns=` filter works for both backends.\n\n---\n\n### 4. Iterate all pages (Paid mode)\n\n```python\nfor page_df in client.paginate(\"dataset_historical_price\", limit=100, max_pages=5):\n    print(page_df.shape)\n```\n\n---\n\n### 5. Download data to file\n\n```python\n# Download all pages of a small dataset (76 pages, ~7.5k rows)\ndownload_result = client.download_data(\n    dataset_code=\"gross_domestic_product_dataset_ds\",\n    output_path=\"data.csv\",\n    file_format=\"csv\",     # \"csv\" or \"json\"\n    start_page=1,\n    end_page=None,         # None = download until the last page\n    limit=100,             # max per-request page size (see note above)\n    show_progress=True,\n)\nprint(download_result)\n# {\"output_path\": \"data.csv\", \"pages_downloaded\": 76, \"rows_downloaded\": 7551, ...}\n\n# `dataset_historical_price` is large (~3.7M rows / 37k pages at limit=100);\n# expect it to take a long time and a lot of network.\n\n# Download only first 3 pages, filtered to specific columns (CSV only)\ndownload_result = client.download_data(\n    dataset_code=\"dataset_historical_price\",\n    columns=[\"symbol\", \"date\", \"close_price\"],\n    output_path=\"data_page1_3.csv\",\n    file_format=\"csv\",\n    start_page=1,\n    end_page=3,\n    show_progress=True,\n)\n```\n\n\u003e `columns` filtering only applies to `file_format=\"csv\"`. JSON output preserves the full raw API response.\n\n---\n\n## Method Summary\n\n| Method | Description | Requires API key |\n|---|---|---|\n| `preview(dataset_code, columns, return_type)` | Preview a dataset (pandas or polars) | No |\n| `preview_raw(dataset_code)` | Preview a dataset, raw dict response | No |\n| `get_data(dataset_code, ...)` | Fetch data, returns `{\"data\", \"info\"}` by default | Yes |\n| `get_dataframe(dataset_code, ...)` | Fetch data, returns pandas DataFrame directly | Yes |\n| `get_polars(dataset_code, ...)` | Fetch data, returns polars DataFrame directly *(needs `[polars]` extra)* | Yes |\n| `get_data_info(dataset_code, ...)` | Get dataset metadata summary | Yes |\n| `paginate(dataset_code, ...)` | Generator yielding one pandas DataFrame per page | Yes |\n| `download_data(dataset_code, output_path, ...)` | Download data to CSV/JSON file | Yes |\n| `set_api_key(api_key)` | Set / replace the API key on an existing client | — |\n| `is_authenticated()` | Returns `True` if an API key is configured | — |\n\n---\n\n## Error Handling\n\n| Error | Cause | Solution |\n|---|---|---|\n| `AuthenticationError` | Missing or invalid API key (HTTP 401 or `httpCode:401` in body) | Pass `api_key=` or set `X_API_KEY` in `.env` |\n| `PermissionDeniedError` | No access to dataset (HTTP 403) | Check your subscription plan |\n| `APIRequestError` | Server error, invalid request, or unknown dataset | Check `dataset_code` and `conditions` |\n| `ValueError` | Bad argument (e.g. unknown column, `page \u003c 1`, bad `file_format`) | Check the error message |\n\nAll exceptions inherit from `DatacoreError`, so you can catch them generically:\n\n```python\nfrom datacore import Datacore, DatacoreError\n\ntry:\n    client.get_data(\"dataset_historical_price\")\nexcept DatacoreError as e:\n    print(f\"Datacore call failed: {e}\")\n```\n\n---\n\n## License\n\nMIT — see [LICENSE](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdatacore-vietnam%2Fdatacore-python","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdatacore-vietnam%2Fdatacore-python","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdatacore-vietnam%2Fdatacore-python/lists"}