Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Design by wishful thinking for Connect SDK #16

Merged
merged 6 commits into from
Feb 14, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions src/posit/connect/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
## Posit Connect SDK

> Note: this is design-by-wishful-thinking, not how things actually work today.

nealrichardson marked this conversation as resolved.
Show resolved Hide resolved
To get started, import the Connect `Client` and create a connect. You can specify `endpoint` for your Connect server URL and your `api_key`; if not specified, they'll be pulled from the environment (`CONNECT_SERVER` and `CONNECT_API_KEY`).
tdstein marked this conversation as resolved.
Show resolved Hide resolved

```
from posit.connect import Client

con = Client()
```
Comment on lines +11 to +15
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
```
from posit.connect import Client
con = Client()
```
from posit.connect import create_client
with create_client() as client:
client...

This helps with resource management.

@contextmanager
def create_client(
    api_key: Optional[str] = None, endpoint: Optional[str] = None
) -> Generator[Client, None, None]:
    """Creates a new :class:`Client` instance

    Keyword Arguments:
        api_key -- an api_key for authentication (default: {None})
        endpoint -- a base api endpoint (url) (default: {None})

    Returns:
        A :class:`Client` instance
    """
    client = Client(api_key=api_key, endpoint=endpoint)
    try:
        yield client
    finally:
        del client

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What resource do you expect client to be holding onto?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently, it holds a requests.Session object, which has a close method.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there anything that needs to be cleaned up that won't be handled on exit?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just the requests.Session instance that needs to be released. Otherwise, the GC should handle most scenarios.


All of the general collections of entities can be referenced as properties of the Client object. Some collections belong to a single entity and are referenced from them similarly.

All collections have a `.find()` method that returns an iterable List-like object, and `.find_one()` methods that return a single entity.
nealrichardson marked this conversation as resolved.
Show resolved Hide resolved

Entities have methods that are appropriate to them. Fields in the entity bodies can be accessed as properties.

```
for st in con.content.find({"app_mode": "streamlit"}):
print(st.title)

my_app = con.content.find_one(guid="1234-5678-90ab-cdef")
for perm in my_app.permissions.find():
print(perm.role)
```

Entities have an `.update()` method that maps to a `PATCH` request. `.delete()` is `DELETE`.

```
my_app.update({"title": "Quarterly Analysis of Team Velocity"})
my_app.permissions.find_one(email="[email protected]").update({"role": "owner"})
my_app.permissions.find_one(email="[email protected]").delete()
```

Collections have a `.create()` method that maps to `POST` to create a new entity. It may be aliased to other verbs as appropriate for the entity.

```
my_app.permissions.add("[email protected]", "viewer")
```
Loading