Skip to content

Commit aa25b9d

Browse files
committed
added readme and setup.py
1 parent 14ec5ec commit aa25b9d

File tree

7 files changed

+87
-17
lines changed

7 files changed

+87
-17
lines changed

README.md

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Typesense-orm
2+
This is an ORM client for typesense-server. It is still under construction (now only write operations work)
3+
### Installation
4+
5+
### Description
6+
This client has aiohttp under the hood, but you can specify a mode (see example) and work in either a synchronized manner, or in an async mode.<br/>
7+
The ORM is based on pydantic here (actually models are inherited from pydantic base model with some methods overriden). (to be continued)

examples/basic_example.py

+2-6
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
1-
from typesense_orm.api_caller import ApiCallerAsync, Node, ApiCallerSync
2-
from typesense_orm.base_model import create_base_model
3-
from typesense_orm.field import Field
4-
from typesense_orm.types import int32
5-
from typesense_orm.higher_client import Client
1+
from typesense_orm import ApiCallerAsync, Node, ApiCallerSync, create_base_model, Field, int32, Client
62
from typing import List, get_args
73

84
node = Node(url="http://localhost:8108")
@@ -26,9 +22,9 @@ class Config:
2622

2723
book1 = Books(title="harry potter", year=2001)
2824
book2 = Books(title="hp 2", year=2002)
29-
# it = client.import_json(Books, [book1.json(exclude_unset=True), book2.json(exclude_unset=True)], schedule=True, name="import_task", action="upsert")
3025
it = client.import_objects([book1, book2])
3126
for i in it:
3227
print(i)
28+
print(Books.title)
3329

3430
client.close()

requirements.txt

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
aiohttp==3.8.1
2+
aiologger==0.6.1
3+
aiosignal==1.2.0
4+
async-timeout==4.0.2
5+
asyncstdlib==3.10.5
6+
attrs==21.4.0
7+
charset-normalizer==2.0.12
8+
frozenlist==1.3.0
9+
idna==3.3
10+
multidict==6.0.2
11+
mypy-extensions==0.4.3
12+
nest-asyncio==1.5.5
13+
pip==21.3.1
14+
pydantic==1.9.1
15+
setuptools==60.2.0
16+
typing-extensions==4.2.0
17+
typing-inspect==0.7.1
18+
wheel==0.37.1
19+
yarl==1.7.2

setup.py

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import typesense_orm
2+
from setuptools import setup, find_packages
3+
4+
5+
def parse_requirements(requirements):
6+
with open(requirements, "r") as req_file:
7+
return [line.strip('\n') for line in req_file if line.strip('\n')
8+
and not line.startswith('#')]
9+
10+
11+
requires = parse_requirements("requirements.txt")
12+
13+
with open('README.md') as f:
14+
long_description = f.read()
15+
16+
setup(
17+
name="typesense_orm",
18+
packages=find_packages(),
19+
version=typesense_orm.__version__,
20+
description="A typesense-server client using orm paradigm based on pydantic",
21+
long_description=long_description,
22+
long_description_content_type="text/markdown",
23+
author="Oleg Demianchenko",
24+
author_email="oleg.demianchenko@gmail.com",
25+
license="MIT",
26+
platforms="OS Independent",
27+
url="https://github.com/RedSnail/typesense_orm",
28+
python_requires='>=3.8',
29+
include_package_data=False,
30+
install_requires=requires
31+
)
32+

typesense_orm/__init__.py

+8
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
11
import nest_asyncio
2+
from .api_caller import Node, ApiCallerSync, ApiCallerAsync, ApiCaller
3+
from .higher_client import Client
4+
from .field import Field
5+
from .base_model import create_base_model
6+
from .types import int32, int64
27

38
nest_asyncio.apply()
9+
__version__ = "0.0.1"
10+
11+

typesense_orm/base_model.py

+13-6
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@ class ModelMetaclass(pydantic.main.ModelMetaclass):
1919
def to_schema(cls) -> Schema:
2020
field_dict = cls.__fields__.copy()
2121
field_dict.pop("id", None)
22-
fields = list(map(lambda field: FieldArgs(name=field.name,
23-
type=field.type_,
24-
index=field.field_info.extra.get("index", False),
25-
facet=field.field_info.extra.get("facet", False),
26-
optional=field.field_info.extra.get("optional", True)),
22+
fields = dict(map(lambda field: (field.name, FieldArgs(name=field.name,
23+
type=field.type_,
24+
index=field.field_info.extra.get("index", False),
25+
facet=field.field_info.extra.get("facet", False),
26+
optional=field.field_info.extra.get("optional", True))),
2727
field_dict.values()))
2828
schema = Schema(name=cls.schema_name,
2929
fields=fields,
@@ -33,6 +33,12 @@ def to_schema(cls) -> Schema:
3333

3434
return schema
3535

36+
def __getattr__(cls, item):
37+
res = cls.schema.fields.get(item, None)
38+
if res:
39+
return res
40+
super().__getattr__(item)
41+
3642
@property
3743
def endpoint_path(cls):
3844
return f"{COLLECTIONS_PATH}/{cls.schema_name}/{DOC_ENDPOINT}"
@@ -62,7 +68,8 @@ def __new__(mcs, name, bases, namespace, **kwargs):
6268
namespace.update({"__client__": client})
6369
break
6470

65-
client.create_collection(ret.to_schema())
71+
ret.schema = ret.to_schema()
72+
client.create_collection(ret.schema)
6673

6774
return ret
6875

typesense_orm/schema.py

+6-5
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,20 @@
55

66

77
def json_dumper(v, *, default):
8-
for field in v["fields"]:
8+
for field in v["fields"].values():
99
_, field_type = get_from_opt(field["type"])
1010
field["type"] = allowed_types[field_type]
1111

12+
v["fields"] = list(v["fields"].values())
1213
return json.dumps(v)
1314

1415

1516
def json_loader(js_string):
1617
js_dict = json.loads(js_string)
17-
fields = []
18+
fields = {}
1819
for field in js_dict["fields"]:
1920
field["type"] = allowed_types_rev[field["type"]]
20-
fields.append(FieldArgs(**field))
21+
fields.update({field["name"]: FieldArgs(**field)})
2122

2223
js_dict["fields"] = fields
2324
return js_dict
@@ -33,7 +34,7 @@ class FieldArgs(BaseModel):
3334

3435
class Schema(BaseModel):
3536
name: str
36-
fields: Sequence[FieldArgs]
37+
fields: Dict[str, FieldArgs]
3738
token_separators: Optional[Sequence[str]]
3839
symbols_to_index: Optional[Sequence[str]]
3940
default_sorting_field: Optional[str]
@@ -47,7 +48,7 @@ def from_dict(cls, dict_schema: Dict[str, Any]):
4748
field["type"] = allowed_types_rev[field["type"]]
4849
fields.append(FieldArgs(**field))
4950

50-
dict_schema["fields"] = fields
51+
dict_schema["fields"] = dict(map(lambda f: (f["name"], f), dict_schema["fields"]))
5152
return cls(**dict_schema)
5253

5354
class Config:

0 commit comments

Comments
 (0)