build: add ruff and format code
This commit is contained in:
		
							parent
							
								
									afadffbaac
								
							
						
					
					
						commit
						9d24f79436
					
				
					 20 changed files with 122 additions and 60 deletions
				
			
		|  | @ -1,10 +1,8 @@ | ||||||
| from logging.config import fileConfig | from logging.config import fileConfig | ||||||
| 
 | 
 | ||||||
| from sqlalchemy import engine_from_config | from sqlalchemy import engine_from_config, pool | ||||||
| from sqlalchemy import pool |  | ||||||
| 
 | 
 | ||||||
| from alembic import context | from alembic import context | ||||||
| 
 |  | ||||||
| from foxnouns.db import Base | from foxnouns.db import Base | ||||||
| from foxnouns.db.sync import SYNC_DATABASE_URL | from foxnouns.db.sync import SYNC_DATABASE_URL | ||||||
| 
 | 
 | ||||||
|  | @ -70,9 +68,7 @@ def run_migrations_online() -> None: | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     with connectable.connect() as connection: |     with connectable.connect() as connection: | ||||||
|         context.configure( |         context.configure(connection=connection, target_metadata=target_metadata) | ||||||
|             connection=connection, target_metadata=target_metadata |  | ||||||
|         ) |  | ||||||
| 
 | 
 | ||||||
|         with context.begin_transaction(): |         with context.begin_transaction(): | ||||||
|             context.run_migrations() |             context.run_migrations() | ||||||
|  |  | ||||||
|  | @ -5,11 +5,12 @@ Revises: | ||||||
| Create Date: 2024-03-09 16:32:28.590145 | Create Date: 2024-03-09 16:32:28.590145 | ||||||
| 
 | 
 | ||||||
| """ | """ | ||||||
|  | 
 | ||||||
| from typing import Sequence, Union | from typing import Sequence, Union | ||||||
| 
 | 
 | ||||||
| from alembic import op |  | ||||||
| import sqlalchemy as sa | import sqlalchemy as sa | ||||||
| 
 | 
 | ||||||
|  | from alembic import op | ||||||
| 
 | 
 | ||||||
| # revision identifiers, used by Alembic. | # revision identifiers, used by Alembic. | ||||||
| revision: str = "b39613fd7327" | revision: str = "b39613fd7327" | ||||||
|  |  | ||||||
|  | @ -5,12 +5,14 @@ Revises: b39613fd7327 | ||||||
| Create Date: 2024-03-13 17:01:50.434602 | Create Date: 2024-03-13 17:01:50.434602 | ||||||
| 
 | 
 | ||||||
| """ | """ | ||||||
|  | 
 | ||||||
| from typing import Sequence, Union | from typing import Sequence, Union | ||||||
| 
 | 
 | ||||||
| from alembic import op |  | ||||||
| import sqlalchemy as sa | import sqlalchemy as sa | ||||||
| from sqlalchemy.dialects import postgresql | from sqlalchemy.dialects import postgresql | ||||||
| 
 | 
 | ||||||
|  | from alembic import op | ||||||
|  | 
 | ||||||
| # revision identifiers, used by Alembic. | # revision identifiers, used by Alembic. | ||||||
| revision: str = "0b63f7c8ab96" | revision: str = "0b63f7c8ab96" | ||||||
| down_revision: Union[str, None] = "b39613fd7327" | down_revision: Union[str, None] = "b39613fd7327" | ||||||
|  |  | ||||||
|  | @ -5,12 +5,14 @@ Revises: 0b63f7c8ab96 | ||||||
| Create Date: 2024-03-20 15:36:08.756635 | Create Date: 2024-03-20 15:36:08.756635 | ||||||
| 
 | 
 | ||||||
| """ | """ | ||||||
|  | 
 | ||||||
| from typing import Sequence, Union | from typing import Sequence, Union | ||||||
| 
 | 
 | ||||||
| from alembic import op |  | ||||||
| import sqlalchemy as sa | import sqlalchemy as sa | ||||||
| from sqlalchemy.dialects import postgresql | from sqlalchemy.dialects import postgresql | ||||||
| 
 | 
 | ||||||
|  | from alembic import op | ||||||
|  | 
 | ||||||
