Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
4 changes: 2 additions & 2 deletions .semaphore/semaphore.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ name: replit-py
agent:
machine:
type: e1-standard-2
os_image: ubuntu1804
os_image: ubuntu2004
blocks:
- name: Lint and test
run:
when: "change_in('/src')"
when: "change_in(['/src', '/pyproject.toml', '/tests'])"
task:
secrets:
- name: replit-database
Expand Down
16 changes: 15 additions & 1 deletion poetry.lock

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

1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ flake8-annotations = ">=2.3.0"
flake8-docstrings = ">=1.5.0"
mypy = ">=1.5.0"
coverage = ">=5.2.1"
types-requests = "^2.31.0.10"

[tool.poetry.group.docs.dependencies]
Sphinx = ">=7.0.1"
Expand Down
18 changes: 12 additions & 6 deletions src/replit/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,19 @@ def cli() -> None:
@click.argument("prefix")
def find_matches(prefix: str) -> None:
"""List all keys that match the given prefix."""
if database is None:
click.echo(
failure("Database connection not available. Ensure REPLIT_DB_URL is set!")
)
return

matches = list(database.prefix(prefix))

if matches:
click.echo(success(f"Matches found for '{prefix}':\n"))
click.echo(success(f"Matches found for {prefix!r}:\n"))
click.echo("\n".join(matches))
else:
click.echo(failure(f"No matches found for '{prefix}'"))
click.echo(failure(f"No matches found for {prefix!r}"))


@cli.command(name="set")
Expand All @@ -51,7 +57,7 @@ def find_matches(prefix: str) -> None:
def set_value(key: str, val: str) -> None:
"""Add a given key-value pair to the DB."""
database[key] = val
click.echo(success(f"DB[{key}] was successfully set to '{val}'"))
click.echo(success(f"DB[{key!r}] was successfully set to {val!r}"))


@cli.command(name="del")
Expand All @@ -61,10 +67,10 @@ def del_value(key: str) -> None:
try:
del database[key]
except KeyError:
click.echo(failure(f"The key '{key}' was not found in the DB."))
click.echo(failure(f"The key {key!r} was not found in the DB."))
else:
del database[key]
click.echo(success(f"db['{key}'] was successfully deleted."))
click.echo(success(f"db[{key!r}] was successfully deleted."))


@cli.command(name="nuke")
Expand Down Expand Up @@ -98,7 +104,7 @@ def list_all(file_path: str) -> None:

json.dump(binds, f)

click.echo(success(f"Output successfully dumped to '{file_path}'"))
click.echo(success(f"Output successfully dumped to {file_path!r}"))


if __name__ == "__main__":
Expand Down
9 changes: 4 additions & 5 deletions src/replit/database/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from collections import abc
import json
from typing import (
AbstractSet,
Any,
Callable,
Dict,
Expand All @@ -13,7 +12,7 @@
Tuple,
Union,
)
import urllib
import urllib.parse

import aiohttp
from aiohttp_retry import ExponentialRetry, RetryClient # type: ignore
Expand Down Expand Up @@ -597,7 +596,7 @@ def prefix(self, prefix: str) -> Tuple[str, ...]:
else:
return tuple(urllib.parse.unquote(k) for k in r.text.split("\n"))

def keys(self) -> AbstractSet[str]:
def keys(self) -> abc.KeysView[str]:
"""Returns all of the keys in the database.

Returns:
Expand All @@ -611,7 +610,7 @@ def keys(self) -> AbstractSet[str]:
# type db.keys() in an interactive prompt.

# TODO: Return a set from prefix since keys are guaranteed unique
return set(self.prefix(""))
return abc.KeysView(self)

def dumps(self, val: Any) -> str:
"""JSON encodes a value that can be a special DB object."""
Expand All @@ -623,7 +622,7 @@ def __repr__(self) -> str:
Returns:
A string representation of the database object.
"""
return f"<{self.__class__.__name__}(db_url={self.db_url!r})>"
return f"<{self.__class__.__name__}(db_url=...)>"

def close(self) -> None:
"""Closes the database client connection."""
Expand Down
1 change: 1 addition & 0 deletions tests/test_database.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ async def asyncTearDown(self) -> None:
"""Nuke whatever the test added."""
for k in await self.db.keys():
await self.db.delete(k)
await self.db.sess.close()

async def test_get_set_delete(self) -> None:
"""Test that we can get, set, and delete a key."""
Expand Down