Compare commits

...

12 Commits

Author SHA1 Message Date
52307f6028 fix: fixed deprecation warning 2025-01-21 22:17:08 +01:00
8019b566f2 fix: added string method for base model 2025-01-21 22:16:07 +01:00
83726f517c feat: added stripe service 2025-01-21 22:12:03 +01:00
abe84bcfcb Merge pull request #22 from creyD/dev
Major Version 3.0.0
2025-01-21 12:15:43 +01:00
vikynoah
2d6de99585 fix: post_file method change for testing (#29)
* fix: post_file method change for testing

* changes
2025-01-16 09:35:23 +01:00
vikynoah
573f59349f fix: changes to post method in testing_async (#28) 2025-01-08 19:37:10 +01:00
creyD
32bf089456 Adjusted files for isort & autopep 2025-01-02 22:20:49 +00:00
vikynoah
d75fede3d1 fix: Force postgresql SSL mode (#27)
* fix: Force postgresql SSL mode

* changes
2025-01-02 23:20:17 +01:00
creyD
f8b781b3e7 Adjusted files for isort & autopep 2024-12-11 16:15:33 +00:00
vikynoah
93c7f6f6cb fix: Async Testing (#26)
* fix: httpx fix as per latest version

* fix: Fix Async Testing client
2024-12-11 17:14:59 +01:00
creyD
2e44453915 Adjusted files for isort & autopep 2024-12-09 15:29:15 +00:00
vikynoah
2a22471de9 fix: httpx fix as per latest version (#25) 2024-12-09 16:28:44 +01:00
12 changed files with 78 additions and 13 deletions

View File

@@ -5,7 +5,9 @@ from sqlalchemy.orm import sessionmaker
from .common import SQLALCHEMY_DATABASE_URL, name from .common import SQLALCHEMY_DATABASE_URL, name
async_engine = create_async_engine(SQLALCHEMY_DATABASE_URL + name, pool_pre_ping=True) async_engine = create_async_engine(
SQLALCHEMY_DATABASE_URL + name, pool_pre_ping=True, connect_args={"sslmode": "require"}
)
AsyncSessionLocal = sessionmaker( AsyncSessionLocal = sessionmaker(
bind=async_engine, bind=async_engine,

View File

@@ -6,7 +6,9 @@ from sqlalchemy.orm.session import Session
from .common import SQLALCHEMY_DATABASE_URL, name from .common import SQLALCHEMY_DATABASE_URL, name
engine = create_engine(SQLALCHEMY_DATABASE_URL + name, pool_pre_ping=True) engine = create_engine(
SQLALCHEMY_DATABASE_URL + name, pool_pre_ping=True, connect_args={"sslmode": "require"}
)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

View File

@@ -1,5 +1,5 @@
import uuid import uuid
from datetime import datetime from datetime import datetime, timezone
from sqlalchemy import Column, DateTime, String from sqlalchemy import Column, DateTime, String
from sqlalchemy.dialects.postgresql import UUID from sqlalchemy.dialects.postgresql import UUID
@@ -14,15 +14,30 @@ class Base:
# Primary key as uuid # Primary key as uuid
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
created_at = Column(DateTime(timezone=True), server_default=func.now()) created_at = Column(DateTime(timezone=True), server_default=func.now())
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) updated_at = Column(
DateTime(timezone=True),
default=lambda: datetime.now(timezone.utc),
onupdate=lambda: datetime.now(timezone.utc),
)
created_by_id = Column(String) created_by_id = Column(String)
__name__: str __name__: str
# TODO: Add default representation string
# TODO: Add automated foreign key resolution # TODO: Add automated foreign key resolution
# Generate __tablename__ automatically # Generate __tablename__ automatically
@declared_attr @declared_attr
def __tablename__(cls) -> str: def __tablename__(cls) -> str:
return cls.__name__.lower() return cls.__name__.lower()
def __str__(self) -> str:
# if the object has a name, title or similar attribute, return it
if hasattr(self, "name"):
return str(self.name) # type: ignore
# if the object has a title attribute, return it
if hasattr(self, "title"):
return str(self.title) # type: ignore
# otherwise return the object's id
return str(self.id)

View File

@@ -41,7 +41,7 @@ class GenericClient(TestClient):
re = self.c.post( re = self.c.post(
url, url,
files={"file": file}, files={"file": file},
headers=self.default_headers | {"Content-Type": "application/json"}, headers=self.default_headers,
*args, *args,
**kwargs, **kwargs,
) )

View File

@@ -1,11 +1,14 @@
import json import json
from httpx import AsyncClient
from httpx import ASGITransport, AsyncClient
class AsyncGenericClient: class AsyncGenericClient:
def __init__(self, app): def __init__(self, app, headers={}):
self.c = AsyncClient(app=app, base_url="http://testserver", follow_redirects=True) self.c = AsyncClient(
self.default_headers = {} transport=ASGITransport(app=app), base_url="http://testserver", follow_redirects=True
)
self.default_headers = headers
async def get(self, url: str, r_code: int = 200, parse_json=True): async def get(self, url: str, r_code: int = 200, parse_json=True):
re = await self.c.get(url, headers=self.default_headers) re = await self.c.get(url, headers=self.default_headers)
@@ -33,7 +36,8 @@ class AsyncGenericClient:
) )
if re.status_code != r_code: if re.status_code != r_code:
print(re.content) print(re.content)
assert r_code == re.status_code if not raw_response:
assert r_code == re.status_code
return re.json() if not raw_response else re return re.json() if not raw_response else re
async def post_file( async def post_file(
@@ -42,7 +46,7 @@ class AsyncGenericClient:
re = await self.c.post( re = await self.c.post(
url, url,
files={"file": file}, files={"file": file},
headers=self.default_headers | {"Content-Type": "application/json"}, headers=self.default_headers,
*args, *args,
**kwargs, **kwargs,
) )

View File

@@ -1 +1,2 @@
from .auth0 import * # noqa from .auth0 import * # noqa
from .stripe import * # noqa

View File

@@ -1,3 +1,4 @@
from .exceptions import * # noqa from .exceptions import * # noqa
from .manage import * # noqa from .manage import * # noqa
from .testing import * # noqa
from .utils import * # noqa from .utils import * # noqa

View File

@@ -0,0 +1 @@
from .testing import * # noqa

View File

@@ -0,0 +1,23 @@
class ItemReturn:
quantity = 1
class SubscriptionItem:
def retrieve(self, id: str = ""):
return ItemReturn
def modify(self, id: str, quantity: int):
return ItemReturn
class StripeAPI:
def __init__(self, key: str):
pass
@property
def SubscriptionItem(self):
return SubscriptionItem
def get_stripe_api():
return StripeAPI("test")

View File

@@ -0,0 +1,11 @@
import os
import stripe
from dotenv import load_dotenv
load_dotenv()
def get_stripe_api():
stripe.api_key = os.getenv("STRIPE_API_KEY", "")
return stripe

1
requirements.stripe.txt Normal file
View File

@@ -0,0 +1 @@
stripe==10.12.0 # Stripe

View File

@@ -14,6 +14,9 @@ with open("requirements.pg.txt") as f:
with open("requirements.auth0.txt") as f: with open("requirements.auth0.txt") as f:
auth0_requirements = f.read().splitlines() auth0_requirements = f.read().splitlines()
with open("requirements.stripe.txt") as f:
stripe_requirements = f.read().splitlines()
def get_latest_git_tag() -> str: def get_latest_git_tag() -> str:
try: try:
@@ -46,7 +49,8 @@ setup(
"build": build_requirements, "build": build_requirements,
"postgres": pg_requirements, "postgres": pg_requirements,
"auth0": auth0_requirements, "auth0": auth0_requirements,
"all": build_requirements + pg_requirements + auth0_requirements, "stripe": stripe_requirements,
"all": build_requirements + pg_requirements + auth0_requirements + stripe_requirements,
}, },
keywords=[ keywords=[
"creyPY", "creyPY",