| # revision identifiers, used by Alembic. | # revision identifiers, used by Alembic. | ||||||
| revision: str = "1d8f8443a7f5" | revision: str = "1d8f8443a7f5" | ||||||
| down_revision: Union[str, None] = "0b63f7c8ab96" | down_revision: Union[str, None] = "0b63f7c8ab96" | ||||||
|  |  | ||||||
|  | @ -5,37 +5,43 @@ Revises: 1d8f8443a7f5 | ||||||
| Create Date: 2024-03-20 16:00:59.251354 | Create Date: 2024-03-20 16:00:59.251354 | ||||||
| 
 | 
 | ||||||
| """ | """ | ||||||
|  | 
 | ||||||
| from typing import Sequence, Union | from typing import Sequence, Union | ||||||
| 
 | 
 | ||||||
| from alembic import op |  | ||||||
| import sqlalchemy as sa | import sqlalchemy as sa | ||||||
| from sqlalchemy.dialects import postgresql | from sqlalchemy.dialects import postgresql | ||||||
| 
 | 
 | ||||||
|  | from alembic import op | ||||||
|  | 
 | ||||||
| # revision identifiers, used by Alembic. | # revision identifiers, used by Alembic. | ||||||
| revision: str = '17cc8cb77be5' | revision: str = "17cc8cb77be5" | ||||||
| down_revision: Union[str, None] = '1d8f8443a7f5' | down_revision: Union[str, None] = "1d8f8443a7f5" | ||||||
| branch_labels: Union[str, Sequence[str], None] = None | branch_labels: Union[str, Sequence[str], None] = None | ||||||
| depends_on: Union[str, Sequence[str], None] = None | depends_on: Union[str, Sequence[str], None] = None | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def upgrade() -> None: | def upgrade() -> None: | ||||||
|     # ### commands auto generated by Alembic - please adjust! ### |     # ### commands auto generated by Alembic - please adjust! ### | ||||||
|     op.create_table('members', |     op.create_table( | ||||||
|     sa.Column('id', sa.BigInteger(), nullable=False), |         "members", | ||||||
|     sa.Column('name', sa.Text(), nullable=False), |         sa.Column("id", sa.BigInteger(), nullable=False), | ||||||
|     sa.Column('display_name', sa.Text(), nullable=True), |         sa.Column("name", sa.Text(), nullable=False), | ||||||
|     sa.Column('bio', sa.Text(), nullable=True), |         sa.Column("display_name", sa.Text(), nullable=True), | ||||||
|     sa.Column('names', postgresql.JSONB(astext_type=sa.Text()), nullable=False), |         sa.Column("bio", sa.Text(), nullable=True), | ||||||
|     sa.Column('pronouns', postgresql.JSONB(astext_type=sa.Text()), nullable=False), |         sa.Column("names", postgresql.JSONB(astext_type=sa.Text()), nullable=False), | ||||||
|     sa.Column('fields', postgresql.JSONB(astext_type=sa.Text()), nullable=False), |         sa.Column("pronouns", postgresql.JSONB(astext_type=sa.Text()), nullable=False), | ||||||
|     sa.Column('user_id', sa.BigInteger(), nullable=False), |         sa.Column("fields", postgresql.JSONB(astext_type=sa.Text()), nullable=False), | ||||||
|     sa.ForeignKeyConstraint(['user_id'], ['users.id'], ), |         sa.Column("user_id", sa.BigInteger(), nullable=False), | ||||||
|     sa.PrimaryKeyConstraint('id') |         sa.ForeignKeyConstraint( | ||||||
|  |             ["user_id"], | ||||||
|  |             ["users.id"], | ||||||
|  |         ), | ||||||
|  |         sa.PrimaryKeyConstraint("id"), | ||||||
|     ) |     ) | ||||||
|     # ### end Alembic commands ### |     # ### end Alembic commands ### | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def downgrade() -> None: | def downgrade() -> None: | ||||||
|     # ### commands auto generated by Alembic - please adjust! ### |     # ### commands auto generated by Alembic - please adjust! ### | ||||||
|     op.drop_table('members') |     op.drop_table("members") | ||||||
|     # ### end Alembic commands ### |     # ### end Alembic commands ### | ||||||
|  |  | ||||||
|  | @ -5,11 +5,12 @@ Revises: 17cc8cb77be5 | ||||||
| Create Date: 2024-03-21 15:52:09.403257 | Create Date: 2024-03-21 15:52:09.403257 | ||||||
| 
 | 
 | ||||||
