Skip to content

Commit

Permalink
Restructure project and add v0 of setup.py
Browse files Browse the repository at this point in the history
  • Loading branch information
AndyTitu committed Mar 12, 2024
1 parent 95398a1 commit a063dd6
Show file tree
Hide file tree
Showing 18 changed files with 186 additions and 97 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
run: |
pip install pytest &&
pip install pytest-asyncio &&
python -m pytest src/onepassword/*.py
python -m pytest onepassword/*.py
- name: Lint with Ruff
run: |
Expand Down
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.pytest_cache
.idea
*__pycache__
.dist
.onepassword.egg-info
8 changes: 8 additions & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions .idea/onepassword-sdk-python.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

52 changes: 52 additions & 0 deletions .idea/workspace.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions src/onepassword/example.py → example.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@

async def main():
# Your service account token here
token = os.environ("OP_SERVICE_ACCOUNT_TOKEN")
token = os.getenv("OP_SERVICE_ACCOUNT_TOKEN")

# Connect to 1Password
client = await Client.authenticate(auth=token, integration_name=DEFAULT_INTEGRATION_NAME, integration_version=DEFAULT_INTEGRATION_VERSION)

# Retrieve secret from 1Password
value = await client.secrets.resolve("op://Test Login/test_username")
value = await client.secrets.resolve("op://Russian Blue Vault/hers/department")
print(value)

if __name__ == '__main__':
Expand Down
File renamed without changes.
20 changes: 10 additions & 10 deletions src/onepassword/client.py → onepassword/client.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import sys
import platform
from src.onepassword.core import InitClient, ReleaseClient
from src.onepassword.secrets_api import Secrets
from onepassword.core import _init_client, _release_client
from onepassword.secrets_api import Secrets
import weakref

SDK_LANGUAGE = "Go"
SDK_LANGUAGE = "Python"
SDK_VERSION = "0010001" # v0.1.0
DEFAULT_INTEGRATION_NAME = "Unknown"
DEFAULT_INTEGRATION_VERSION = "Unknown"
DEFAULT_REQUEST_LIBRARY = "net/http"
DEFAULT_REQUEST_LIBRARY = "Reqwest"
DEFAULT_OS_VERSION = "0.0.0"


Expand All @@ -18,10 +18,10 @@ class Client:
@classmethod
async def authenticate(cls, auth, integration_name, integration_version):
self = cls()
self.config = new_default_config(auth=auth, integration_name=integration_name, integration_version=integration_version)
self.client_id = int(await InitClient(self.config))
self.secrets = Secrets(client_id=self.client_id)
self._finalizer = weakref.finalize(self, ReleaseClient, self.client_id)
config = new_default_config(auth=auth, integration_name=integration_name, integration_version=integration_version)
client_id = int(await _init_client(config))
self.secrets = Secrets(client_id)
self._finalizer = weakref.finalize(self, _release_client, client_id)

return self

Expand All @@ -35,8 +35,8 @@ def new_default_config(auth, integration_name, integration_version):
"integrationVersion": integration_version,
"requestLibraryName": DEFAULT_REQUEST_LIBRARY,
"requestLibraryVersion": str(sys.version_info[0]) + "." + str(sys.version_info[1]) + "." + str(sys.version_info[2]),
"os": platform.system(),
"os": platform.system().lower(),
"osVersion": DEFAULT_OS_VERSION,
"architecture": platform.architecture()[0],
"architecture": platform.machine(),
}
return client_config_dict
14 changes: 14 additions & 0 deletions onepassword/core.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import json
import onepassword.op_uniffi_core as core

# InitClient creates a client instance in the current core module and returns its unique ID.
async def _init_client(client_config):
return await core.init_client(json.dumps(client_config))

# Invoke calls specified business logic from core.
async def _invoke(invoke_config):
return await core.invoke(json.dumps(invoke_config))

# ReleaseClient releases memory in the core associated with the given client ID.
def _release_client(client_id):
return core.release_client(json.dumps(client_id))
File renamed without changes.
File renamed without changes.
File renamed without changes.
4 changes: 2 additions & 2 deletions src/onepassword/secrets_api.py → onepassword/secrets_api.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from src.onepassword.core import Invoke
from onepassword.core import _invoke

"""Secrets represents all operations the SDK client can perform on 1Password secrets."""
class Secrets:
Expand All @@ -7,7 +7,7 @@ def __init__(self, client_id):

"""resolve returns the secret the provided reference points to."""
async def resolve(self, reference):
response = await Invoke({
response = await _invoke({
"clientId": self.client_id,
"invocation": {
"name": "Resolve",
Expand Down
68 changes: 68 additions & 0 deletions onepassword/test_client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import sys
from onepassword.client import Client, new_default_config, DEFAULT_INTEGRATION_NAME, DEFAULT_INTEGRATION_VERSION, SDK_LANGUAGE, SDK_VERSION, DEFAULT_OS_VERSION, DEFAULT_REQUEST_LIBRARY
import os
import platform
import pytest

TOKEN = os.getenv('OP_SERVICE_ACCOUNT_TOKEN')

## test resolve function

# valid
@pytest.mark.asyncio
async def test_valid_resolve():
client = await Client.authenticate(auth=TOKEN, integration_name=DEFAULT_INTEGRATION_NAME, integration_version=DEFAULT_INTEGRATION_VERSION)
result = await client.secrets.resolve(reference="op://gowwbvgow7kxocrfmfvtwni6vi/6ydrn7ne6mwnqc2prsbqx4i4aq/password")
assert(result == "test_password_42")

# invalid
@pytest.mark.asyncio
async def test_invalid_resolve():
client = await Client.authenticate(auth=TOKEN, integration_name=DEFAULT_INTEGRATION_NAME, integration_version=DEFAULT_INTEGRATION_VERSION)
with pytest.raises(Exception, match="error resolving secret reference: secret reference is not prefixed with \"op://\""):
await client.secrets.resolve(reference="invalid_reference")

## test client constructor

# valid
@pytest.mark.asyncio
async def test_good_client_construction():
client = await Client.authenticate(auth=TOKEN, integration_name=DEFAULT_INTEGRATION_NAME, integration_version=DEFAULT_INTEGRATION_VERSION)
assert(client.config['serviceAccountToken'] == TOKEN)
assert(client.config['integrationName'] == DEFAULT_INTEGRATION_NAME)
assert(client.config['integrationVersion'] == DEFAULT_INTEGRATION_VERSION)

# invalid
@pytest.mark.asyncio
async def test_client_construction_no_auth():
with pytest.raises(Exception, match='invalid client configuration: encountered the following errors: service account token was not specified; service account token had invalid format'):
await Client.authenticate(auth="", integration_name=DEFAULT_INTEGRATION_NAME, integration_version=DEFAULT_INTEGRATION_VERSION)

# invalid
@pytest.mark.asyncio
async def test_client_construction_no_name():
with pytest.raises(Exception, match='invalid client configuration: encountered the following errors: integration name was not specified'):
await Client.authenticate(auth=TOKEN, integration_name="", integration_version=DEFAULT_INTEGRATION_VERSION)

# invalid
@pytest.mark.asyncio
async def test_client_construction_no_version():
with pytest.raises(Exception, match='invalid client configuration: encountered the following errors: integration version was not specified'):
await Client.authenticate(auth=TOKEN, integration_name=DEFAULT_INTEGRATION_NAME, integration_version="")

## test config function

# valid
def test_good_new_default_config():
config = new_default_config(auth=TOKEN, integration_name=DEFAULT_INTEGRATION_NAME, integration_version=DEFAULT_INTEGRATION_VERSION)

assert(config["serviceAccountToken"] == TOKEN)
assert(config["programmingLanguage"] == SDK_LANGUAGE)
assert(config["sdkVersion"] == SDK_VERSION)
assert(config["integrationName"] == DEFAULT_INTEGRATION_NAME)
assert(config["integrationVersion"] == DEFAULT_INTEGRATION_VERSION)
assert(config["requestLibraryName"] == DEFAULT_REQUEST_LIBRARY)
assert(config["requestLibraryVersion"] == str(sys.version_info[0]) + "." + str(sys.version_info[1]) + "." + str(sys.version_info[2]))
assert(config["os"] == platform.system().lower())
assert(config["osVersion"] == DEFAULT_OS_VERSION)
assert(config["architecture"] == platform.machine())
9 changes: 9 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from setuptools import setup, find_packages

setup(
name='onepassword',
version='0.1.0',
packages=find_packages(),
author='1Password',
url='https://github.com/1Password/onepassword-sdk-python',
)
14 changes: 0 additions & 14 deletions src/onepassword/core.py

This file was deleted.

68 changes: 0 additions & 68 deletions src/onepassword/test_client.py

This file was deleted.

0 comments on commit a063dd6

Please sign in to comment.