# Gwenlake Atlas > Documentation of Gwenlake Atlas, the platform that gets AI projects to production: Python SDK, transforms, inference and REST API. ## Docs - [Introduction](/atlas/index): Build on Gwenlake Atlas: catalog, transforms, inference and training, from Python or over HTTP. - [Quickstart](/atlas/quickstart): Install the library, authenticate and run your first query. - [Authentication](/atlas/authentication): API keys, credential profiles and OAuth2 clients. - [Command line](/atlas/cli): The gwenlake command: every Atlas resource from the terminal, and the gwenlake-train command. - [Core concepts](/atlas/concepts/overview): The resources of the Gwenlake catalog and how they relate. - [Handles and identifiers](/atlas/concepts/handles): Typed ids, slugs and the handle that names a resource everywhere. - [Lineage, builds and branches](/atlas/concepts/lineage): How the platform knows what feeds what, and runs it. - [Roles, scopes and API keys](/atlas/concepts/permissions): Who may do what, and how an API key narrows it. - [Organizations](/atlas/guides/organizations): The root of everything: storage, git, members, API keys, plan and usage. - [Projects](/atlas/guides/projects): List, create and update projects. - [Datasets](/atlas/guides/datasets): Tables and files: create, read, write, inspect and empty datasets. - [Mediasets](/atlas/guides/mediasets): Stores of documents, images, audio or video, where a document pipeline starts. - [Connections](/atlas/guides/connections): Read the files behind a datasource the platform holds the credentials of. - [Data branches](/atlas/guides/branches): Write somewhere else than the trunk, check the result, then promote it. - [Ontologies](/atlas/guides/ontologies): A typed model of the objects, links and actions of your domain, bound to your datasets and served as JSON-LD. - [Repositories](/atlas/guides/repositories): The git repositories that hold your transforms, trainings, SQL files and agents. - [Queries](/atlas/guides/queries): SQL on your datasets: run a statement, or keep a query on the platform and have it produce a dataset. - [Transforms](/atlas/guides/transforms): Write dataset-to-dataset transformations as decorated Python functions. - [Syncs](/atlas/guides/syncs): Copy what a connection holds into a dataset or a mediaset, on demand or on a schedule. - [Workflows](/atlas/guides/workflows): Chain transforms through the lineage, schedule them, test a change on a branch, promote it. - [Schedules](/atlas/guides/schedules): Run builds, maintenance or flows on a cron, in your time zone. - [Builds](/atlas/guides/build-environment): What happens when the platform runs your code: the environment, the identity, the settings, the logs. - [Training](/atlas/guides/training): Train a model from datasets: a short fit in a transform, or a long training on the GPU pool. - [Running](/atlas/guides/running): Load a trained model in a transform and score a dataset with it. - [MLflow](/atlas/guides/mlflow): Track trainings with MLflow on the platform's tracking server: parameters, metrics, checkpoints, resumable runs. - [Chat](/atlas/guides/chat): Call the chat models served by Gwenlake, with or without streaming. - [Embeddings](/atlas/guides/embeddings): Turn texts into vectors. - [Rerank](/atlas/guides/rerank): Order documents by relevance to a query. - [Agents](/atlas/guides/agents): Define an agent as a file in your repository, give it your data as tools, and talk to it over sessions. - [Skills](/atlas/guides/skills): Instructions an agent loads when a task calls for them: a SKILL.md file, versioned in a project. - [MCP servers](/atlas/guides/mcp): Give an agent the tools of a remote MCP server, with the credential kept encrypted on the platform. - [Telemetry](/atlas/guides/telemetry): Every agent turn is traced with OpenTelemetry: the model calls, the tool calls, the tokens, filed under your project. - [Client configuration](/atlas/guides/configuration): Base URL, timeouts, retries and environment variables. - [Async client](/atlas/guides/async): Use the library with asyncio. - [Errors](/atlas/guides/errors): What the library raises and what the API answers. - [Changelog](/atlas/changelog): What changed in the platform and the Python library. - [REST API](/atlas/api-reference/introduction): Call the Gwenlake API directly over HTTP. - [List models](/atlas/api-reference/endpoints/get-models): The inference models available to the caller: chat, embedding and rerank models. Use an `id` as the `model` of the other inference endpoints. - [Create a chat completion](/atlas/api-reference/endpoints/post-chat-completions): OpenAI-compatible chat completion, run by the v2 inference service as the caller. The body is relayed as-is (`stream: true` streams the SSE frames back). - [Create embeddings](/atlas/api-reference/endpoints/post-embeddings): OpenAI-compatible embeddings, run by the v2 inference service as the caller. - [Rerank documents](/atlas/api-reference/endpoints/post-rerank): Reranking, run by the v2 inference service as the caller. - [List models](/atlas/api-reference/inference/list-models): The inference models available to the caller: chat, embedding and rerank models. Use an `id` as the `model` of the other inference endpoints. - [Create a chat completion](/atlas/api-reference/inference/create-a-chat-completion): OpenAI-compatible chat completion, run by the v2 inference service as the caller. The body is relayed as-is (`stream: true` streams the SSE frames back). - [Create embeddings](/atlas/api-reference/inference/create-embeddings): OpenAI-compatible embeddings, run by the v2 inference service as the caller. - [Rerank documents](/atlas/api-reference/inference/rerank-documents): Reranking, run by the v2 inference service as the caller. - [List projects](/atlas/api-reference/projects/list-projects) - [Create a project](/atlas/api-reference/projects/create-a-project) - [Get a project](/atlas/api-reference/projects/get-a-project) - [Delete a project](/atlas/api-reference/projects/delete-a-project) - [Update a project](/atlas/api-reference/projects/update-a-project) - [List a project's datasets](/atlas/api-reference/projects/list-a-projects-datasets) - [List a project's connections](/atlas/api-reference/projects/list-a-projects-connections) - [List datasets](/atlas/api-reference/datasets/list-datasets) - [Create a dataset](/atlas/api-reference/datasets/create-a-dataset) - [Get a dataset](/atlas/api-reference/datasets/get-a-dataset) - [Delete a dataset](/atlas/api-reference/datasets/delete-a-dataset) - [Update a dataset](/atlas/api-reference/datasets/update-a-dataset) - [Get a dataset summary](/atlas/api-reference/datasets/get-a-dataset-summary) - [Empty a dataset](/atlas/api-reference/datasets/empty-a-dataset): Remove all content from a dataset while keeping the dataset resource: every file under its prefix (files datasets) or every row of its Iceberg table on `branch` (iceberg datasets). On a files overlay branch, the branch's diff is cleared and trunk's files are tombstoned — trunk itself is untouched. Used before a SNAPSHOT reload; the same clearing an `import-table`/`import-file` SNAPSHOT performs internally. - [List data branches](/atlas/api-reference/datasets/list-data-branches): List a dataset's data branches: Iceberg refs for an iceberg dataset, overlay branches (trunk included) for a files dataset. - [List files](/atlas/api-reference/files/list-files) - [Upload a file](/atlas/api-reference/files/upload-a-file) - [Upload a file into a subdirectory](/atlas/api-reference/files/upload-a-file-into-a-subdirectory) - [Download a file](/atlas/api-reference/files/download-a-file) - [Delete a file](/atlas/api-reference/files/delete-a-file) - [Create a presigned URL](/atlas/api-reference/files/create-a-presigned-url) - [Run a SQL statement](/atlas/api-reference/sql/run-a-sql-statement): Run a read-only statement. Without a LIMIT of its own, the result is capped (1000 rows unless `limit` says otherwise); a cut is reported — in the JSON body (`truncated`, `limit`) and, for every format, in the `X-Gwenlake-Truncated` / `X-Gwenlake-Row-Limit` headers — so a client reading a whole table can tell it must page. - [List connections](/atlas/api-reference/connections/list-connections): Connections the caller can see — identity only. No `configuration` on the rows: it lives in connection-service, keyed by id, and filling it in here would be one call per row. `type` is on each row, so a picker can still render what kind of datasource each one is; fetch the configuration from `GET /connections/{id}` when a form actually opens. - [Get a connection](/atlas/api-reference/connections/get-a-connection): One connection, with its configuration — credentials absent, always. - [List a connection's files](/atlas/api-reference/connections/list-a-connections-files): The files a connection holds — what a python transform declaring the connection as an input walks (`Connection(...).filesystem().ls()`), relayed from connection-service so no credential ever reaches project code. Every file source lists recursively; paths are relative to the connection's root. `connections:read` on the connection, like every other read of it. - [Read a connection's file](/atlas/api-reference/connections/read-a-connections-file): One file's bytes (`Connection(...).filesystem().open(path)`). Read-only: a connection is a source, never a destination — a transform writes into its output dataset. Streamed from connection-service as it arrives, so the pod holds a chunk at a time whatever the file's size. A source that fails part-way can only cut the body short — the status is sent — and the client sees a truncated transfer rather than a short file: a 200 is chunked, with no length, and a 206 declares its `Content-Length`. **Part of the file** with a standard `Range` header holding one range of bytes (`parse_range`): connection-service seeks where the connector can (`download_range`: smb, s3, gcs, azureblob) and the answer is a 206 with `Content-Range`, `Content-Length` and `Accept-Ranges` relayed — how a reader that needs the head of a 6.5 GB clip and the index at its end moves a few MB of it. A connector that cannot seek ignores the range and sends the whole file as a 200 (`Accept-Ranges: none`); the caller tells by the status. A range that starts at or past the end is a 416 whose `Content-Range: bytes */size` gives the size. A header this relay does not take — another unit, several ranges, a malformed one — is ignored, as RFC 9110 allows: the whole file, a 200. `bytes=-0` is a 416 with no size, no source being asked. - [List projects](/atlas/api-reference/endpoints/get-filesystem-projects) - [Create a project](/atlas/api-reference/endpoints/post-filesystem-projects) - [Get a project](/atlas/api-reference/endpoints/get-filesystem-projects-project-id) - [Update a project](/atlas/api-reference/endpoints/patch-filesystem-projects-project-id) - [Delete a project](/atlas/api-reference/endpoints/delete-filesystem-projects-project-id) - [List a project's datasets](/atlas/api-reference/endpoints/get-filesystem-projects-project-id-datasets) - [List a project's connections](/atlas/api-reference/endpoints/get-filesystem-projects-project-id-connections) - [List datasets](/atlas/api-reference/endpoints/get-datasets) - [Create a dataset](/atlas/api-reference/endpoints/post-datasets) - [Get a dataset](/atlas/api-reference/endpoints/get-datasets-dataset-id) - [Update a dataset](/atlas/api-reference/endpoints/patch-datasets-dataset-id) - [Delete a dataset](/atlas/api-reference/endpoints/delete-datasets-dataset-id) - [Get a dataset summary](/atlas/api-reference/endpoints/get-datasets-dataset-id-summary) - [Empty a dataset](/atlas/api-reference/endpoints/post-datasets-dataset-id-empty): Remove all content from a dataset while keeping the dataset resource: every file under its prefix (files datasets) or every row of its Iceberg table on `branch` (iceberg datasets). On a files overlay branch, the branch's diff is cleared and trunk's files are tombstoned — trunk itself is untouched. Used before a SNAPSHOT reload; the same clearing an `import-table`/`import-file` SNAPSHOT performs internally. - [List data branches](/atlas/api-reference/endpoints/get-datasets-dataset-id-branches): List a dataset's data branches: Iceberg refs for an iceberg dataset, overlay branches (trunk included) for a files dataset. - [List files](/atlas/api-reference/endpoints/get-datasets-dataset-id-files) - [Upload a file](/atlas/api-reference/endpoints/post-datasets-dataset-id-files) - [Upload a file into a subdirectory](/atlas/api-reference/endpoints/post-datasets-dataset-id-files-path) - [Download a file](/atlas/api-reference/endpoints/get-datasets-dataset-id-files-filepath) - [Delete a file](/atlas/api-reference/endpoints/delete-datasets-dataset-id-files-filepath) - [Create a presigned URL](/atlas/api-reference/endpoints/get-datasets-dataset-id-files-filepath-presigned-url) - [Run a SQL statement](/atlas/api-reference/endpoints/post-sql-statements): Run a read-only statement. Without a LIMIT of its own, the result is capped (1000 rows unless `limit` says otherwise); a cut is reported — in the JSON body (`truncated`, `limit`) and, for every format, in the `X-Gwenlake-Truncated` / `X-Gwenlake-Row-Limit` headers — so a client reading a whole table can tell it must page. - [List connections](/atlas/api-reference/endpoints/get-connections): Connections the caller can see — identity only. No `configuration` on the rows: it lives in connection-service, keyed by id, and filling it in here would be one call per row. `type` is on each row, so a picker can still render what kind of datasource each one is; fetch the configuration from `GET /connections/{id}` when a form actually opens. - [Get a connection](/atlas/api-reference/endpoints/get-connections-connection-id): One connection, with its configuration — credentials absent, always. - [List a connection's files](/atlas/api-reference/endpoints/get-connections-connection-id-files): The files a connection holds — what a python transform declaring the connection as an input walks (`Connection(...).filesystem().ls()`), relayed from connection-service so no credential ever reaches project code. Every file source lists recursively; paths are relative to the connection's root. `connections:read` on the connection, like every other read of it. - [Read a connection's file](/atlas/api-reference/endpoints/get-connections-connection-id-files-content): One file's bytes (`Connection(...).filesystem().open(path)`). Read-only: a connection is a source, never a destination — a transform writes into its output dataset. Streamed from connection-service as it arrives, so the pod holds a chunk at a time whatever the file's size. A source that fails part-way can only cut the body short — the status is sent — and the client sees a truncated transfer rather than a short file: a 200 is chunked, with no length, and a 206 declares its `Content-Length`. **Part of the file** with a standard `Range` header holding one range of bytes (`parse_range`): connection-service seeks where the connector can (`download_range`: smb, s3, gcs, azureblob) and the answer is a 206 with `Content-Range`, `Content-Length` and `Accept-Ranges` relayed — how a reader that needs the head of a 6.5 GB clip and the index at its end moves a few MB of it. A connector that cannot seek ignores the range and sends the whole file as a 200 (`Accept-Ranges: none`); the caller tells by the status. A range that starts at or past the end is a 416 whose `Content-Range: bytes */size` gives the size. A header this relay does not take — another unit, several ranges, a malformed one — is ignored, as RFC 9110 allows: the whole file, a 200. `bytes=-0` is a 416 with no size, no source being asked.