| """ | """ | ||||||
|  | 
 | ||||||
| from typing import Sequence, Union | from typing import Sequence, Union | ||||||
| 
 | 
 | ||||||
| from alembic import op |  | ||||||
| import sqlalchemy as sa | import sqlalchemy as sa | ||||||
| 
 | 
 | ||||||
|  | from alembic import op | ||||||
| 
 | 
 | ||||||
| # revision identifiers, used by Alembic. | # revision identifiers, used by Alembic. | ||||||
| revision: str = "a000d800f45f" | revision: str = "a000d800f45f" | ||||||
|  |  | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
| from quart import Quart, request, g | from quart import Quart, g, request | ||||||
| from quart_schema import QuartSchema, RequestSchemaValidationError | from quart_schema import QuartSchema, RequestSchemaValidationError | ||||||
| 
 | 
 | ||||||
| from .blueprints import users_blueprint, members_blueprint | from .blueprints import members_blueprint, users_blueprint | ||||||
| from .db.aio import async_session | from .db.aio import async_session | ||||||
| from .db.util import validate_token | from .db.util import validate_token | ||||||
| from .exceptions import ExpectedError | from .exceptions import ExpectedError | ||||||
|  |  | ||||||
|  | @ -1,14 +1,15 @@ | ||||||
| from functools import wraps | from functools import wraps | ||||||
|  | 
 | ||||||
| from quart import g | from quart import g | ||||||
| 
 | 
 | ||||||
| from foxnouns.exceptions import ForbiddenError, ErrorCode | from foxnouns.exceptions import ErrorCode, ForbiddenError | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def require_auth(*, scope: str | None = None): | def require_auth(*, scope: str | None = None): | ||||||
|     def decorator(func): |     def decorator(func): | ||||||
|         @wraps(func) |         @wraps(func) | ||||||
|         async def wrapper(*args, **kwargs): |         async def wrapper(*args, **kwargs): | ||||||
|             if not ("user" in g) or not ("token" in g): |             if "user" not in g or "token" not in g: | ||||||
|                 raise ForbiddenError("Not authenticated", type=ErrorCode.Forbidden) |                 raise ForbiddenError("Not authenticated", type=ErrorCode.Forbidden) | ||||||
| 
 | 
 | ||||||
|             if scope and not g.token.has_scope(scope): |             if scope and not g.token.has_scope(scope): | ||||||
|  |  | ||||||
|  | @ -1,2 +1,4 @@ | ||||||
| from .v2.users import bp as users_blueprint |  | ||||||
| from .v2.members import bp as members_blueprint | from .v2.members import bp as members_blueprint | ||||||
|  | from .v2.users import bp as users_blueprint | ||||||
|  | 
 | ||||||
|  | __all__ = [users_blueprint, members_blueprint] | ||||||
|  |  | ||||||
|  | @ -1,13 +1,12 @@ | ||||||
| from pydantic import Field | from pydantic import Field | ||||||
| from quart import Blueprint, g | from quart import Blueprint, g | ||||||
| from quart_schema import validate_response, validate_request | from quart_schema import validate_request, validate_response | ||||||
| from sqlalchemy import select |  | ||||||
| 
 | 
 | ||||||
| from foxnouns.auth import require_auth | from foxnouns.auth import require_auth | ||||||
| from foxnouns.db import Member | from foxnouns.db import Member | ||||||
| from foxnouns.db.aio import async_session | from foxnouns.db.aio import async_session | ||||||
| from foxnouns.db.util import user_from_ref, is_self | from foxnouns.db.util import user_from_ref | ||||||
| from foxnouns.exceptions import NotFoundError, ErrorCode | from foxnouns.exceptions import ErrorCode, NotFoundError | ||||||
| from foxnouns.models.member import FullMemberModel, MemberPatchModel | from foxnouns.models.member import FullMemberModel, MemberPatchModel | ||||||
| from foxnouns.settings import BASE_DOMAIN | from foxnouns.settings import BASE_DOMAIN | ||||||
| 
 | 
 | ||||||
|  | @ -50,6 +49,9 @@ async def create_member(data: MemberCreateModel): | ||||||
| 
 | 
 | ||||||
