-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch '31-restructure-examples-folder' into 'dev'
Resolve "Restructure examples folder" Closes #31 See merge request objectbox/objectbox-python!19
- Loading branch information
Showing
9 changed files
with
427 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
# ObjectBox-Python Examples | ||
|
||
The following examples are available from this repository. | ||
|
||
## Application Example: Tasks | ||
|
||
This is our classic Tasks application using a CLI. | ||
|
||
``` | ||
cd example | ||
python -m tasks | ||
Welcome to the ObjectBox tasks-list app example. Type help or ? for a list of commands. | ||
> new buy oat | ||
> new buy yeast | ||
> new bake bread | ||
> ls | ||
ID Created Finished Text | ||
1 Mon Apr 22 11:02:27 2024 buy oat | ||
2 Mon Apr 22 11:02:30 2024 buy yeast | ||
3 Mon Apr 22 11:02:34 2024 bake bread | ||
> done 1 | ||
> done 2 | ||
> ls | ||
> ls | ||
ID Created Finished Text | ||
1 Mon Apr 22 11:02:27 2024 Mon Apr 22 11:03:02 2024 buy oat | ||
2 Mon Apr 22 11:02:30 2024 Mon Apr 22 11:03:18 2024 buy yeast | ||
3 Mon Apr 22 11:02:34 2024 bake bread | ||
> exit | ||
``` | ||
|
||
## Vector-Search Example: Cities | ||
|
||
This example application starts with a pre-defined set of capital cities and their geo coordinates. | ||
It allows to search for nearest neighbors of a city (`city_neighbors`) or by coordinates (`neighbors`) as well as adding more locations (`add`). | ||
|
||
``` | ||
python -m vectorsearch-cities | ||
Welcome to the ObjectBox vectorsearch-cities example. Type help or ? for a list of commands. | ||
> ls | ||
ID Name Latitude Longitude | ||
1 Abuja 9.08 7.40 | ||
2 Accra 5.60 -0.19 | ||
[..] | ||
212 Yerevan 40.19 44.52 | ||
213 Zagreb 45.81 15.98 | ||
> ls Ber | ||
ID Name Latitude Longitude | ||
28 Berlin 52.52 13.40 | ||
29 Bern 46.95 7.45 | ||
> city_neighbors Berlin | ||
ID Name Latitude Longitude Score | ||
147 Prague 50.08 14.44 7.04 | ||
49 Copenhagen 55.68 12.57 10.66 | ||
200 Vienna 48.21 16.37 27.41 | ||
34 Bratislava 48.15 17.11 32.82 | ||
89 Ljubljana 46.06 14.51 42.98 | ||
> neighbors 6,52.52,13.405 | ||
ID Name Latitude Longitude Score | ||
28 Berlin 52.52 13.40 0.00 | ||
147 Prague 50.08 14.44 7.04 | ||
49 Copenhagen 55.68 12.57 10.66 | ||
200 Vienna 48.21 16.37 27.41 | ||
34 Bratislava 48.15 17.11 32.82 | ||
89 Ljubljana 46.06 14.51 42.98 | ||
> add Area51, 37.23, -115.81 | ||
> city_neighbors Area51 | ||
ID Name Latitude Longitude Score | ||
107 Mexico City 19.43 -99.13 594.86 | ||
27 Belmopan 17.25 -88.76 1130.92 | ||
64 Guatemala City 14.63 -90.51 1150.79 | ||
164 San Salvador 13.69 -89.22 1261.12 | ||
67 Havana 23.11 -82.37 1317.73 | ||
``` |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
from cmd import Cmd | ||
import objectbox | ||
import time | ||
from .model import * | ||
import csv | ||
import os | ||
|
||
def list_cities(cities): | ||
print("{:3s} {:25s} {:>9s} {:>9s}".format("ID", "Name", "Latitude", "Longitude")) | ||
for city in cities: | ||
print("{:3d} {:25s} {:>9.2f} {:>9.2f}".format( | ||
city.id, city.name, city.location[0], city.location[1])) | ||
|
||
def list_cities_with_scores(city_score_tuples): | ||
print("{:3s} {:25s} {:>9s} {:>9s} {:>5s}".format("ID", "Name", "Latitude", "Longitude", "Score")) | ||
for (city,score) in city_score_tuples: | ||
print("{:3d} {:25s} {:>9.2f} {:>9.2f} {:>5.2f}".format( | ||
city.id, city.name, city.location[0], city.location[1], score)) | ||
|
||
class VectorSearchCitiesCmd(Cmd): | ||
prompt = "> " | ||
def __init__(self, *args): | ||
Cmd.__init__(self, *args) | ||
dbdir = "cities-db" | ||
new_db = not os.path.exists(dbdir) | ||
self._ob = objectbox.Builder().model(get_objectbox_model()).directory(dbdir).build() | ||
self._box = objectbox.Box(self._ob, City) | ||
self._name_prop: Property = City.get_property("name") | ||
self._location_prop: Property = City.get_property("location") | ||
if new_db: | ||
with open(os.path.join(os.path.dirname(__file__), 'cities.csv')) as f: | ||
r = csv.reader(f) | ||
cities = [] | ||
for row in r: | ||
city = City() | ||
city.name = row[0] | ||
city.location = [ row[1], row[2] ] | ||
cities.append(city) | ||
self._box.put(*cities) | ||
|
||
def do_ls(self, name: str = ""): | ||
"""list all cities or starting with <prefix>\nusage: ls [<prefix>]""" | ||
qb = self._box.query() | ||
qb.starts_with_string(self._name_prop, name) | ||
query = qb.build() | ||
list_cities(query.find()) | ||
|
||
def do_city_neighbors(self, args: str): | ||
"""find <num> (default: 5) next neighbors to city <name>\nusage: city_neighbors <name> [,<num>]""" | ||
try: | ||
args = args.split(',') | ||
if len(args) > 2: | ||
raise ValueError() | ||
city = args[0] | ||
if len(city) == 0: | ||
raise ValueError() | ||
num = 5 | ||
if len(args) == 2: | ||
num = int(args[1]) | ||
qb = self._box.query() | ||
qb.equals_string(self._name_prop, city) | ||
query = qb.build() | ||
cities = query.find() | ||
if len(cities) == 1: | ||
location = cities[0].location | ||
qb = self._box.query() | ||
qb.nearest_neighbors_f32(self._location_prop, location, num+1) # +1 for the city | ||
qb.not_equals_string(self._name_prop, city) | ||
neighbors = qb.build().find_with_scores() | ||
list_cities_with_scores(neighbors) | ||
else: | ||
print(f"no city found named '{city}'") | ||
except ValueError: | ||
print("usage: city_neighbors <name>[,<num: default 5>]") | ||
|
||
def do_neighbors(self, args): | ||
"""find <num> neighbors next to geo-coord <lat> <long>.\nusage: neighbors <num>,<latitude>,<longitude>""" | ||
try: | ||
args = args.split(',') | ||
if len(args) != 3: | ||
raise ValueError() | ||
num = int(args[0]) | ||
geocoord = [ float(args[1]), float(args[2]) ] | ||
qb = self._box.query() | ||
qb.nearest_neighbors_f32(self._location_prop, geocoord, num) | ||
neighbors = qb.build().find_with_scores() | ||
list_cities_with_scores(neighbors) | ||
except ValueError: | ||
print("usage: neighbors <num>,<latitude>,<longitude>") | ||
|
||
def do_add(self, args: str): | ||
"""add new location\nusage: add <name>,<lat>,<long>""" | ||
try: | ||
args = args.split(',') | ||
if len(args) != 3: | ||
raise ValueError() | ||
name = str(args[0]) | ||
lat = float(args[1]) | ||
long = float(args[2]) | ||
city = City() | ||
city.name = name | ||
city.location = [lat,long] | ||
self._box.put(city) | ||
except ValueError: | ||
print("usage: add <name>,<latitude>,<longitude>") | ||
|
||
def do_exit(self, _): | ||
"""close the program""" | ||
raise SystemExit() | ||
|
||
|
||
if __name__ == '__main__': | ||
app = VectorSearchCitiesCmd() | ||
app.cmdloop('Welcome to the ObjectBox vectorsearch-cities example. Type help or ? for a list of commands.') |
Oops, something went wrong.