Managing Projects
Retrieve a project or enumerate projects
Initialize a usable remote client before calling flyte.remote.Project; both project operations call ensure_client() and require an endpoint or API key.
import flyte
from flyte.remote import Project
flyte.init(endpoint="dns:///flyte.example.com", api_key="<api-key>")
project = Project.get("my-project")
print(project.pb2.name)
for project in Project.listall():
print(project.pb2.name)
Project is the public remote project entity. It is defined in remote/_project.py as a dataclass containing one field, pb2, a flyteidl.admin.project_pb2.Project message. The public import is from flyte.remote import Project, as used by the SDK's get project CLI command.
Retrieve one project
Pass the project value to Project.get:
from flyte.remote import Project
project = Project.get("my-project")
Project.get(name, org=None) obtains get_client().project_domain_service, builds a project_pb2.ProjectGetRequest with id=name, awaits GetProject, and wraps the returned protobuf as Project. The org parameter is accepted by the method but is not included in the request; the org=org line is currently commented out in remote/_project.py.
The method is wrapped with syncify. The direct call above is the synchronous form. In an asynchronous application, use its .aio() form:
import flyte
from flyte.remote import Project
async def show_project() -> Project:
await flyte.init.aio(endpoint="dns:///flyte.example.com", api_key="<api-key>")
return await Project.get.aio("my-project")
The returned wrapper keeps the generated message in project.pb2, so the available fields and enum values come from the installed FlyteIDL version.
List projects
Project.listall() returns an iterator rather than a materialized list. Iterate it directly:
from flyte.remote import Project
for project in Project.listall():
print(project.pb2.name, project.pb2.id)
The SDK's CLI uses the same two paths: get project NAME calls pretty_repr(Project.get(name)), while get project without a name passes Project.listall() to its configured formatter.
You can pass a filter string and a (field, order) sort tuple:
from flyte.remote import Project
projects = Project.listall(
filters="state = ACTIVE",
sort_by=("created_at", "desc"),
)
for project in projects:
print(project.pb2.name)
listall maps "asc" to common_pb2.Sort.ASCENDING and "desc" to common_pb2.Sort.DESCENDING. If sort_by is omitted, it uses ("created_at", "asc"). The wrapper passes filters directly to project_pb2.ProjectListRequest; it does not parse or validate the filter expression. The annotation specifies the order as exactly "asc" or "desc", but the implementation treats any value other than "asc" as descending.
Each request uses a limit of 100. The method starts with no continuation token, sends ListProjects, yields every protobuf project in resp.projects as Project(p), then repeats with resp.token. Iteration ends when the response token is empty. Consume the iterator lazily so that all pages can be fetched as needed.
As with get, listing supports the asynchronous syncify form:
from flyte.remote import Project
async def print_projects() -> None:
async for project in Project.listall.aio(sort_by=("name", "asc")):
print(project.pb2.name)
Inspect and serialize the result
Because Project inherits ToJSONMixin, a retrieved or listed wrapper can be serialized with to_dict() or to_json():
from flyte.remote import Project
project = Project.get("my-project")
project_dict = project.to_dict()
project_json = project.to_json()
Rich rendering is provided by Project.__rich_repr__(). It exposes name, id, description, the symbolic protobuf project state, and labels formatted as key: value pairs. When the protobuf has no labels field, the labels value rendered by this method is None.
from flyte.remote import Project
from rich import print
print(Project.get("my-project"))
Understand the service integration
Applications do not instantiate ProjectDomainService to use Project. ClientSet.project_domain_service returns the client's Admin stub and types that property as ProjectDomainService:
@property
def project_domain_service(self) -> ProjectDomainService:
return self._admin_client
remote._client._protocols.ProjectDomainService is a Protocol describing the Admin project/domain RPC surface. Its project retrieval methods are:
class ProjectDomainService(Protocol):
async def GetProject(
self, request: project_pb2.ProjectGetRequest
) -> project_pb2.Project: ...
async def ListProjects(
self, request: project_pb2.ProjectListRequest
) -> project_pb2.Projects: ...
The protocol also declares registration and update operations, domain discovery, and project/domain attribute operations. The Project wrapper currently uses only GetProject and ListProjects; the remaining RPCs are part of the lower-level typed service contract, not additional methods on Project.
Troubleshooting and current limitations
- Client initialization errors: Call
flyte.init(...)with a validendpointorapi_keybeforeProject.getorProject.listall. Calling either method without an initialized client reachesensure_client()and raises the SDK's initialization error. - Organization selection:
Project.get("my-project", org="my-org")acceptsorg, butremote/_project.pydoes not send it. The project list request likewise has its organization field commented out. Do not use the argument as evidence that organization filtering is active. - Filters: The wrapper forwards
filtersunchanged toProjectListRequest; filter grammar is therefore handled by the backend rather than byProject.listall. - Iteration:
listallperforms paginated RPCs internally with a page limit of 100. Treat its result as an iterator and do not assume that calling it creates a complete in-memory list. - Project context: Although
flyte.initacceptsproject,domain, andorg, the project get/list implementation does not use those initialized values when constructing its requests.