|         session.add(member) |         session.add(member) | ||||||
|         await session.commit() |         await session.commit() | ||||||
|  |         # This has to be fetched before we can pass the model to Pydantic. | ||||||
|  |         # In a normal SELECT this is automatically fetched, but because we just created the object, | ||||||
|  |         # we have to do it manually. | ||||||
|         await member.awaitable_attrs.user |         await member.awaitable_attrs.user | ||||||
| 
 | 
 | ||||||
|         return FullMemberModel.model_validate(member) |         return FullMemberModel.model_validate(member) | ||||||
|  |  | ||||||
|  | @ -1,16 +1,16 @@ | ||||||
| from pydantic import Field, field_validator | from pydantic import Field, field_validator | ||||||
| from quart import Blueprint, g | from quart import Blueprint, g | ||||||
| from quart_schema import validate_response, validate_request | from quart_schema import validate_request, validate_response | ||||||
| from sqlalchemy import select | from sqlalchemy import select | ||||||
| 
 | 
 | ||||||
| from foxnouns.auth import require_auth | from foxnouns.auth import require_auth | ||||||
| from foxnouns.db import User | from foxnouns.db import User | ||||||
| from foxnouns.db.aio import async_session | from foxnouns.db.aio import async_session | ||||||
| from foxnouns.db.snowflake import Snowflake | from foxnouns.db.snowflake import Snowflake | ||||||
| from foxnouns.db.util import user_from_ref, is_self, create_token, generate_token | from foxnouns.db.util import create_token, generate_token, is_self, user_from_ref | ||||||
| from foxnouns.exceptions import NotFoundError, ErrorCode | from foxnouns.exceptions import ErrorCode, NotFoundError | ||||||
| from foxnouns.models import BasePatchModel | from foxnouns.models import BasePatchModel | ||||||
| from foxnouns.models.user import UserModel, SelfUserModel, check_username | from foxnouns.models.user import SelfUserModel, UserModel, check_username | ||||||
| from foxnouns.settings import BASE_DOMAIN | from foxnouns.settings import BASE_DOMAIN | ||||||
| 
 | 
 | ||||||
| bp = Blueprint("users_v2", __name__) | bp = Blueprint("users_v2", __name__) | ||||||
|  |  | ||||||
|  | @ -1,3 +1,5 @@ | ||||||
| from .base import Base | from .base import Base | ||||||
| from .user import User, Token, AuthMethod, FediverseApp |  | ||||||
| from .member import Member | from .member import Member | ||||||
|  | from .user import AuthMethod, FediverseApp, Token, User | ||||||
|  | 
 | ||||||
|  | __all__ = [Base, User, Token, AuthMethod, FediverseApp, Member] | ||||||
|  |  | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| from sqlalchemy import URL | from sqlalchemy import URL | ||||||
| from sqlalchemy.ext.asyncio import create_async_engine, async_sessionmaker | from sqlalchemy.ext.asyncio import async_sessionmaker, create_async_engine | ||||||
| 
 | 
 | ||||||
| from foxnouns.settings import DATABASE, ECHO_SQL | from foxnouns.settings import DATABASE, ECHO_SQL | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| from typing import Any | from typing import Any | ||||||
| 
 | 
 | ||||||
| from sqlalchemy import Text, BigInteger, ForeignKey, Index, func, text | from sqlalchemy import BigInteger, ForeignKey, Index, Text, func, text | ||||||
| from sqlalchemy.dialects.postgresql import JSONB | from sqlalchemy.dialects.postgresql import JSONB | ||||||
| from sqlalchemy.orm import Mapped, mapped_column, relationship | from sqlalchemy.orm import Mapped, mapped_column, relationship | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,8 +1,8 @@ | ||||||
| from datetime import datetime |  | ||||||
| import enum | import enum | ||||||
|  | from datetime import datetime | ||||||
| from typing import Any | from typing import Any | ||||||
| 
 | 
 | ||||||
| from sqlalchemy import Text, Integer, BigInteger, ForeignKey, DateTime | from sqlalchemy import BigInteger, DateTime, ForeignKey, Integer, Text | ||||||
| from sqlalchemy.dialects.postgresql import ARRAY, JSONB | from sqlalchemy.dialects.postgresql import ARRAY, JSONB | ||||||
| from sqlalchemy.orm import Mapped, mapped_column, relationship | from sqlalchemy.orm import Mapped, mapped_column, relationship | ||||||
| 
 | 
 | ||||||
