Scope switching — with_scope and use_project¶
Two patterns for talking to a project / company other than the client's default.
with_scope — returns a copy¶
Snapshot the new scope into a separate client. The copy shares the authenticated session, so no re-login happens.
default = RtlsClient.from_env()
a = default.with_scope(project_uid="proj-a")
b = default.with_scope(project_uid="proj-b")
a.tags.list() # uses proj-a
b.tags.list() # uses proj-b
default.tags.list() # uses the env default — unchanged
with_scope returns a separate RtlsClient instance sharing the
underlying httpx.Client and _AuthState. The original isn't mutated.
Use with_scope when:
- You need both scopes alive at the same time (e.g. parallel work).
- You're servicing concurrent requests on different scopes.
- You want a guarantee that the original scope is preserved.
use_project / use_company — mutates in place¶
client = RtlsClient.from_env()
client.use_project("proj-b") # all subsequent calls use proj-b
client.tags.list()
use_* rebinds the client's default scope. Every sub-client and every
future call sees the new scope.
Thread-safety: use_* mutates shared state. Don't call it from
one thread while another thread is making requests on the same
client — for concurrent work use with_scope.
Resource sharing¶
Both forms preserve:
- The cached token (no re-login).
- The HTTP connection pool.
- The user identity (
X-User-Email).
Only the scope headers (X-User-Project, X-User-Subcontractor)
differ between scopes.
Cleanup¶
Only the original client owns the underlying pool. close() on a
with_scope copy is a no-op:
default = RtlsClient.from_env()
copy = default.with_scope(project_uid="proj-b")
copy.close() # no-op
default.close() # frees the pool, clears the token
Closing the original after copies are still in use is a bug — copies become unusable.