|  | @ -38,7 +38,9 @@ class User(Base): | ||||||
|         return f"User(id={self.id!r}, username={self.username!r})" |         return f"User(id={self.id!r}, username={self.username!r})" | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| from .member import Member | # Import Member here--it's needed for the back reference in User, but Member references User, so we can only import it | ||||||
|  | # after User is initialized. | ||||||
|  | from .member import Member  # noqa: E402 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class Token(Base): | class Token(Base): | ||||||
|  |  | ||||||
|  | @ -2,16 +2,17 @@ import datetime | ||||||
| 
 | 
 | ||||||
| from itsdangerous import BadSignature | from itsdangerous import BadSignature | ||||||
| from itsdangerous.url_safe import URLSafeTimedSerializer | from itsdangerous.url_safe import URLSafeTimedSerializer | ||||||
| from sqlalchemy.ext.asyncio import AsyncSession |  | ||||||
| from sqlalchemy import select, insert |  | ||||||
| from sqlalchemy.orm import selectinload |  | ||||||
| from quart import g | from quart import g | ||||||
|  | from sqlalchemy import insert, select | ||||||
|  | from sqlalchemy.ext.asyncio import AsyncSession | ||||||
|  | from sqlalchemy.orm import selectinload | ||||||
| 
 | 
 | ||||||
| from .user import User, Token | from foxnouns.exceptions import ErrorCode, ForbiddenError | ||||||
| from .member import Member |  | ||||||
| from foxnouns.exceptions import ForbiddenError, ErrorCode |  | ||||||
| from foxnouns.settings import SECRET_KEY | from foxnouns.settings import SECRET_KEY | ||||||
| 
 | 
 | ||||||
|  | from .member import Member | ||||||
|  | from .user import Token, User | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| async def user_from_ref(session: AsyncSession, user_ref: str): | async def user_from_ref(session: AsyncSession, user_ref: str): | ||||||
|     """Returns a user from a `user_ref` value. If `user_ref` is `@me`, returns the current user. |     """Returns a user from a `user_ref` value. If `user_ref` is `@me`, returns the current user. | ||||||
|  | @ -25,7 +26,7 @@ async def user_from_ref(session: AsyncSession, user_ref: str): | ||||||
|                 query = query.where(User.id == g.user.id) |                 query = query.where(User.id == g.user.id) | ||||||
|             else: |             else: | ||||||
|                 raise ForbiddenError( |                 raise ForbiddenError( | ||||||
|                     f"Missing scope 'user.read'", type=ErrorCode.MissingScope |                     "Missing scope 'user.read'", type=ErrorCode.MissingScope | ||||||
|                 ) |                 ) | ||||||
|         else: |         else: | ||||||
|             raise ForbiddenError("Not authenticated") |             raise ForbiddenError("Not authenticated") | ||||||
|  | @ -63,7 +64,7 @@ async def create_token(session: AsyncSession, user: User, scopes: list[str] = [" | ||||||
|     return await session.scalar(query) |     return await session.scalar(query) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| async def validate_token(session: AsyncSession, header: str) -> (Token, User): | async def validate_token(session: AsyncSession, header: str) -> tuple[Token, User]: | ||||||
|     try: |     try: | ||||||
|         token_id = serializer.loads(header) |         token_id = serializer.loads(header) | ||||||
|     except BadSignature: |     except BadSignature: | ||||||
|  |  | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
| from pydantic import Field | from pydantic import Field | ||||||
| 
 | 
 | ||||||
| from . import BaseSnowflakeModel | from . import BaseSnowflakeModel | ||||||
| from .fields import ProfileField, FieldEntry, PronounEntry | from .fields import FieldEntry, ProfileField, PronounEntry | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class BaseUserModel(BaseSnowflakeModel): | class BaseUserModel(BaseSnowflakeModel): | ||||||
|  |  | ||||||
							
								
								
									
										29
									
								
								poetry.lock
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										29
									
								
								poetry.lock
									
										
									
										generated
									
									
									
								
							|  | @ -1010,6 +1010,33 @@ async-timeout = {version = ">=4.0.3", markers = "python_full_version < \"3.11.3\ | ||||||
| hiredis = ["hiredis (>=1.0.0)"] | hiredis = ["hiredis (>=1.0.0)"] | ||||||
| ocsp = ["cryptography (>=36.0.1)", "pyopenssl (==20.0.1)", "requests (>=2.26.0)"] | ocsp = ["cryptography (>=36.0.1)", "pyopenssl (==20.0.1)", "requests (>=2.26.0)"] | ||||||
| 
 | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "ruff" | ||||||
|  | version = "0.3.4" | ||||||
|  | description = "An extremely fast Python linter and code formatter, written in Rust." | ||||||
|  | category = "dev" | ||||||
|  | optional = false | ||||||
|  | python-versions = ">=3.7" | ||||||
|  | files = [ | ||||||
|  |     {file = "ruff-0.3.4-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:60c870a7d46efcbc8385d27ec07fe534ac32f3b251e4fc44b3cbfd9e09609ef4"}, | ||||||
|  |     {file = "ruff-0.3.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:6fc14fa742e1d8f24910e1fff0bd5e26d395b0e0e04cc1b15c7c5e5fe5b4af91"}, | ||||||
|  |     {file = "ruff-0.3.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3ee7880f653cc03749a3bfea720cf2a192e4f884925b0cf7eecce82f0ce5854"}, | ||||||
|  |     {file = "ruff-0.3.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:cf133dd744f2470b347f602452a88e70dadfbe0fcfb5fd46e093d55da65f82f7"}, | ||||||
|  |     {file = "ruff-0.3.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3f3860057590e810c7ffea75669bdc6927bfd91e29b4baa9258fd48b540a4365"}, | ||||||
|  |     {file = "ruff-0.3.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:986f2377f7cf12efac1f515fc1a5b753c000ed1e0a6de96747cdf2da20a1b369"}, | ||||||
|  |     {file = "ruff-0.3.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4fd98e85869603e65f554fdc5cddf0712e352fe6e61d29d5a6fe087ec82b76c"}, | ||||||
|  |     {file = "ruff-0.3.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:64abeed785dad51801b423fa51840b1764b35d6c461ea8caef9cf9e5e5ab34d9"}, | ||||||
|  |     {file = "ruff-0.3.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:df52972138318bc7546d92348a1ee58449bc3f9eaf0db278906eb511889c4b50"}, | ||||||
|  |     {file = "ruff-0.3.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:98e98300056445ba2cc27d0b325fd044dc17fcc38e4e4d2c7711585bd0a958ed"}, | ||||||
|  |     {file = "ruff-0.3.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:519cf6a0ebed244dce1dc8aecd3dc99add7a2ee15bb68cf19588bb5bf58e0488"}, | ||||||
|  |     {file = "ruff-0.3.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:bb0acfb921030d00070539c038cd24bb1df73a2981e9f55942514af8b17be94e"}, | ||||||
|  |     {file = "ruff-0.3.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:cf187a7e7098233d0d0c71175375c5162f880126c4c716fa28a8ac418dcf3378"}, | ||||||
|  |     {file = "ruff-0.3.4-py3-none-win32.whl", hash = "sha256:af27ac187c0a331e8ef91d84bf1c3c6a5dea97e912a7560ac0cef25c526a4102"}, | ||||||
|  |     {file = "ruff-0.3.4-py3-none-win_amd64.whl", hash = "sha256:de0d5069b165e5a32b3c6ffbb81c350b1e3d3483347196ffdf86dc0ef9e37dd6"}, | ||||||
|  |     {file = "ruff-0.3.4-py3-none-win_arm64.whl", hash = "sha256:6810563cc08ad0096b57c717bd78aeac888a1bfd38654d9113cb3dc4d3f74232"}, | ||||||
|  |     {file = "ruff-0.3.4.tar.gz", hash = "sha256:f0f4484c6541a99862b693e13a151435a279b271cff20e37101116a21e2a1ad1"}, | ||||||
|  | ] | ||||||
|  | 
 | ||||||
| [[package]] | [[package]] | ||||||
| name = "six" | name = "six" | ||||||
| version = "1.16.0" | version = "1.16.0" | ||||||
|  | @ -1213,4 +1240,4 @@ h11 = ">=0.9.0,<1" | ||||||
| [metadata] | [metadata] | ||||||
| lock-version = "2.0" | lock-version = "2.0" | ||||||
| python-versions = "^3.11" | python-versions = "^3.11" | ||||||
| content-hash = "c4719965b47a0a85c480b6a26e0c7fd84d61e281a4bb012049fac9c61cd813df" | content-hash = "a04cf866b1b5efd1f9484114b0e5924947a4044c7b7e70127f042778246c0ce6" | ||||||
|  |  | ||||||
|  | @ -23,6 +23,12 @@ asyncpg = "^0.29.0" | ||||||
| environs = "^11.0.0" | environs = "^11.0.0" | ||||||
| alembic = "^1.13.1" | alembic = "^1.13.1" | ||||||
| 
 | 
 | ||||||
|  | [tool.poetry.group.dev] | ||||||
|  | optional = true | ||||||
|  | 
 | ||||||
|  | [tool.poetry.group.dev.dependencies] | ||||||
|  | ruff = "^0.3.4" | ||||||
|  | 
 | ||||||
| [tool.poetry.group.test] | [tool.poetry.group.test] | ||||||
| optional = true | optional = true | ||||||
| 
 | 
 | ||||||
|  | @ -30,11 +36,23 @@ optional = true | ||||||
| pytest = "^8.0.2" | pytest = "^8.0.2" | ||||||
| pytest-asyncio = "^0.23.5.post1" | pytest-asyncio = "^0.23.5.post1" | ||||||
| 
 | 
 | ||||||
|  | [tool.poe.tasks.dev] | ||||||
|  | help = "Run a development server with auto-reload" | ||||||
|  | cmd = "env QUART_APP=foxnouns.app:app quart --debug run --reload" | ||||||
|  | 
 | ||||||
|  | [tool.poe.tasks.server] | ||||||
|  | help = "Run a production server" | ||||||
|  | cmd = "uvicorn 'foxnouns.app:app'" | ||||||
|  | 
 | ||||||
|  | [tool.poe.tasks.migrate] | ||||||
|  | help = "Migrate the database to the latest revision" | ||||||
|  | cmd = "alembic upgrade head" | ||||||
|  | 
 | ||||||
| [tool.poe.tasks] | [tool.poe.tasks] | ||||||
| dev = "env QUART_APP=foxnouns.app:app quart --debug run --reload" |  | ||||||
| server = "uvicorn 'foxnouns.app:app'" |  | ||||||
| migrate = "alembic upgrade head" |  | ||||||
| test = "pytest" | test = "pytest" | ||||||
|  | lint = "ruff check" | ||||||
|  | format = "ruff format" | ||||||
|  | "sort-imports" = "ruff check --select I --fix " | ||||||
| 
 | 
 | ||||||
| [tool.pytest.ini_options] | [tool.pytest.ini_options] | ||||||
| addopts = ["--import-mode=importlib"] | addopts = ["--import-mode=importlib"] | ||||||
|  |  | ||||||
|  | @ -1,11 +1,10 @@ | ||||||
| import pytest | import pytest | ||||||
| import pytest_asyncio | import pytest_asyncio | ||||||
| from sqlalchemy import text, delete | from sqlalchemy import delete, text | ||||||
| 
 | 
 | ||||||
| from foxnouns.db import Base | from foxnouns.db import Base | ||||||
| from foxnouns.settings import DATABASE | from foxnouns.settings import DATABASE | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| # Override the database name to the testing database | # Override the database name to the testing database | ||||||
| DATABASE["NAME"] = f"{DATABASE['NAME']}_test" | DATABASE["NAME"] = f"{DATABASE['NAME']}_test" | ||||||
| 
 | 
 | ||||||
|  | @ -25,8 +24,8 @@ def pytest_collection_modifyitems(items): | ||||||
| def setup(): | def setup(): | ||||||
|     """Migrate the testing database to the latest migration, and once the tests complete, clear the database again.""" |     """Migrate the testing database to the latest migration, and once the tests complete, clear the database again.""" | ||||||
| 
 | 
 | ||||||
|     from foxnouns.db.sync import engine |  | ||||||
|     from alembic import command, config |     from alembic import command, config | ||||||
|  |     from foxnouns.db.sync import engine | ||||||
| 
 | 
 | ||||||
|     cfg = config.Config("alembic.ini") |     cfg = config.Config("alembic.ini") | ||||||
|     cfg.attributes["connection"] = engine.connect() |     cfg.attributes["connection"] = engine.connect() | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue